diff --git a/client/src/app/instance/search/components/output/output-by-family.component.html b/client/src/app/instance/search/components/output/output-by-family.component.html index e4acc92e4ef7ec35c395e3475237bd9f03edd687..b880a0bbcee55e3f10209d38eee79ed8dc96f0ab 100644 --- a/client/src/app/instance/search/components/output/output-by-family.component.html +++ b/client/src/app/instance/search/components/output/output-by-family.component.html @@ -1,5 +1,5 @@ <div class="row"> - <div *ngFor="let category of getCategoryByFamilySortedByDisplay(outputFamily.id)" + <div *ngFor="let category of getCategoryListByFamily(outputFamily.id)" class="col-12 col-md-6 my-3 text-center"> <app-output-by-category [categoryLabel]="category.label" diff --git a/client/src/app/instance/search/components/output/output-by-family.component.spec.ts b/client/src/app/instance/search/components/output/output-by-family.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..7fad3c926399eb7bf234e96ce687776ab64043b9 --- /dev/null +++ b/client/src/app/instance/search/components/output/output-by-family.component.spec.ts @@ -0,0 +1,292 @@ +import { Component, Input } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; + +import { AccordionModule } from 'ngx-bootstrap/accordion'; + +import { OutputByFamilyComponent } from './output-by-family.component'; +import { Attribute, OutputCategory, OutputFamily } from '../../../../metamodel/models'; + +describe('[Instance][Search][Component][Output] OutputByFamilyComponent', () => { + @Component({ selector: 'app-output-by-category', template: '' }) + class OutputByCategoryStubComponent { + @Input() categoryLabel: string; + @Input() attributeList: Attribute[]; + @Input() outputList: number[]; + @Input() designColor: string; + @Input() isAllSelected: boolean; + @Input() isAllUnselected: boolean; + } + + let component: OutputByFamilyComponent; + let fixture: ComponentFixture<OutputByFamilyComponent>; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [ + OutputByFamilyComponent, + OutputByCategoryStubComponent + ], + imports: [ + AccordionModule.forRoot(), + BrowserAnimationsModule + ] + }); + fixture = TestBed.createComponent(OutputByFamilyComponent); + component = fixture.componentInstance; + }); + + it('should create the component', () => { + expect(component).toBeTruthy(); + }); + + it('#getCategoryListByFamily(idFamily) should return categories belonging to idFamily', () => { + component.outputCategoryList = [ + { + id: 1, + label: 'Another output category', + display: 20, + id_output_family: 1 + }, + { + id: 3, + label: 'The last output category', + display: 10, + id_output_family: 2 + }, + { + id: 2, + label: 'Default output category', + display: 10, + id_output_family: 1 + } + ]; + const sortedCategoryList: OutputCategory[] = component.getCategoryListByFamily(1); + expect(sortedCategoryList.length).toBe(2); + expect(sortedCategoryList[0].id).not.toBe(3); + expect(sortedCategoryList[1].id).not.toBe(3); + }); + + it('#getAttributeByCategory(idCategory) should return attributes belonging to idCategory', () => { + component.attributeList = [ + { + id: 2, + name: 'name_two', + label: 'label_two', + form_label: 'form_label_two', + description : 'description_two', + output_display: 1, + criteria_display: 1, + search_flag : 'SPECTRUM_1D', + search_type : 'field', + operator : '=', + type: '', + display_detail: 1, + id_output_category: 2 + }, + { + id: 1, + name: 'name_one', + label: 'label_one', + form_label: 'form_label_one', + description: 'description_one', + output_display: 2, + criteria_display: 2, + search_flag: 'ID', + search_type: 'field', + operator: '=', + type: 'integer', + display_detail: 2, + id_output_category: 1 + } + ]; + expect(component.getAttributeByCategory(1).length).toBe(1); + expect(component.getAttributeByCategory(1)[0].id).toBe(1); + }); + + it('#getIsAllSelected(idCategory) should return true if all outputs of idCategory are selected', () => { + component.attributeList = [ + { + id: 2, + name: 'name_two', + label: 'label_two', + form_label: 'form_label_two', + description : 'description_two', + output_display: 1, + criteria_display: 1, + search_flag : 'SPECTRUM_1D', + search_type : 'field', + operator : '=', + type: '', + display_detail: 1, + id_output_category: 1 + }, + { + id: 1, + name: 'name_one', + label: 'label_one', + form_label: 'form_label_one', + description: 'description_one', + output_display: 2, + criteria_display: 2, + search_flag: 'ID', + search_type: 'field', + operator: '=', + type: 'integer', + display_detail: 2, + id_output_category: 1 + } + ]; + component.outputList = [1, 2]; + expect(component.getIsAllSelected(1)).toBeTruthy(); + }); + + it('#getIsAllSelected(idCategory) should return false if not all outputs of idCategory are selected', () => { + component.attributeList = [ + { + id: 2, + name: 'name_two', + label: 'label_two', + form_label: 'form_label_two', + description : 'description_two', + output_display: 1, + criteria_display: 1, + search_flag : 'SPECTRUM_1D', + search_type : 'field', + operator : '=', + type: '', + display_detail: 1, + id_output_category: 1 + }, + { + id: 1, + name: 'name_one', + label: 'label_one', + form_label: 'form_label_one', + description: 'description_one', + output_display: 2, + criteria_display: 2, + search_flag: 'ID', + search_type: 'field', + operator: '=', + type: 'integer', + display_detail: 2, + id_output_category: 1 + } + ]; + component.outputList = [1]; + expect(component.getIsAllSelected(1)).toBeFalsy(); + }); + + it('#getIsAllUnselected(idCategory) should return true if all outputs of idCategory are not selected', () => { + component.attributeList = [ + { + id: 2, + name: 'name_two', + label: 'label_two', + form_label: 'form_label_two', + description : 'description_two', + output_display: 1, + criteria_display: 1, + search_flag : 'SPECTRUM_1D', + search_type : 'field', + operator : '=', + type: '', + display_detail: 1, + id_output_category: 1 + }, + { + id: 1, + name: 'name_one', + label: 'label_one', + form_label: 'form_label_one', + description: 'description_one', + output_display: 2, + criteria_display: 2, + search_flag: 'ID', + search_type: 'field', + operator: '=', + type: 'integer', + display_detail: 2, + id_output_category: 1 + } + ]; + component.outputList = []; + expect(component.getIsAllUnselected(1)).toBeTruthy(); + }); + + it('#getIsAllUnselected(idCategory) should return false if not all outputs of idCategory are not selected', () => { + component.attributeList = [ + { + id: 2, + name: 'name_two', + label: 'label_two', + form_label: 'form_label_two', + description : 'description_two', + output_display: 1, + criteria_display: 1, + search_flag : 'SPECTRUM_1D', + search_type : 'field', + operator : '=', + type: '', + display_detail: 1, + id_output_category: 1 + }, + { + id: 1, + name: 'name_one', + label: 'label_one', + form_label: 'form_label_one', + description: 'description_one', + output_display: 2, + criteria_display: 2, + search_flag: 'ID', + search_type: 'field', + operator: '=', + type: 'integer', + display_detail: 2, + id_output_category: 1 + } + ]; + component.outputList = [1]; + expect(component.getIsAllUnselected(1)).toBeFalsy(); + }); + + it('#emitChange(outputList) should raise change event', () => { + component.attributeList = [ + { + id: 2, + name: 'name_two', + label: 'label_two', + form_label: 'form_label_two', + description : 'description_two', + output_display: 1, + criteria_display: 1, + search_flag : 'SPECTRUM_1D', + search_type : 'field', + operator : '=', + type: '', + display_detail: 1, + id_output_category: 1 + }, + { + id: 1, + name: 'name_one', + label: 'label_one', + form_label: 'form_label_one', + description: 'description_one', + output_display: 2, + criteria_display: 2, + search_flag: 'ID', + search_type: 'field', + operator: '=', + type: 'integer', + display_detail: 2, + id_output_category: 1 + } + ]; + const expectedOutputList = [1]; + component.change.subscribe((event: number[]) => expect(event).toEqual(expectedOutputList)); + component.emitChange([1]); + }); +}); diff --git a/client/src/app/instance/search/components/output/output-by-family.component.ts b/client/src/app/instance/search/components/output/output-by-family.component.ts index 331058f4052dcfda301b16856e7c8527164b96ce..522f090ccb589a067c04f402608b92730a5b824a 100644 --- a/client/src/app/instance/search/components/output/output-by-family.component.ts +++ b/client/src/app/instance/search/components/output/output-by-family.component.ts @@ -11,15 +11,15 @@ import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy } from import { OutputFamily, OutputCategory, Attribute } from 'src/app/metamodel/models'; +/** + * @class + * @classdesc Search output by family component. + */ @Component({ selector: 'app-output-by-family', templateUrl: 'output-by-family.component.html', changeDetection: ChangeDetectionStrategy.OnPush }) -/** - * @class - * @classdesc Search output by family component. - */ export class OutputByFamilyComponent { @Input() outputFamily: OutputFamily; @Input() outputCategoryList: OutputCategory[]; @@ -29,15 +29,14 @@ export class OutputByFamilyComponent { @Output() change: EventEmitter<number[]> = new EventEmitter(); /** - * Returns category list sorted by display, for the given output family ID. + * Returns category list for the given output family ID. * * @param {number} idFamily - The output family ID. * * @return Category[] */ - getCategoryByFamilySortedByDisplay(idFamily: number): OutputCategory[] { - return this.outputCategoryList - .filter(category => category.id_output_family === idFamily); + getCategoryListByFamily(idFamily: number): OutputCategory[] { + return this.outputCategoryList.filter(category => category.id_output_family === idFamily); } /** @@ -48,8 +47,7 @@ export class OutputByFamilyComponent { * @return Attribute[] */ getAttributeByCategory(idCategory: number): Attribute[] { - return this.attributeList - .filter(attribute => attribute.id_output_category === idCategory); + return this.attributeList.filter(attribute => attribute.id_output_category === idCategory); } /** diff --git a/client/src/app/instance/search/components/output/output-tabs.component.html b/client/src/app/instance/search/components/output/output-tabs.component.html index b90fc7bfb85065a187230e8cdb22202d2a304f73..75cdf72a8d795ec48d473b0c22642316adf09677 100644 --- a/client/src/app/instance/search/components/output/output-tabs.component.html +++ b/client/src/app/instance/search/components/output/output-tabs.component.html @@ -8,7 +8,7 @@ <span *ngIf="!ag.isOpen"><span class="fas fa-chevron-down"></span></span> </span> </button> - <app-output-by-family + <app-output-by-family [outputFamily]="family" [attributeList]="attributeList" [outputCategoryList]="outputCategoryList" diff --git a/client/src/app/instance/search/components/output/output-tabs.component.spec.ts b/client/src/app/instance/search/components/output/output-tabs.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..6dc16a108f534430de9e55f6e04ab79856d3fbf5 --- /dev/null +++ b/client/src/app/instance/search/components/output/output-tabs.component.spec.ts @@ -0,0 +1,41 @@ +import { Component, Input } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; + +import { AccordionModule } from 'ngx-bootstrap/accordion'; + +import { OutputTabsComponent } from './output-tabs.component'; +import { Attribute, OutputCategory, OutputFamily } from '../../../../metamodel/models'; + +describe('[Instance][Search][Component][Output] OutputTabsComponent', () => { + @Component({ selector: 'app-output-by-family', template: '' }) + class OutputByFamilyStubComponent { + @Input() outputFamily: OutputFamily; + @Input() outputCategoryList: OutputCategory[]; + @Input() attributeList: Attribute[]; + @Input() outputList: number[]; + @Input() designColor: string; + } + + let component: OutputTabsComponent; + let fixture: ComponentFixture<OutputTabsComponent>; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [ + OutputTabsComponent, + OutputByFamilyStubComponent + ], + imports: [ + AccordionModule.forRoot(), + BrowserAnimationsModule + ] + }); + fixture = TestBed.createComponent(OutputTabsComponent); + component = fixture.componentInstance; + }); + + it('should create the component', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/client/src/app/instance/search/components/output/output-tabs.component.ts b/client/src/app/instance/search/components/output/output-tabs.component.ts index 6bf1afefdd5168956fdf19f7833a206f92706464..28cdb42f1657d686e11d1954b6eb5b2606e4db00 100644 --- a/client/src/app/instance/search/components/output/output-tabs.component.ts +++ b/client/src/app/instance/search/components/output/output-tabs.component.ts @@ -9,19 +9,17 @@ import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy } from '@angular/core'; -import { ToastrService } from 'ngx-toastr'; - import { OutputFamily, OutputCategory, Attribute } from 'src/app/metamodel/models'; +/** + * @class + * @classdesc Search output tabs component. + */ @Component({ selector: 'app-output-tabs', templateUrl: 'output-tabs.component.html', changeDetection: ChangeDetectionStrategy.OnPush }) -/** - * @class - * @classdesc Search output tab component. - */ export class OutputTabsComponent { @Input() outputFamilyList: OutputFamily[]; @Input() outputCategoryList: OutputCategory[]; @@ -29,6 +27,4 @@ export class OutputTabsComponent { @Input() outputList: number[]; @Input() designColor: string; @Output() change: EventEmitter<number[]> = new EventEmitter(); - - constructor(private toastr: ToastrService) { } }