Another approach for unit tests

This commit is contained in:
Piotr Pekala 2019-03-06 07:54:56 -08:00
parent 2b0bb19f88
commit 42c0297daf
5 changed files with 143 additions and 64 deletions

View File

@ -32,6 +32,7 @@
<mat-form-field class="form-field">
<input
matInput
class="filename"
type="text"
[(ngModel)]="dockerTemplate.image"
formControlName="filename"
@ -45,6 +46,7 @@
<mat-form-field class="form-field">
<input
matInput
class="templatename"
type="text"
[(ngModel)]="dockerTemplate.name"
formControlName="templateName"
@ -57,6 +59,7 @@
<mat-form-field class="form-field">
<input
matInput
class="networkadapter"
type="number"
[(ngModel)]="dockerTemplate.adapters"
formControlName="adapters"
@ -92,7 +95,7 @@
</div>
<div class="buttons-bar">
<button mat-button class="cancel-button" (click)="goBack()">Cancel</button>
<button mat-raised-button color="primary" (click)="addTemplate()">Add template</button>
<button mat-raised-button class="add-button" color="primary" (click)="addTemplate()">Add template</button>
</div>
</div>
</div>

View File

@ -1,9 +1,9 @@
import { ComponentFixture, async, TestBed } from '@angular/core/testing';
import { MatInputModule, MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, MatSelectModule, MatFormFieldModule, MatAutocompleteModule, MatTableModule, MatStepperModule } from '@angular/material';
import { MatInputModule, MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, MatSelectModule, MatFormFieldModule, MatAutocompleteModule, MatTableModule, MatStepperModule, MatRadioModule, MatCommonModule } from '@angular/material';
import { CommonModule } from '@angular/common';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { RouterTestingModule } from '@angular/router/testing';
import { ActivatedRoute } from '@angular/router';
import { ActivatedRoute, Route } from '@angular/router';
import { of } from 'rxjs';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { MockedServerService } from '../../../../services/server.service.spec';
@ -13,11 +13,13 @@ import { ToasterService } from '../../../../services/toaster.service';
import { TemplateMocksService } from '../../../../services/template-mocks.service';
import { MockedToasterService } from '../../../../services/toaster.service.spec';
import { MockedActivatedRoute } from '../../preferences.component.spec';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { FormsModule, ReactiveFormsModule, AbstractControlDirective, FormControl } from '@angular/forms';
import { DockerTemplate } from '../../../../models/templates/docker-template';
import { AddDockerTemplateComponent } from './add-docker-template.component';
import { DockerService } from '../../../../services/docker.service';
import { DockerConfigurationService } from '../../../../services/docker-configuration.service';
import { StepperOrientation, STEPPER_GLOBAL_OPTIONS, STEP_STATE, CdkStep } from '@angular/cdk/stepper';
import { By } from '@angular/platform-browser';
export class MockedDockerService {
public addTemplate(server: Server, dockerTemplate: DockerTemplate) {
@ -36,76 +38,151 @@ describe('AddDockerTemplateComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [MatStepperModule, FormsModule, MatTableModule, MatAutocompleteModule, MatFormFieldModule, MatInputModule, ReactiveFormsModule, MatSelectModule, MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])],
imports: [
MatStepperModule,
MatAutocompleteModule,
MatCommonModule,
MatRadioModule,
FormsModule,
MatTableModule,
MatAutocompleteModule,
MatFormFieldModule,
MatInputModule,
ReactiveFormsModule,
MatSelectModule,
MatIconModule,
MatToolbarModule,
MatMenuModule,
MatCheckboxModule,
CommonModule,
NoopAnimationsModule,
RouterTestingModule.withRoutes([{path: 'server/1/preferences/docker/templates', component: AddDockerTemplateComponent}])
],
providers: [
{
provide: ActivatedRoute, useValue: activatedRoute
},
{ provide: ActivatedRoute, useValue: activatedRoute },
{ provide: ServerService, useValue: mockedServerService },
{ provide: DockerService, useValue: mockedDockerService },
{ provide: ToasterService, useValue: mockedToasterService},
{ provide: TemplateMocksService, useClass: TemplateMocksService },
{ provide: DockerConfigurationService, useClass: DockerConfigurationService }
{ provide: DockerConfigurationService, useClass: DockerConfigurationService },
{ provide: AbstractControlDirective, useExisting: FormControl, useMulti: true },
],
declarations: [
AddDockerTemplateComponent
],
schemas: [NO_ERRORS_SCHEMA]
]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AddDockerTemplateComponent);
component = fixture.componentInstance;
});
afterEach(() => {
fixture.destroy();
});
it('should open first step at start', async(() => {
fixture.detectChanges();
});
fixture.whenStable().then(() => {
let stepperComponent = fixture.debugElement
.query(By.css('mat-vertical-stepper')).componentInstance;
it('should create', () => {
expect(component).toBeTruthy();
expect(stepperComponent.selectedIndex).toBe(0);
});
}));
it('should call add template', () => {
it('should display correct label at start', async(() => {
fixture.detectChanges();
fixture.whenStable().then(() => {
let selectedLabel = fixture.nativeElement
.querySelector('[aria-selected="true"]');
expect(selectedLabel.textContent).toMatch('Server type');
});
}));
it('should not call add template when required fields are empty', async(() => {
fixture.detectChanges();
fixture.whenStable().then(() => {
let addButton = fixture.debugElement.nativeElement
.querySelector('.add-button');
spyOn(mockedDockerService, 'addTemplate').and.returnValue(of({} as DockerTemplate));
component.virtualMachineForm.controls['filename'].setValue('sample name');
component.containerNameForm.controls['templateName'].setValue('template name');
component.networkAdaptersForm.controls['adapters'].setValue(1);
component.server = {id: 1} as Server;
component.addTemplate();
addButton.click();
expect(mockedDockerService.addTemplate).not.toHaveBeenCalled();
});
}));
it('should call add template when required fields are filled', async(() => {
fixture.detectChanges();
fixture.whenStable().then(() => {
let stepperComponent = fixture.debugElement
.query(By.css('mat-vertical-stepper')).componentInstance;
stepperComponent.selectedIndex = 1;
component.newImageSelected = true;
fixture.detectChanges();
fixture.whenStable().then(() => {
let selectedLabel = fixture.nativeElement
.querySelector('[aria-selected="true"]');
expect(selectedLabel.textContent).toMatch('Docker Virtual Machine');
let filenameInput = fixture.debugElement.nativeElement
.querySelector('.filename');
filenameInput.value = 'sample filename';
filenameInput.dispatchEvent(new Event('input'));
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(component.dockerTemplate.image).toBe('sample filename');
stepperComponent.selectedIndex = 2;
fixture.detectChanges();
fixture.whenStable().then(() => {
selectedLabel = fixture.nativeElement
.querySelector('[aria-selected="true"]');
expect(selectedLabel.textContent).toMatch('Container name');
let templatenameInput = fixture.debugElement.nativeElement
.querySelector('.templatename');
templatenameInput.value = 'sample templatename';
templatenameInput.dispatchEvent(new Event('input'));
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(component.dockerTemplate.name).toBe('sample templatename');
stepperComponent.selectedIndex = 3;
fixture.detectChanges();
fixture.whenStable().then(() => {
selectedLabel = fixture.nativeElement
.querySelector('[aria-selected="true"]');
expect(selectedLabel.textContent).toMatch('Network adapters');
let networkadapterInput = fixture.debugElement.nativeElement
.querySelector('.networkadapter');
networkadapterInput.value = 2;
networkadapterInput.dispatchEvent(new Event('input'));
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(component.dockerTemplate.adapters).toBe(2);
let addButton = fixture.debugElement.nativeElement
.querySelector('.add-button');
spyOn(mockedDockerService, 'addTemplate').and.returnValue(of({} as DockerTemplate));
addButton.click();
expect(mockedDockerService.addTemplate).toHaveBeenCalled();
});
it('should not call add template when file name is missing', () => {
spyOn(mockedDockerService, 'addTemplate').and.returnValue(of({} as DockerTemplate));
component.containerNameForm.controls['templateName'].setValue('template name');
component.networkAdaptersForm.controls['adapters'].setValue(1);
component.server = {id: 1} as Server;
component.addTemplate();
expect(mockedDockerService.addTemplate).not.toHaveBeenCalled();
});
it('should not call add template when template name is missing', () => {
spyOn(mockedDockerService, 'addTemplate').and.returnValue(of({} as DockerTemplate));
component.virtualMachineForm.controls['filename'].setValue('sample name');
component.networkAdaptersForm.controls['adapters'].setValue(1);
component.server = {id: 1} as Server;
component.addTemplate();
expect(mockedDockerService.addTemplate).not.toHaveBeenCalled();
});
it('should not call add template when adapters field is empty', () => {
spyOn(mockedDockerService, 'addTemplate').and.returnValue(of({} as DockerTemplate));
component.virtualMachineForm.controls['filename'].setValue('sample name');
component.containerNameForm.controls['templateName'].setValue('template name');
component.server = {id: 1} as Server;
component.addTemplate();
expect(mockedDockerService.addTemplate).not.toHaveBeenCalled();
});
});
});
});
});
});
}));
});

