From 070d0e234878356d885bce630243168ba6bf40a3 Mon Sep 17 00:00:00 2001
From: Tifenn Guillas <tifenn.guillas@gmail.com>
Date: Mon, 4 Oct 2021 15:49:13 +0200
Subject: [PATCH] WIP: Tests on search output components

---
 .../output/output-by-family.component.html    |   2 +-
 .../output/output-by-family.component.spec.ts | 292 ++++++++++++++++++
 .../output/output-by-family.component.ts      |  18 +-
 .../output/output-tabs.component.html         |   2 +-
 .../output/output-tabs.component.spec.ts      |  41 +++
 .../output/output-tabs.component.ts           |  12 +-
 6 files changed, 347 insertions(+), 20 deletions(-)
 create mode 100644 client/src/app/instance/search/components/output/output-by-family.component.spec.ts
 create mode 100644 client/src/app/instance/search/components/output/output-tabs.component.spec.ts

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 e4acc92e..b880a0bb 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 00000000..7fad3c92
--- /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 331058f4..522f090c 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 b90fc7bf..75cdf72a 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 00000000..6dc16a10
--- /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 6bf1afef..28cdb42f 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) { }
 }
-- 
GitLab