diff --git a/client/src/app/instance/search/components/criteria/search-type/list.component.spec.ts b/client/src/app/instance/search/components/criteria/search-type/list.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..ea009ff97fffc95a0f6daa9090212ff192d258f5 --- /dev/null +++ b/client/src/app/instance/search/components/criteria/search-type/list.component.spec.ts @@ -0,0 +1,82 @@ +import { Component, ViewChild } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; + +import { ListComponent } from './list.component'; +import { ListCriterion } from '../../../../store/models/criterion'; + +describe('[Instance][Search][Component][Criteria][SearchType] ListComponent', () => { + @Component({ + selector: `app-host`, + template: ` + <app-list + [id]="id" + [label]="label" + [placeholder]="placeholder" + [criterion]="criterion"> + </app-list>` + }) + class TestHostComponent { + @ViewChild(ListComponent, { static: false }) + public testedComponent: ListComponent; + public id: number = undefined; + public label: string = undefined; + public placeholder: string = undefined; + public criterion: ListCriterion = undefined; + } + + let testHostComponent: TestHostComponent; + let testHostFixture: ComponentFixture<TestHostComponent>; + let testedComponent: ListComponent; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [ + ListComponent, + TestHostComponent + ], + imports: [ + FormsModule, + ReactiveFormsModule + ] + }); + testHostFixture = TestBed.createComponent(TestHostComponent); + testHostComponent = testHostFixture.componentInstance; + testHostFixture.detectChanges(); + testedComponent = testHostComponent.testedComponent; + }); + + it('should create the component', () => { + expect(testedComponent).toBeTruthy(); + }); + + it('should call ngOnChanges and apply changes', () => { + const spy = jest.spyOn(testedComponent, 'ngOnChanges'); + testHostComponent.criterion = { id: testedComponent.id, type: 'list', values: ['1', '2'] } as ListCriterion; + testHostFixture.detectChanges(); + expect(testedComponent.form.controls.list.value).toEqual('1\n2'); + expect(testedComponent.form.disabled).toBeTruthy(); + testHostComponent.criterion = undefined; + testHostFixture.detectChanges(); + expect(testedComponent.form.controls.list.value).toBeNull(); + expect(testedComponent.form.enabled).toBeTruthy(); + expect(spy).toHaveBeenCalledTimes(2); + }); + + it('#getPlaceholder() should fill the placeholder if defined', () => { + testedComponent.placeholder = 'placeholder'; + expect(testedComponent.getPlaceholder()).toEqual('placeholder'); + }); + + it('#getPlaceholder() should not fill the placeholder if not defined', () => { + expect(testedComponent.getPlaceholder()).toEqual(''); + }); + + it('raises the add criterion event when clicked', () => { + testedComponent.id = 1; + testedComponent.form.controls.list.setValue('1\n2'); + const expectedCriterion = { id: testedComponent.id, type: 'list', values: ['1', '2'] } as ListCriterion; + testedComponent.addCriterion.subscribe((event: ListCriterion) => expect(event).toEqual(expectedCriterion)); + testedComponent.emitAdd(); + }); +}); diff --git a/client/src/app/instance/search/components/criteria/search-type/list.component.ts b/client/src/app/instance/search/components/criteria/search-type/list.component.ts index 9887535bcc2efce141b4bb5695e7818bc6dd6c16..ed743f7918a81be046f8195abe5572f63cfe3c5b 100644 --- a/client/src/app/instance/search/components/criteria/search-type/list.component.ts +++ b/client/src/app/instance/search/components/criteria/search-type/list.component.ts @@ -12,16 +12,18 @@ import { FormGroup, FormControl, Validators } from '@angular/forms'; import { ListCriterion, Criterion } from 'src/app/instance/store/models'; +/** + * @class + * @classdesc List search type component. + * + * @implements OnChanges + */ @Component({ selector: 'app-list', templateUrl: 'list.component.html', styleUrls: ['operator.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, }) -/** - * @class - * @classdesc List search type component. - */ export class ListComponent implements OnChanges { @Input() id: number; @Input() label: string; @@ -34,7 +36,7 @@ export class ListComponent implements OnChanges { list: new FormControl('', [Validators.required]) }); - ngOnChanges(changes: SimpleChanges) { + ngOnChanges(changes: SimpleChanges): void { if (changes.criterion && changes.criterion.currentValue) { const criterion = changes.criterion.currentValue as ListCriterion; diff --git a/client/src/app/instance/search/components/criteria/search-type/operator.component.spec.ts b/client/src/app/instance/search/components/criteria/search-type/operator.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..e9eb1da2bc2117252644ee5cb66d7c73b3ab5d84 --- /dev/null +++ b/client/src/app/instance/search/components/criteria/search-type/operator.component.spec.ts @@ -0,0 +1,36 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { OperatorComponent } from './operator.component'; + +describe('[Instance][Search][Component][Criteria][SearchType] OperatorComponent', () => { + let component: OperatorComponent; + let fixture: ComponentFixture<OperatorComponent>; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [OperatorComponent] + }); + fixture = TestBed.createComponent(OperatorComponent); + component = fixture.componentInstance; + }); + + it('should create the component', () => { + expect(component).toBeTruthy(); + }); + + it('raises the changeOperator event when the value change', () => { + component.changeOperator.subscribe((event: string) => expect(event).toEqual('eq')); + component.emitChange('eq'); + }); + + it('#getLabel() should return the correct operator form label', () => { + expect(component.getLabel('eq')).toBe('='); + expect(component.getLabel('neq')).toBe('≠'); + expect(component.getLabel('gt')).toBe('>'); + expect(component.getLabel('gte')).toBe('>='); + expect(component.getLabel('lt')).toBe('<'); + expect(component.getLabel('lte')).toBe('<='); + expect(component.getLabel('lk')).toBe('like'); + expect(component.getLabel('nlk')).toBe('not like'); + }); +}); diff --git a/client/src/app/instance/search/components/criteria/search-type/operator.component.ts b/client/src/app/instance/search/components/criteria/search-type/operator.component.ts index 32b44df3a8c96a908f11fc7de304c549c724c417..1d0ac8665cd81ee5a454bf35a7d75eda1a686b56 100644 --- a/client/src/app/instance/search/components/criteria/search-type/operator.component.ts +++ b/client/src/app/instance/search/components/criteria/search-type/operator.component.ts @@ -9,16 +9,16 @@ import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy } from '@angular/core'; +/** + * @class + * @classdesc Operator component. + */ @Component({ selector: 'app-operator', templateUrl: 'operator.component.html', styleUrls: ['operator.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) -/** - * @class - * @classdesc Operator component. - */ export class OperatorComponent { @Input() operator: string; @Input() searchType: string; diff --git a/client/src/app/instance/search/components/criteria/search-type/radio.component.spec.ts b/client/src/app/instance/search/components/criteria/search-type/radio.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..c6abb7b3a56111ef3aa113622958b7fed939998c --- /dev/null +++ b/client/src/app/instance/search/components/criteria/search-type/radio.component.spec.ts @@ -0,0 +1,82 @@ +import { Component, Input, ViewChild } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; + +import { RadioComponent } from './radio.component'; +import { FieldCriterion } from '../../../../store/models/criterion'; +import { Option } from '../../../../../metamodel/models'; + +describe('[Instance][Search][Component][Criteria][SearchType] RadioComponent', () => { + @Component({ + selector: `app-host`, + template: ` + <app-radio + [id]="id" + [label]="label" + [operator]="operator" + [options]="options" + [criterion]="criterion"> + </app-radio>` + }) + class TestHostComponent { + @ViewChild(RadioComponent, { static: false }) + public testedComponent: RadioComponent; + public id: number = undefined; + public label: string = undefined; + public operator: string = undefined; + public options: Option[] = undefined; + public criterion: FieldCriterion = undefined; + } + + let testHostComponent: TestHostComponent; + let testHostFixture: ComponentFixture<TestHostComponent>; + let testedComponent: RadioComponent; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [ + RadioComponent, + TestHostComponent + ], + imports: [ + FormsModule, + ReactiveFormsModule + ] + }); + testHostFixture = TestBed.createComponent(TestHostComponent); + testHostComponent = testHostFixture.componentInstance; + testHostFixture.detectChanges(); + testedComponent = testHostComponent.testedComponent; + }); + + it('should create the component', () => { + expect(testedComponent).toBeTruthy(); + }); + + it('should call ngOnChanges and apply changes', () => { + const spy = jest.spyOn(testedComponent, 'ngOnChanges'); + testHostComponent.criterion = { id: 1, type: 'field', operator: 'eq', value: 'three' } as FieldCriterion; + testHostFixture.detectChanges(); + expect(testedComponent.form.controls.radio.value).toEqual('three'); + expect(testedComponent.form.disabled).toBeTruthy(); + testHostComponent.criterion = undefined; + testHostFixture.detectChanges(); + expect(testedComponent.form.controls.radio.value).toBeNull(); + expect(testedComponent.form.enabled).toBeTruthy(); + expect(spy).toHaveBeenCalledTimes(2); + }); + + it('raises the add criterion event when clicked', () => { + testedComponent.id = 1; + testedComponent.operator = 'eq'; + testedComponent.form.controls.radio.setValue('three'); + testedComponent.options = [ + { label: 'One', value: 'one', display: 1 }, + { label: 'Two', value: 'two', display: 2 }, + { label: 'Three', value: 'three', display: 3 } + ]; + const expectedCriterion = { id: testedComponent.id, type: 'field', operator: 'eq', value: 'three' } as FieldCriterion; + testedComponent.addCriterion.subscribe((event: FieldCriterion) => expect(event).toEqual(expectedCriterion)); + testedComponent.emitAdd(); + }); +}); diff --git a/client/src/app/instance/search/components/criteria/search-type/radio.component.ts b/client/src/app/instance/search/components/criteria/search-type/radio.component.ts index 8e43cccee5cade29d9444f838fac3baf1e4ac07c..c61794addbb6423d4f68eff16a84a2b09fe96d4c 100644 --- a/client/src/app/instance/search/components/criteria/search-type/radio.component.ts +++ b/client/src/app/instance/search/components/criteria/search-type/radio.component.ts @@ -13,15 +13,17 @@ import { FormGroup, FormControl, Validators } from '@angular/forms'; import { Criterion, FieldCriterion } from 'src/app/instance/store/models'; import { Option } from 'src/app/metamodel/models'; +/** + * @class + * @classdesc Radio search type component. + * + * @implements OnChanges + */ @Component({ selector: 'app-radio', templateUrl: 'radio.component.html', changeDetection: ChangeDetectionStrategy.OnPush }) -/** - * @class - * @classdesc Radio search type component. - */ export class RadioComponent implements OnChanges { @Input() id: number; @Input() operator: string; @@ -35,7 +37,7 @@ export class RadioComponent implements OnChanges { radio: new FormControl('', [Validators.required]) }); - ngOnChanges(changes: SimpleChanges) { + ngOnChanges(changes: SimpleChanges): void { if (changes.criterion && changes.criterion.currentValue) { const criterion = this.criterion as FieldCriterion; diff --git a/client/src/app/instance/search/components/criteria/search-type/select-multiple.component.spec.ts b/client/src/app/instance/search/components/criteria/search-type/select-multiple.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..b89f4fafbfe25557039c654e5176c4614ad1fa3f --- /dev/null +++ b/client/src/app/instance/search/components/criteria/search-type/select-multiple.component.spec.ts @@ -0,0 +1,88 @@ +import { Component, ViewChild } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; + +import { NgSelectModule } from '@ng-select/ng-select'; + +import { SelectMultipleComponent } from './select-multiple.component'; +import { SelectMultipleCriterion } from '../../../../store/models/criterion'; +import { Option } from '../../../../../metamodel/models'; + +describe('[Instance][Search][Component][Criteria][SearchType] SelectMultipleComponent', () => { + @Component({ + selector: `app-host`, + template: ` + <app-select-multiple + [id]="id" + [label]="label" + [options]="options" + [criterion]="criterion"> + </app-select-multiple>` + }) + class TestHostComponent { + @ViewChild(SelectMultipleComponent, { static: false }) + public testedComponent: SelectMultipleComponent; + public id: number = undefined; + public label: string = undefined; + public options: Option[] = undefined; + public criterion: SelectMultipleCriterion = undefined; + } + + let testHostComponent: TestHostComponent; + let testHostFixture: ComponentFixture<TestHostComponent>; + let testedComponent: SelectMultipleComponent; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [ + SelectMultipleComponent, + TestHostComponent + ], + imports: [ + NgSelectModule, + FormsModule, + ReactiveFormsModule + ] + }); + testHostFixture = TestBed.createComponent(TestHostComponent); + testHostComponent = testHostFixture.componentInstance; + testHostFixture.detectChanges(); + testedComponent = testHostComponent.testedComponent; + }); + + it('should create the component', () => { + expect(testedComponent).toBeTruthy(); + }); + + it('should call ngOnChanges and apply changes', () => { + const spy = jest.spyOn(testedComponent, 'ngOnChanges'); + const options: Option[] = [ + { label: 'One', value: 'one', display: 1 }, + { label: 'Two', value: 'two', display: 2 }, + { label: 'Three', value: 'three', display: 3 } + ]; + testHostComponent.criterion = { id: 1, type: 'multiple', options } as SelectMultipleCriterion; + testHostFixture.detectChanges(); + expect(testedComponent.form.controls.select.value).toEqual(['one', 'two', 'three']); + expect(testedComponent.form.disabled).toBeTruthy(); + testHostComponent.criterion = undefined; + testHostFixture.detectChanges(); + expect(testedComponent.form.controls.select.value).toBeNull(); + expect(testedComponent.form.enabled).toBeTruthy(); + expect(spy).toHaveBeenCalledTimes(2); + }); + + it('raises the add criterion event when clicked', () => { + testedComponent.id = 1; + testedComponent.options = [ + { label: 'One', value: 'one', display: 1 }, + { label: 'Two', value: 'two', display: 2 }, + { label: 'Three', value: 'three', display: 3 } + ]; + testedComponent.form.controls.select.setValue(['three']); + const expectedValue = [{ label: 'Three', value: 'three', display: 3 }]; + const expectedCriterion = { id: testedComponent.id, type: 'multiple', options: expectedValue } as SelectMultipleCriterion; + testedComponent.addCriterion.subscribe((event: SelectMultipleCriterion) => expect(event).toEqual(expectedCriterion)); + testedComponent.emitAdd(); + }); +}); diff --git a/client/src/app/instance/search/components/criteria/search-type/select-multiple.component.ts b/client/src/app/instance/search/components/criteria/search-type/select-multiple.component.ts index 650ac066033ccf4ed998fcdf689b7215f777edbf..630b13a0832e0f206bf8f402de667ee19d6843c8 100644 --- a/client/src/app/instance/search/components/criteria/search-type/select-multiple.component.ts +++ b/client/src/app/instance/search/components/criteria/search-type/select-multiple.component.ts @@ -13,16 +13,18 @@ import { FormGroup, FormControl, Validators } from '@angular/forms'; import { Criterion, SelectMultipleCriterion } from 'src/app/instance/store/models'; import { Option } from 'src/app/metamodel/models'; +/** + * @class + * @classdesc Select multiple search type component. + * + * @implements OnChanges + */ @Component({ selector: 'app-select-multiple', templateUrl: 'select-multiple.component.html', styleUrls: ['operator.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) -/** - * @class - * @classdesc Select multiple search type component. - */ export class SelectMultipleComponent implements OnChanges { @Input() id: number; @Input() label: string; @@ -35,7 +37,7 @@ export class SelectMultipleComponent implements OnChanges { select: new FormControl('', [Validators.required]) }); - ngOnChanges(changes: SimpleChanges) { + ngOnChanges(changes: SimpleChanges): void { if (changes.criterion && changes.criterion.currentValue) { const multipleCriterion = this.criterion as SelectMultipleCriterion; @@ -59,7 +61,7 @@ export class SelectMultipleComponent implements OnChanges { const values = this.form.value.select as string[]; const options = this.options.filter(option => values.includes(option.value)); - const ms = {id: this.id, type: 'multiple', options}; + const ms = { id: this.id, type: 'multiple', options }; this.addCriterion.emit(ms); } } diff --git a/client/src/app/instance/search/components/criteria/search-type/select.component.spec.ts b/client/src/app/instance/search/components/criteria/search-type/select.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..b4496d00f25b3d1efe1e88eaa6ca0968fa782b08 --- /dev/null +++ b/client/src/app/instance/search/components/criteria/search-type/select.component.spec.ts @@ -0,0 +1,108 @@ +import { Component, Input, ViewChild } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; + +import { NgSelectModule } from '@ng-select/ng-select'; +import { TooltipModule } from 'ngx-bootstrap/tooltip'; + +import { SelectComponent } from './select.component'; +import { FieldCriterion } from '../../../../store/models/criterion'; +import { Option } from '../../../../../metamodel/models'; + +describe('[Instance][Search][Component][Criteria][SearchType] SelectComponent', () => { + @Component({ + selector: `app-host`, + template: ` + <app-select + [id]="id" + [label]="label" + [operator]="operator" + [options]="options" + [criterion]="criterion" + [advancedForm]="advancedForm"> + </app-select>` + }) + class TestHostComponent { + @ViewChild(SelectComponent, { static: false }) + public testedComponent: SelectComponent; + public id: number = undefined; + public label: string = undefined; + public operator: string = undefined; + public options: Option[] = undefined; + public criterion: FieldCriterion = undefined; + public advancedForm: boolean = false; + } + + @Component({ selector: 'app-operator', template: '' }) + class OperatorStubComponent { + @Input() operator: string; + @Input() searchType: string; + @Input() advancedForm: boolean; + @Input() disabled: boolean; + } + + @Component({ selector: 'app-help-like', template: '' }) + class HelpLikeStubComponent { } + + let testHostComponent: TestHostComponent; + let testHostFixture: ComponentFixture<TestHostComponent>; + let testedComponent: SelectComponent; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [ + SelectComponent, + TestHostComponent, + OperatorStubComponent, + HelpLikeStubComponent + ], + imports: [ + NgSelectModule, + FormsModule, + ReactiveFormsModule, + TooltipModule.forRoot() + ] + }); + testHostFixture = TestBed.createComponent(TestHostComponent); + testHostComponent = testHostFixture.componentInstance; + testHostFixture.detectChanges(); + testedComponent = testHostComponent.testedComponent; + }); + + it('should create the component', () => { + expect(testedComponent).toBeTruthy(); + }); + + it('should call ngOnChanges and apply changes', () => { + const spy = jest.spyOn(testedComponent, 'ngOnChanges'); + testHostComponent.criterion = { id: 1, type: 'field', operator: 'eq', value: 'three' } as FieldCriterion; + testHostFixture.detectChanges(); + expect(testedComponent.form.controls.select.value).toEqual('three'); + expect(testedComponent.form.disabled).toBeTruthy(); + testHostComponent.criterion = undefined; + testHostFixture.detectChanges(); + expect(testedComponent.form.controls.select.value).toBeNull(); + expect(testedComponent.form.enabled).toBeTruthy(); + expect(spy).toHaveBeenCalledTimes(2); + }); + + it('#changeOperator() should change the operator', () => { + expect(testedComponent.operator).toBeUndefined(); + testedComponent.changeOperator('toto'); + expect(testedComponent.operator).toBe('toto'); + }); + + it('raises the add criterion event when clicked', () => { + testedComponent.id = 1; + testedComponent.operator = 'eq'; + testedComponent.form.controls.select.setValue('three'); + testedComponent.options = [ + { label: 'One', value: 'one', display: 1 }, + { label: 'Two', value: 'two', display: 2 }, + { label: 'Three', value: 'three', display: 3 } + ]; + const expectedCriterion = { id: testedComponent.id, type: 'field', operator: 'eq', value: 'three' } as FieldCriterion; + testedComponent.addCriterion.subscribe((event: FieldCriterion) => expect(event).toEqual(expectedCriterion)); + testedComponent.emitAdd(); + }); +}); diff --git a/client/src/app/instance/search/components/criteria/search-type/select.component.ts b/client/src/app/instance/search/components/criteria/search-type/select.component.ts index 26dda32e7688634cf7a2dd823f9bb8fff8577621..489df7ea805eaf4c8435f6bec53a3687a960e1a8 100644 --- a/client/src/app/instance/search/components/criteria/search-type/select.component.ts +++ b/client/src/app/instance/search/components/criteria/search-type/select.component.ts @@ -13,15 +13,17 @@ import { FormGroup, FormControl, Validators } from '@angular/forms'; import { Criterion, FieldCriterion } from 'src/app/instance/store/models'; import { Option } from 'src/app/metamodel/models'; +/** + * @class + * @classdesc Select search type component. + * + * @implements OnChanges + */ @Component({ selector: 'app-select', templateUrl: 'select.component.html', changeDetection: ChangeDetectionStrategy.OnPush }) -/** - * @class - * @classdesc Select search type component. - */ export class SelectComponent implements OnChanges { @Input() id: number; @Input() operator: string; @@ -38,7 +40,7 @@ export class SelectComponent implements OnChanges { disabledOperator: boolean; - ngOnChanges(changes: SimpleChanges) { + ngOnChanges(changes: SimpleChanges): void { if (changes.criterion && changes.criterion.currentValue) { this.form.controls.select.setValue(changes.criterion.currentValue.value); this.form.disable(); diff --git a/client/src/app/instance/search/components/criteria/search-type/time.component.spec.ts b/client/src/app/instance/search/components/criteria/search-type/time.component.spec.ts index d5f3df138867e78e65dc1c4330a28b1aa2c248ab..4b627ac6599797d1a5edddabef980fc023e66cd3 100644 --- a/client/src/app/instance/search/components/criteria/search-type/time.component.spec.ts +++ b/client/src/app/instance/search/components/criteria/search-type/time.component.spec.ts @@ -1,16 +1,34 @@ -import { Component, Input } from '@angular/core'; +import { Component, Input, ViewChild } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { FormsModule, ReactiveFormsModule, FormControl } from '@angular/forms'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; - -import { AccordionModule } from 'ngx-bootstrap/accordion'; +import { NgSelectModule } from '@ng-select/ng-select'; import { TimeComponent } from './time.component'; -import { NgSelectModule } from '@ng-select/ng-select'; import { FieldCriterion } from '../../../../store/models/criterion'; describe('[Instance][Search][Component][Criteria][SearchType] TimeComponent', () => { + @Component({ + selector: `app-host`, + template: ` + <app-time + [id]="id" + [label]="label" + [operator]="operator" + [criterion]="criterion" + [advancedForm]="advancedForm"> + </app-time>` + }) + class TestHostComponent { + @ViewChild(TimeComponent, { static: false }) + public testedComponent: TimeComponent; + public id: number = undefined; + public label: string = undefined; + public operator: string = undefined; + public criterion: FieldCriterion = undefined; + public advancedForm: boolean = false; + } + @Component({ selector: 'app-operator', template: '' }) class OperatorStubComponent { @Input() operator: string; @@ -19,13 +37,15 @@ describe('[Instance][Search][Component][Criteria][SearchType] TimeComponent', () @Input() disabled: boolean; } - let component: TimeComponent; - let fixture: ComponentFixture<TimeComponent>; + let testHostComponent: TestHostComponent; + let testHostFixture: ComponentFixture<TestHostComponent>; + let testedComponent: TimeComponent; beforeEach(() => { TestBed.configureTestingModule({ declarations: [ TimeComponent, + TestHostComponent, OperatorStubComponent ], imports: [ @@ -34,34 +54,51 @@ describe('[Instance][Search][Component][Criteria][SearchType] TimeComponent', () ReactiveFormsModule ] }); - fixture = TestBed.createComponent(TimeComponent); - component = fixture.componentInstance; + testHostFixture = TestBed.createComponent(TestHostComponent); + testHostComponent = testHostFixture.componentInstance; + testHostFixture.detectChanges(); + testedComponent = testHostComponent.testedComponent; }); it('should create the component', () => { - expect(component).toBeTruthy(); + expect(testedComponent).toBeTruthy(); + }); + + it('should call ngOnChanges and apply changes', () => { + const spy = jest.spyOn(testedComponent, 'ngOnChanges'); + testHostComponent.criterion = { id: 1, type: 'field', operator: 'eq', value: '15:47' } as FieldCriterion; + testHostFixture.detectChanges(); + expect(testedComponent.form.controls.hh.value).toEqual('15'); + expect(testedComponent.form.controls.mm.value).toEqual('47'); + expect(testedComponent.form.disabled).toBeTruthy(); + testHostComponent.criterion = undefined; + testHostFixture.detectChanges(); + expect(testedComponent.form.controls.hh.value).toBeNull(); + expect(testedComponent.form.controls.hh.value).toBeNull(); + expect(testedComponent.form.enabled).toBeTruthy(); + expect(spy).toHaveBeenCalledTimes(2); }); it('#changeOperator() should change the operator', () => { - expect(component.operator).toBeUndefined(); - component.changeOperator('toto'); - expect(component.operator).toBe('toto'); + expect(testedComponent.operator).toBeUndefined(); + testedComponent.changeOperator('toto'); + expect(testedComponent.operator).toBe('toto'); }); it('raises the add criterion event when clicked', () => { - component.id = 1; + testedComponent.id = 1; const operator = 'eq'; - component.operator = operator; - component.form.controls.hh.setValue('15'); - component.form.controls.mm.setValue('47'); - const expectedCriterion = { id: component.id, type: 'field', operator, value: '15:47' } as FieldCriterion; - component.addCriterion.subscribe((event: FieldCriterion) => expect(event).toEqual(expectedCriterion)); - component.emitAdd(); + testedComponent.operator = operator; + testedComponent.form.controls.hh.setValue('15'); + testedComponent.form.controls.mm.setValue('47'); + const expectedCriterion = { id: testedComponent.id, type: 'field', operator, value: '15:47' } as FieldCriterion; + testedComponent.addCriterion.subscribe((event: FieldCriterion) => expect(event).toEqual(expectedCriterion)); + testedComponent.emitAdd(); }); it('#initTime(t) should return an array of string with 2 digits from 0 to t', () => { const n = 10; - expect(component.initTime(n).length).toEqual(n); - expect(component.initTime(n)[5]).toEqual('05'); + expect(testedComponent.initTime(n).length).toEqual(n); + expect(testedComponent.initTime(n)[5]).toEqual('05'); }); }); diff --git a/client/src/app/instance/search/components/criteria/search-type/time.component.ts b/client/src/app/instance/search/components/criteria/search-type/time.component.ts index 9205c7a6b7213e232fe1d286b0d7254412b9ec1e..8c4a4e59675063866f499f8cfe963644fb2f7175 100644 --- a/client/src/app/instance/search/components/criteria/search-type/time.component.ts +++ b/client/src/app/instance/search/components/criteria/search-type/time.component.ts @@ -43,7 +43,7 @@ export class TimeComponent implements OnChanges { mm: new FormControl('', [Validators.required]) }); - ngOnChanges(changes: SimpleChanges) { + ngOnChanges(changes: SimpleChanges): void { if (changes.criterion && changes.criterion.currentValue) { const criterion = changes.criterion.currentValue as FieldCriterion;