View File

@ -85,7 +85,7 @@ export class AddDockerTemplateComponent implements OnInit {
}
addTemplate() {
if (!this.virtualMachineForm.invalid && !this.containerNameForm.invalid && !this.networkAdaptersForm.invalid) {
if ((!this.virtualMachineForm.invalid || !this.newImageSelected) && !this.containerNameForm.invalid && !this.networkAdaptersForm.invalid) {
this.dockerTemplate.template_id = uuid();
this.dockerService.addTemplate(this.server, this.dockerTemplate).subscribe((template: DockerTemplate) => {

View File

@ -11,7 +11,7 @@ import { ServerService } from '../../../../services/server.service';
import { Server } from '../../../../models/server';
import { MockedToasterService } from '../../../../services/toaster.service.spec';
import { ToasterService } from '../../../../services/toaster.service';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { FormsModule, ReactiveFormsModule, AbstractControlDirective, FormControl } from '@angular/forms';
import { MockedActivatedRoute } from '../../preferences.component.spec';
import { QemuTemplate } from '../../../../models/templates/qemu-template';
import { QemuVmTemplateDetailsComponent } from './qemu-vm-template-details.component';
@ -49,13 +49,12 @@ describe('QemuVmTemplateDetailsComponent', () => {
TestBed.configureTestingModule({
imports: [FormsModule, ReactiveFormsModule, MatTableModule, MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])],
providers: [
{
provide: ActivatedRoute, useValue: activatedRoute
},
{ provide: ActivatedRoute, useValue: activatedRoute },
{ provide: ServerService, useValue: mockedServerService },
{ provide: QemuService, useValue: mockedQemuService },
{ provide: ToasterService, useValue: mockedToasterService},
{ provide: QemuConfigurationService, useClass: QemuConfigurationService }
{ provide: QemuConfigurationService, useClass: QemuConfigurationService },
{ provide: AbstractControlDirective, useExisting: FormControl, useMulti: true }
],
declarations: [
QemuVmTemplateDetailsComponent

View File

@ -134,10 +134,10 @@ describe('ServerService', () => {
});
it('should call findAll', done => {
spyOn(db, 'getAll').and.returnValue(Promise.resolve(true));
spyOn(db, 'getAll').and.returnValue(Promise.resolve([]));
service.findAll().then(result => {
expect(result).toEqual(true);
expect(result).toEqual([]);
expect(db.getAll).toHaveBeenCalledWith('servers');
done();
});