diff --git a/client/src/app/instance/search-multiple/components/datasets/dataset-list.component.spec.ts b/client/src/app/instance/search-multiple/components/datasets/dataset-list.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..a3d293e62fa7b846ca8684ae45e809d37bbab8b7 --- /dev/null +++ b/client/src/app/instance/search-multiple/components/datasets/dataset-list.component.spec.ts @@ -0,0 +1,79 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { Component, Input } from '@angular/core'; + +import { TooltipModule } from 'ngx-bootstrap/tooltip'; + +import { DatasetListComponent } from './dataset-list.component'; +import { DATASET_FAMILY_LIST, DATASET_LIST } from '../../../../../test-data'; +import { Dataset, DatasetFamily, Survey } from '../../../../metamodel/models'; + +describe('[Instance][SearchMultiple][Component][Datasets] DatasetListComponent', () => { + @Component({ selector: 'app-datasets-by-family', template: '' }) + class DatasetsByFamilyStubComponent { + @Input() datasetFamily: DatasetFamily; + @Input() datasetList: Dataset[]; + @Input() surveyList: Survey[]; + @Input() selectedDatasets: string[]; + @Input() isAllSelected: boolean; + @Input() isAllUnselected: boolean; + } + + let component: DatasetListComponent; + let fixture: ComponentFixture<DatasetListComponent>; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [ + DatasetListComponent, + DatasetsByFamilyStubComponent + ], + imports: [TooltipModule.forRoot()] + }); + fixture = TestBed.createComponent(DatasetListComponent); + component = fixture.componentInstance; + }); + + it('should create the component', () => { + expect(component).toBeTruthy(); + }); + + it('#getDatasetFamilyList() should return sorted survey list', () => { + component.datasetList = DATASET_LIST; + component.datasetFamilyList = DATASET_FAMILY_LIST; + const sortedDatasetFamilyList: DatasetFamily[] = component.getDatasetFamilyList(); + expect(sortedDatasetFamilyList.length).toBe(1); + expect(sortedDatasetFamilyList[0].label).toBe('My first dataset family'); + }); + + it('#getDatasetsByFamily() should return dataset list for the given dataset family', () => { + component.datasetList = DATASET_LIST; + const datasetList: Dataset[] = component.getDatasetsByFamily(1); + expect(datasetList.length).toBe(2); + expect(datasetList[0].name).toBe('myDataset'); + expect(datasetList[1].name).toBe('anotherDataset'); + }); + + it('#getIsAllSelected() should return true if all datasets of the given dataset family are selected', () => { + component.datasetList = DATASET_LIST; + component.selectedDatasets = ['myDataset', 'anotherDataset']; + expect(component.getIsAllSelected(1)).toBeTruthy(); + }); + + it('#getIsAllSelected() should return false if not all datasets of the given dataset family are selected', () => { + component.datasetList = DATASET_LIST; + component.selectedDatasets = ['myDataset']; + expect(component.getIsAllSelected(1)).toBeFalsy(); + }); + + it('#getIsAllUnselected() should return true if all datasets of the given dataset family are not selected', () => { + component.datasetList = DATASET_LIST; + component.selectedDatasets = []; + expect(component.getIsAllUnselected(1)).toBeTruthy(); + }); + + it('#getIsAllUnselected() should return false if not all datasets of the given dataset family are not selected', () => { + component.datasetList = DATASET_LIST; + component.selectedDatasets = ['myDataset']; + expect(component.getIsAllUnselected(1)).toBeFalsy(); + }); +}); diff --git a/client/src/app/instance/search-multiple/components/datasets/dataset-list.component.ts b/client/src/app/instance/search-multiple/components/datasets/dataset-list.component.ts index f01569abfd679097f564b04a1563c52806e6957e..164643d464f61a837f192f0ba9efb969b0aca732 100644 --- a/client/src/app/instance/search-multiple/components/datasets/dataset-list.component.ts +++ b/client/src/app/instance/search-multiple/components/datasets/dataset-list.component.ts @@ -11,15 +11,15 @@ import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy } from import { Dataset, DatasetFamily, Survey } from 'src/app/metamodel/models'; +/** + * @class + * @classdesc Dataset list component. + */ @Component({ selector: 'app-dataset-list', templateUrl: 'dataset-list.component.html', changeDetection: ChangeDetectionStrategy.OnPush }) -/** - * @class - * @classdesc Search multiple dataset list component. - */ export class DatasetListComponent { @Input() datasetFamilyList: DatasetFamily[]; @Input() datasetList: Dataset[]; @@ -28,9 +28,9 @@ export class DatasetListComponent { @Output() updateSelectedDatasets: EventEmitter<string[]> = new EventEmitter(); /** - * Returns dataset family list sorted by display, that contains datasets with cone search enabled. + * Returns dataset family list that contains datasets with cone search enabled. * - * @return Family[] + * @return DatasetFamily[] */ getDatasetFamilyList(): DatasetFamily[] { const familyId: number[] = []; diff --git a/client/src/app/instance/search-multiple/components/datasets/datasets-by-family.component.spec.ts b/client/src/app/instance/search-multiple/components/datasets/datasets-by-family.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..9f29194b0cbc7f35acc8ce20ee0fdea9b1791745 --- /dev/null +++ b/client/src/app/instance/search-multiple/components/datasets/datasets-by-family.component.spec.ts @@ -0,0 +1,69 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TooltipModule } from 'ngx-bootstrap/tooltip'; + +import { DatasetsByFamilyComponent } from './datasets-by-family.component'; +import { DATASET_LIST, SURVEY_LIST } from '../../../../../test-data'; + +describe('[Instance][SearchMultiple][Component][Datasets] DatasetsByFamilyComponent', () => { + let component: DatasetsByFamilyComponent; + let fixture: ComponentFixture<DatasetsByFamilyComponent>; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [DatasetsByFamilyComponent], + imports: [TooltipModule.forRoot()] + }); + fixture = TestBed.createComponent(DatasetsByFamilyComponent); + component = fixture.componentInstance; + }); + + it('should create the component', () => { + expect(component).toBeTruthy(); + }); + + it('#isSelected() should return true if the given dataset is selected', () => { + component.selectedDatasets = ['toto']; + expect(component.isSelected('toto')).toBeTruthy(); + }); + + it('#isSelected() should return false if the given dataset is not selected', () => { + component.selectedDatasets = []; + expect(component.isSelected('toto')).toBeFalsy(); + }); + + it('#toggleSelection() should remove the given dataset from selectedDatasets and raise updateSelectedDatasets event', () => { + component.selectedDatasets = ['toto']; + const expectedSelectedDatasets = []; + component.updateSelectedDatasets.subscribe((event: string[]) => expect(event).toEqual(expectedSelectedDatasets)); + component.toggleSelection('toto'); + }); + + it('#toggleSelection() should add the given dataset to selectedDatasets and raise updateSelectedDatasets event', () => { + component.selectedDatasets = []; + const expectedSelectedDatasets = ['toto']; + component.updateSelectedDatasets.subscribe((event: string[]) => expect(event).toEqual(expectedSelectedDatasets)); + component.toggleSelection('toto'); + }); + + it('#selectAll() should add all datasets to selectedDatasets and raise updateSelectedDatasets event', () => { + component.datasetList = DATASET_LIST.filter(d => d.id_dataset_family === 1); + component.selectedDatasets = []; + const expectedSelectedDatasets = ['myDataset', 'anotherDataset']; + component.updateSelectedDatasets.subscribe((event: string[]) => expect(event).toEqual(expectedSelectedDatasets)); + component.selectAll(); + }); + + it('#unselectAll() should remove all datasets to selectedDatasets and raise updateSelectedDatasets event', () => { + component.datasetList = DATASET_LIST.filter(d => d.id_dataset_family === 1); + component.selectedDatasets = ['myDataset', 'anotherDataset']; + const expectedSelectedDatasets = []; + component.updateSelectedDatasets.subscribe((event: string[]) => expect(event).toEqual(expectedSelectedDatasets)); + component.unselectAll(); + }); + + it('#getSurveyDescription() should return the description of the given survey', () => { + component.surveyList = SURVEY_LIST; + expect(component.getSurveyDescription('survey-one')).toEqual('This is the description of first survey'); + }); +}); diff --git a/client/src/app/instance/search-multiple/components/datasets/datasets-by-family.component.ts b/client/src/app/instance/search-multiple/components/datasets/datasets-by-family.component.ts index 8a1a260c5e72f0f86b46ee6910c9e76f1bfe5976..85cb44b08f04300feebeaf717f9593d1c167f857 100644 --- a/client/src/app/instance/search-multiple/components/datasets/datasets-by-family.component.ts +++ b/client/src/app/instance/search-multiple/components/datasets/datasets-by-family.component.ts @@ -11,6 +11,10 @@ import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy, ViewEn import { Dataset, DatasetFamily, Survey } from 'src/app/metamodel/models'; +/** + * @class + * @classdesc Datasets by family component. + */ @Component({ selector: 'app-datasets-by-family', templateUrl: 'datasets-by-family.component.html', @@ -18,10 +22,6 @@ import { Dataset, DatasetFamily, Survey } from 'src/app/metamodel/models'; changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None }) -/** - * @class - * @classdesc Search multiple datasets by family component. - */ export class DatasetsByFamilyComponent { @Input() datasetFamily: DatasetFamily; @Input() datasetList: Dataset[]; diff --git a/client/src/app/instance/search-multiple/components/progress-bar-multiple.component.spec.ts b/client/src/app/instance/search-multiple/components/progress-bar-multiple.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..a86e34f952555f07fd597b550583aadb210a5313 --- /dev/null +++ b/client/src/app/instance/search-multiple/components/progress-bar-multiple.component.spec.ts @@ -0,0 +1,54 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { RouterTestingModule } from '@angular/router/testing'; + +import { ProgressBarMultipleComponent } from './progress-bar-multiple.component'; +import { INSTANCE } from '../../../../test-data'; + +describe('[Instance][SearchMultiple][Component] ProgressBarMultipleComponent', () => { + let component: ProgressBarMultipleComponent; + let fixture: ComponentFixture<ProgressBarMultipleComponent>; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [ProgressBarMultipleComponent], + imports: [RouterTestingModule] + }); + fixture = TestBed.createComponent(ProgressBarMultipleComponent); + component = fixture.componentInstance; + }); + + it('should create the component', () => { + expect(component).toBeTruthy(); + }); + + it('#getStepClass() should return correct step class', () => { + let style = component.getStepClass(); + expect(style).toBe('positionStep'); + component.currentStep = 'position'; + style = component.getStepClass(); + expect(style).toBe('positionStep'); + component.currentStep = 'datasets'; + style = component.getStepClass(); + expect(style).toBe('datasetsStep'); + component.currentStep = 'result'; + style = component.getStepClass(); + expect(style).toBe('resultStep'); + }); + + it('#getNavItemAStyle() should return correct style for navigation link', () => { + component.currentStep = 'step'; + component.instance = INSTANCE; + expect(component.getNavItemAStyle('', false)).toBeNull(); + expect(component.getNavItemAStyle('step', true)).toEqual({ color: 'green' }); + }); + + it('#getNavItemIconCircleStyle() should return correct style for icon circle', () => { + component.currentStep = 'step'; + component.instance = INSTANCE; + expect(component.getNavItemIconCircleStyle('', false)).toEqual({ }); + const expectedWithStep = { 'border-color': 'green', 'background-color': 'green' }; + expect(component.getNavItemIconCircleStyle('step', false)).toEqual(expectedWithStep); + const expectedWithChecked = { 'border-color': 'green', 'color': 'green' }; + expect(component.getNavItemIconCircleStyle('', true)).toEqual(expectedWithChecked); + }); +}); diff --git a/client/src/app/instance/search-multiple/components/progress-bar-multiple.component.ts b/client/src/app/instance/search-multiple/components/progress-bar-multiple.component.ts index ece4925478828db29a2a9df8e097e3287ca2900e..0fbeafa0d654dac7fc133ccde1ee597140fbc43a 100644 --- a/client/src/app/instance/search-multiple/components/progress-bar-multiple.component.ts +++ b/client/src/app/instance/search-multiple/components/progress-bar-multiple.component.ts @@ -12,16 +12,16 @@ import { Component, Input, ChangeDetectionStrategy } from '@angular/core'; import { Instance } from 'src/app/metamodel/models'; import { ConeSearch, SearchMultipleQueryParams } from 'src/app/instance/store/models'; +/** + * @class + * @classdesc Progress bar multiple component. + */ @Component({ selector: 'app-progress-bar-multiple', templateUrl: 'progress-bar-multiple.component.html', styleUrls: ['progress-bar-multiple.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) -/** - * @class - * @classdesc Search multiple progress bar component. - */ export class ProgressBarMultipleComponent { @Input() instance: Instance; @Input() currentStep: string; @@ -50,17 +50,30 @@ export class ProgressBarMultipleComponent { } } - getNavItemAStyle(currentStep: string, checked: boolean) { + /** + * Returns navigation link style. + * + * @param {string} currentStep - The current step. + * @param {boolean} checked - The checked status of current step. + * + * @return { color: string } | null + */ + getNavItemAStyle(currentStep: string, checked: boolean): { color: string } | null { if (this.currentStep === currentStep || checked) { - return { - 'color': this.instance.config.design.design_color - } - } else { - return null; + return { 'color': this.instance.config.design.design_color } } + return null; } - getNavItemIconCircleStyle(currentStep: string, checked: boolean) { + /** + * Returns navigation icon circle style. + * + * @param {string} currentStep - The current step. + * @param {boolean} checked - The checked status of current step. + * + * @return any + */ + getNavItemIconCircleStyle(currentStep: string, checked: boolean): any { let style = {}; if (this.currentStep === currentStep) { style['border-color'] = this.instance.config.design.design_color; diff --git a/client/src/app/instance/search-multiple/components/result/overview.component.spec.ts b/client/src/app/instance/search-multiple/components/result/overview.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..68532aaec60f06a8f61abcca51d232d1e4ab345b --- /dev/null +++ b/client/src/app/instance/search-multiple/components/result/overview.component.spec.ts @@ -0,0 +1,60 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { RouterTestingModule } from '@angular/router/testing'; + +import { OverviewComponent } from './overview.component'; +import { Dataset, DatasetFamily } from '../../../../metamodel/models'; +import { DATASET_FAMILY_LIST, DATASET_LIST } from '../../../../../test-data'; + +describe('[Instance][SearchMultiple][Component][Result] OverviewComponent', () => { + let component: OverviewComponent; + let fixture: ComponentFixture<OverviewComponent>; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [OverviewComponent], + imports: [RouterTestingModule] + }); + fixture = TestBed.createComponent(OverviewComponent); + component = fixture.componentInstance; + }); + + it('should create the component', () => { + expect(component).toBeTruthy(); + }); + + it('#getTotalObject() should return the sum of results for each dataset', () => { + component.dataLength = [{ datasetName: 'firstDataset', length: 1 }, { datasetName: 'secondDataset', length: 1 }]; + expect(component.getTotalObject()).toEqual(2); + }); + + it('#getTotalDatasets() should return count datasets with results', () => { + component.dataLength = [{ datasetName: 'firstDataset', length: 1 }, { datasetName: 'secondDataset', length: 1 }]; + expect(component.getTotalDatasets()).toEqual(2); + }); + + it('#getSortedDatasetFamilyList() should return sorted dataset family list with selected datasets in it', () => { + component.selectedDatasets = ['myDataset', 'anotherDataset']; + component.datasetList = DATASET_LIST; + component.datasetFamilyList = DATASET_FAMILY_LIST; + const sortedDatasetFamilyList: DatasetFamily[] = component.getSortedDatasetFamilyList(); + expect(sortedDatasetFamilyList.length).toEqual(1); + expect(sortedDatasetFamilyList[0].label).toBe('My first dataset family'); + }); + + it('#getSelectedDatasetsByFamily() should return selected dataset that belongs to the given dataset family', () => { + component.selectedDatasets = ['myDataset']; + component.datasetList = DATASET_LIST; + const selectedDatasets: Dataset[] = component.getSelectedDatasetsByFamily(1); + expect(selectedDatasets.length).toEqual(1); + }); + + it('#getCountByDataset() should return count for the given dataset', () => { + component.dataLength = [{ datasetName: 'firstDataset', length: 1 }, { datasetName: 'secondDataset', length: 2 }]; + expect(component.getCountByDataset('firstDataset')).toEqual(1); + }); + + it('#getCsQueryParams() should return cone search query parameters', () => { + component.coneSearch = { ra: 1, dec: 2, radius: 3 }; + expect(component.getCsQueryParams()).toEqual({ cs: '1:2:3' }); + }); +}); diff --git a/client/src/app/instance/search-multiple/components/result/overview.component.ts b/client/src/app/instance/search-multiple/components/result/overview.component.ts index e85af4d2feed7f641e352c6f5a998a7a596899c8..25fc216d76b3bebd419f902d9044c8366502d70d 100644 --- a/client/src/app/instance/search-multiple/components/result/overview.component.ts +++ b/client/src/app/instance/search-multiple/components/result/overview.component.ts @@ -12,6 +12,10 @@ import { Component, Input } from '@angular/core'; import { DatasetFamily, Dataset } from 'src/app/metamodel/models'; import { ConeSearch, SearchMultipleDatasetLength, SearchMultipleQueryParams } from 'src/app/instance/store/models'; +/** + * @class + * @classdesc Overview component. + */ @Component({ selector: 'app-overview', templateUrl: 'overview.component.html' @@ -37,7 +41,7 @@ export class OverviewComponent { } /** - * Returns total number of datasets with results. + * Returns count of datasets with results. * * @return number */ @@ -46,9 +50,9 @@ export class OverviewComponent { } /** - * Returns dataset families sorted by display, that contains selected datasets. + * Returns dataset families that contains selected datasets. * - * @return Family[] + * @return DatasetFamily[] */ getSortedDatasetFamilyList(): DatasetFamily[] { let datasetFamiliesWithSelectedDataset: DatasetFamily[] = []; @@ -76,7 +80,7 @@ export class OverviewComponent { } /** - * Returns the result number for the given dataset name. + * Returns the result count for the given dataset name. * * @param {string} dname - The dataset name. * @@ -86,9 +90,12 @@ export class OverviewComponent { return this.dataLength.find(datasetLength => datasetLength.datasetName === dname).length; } - getCsQueryParams() { - return { - cs: `${this.coneSearch.ra}:${this.coneSearch.dec}:${this.coneSearch.radius}` - } + /** + * Returns the cone search query parameters. + * + * @return { cs: string } + */ + getCsQueryParams(): { cs: string } { + return { cs: `${this.coneSearch.ra}:${this.coneSearch.dec}:${this.coneSearch.radius}` } } } diff --git a/client/src/app/instance/search-multiple/components/summary-multiple.component.spec.ts b/client/src/app/instance/search-multiple/components/summary-multiple.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..37133619d27c1201b33d16de6774f0e9243e0cb2 --- /dev/null +++ b/client/src/app/instance/search-multiple/components/summary-multiple.component.spec.ts @@ -0,0 +1,43 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; + +import { AccordionModule } from 'ngx-bootstrap/accordion'; +import { TooltipModule } from 'ngx-bootstrap/tooltip'; + +import { SummaryMultipleComponent } from './summary-multiple.component'; +import { DATASET, DATASET_FAMILY_LIST, DATASET_LIST } from '../../../../test-data'; + +describe('[Instance][SearchMultiple][Component] SummaryMultipleComponent', () => { + let component: SummaryMultipleComponent; + let fixture: ComponentFixture<SummaryMultipleComponent>; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [SummaryMultipleComponent], + imports: [ + AccordionModule.forRoot(), + TooltipModule.forRoot(), + BrowserAnimationsModule + ] + }); + fixture = TestBed.createComponent(SummaryMultipleComponent); + component = fixture.componentInstance; + }); + + it('should create the component', () => { + expect(component).toBeTruthy(); + }); + + it('#getDatasetFamilyList() should return list of dataset families that contains datasets with cone search enabled', () => { + component.datasetFamilyList = DATASET_FAMILY_LIST; + component.datasetList = [DATASET]; + expect(component.getDatasetFamilyList()[0].label).toBe('My first dataset family'); + }); + + it('#getSelectedDatasetsByFamily() should return list of selected datasets for the given dataset family', () => { + component.datasetList = DATASET_LIST; + component.selectedDatasets = ['myDataset']; + expect(component.getSelectedDatasetsByFamily(1).length).toEqual(1); + expect(component.getSelectedDatasetsByFamily(1)[0].name).toEqual('myDataset'); + }); +}); diff --git a/client/src/app/instance/search-multiple/components/summary-multiple.component.ts b/client/src/app/instance/search-multiple/components/summary-multiple.component.ts index 790fcd5c75c8862f0dab3bef3ff867edc4c7a361..fb6900bee9918b8a0ff344e25a881f3b67224841 100644 --- a/client/src/app/instance/search-multiple/components/summary-multiple.component.ts +++ b/client/src/app/instance/search-multiple/components/summary-multiple.component.ts @@ -12,16 +12,16 @@ import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; import { SearchMultipleQueryParams, ConeSearch } from 'src/app/instance/store/models'; import { Dataset, DatasetFamily } from 'src/app/metamodel/models'; +/** + * @class + * @classdesc Summary multiple component. + */ @Component({ selector: 'app-summary-multiple', templateUrl: 'summary-multiple.component.html', styleUrls: ['summary-multiple.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, }) -/** - * @class - * @classdesc Search multiple summary component. - */ export class SummaryMultipleComponent { @Input() currentStep: string; @Input() coneSearch: ConeSearch; @@ -33,7 +33,7 @@ export class SummaryMultipleComponent { accordionFamilyIsOpen = true; /** - * Returns dataset families sorted by display, that contains datasets with cone search enabled. + * Returns dataset families that contains datasets with cone search enabled. * * @return Family[] */ @@ -44,9 +44,7 @@ export class SummaryMultipleComponent { familiesId.push(d.id_dataset_family); } }); - return this.datasetFamilyList - .filter(f => familiesId.includes(f.id)) - //.sort(sortByDisplay); + return this.datasetFamilyList.filter(f => familiesId.includes(f.id)); } /** diff --git a/client/src/app/instance/search-multiple/containers/abstract-search-multiple.component.spec.ts b/client/src/app/instance/search-multiple/containers/abstract-search-multiple.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..69b64e6f6f803b12951d53d835f5593d15e3ea8f --- /dev/null +++ b/client/src/app/instance/search-multiple/containers/abstract-search-multiple.component.spec.ts @@ -0,0 +1,61 @@ +import { Component } from '@angular/core'; +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; + +import { MockStore, provideMockStore } from '@ngrx/store/testing'; +import { of } from 'rxjs'; + +import { AbstractSearchMultipleComponent } from './abstract-search-multiple.component'; +import * as searchActions from '../../store/actions/search.actions'; +import * as searchMultipleActions from '../../store/actions/search-multiple.actions'; + +describe('[Instance][SearchMultiple][Container] AbstractSearchComponent', () => { + @Component({ + selector: 'app-fake', + template: '' + }) + class MyFakeComponent extends AbstractSearchMultipleComponent { + ngOnInit() { + super.ngOnInit(); + } + + ngOnDestroy() { + super.ngOnDestroy(); + } + } + + let component: MyFakeComponent; + let fixture: ComponentFixture<MyFakeComponent>; + let store: MockStore; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [MyFakeComponent], + providers: [provideMockStore({ })] + }); + fixture = TestBed.createComponent(MyFakeComponent); + component = fixture.componentInstance; + store = TestBed.inject(MockStore); + })); + + it('should create the component', () => { + expect(component).toBeTruthy(); + }); + + it('should execute ngOnInit lifecycle', (done) => { + component.datasetListIsLoaded = of(true); + const spy = jest.spyOn(store, 'dispatch'); + component.ngOnInit(); + Promise.resolve(null).then(function() { + expect(spy).toHaveBeenCalledTimes(1); + expect(spy).toHaveBeenCalledWith(searchMultipleActions.initSearch()); + done(); + }); + }); + + it('#ngOnDestroy() should unsubscribe from datasetListSubscription', () => { + component.datasetListSubscription = of().subscribe(); + const spy = jest.spyOn(component.datasetListSubscription, 'unsubscribe'); + component.ngOnDestroy(); + expect(spy).toHaveBeenCalledTimes(1); + }); +}); diff --git a/client/src/app/instance/search-multiple/containers/abstract-search-multiple.component.ts b/client/src/app/instance/search-multiple/containers/abstract-search-multiple.component.ts index d8bbadd476b404c8b20a43d728284d0423c3a67f..9636c26a182b8dda539f9f069a5c25344680312e 100644 --- a/client/src/app/instance/search-multiple/containers/abstract-search-multiple.component.ts +++ b/client/src/app/instance/search-multiple/containers/abstract-search-multiple.component.ts @@ -12,6 +12,14 @@ import * as searchMultipleActions from '../../store/actions/search-multiple.acti import * as searchMultipleSelector from 'src/app/instance/store/selectors/search-multiple.selector'; import * as coneSearchSelector from 'src/app/instance/store/selectors/cone-search.selector'; +/** + * @abstract + * @class + * @classdesc Abstract search multiple container. + * + * @implements OnInit + * @implements OnDestroy + */ @Directive() export abstract class AbstractSearchMultipleComponent implements OnInit, OnDestroy { public pristine: Observable<boolean>; @@ -26,8 +34,7 @@ export abstract class AbstractSearchMultipleComponent implements OnInit, OnDestr public selectedDatasets: Observable<string[]>; public coneSearch: Observable<ConeSearch>; public queryParams: Observable<SearchMultipleQueryParams>; - - private datasetListSubscription: Subscription; + public datasetListSubscription: Subscription; constructor(protected store: Store<{ }>) { this.pristine = this.store.select(searchMultipleSelector.selectPristine); @@ -43,16 +50,18 @@ export abstract class AbstractSearchMultipleComponent implements OnInit, OnDestr this.coneSearch = this.store.select(coneSearchSelector.selectConeSearch); this.queryParams = this.store.select(searchMultipleSelector.selectQueryParams); } - - ngOnInit() { + + ngOnInit(): void { this.datasetListSubscription = this.datasetListIsLoaded.subscribe(datasetListIsLoaded => { if (datasetListIsLoaded) { + // Create a micro task that is processed after the current synchronous code + // This micro task prevent the expression has changed after view init error Promise.resolve(null).then(() => this.store.dispatch(searchMultipleActions.initSearch())); } }) } - ngOnDestroy() { - this.datasetListSubscription.unsubscribe(); + ngOnDestroy(): void { + if (this.datasetListSubscription) this.datasetListSubscription.unsubscribe(); } } diff --git a/client/src/app/instance/search-multiple/containers/datasets.component.spec.ts b/client/src/app/instance/search-multiple/containers/datasets.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..5ca7160f495214a2dd58fd3a76618747c0582bbc --- /dev/null +++ b/client/src/app/instance/search-multiple/containers/datasets.component.spec.ts @@ -0,0 +1,78 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { Component, Input } from '@angular/core'; +import { RouterTestingModule } from '@angular/router/testing'; + +import { MockStore, provideMockStore } from '@ngrx/store/testing'; + +import { DatasetsComponent } from './datasets.component'; +import { Dataset, DatasetFamily, Survey } from '../../../metamodel/models'; +import { ConeSearch, SearchMultipleQueryParams } from '../../store/models'; +import { AbstractSearchMultipleComponent } from './abstract-search-multiple.component'; +import * as searchMultipleActions from '../../store/actions/search-multiple.actions'; + +describe('[Instance][SearchMultiple][Container] DatasetsComponent', () => { + @Component({ selector: 'app-spinner', template: '' }) + class SpinnerStubComponent { } + + @Component({ selector: 'app-dataset-list', template: '' }) + class DatasetListStubComponent { + @Input() datasetFamilyList: DatasetFamily[]; + @Input() datasetList: Dataset[]; + @Input() surveyList: Survey[]; + @Input() selectedDatasets: string[]; + } + + @Component({ selector: 'app-summary-multiple', template: '' }) + class SummaryMultipleStubComponent { + @Input() currentStep: string; + @Input() coneSearch: ConeSearch; + @Input() selectedDatasets: string[]; + @Input() queryParams: SearchMultipleQueryParams; + @Input() datasetFamilyList: DatasetFamily[]; + @Input() datasetList: Dataset[]; + } + + let component: DatasetsComponent; + let fixture: ComponentFixture<DatasetsComponent>; + let store: MockStore; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [RouterTestingModule], + declarations: [ + DatasetsComponent, + SpinnerStubComponent, + DatasetListStubComponent, + SummaryMultipleStubComponent + ], + providers: [provideMockStore({ })] + }); + fixture = TestBed.createComponent(DatasetsComponent); + component = fixture.componentInstance; + store = TestBed.inject(MockStore); + })); + + it('should create the component', () => { + expect(component).toBeTruthy(); + }); + + it('should execute ngOnInit lifecycle', (done) => { + const spy = jest.spyOn(store, 'dispatch'); + jest.spyOn(AbstractSearchMultipleComponent.prototype, 'ngOnInit').mockReturnThis(); + component.ngOnInit(); + Promise.resolve(null).then(function() { + expect(spy).toHaveBeenCalledTimes(2); + expect(spy).toHaveBeenCalledWith(searchMultipleActions.changeStep({ step: 'datasets' })); + expect(spy).toHaveBeenCalledWith(searchMultipleActions.checkDatasets()); + done(); + }); + }); + + it('#updateSelectedDatasets() should dispatch updateSelectedDatasets action', () => { + const selectedDatasets: string[] = ['myDataset', 'myOtherDataset']; + const spy = jest.spyOn(store, 'dispatch'); + component.updateSelectedDatasets(selectedDatasets); + expect(spy).toHaveBeenCalledTimes(1); + expect(spy).toHaveBeenCalledWith(searchMultipleActions.updateSelectedDatasets({ selectedDatasets })); + }); +}); diff --git a/client/src/app/instance/search-multiple/containers/datasets.component.ts b/client/src/app/instance/search-multiple/containers/datasets.component.ts index 5b990465122fc275552cdd57367d0299df39bccc..816fa7c6601cd00d3af5545b559b6e2fdaaf5870 100644 --- a/client/src/app/instance/search-multiple/containers/datasets.component.ts +++ b/client/src/app/instance/search-multiple/containers/datasets.component.ts @@ -7,7 +7,7 @@ * file that was distributed with this source code. */ -import { Component } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; @@ -17,11 +17,18 @@ import { AbstractSearchMultipleComponent } from './abstract-search-multiple.comp import * as searchMultipleActions from '../../store/actions/search-multiple.actions'; import * as surveySelector from 'src/app/metamodel/selectors/survey.selector'; +/** + * @class + * @classdesc Datasets container. + * + * @extends AbstractSearchMultipleComponent + * @implements OnInit + */ @Component({ selector: 'app-datasets', templateUrl: 'datasets.component.html' }) -export class DatasetsComponent extends AbstractSearchMultipleComponent { +export class DatasetsComponent extends AbstractSearchMultipleComponent implements OnInit { public surveyListIsLoading: Observable<boolean>; public surveyListIsLoaded: Observable<boolean>; public surveyList: Observable<Survey[]>; @@ -33,13 +40,20 @@ export class DatasetsComponent extends AbstractSearchMultipleComponent { this.surveyList = store.select(surveySelector.selectAllSurveys); } - ngOnInit() { + ngOnInit(): void { + // Create a micro task that is processed after the current synchronous code + // This micro task prevent the expression has changed after view init error Promise.resolve(null).then(() => this.store.dispatch(searchMultipleActions.changeStep({ step: 'datasets' }))); Promise.resolve(null).then(() => this.store.dispatch(searchMultipleActions.checkDatasets())); super.ngOnInit(); } - updateSelectedDatasets(selectedDatasets: string[]) { + /** + * Dispatches action to update selected datasets. + * + * @param {string[]} selectedDatasets - The selected datasets. + */ + updateSelectedDatasets(selectedDatasets: string[]): void { this.store.dispatch(searchMultipleActions.updateSelectedDatasets({ selectedDatasets })); } } diff --git a/client/src/app/instance/search-multiple/containers/position.component.spec.ts b/client/src/app/instance/search-multiple/containers/position.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..84a0914057bb7b80650f61a4919096a35bd27f54 --- /dev/null +++ b/client/src/app/instance/search-multiple/containers/position.component.spec.ts @@ -0,0 +1,92 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { Component, Input } from '@angular/core'; +import { RouterTestingModule } from '@angular/router/testing'; + +import { MockStore, provideMockStore } from '@ngrx/store/testing'; + +import { PositionComponent } from './position.component'; +import { Dataset, DatasetFamily } from '../../../metamodel/models'; +import { ConeSearch, Resolver, SearchMultipleQueryParams } from '../../store/models'; +import { AbstractSearchMultipleComponent } from './abstract-search-multiple.component'; +import * as searchMultipleActions from '../../store/actions/search-multiple.actions'; +import * as coneSearchActions from '../../store/actions/cone-search.actions'; + +describe('[Instance][SearchMultiple][Container] PositionComponent', () => { + @Component({ selector: 'app-spinner', template: '' }) + class SpinnerStubComponent { } + + @Component({ selector: 'app-cone-search', template: '' }) + class ConeSearchStubComponent { + @Input() coneSearch: ConeSearch; + @Input() resolver: Resolver; + @Input() resolverIsLoading: boolean; + @Input() resolverIsLoaded: boolean; + } + + @Component({ selector: 'app-summary-multiple', template: '' }) + class SummaryMultipleStubComponent { + @Input() currentStep: string; + @Input() coneSearch: ConeSearch; + @Input() selectedDatasets: string[]; + @Input() queryParams: SearchMultipleQueryParams; + @Input() datasetFamilyList: DatasetFamily[]; + @Input() datasetList: Dataset[]; + } + + let component: PositionComponent; + let fixture: ComponentFixture<PositionComponent>; + let store: MockStore; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [RouterTestingModule], + declarations: [ + PositionComponent, + SpinnerStubComponent, + ConeSearchStubComponent, + SummaryMultipleStubComponent + ], + providers: [provideMockStore({ })] + }); + fixture = TestBed.createComponent(PositionComponent); + component = fixture.componentInstance; + store = TestBed.inject(MockStore); + })); + + it('should create the component', () => { + expect(component).toBeTruthy(); + }); + + it('should execute ngOnInit lifecycle', (done) => { + const spy = jest.spyOn(store, 'dispatch'); + jest.spyOn(AbstractSearchMultipleComponent.prototype, 'ngOnInit').mockReturnThis(); + component.ngOnInit(); + Promise.resolve(null).then(function() { + expect(spy).toHaveBeenCalledTimes(1); + expect(spy).toHaveBeenCalledWith(searchMultipleActions.changeStep({ step: 'position' })); + done(); + }); + }); + + it('#addConeSearch() should dispatch addConeSearch action', () => { + const coneSearch: ConeSearch = { ra: 1, dec: 2, radius: 3 }; + const spy = jest.spyOn(store, 'dispatch'); + component.addConeSearch(coneSearch); + expect(spy).toHaveBeenCalledTimes(1); + expect(spy).toHaveBeenCalledWith(coneSearchActions.addConeSearch({ coneSearch })); + }); + + it('#deleteConeSearch() should dispatch deleteConeSearch action', () => { + const spy = jest.spyOn(store, 'dispatch'); + component.deleteConeSearch(); + expect(spy).toHaveBeenCalledTimes(1); + expect(spy).toHaveBeenCalledWith(coneSearchActions.deleteConeSearch()); + }); + + it('#retrieveCoordinates() should dispatch retrieveCoordinates action', () => { + const spy = jest.spyOn(store, 'dispatch'); + component.retrieveCoordinates('toto'); + expect(spy).toHaveBeenCalledTimes(1); + expect(spy).toHaveBeenCalledWith(coneSearchActions.retrieveCoordinates({ name: 'toto' })); + }); +}); diff --git a/client/src/app/instance/search-multiple/containers/position.component.ts b/client/src/app/instance/search-multiple/containers/position.component.ts index dea597950d3f0c527909d7059537152eda0c00f8..a56e99ce0021ad9d2162bda673db692ca65f53e7 100644 --- a/client/src/app/instance/search-multiple/containers/position.component.ts +++ b/client/src/app/instance/search-multiple/containers/position.component.ts @@ -7,7 +7,7 @@ * file that was distributed with this source code. */ -import { Component } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; @@ -18,11 +18,18 @@ import * as searchMultipleActions from '../../store/actions/search-multiple.acti import * as coneSearchActions from '../../store/actions/cone-search.actions'; import * as coneSearchSelector from '../../store/selectors/cone-search.selector'; +/** + * @class + * @classdesc Position container. + * + * @extends AbstractSearchMultipleComponent + * @implements OnInit + */ @Component({ selector: 'app-position', templateUrl: 'position.component.html' }) -export class PositionComponent extends AbstractSearchMultipleComponent { +export class PositionComponent extends AbstractSearchMultipleComponent implements OnInit { public resolver: Observable<Resolver>; public resolverIsLoading: Observable<boolean>; public resolverIsLoaded: Observable<boolean>; @@ -34,19 +41,34 @@ export class PositionComponent extends AbstractSearchMultipleComponent { this.resolverIsLoaded = this.store.select(coneSearchSelector.selectResolverIsLoaded); } - ngOnInit() { + ngOnInit(): void { + // Create a micro task that is processed after the current synchronous code + // This micro task prevent the expression has changed after view init error Promise.resolve(null).then(() => this.store.dispatch(searchMultipleActions.changeStep({ step: 'position' }))); super.ngOnInit(); } + /** + * Dispatches action to add the given cone search. + * + * @param {ConeSearch} coneSearch - The cone search. + */ addConeSearch(coneSearch: ConeSearch): void { this.store.dispatch(coneSearchActions.addConeSearch({ coneSearch })); } + /** + * Dispatches action to remove cone search. + */ deleteConeSearch(): void { this.store.dispatch(coneSearchActions.deleteConeSearch()); } + /** + * Dispatches action to retrieve coordinates of object from its name. + * + * @param {string} name - The object name. + */ retrieveCoordinates(name: string): void { this.store.dispatch(coneSearchActions.retrieveCoordinates({ name })); } diff --git a/client/src/app/instance/search-multiple/containers/result-multiple.component.spec.ts b/client/src/app/instance/search-multiple/containers/result-multiple.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..4cb2ae0c0191b4ceedd1debde6e128842952c307 --- /dev/null +++ b/client/src/app/instance/search-multiple/containers/result-multiple.component.spec.ts @@ -0,0 +1,74 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { Component, Input } from '@angular/core'; +import { RouterTestingModule } from '@angular/router/testing'; + +import { MockStore, provideMockStore } from '@ngrx/store/testing'; +import { of } from 'rxjs'; + +import { ResultMultipleComponent } from './result-multiple.component'; +import { Dataset, DatasetFamily } from '../../../metamodel/models'; +import { ConeSearch, SearchMultipleDatasetLength, SearchMultipleQueryParams } from '../../store/models'; +import { AbstractSearchMultipleComponent } from './abstract-search-multiple.component'; +import * as searchMultipleActions from '../../store/actions/search-multiple.actions'; + +describe('[Instance][SearchMultiple][Container] ResultMultipleComponent', () => { + @Component({ selector: 'app-spinner', template: '' }) + class SpinnerStubComponent { } + + @Component({ selector: 'app-overview', template: '' }) + class OverviewStubComponent { + @Input() instanceSelected: string; + @Input() datasetFamilyList: DatasetFamily[]; + @Input() datasetList: Dataset[]; + @Input() coneSearch: ConeSearch; + @Input() selectedDatasets: string[]; + @Input() dataLength: SearchMultipleDatasetLength[]; + @Input() queryParams: SearchMultipleQueryParams; + } + + let component: ResultMultipleComponent; + let fixture: ComponentFixture<ResultMultipleComponent>; + let store: MockStore; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [RouterTestingModule], + declarations: [ + ResultMultipleComponent, + SpinnerStubComponent, + OverviewStubComponent + ], + providers: [provideMockStore({ })] + }); + fixture = TestBed.createComponent(ResultMultipleComponent); + component = fixture.componentInstance; + store = TestBed.inject(MockStore); + })); + + it('should create the component', () => { + expect(component).toBeTruthy(); + }); + + it('should execute ngOnInit lifecycle', (done) => { + component.pristine = of(false); + const spy = jest.spyOn(store, 'dispatch'); + jest.spyOn(AbstractSearchMultipleComponent.prototype, 'ngOnInit').mockReturnThis(); + component.ngOnInit(); + Promise.resolve(null).then(function() { + expect(spy).toHaveBeenCalledTimes(4); + expect(spy).toHaveBeenCalledWith(searchMultipleActions.changeStep({ step: 'result' })); + expect(spy).toHaveBeenCalledWith(searchMultipleActions.checkDatasets()); + expect(spy).toHaveBeenCalledWith(searchMultipleActions.checkResult()); + expect(spy).toHaveBeenCalledWith(searchMultipleActions.retrieveDataLength()); + done(); + }); + }); + + it('#ngOnDestroy() should unsubscribe from pristineSubscription', () => { + component.pristineSubscription = of().subscribe(); + const spy = jest.spyOn(component.pristineSubscription, 'unsubscribe'); + jest.spyOn(AbstractSearchMultipleComponent.prototype, 'ngOnDestroy').mockReturnThis(); + component.ngOnDestroy(); + expect(spy).toHaveBeenCalledTimes(1); + }); +}); diff --git a/client/src/app/instance/search-multiple/containers/result-multiple.component.ts b/client/src/app/instance/search-multiple/containers/result-multiple.component.ts index 3e4d66b40fbfcad6aabcededb30c6f628554f20d..cd50bfbc06ae6f0320273184cca8b1cb0fb4a733 100644 --- a/client/src/app/instance/search-multiple/containers/result-multiple.component.ts +++ b/client/src/app/instance/search-multiple/containers/result-multiple.component.ts @@ -7,7 +7,7 @@ * file that was distributed with this source code. */ -import { Component } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; import { Observable, Subscription } from 'rxjs'; import { Store } from '@ngrx/store'; @@ -17,19 +17,26 @@ import { AbstractSearchMultipleComponent } from './abstract-search-multiple.comp import * as searchMultipleActions from '../../store/actions/search-multiple.actions'; import * as searchMultipleSelector from 'src/app/instance/store/selectors/search-multiple.selector'; +/** + * @class + * @classdesc Result multiple container. + * + * @extends AbstractSearchMultipleComponent + * @implements OnInit + * @implements OnDestroy + */ @Component({ selector: 'app-result-multiple', templateUrl: 'result-multiple.component.html' }) -export class ResultMultipleComponent extends AbstractSearchMultipleComponent { +export class ResultMultipleComponent extends AbstractSearchMultipleComponent implements OnInit, OnDestroy{ public dataLength: Observable<SearchMultipleDatasetLength[]>; public dataLengthIsLoading: Observable<boolean>; public dataLengthIsLoaded: Observable<boolean>; public data: Observable<SearchMultipleDatasetData[]>; public dataIsLoading: Observable<boolean>; public dataIsLoaded: Observable<boolean>; - - private pristineSubscription: Subscription; + public pristineSubscription: Subscription; constructor(protected store: Store<{ }>) { super(store); @@ -41,7 +48,9 @@ export class ResultMultipleComponent extends AbstractSearchMultipleComponent { this.dataIsLoaded = this.store.select(searchMultipleSelector.selectDataIsLoaded); } - ngOnInit() { + ngOnInit(): void { + // Create a micro task that is processed after the current synchronous code + // This micro task prevent the expression has changed after view init error Promise.resolve(null).then(() => this.store.dispatch(searchMultipleActions.changeStep({ step: 'result' }))); Promise.resolve(null).then(() => this.store.dispatch(searchMultipleActions.checkDatasets())); Promise.resolve(null).then(() => this.store.dispatch(searchMultipleActions.checkResult())); @@ -53,8 +62,8 @@ export class ResultMultipleComponent extends AbstractSearchMultipleComponent { }); } - ngOnDestroy() { - this.pristineSubscription.unsubscribe(); + ngOnDestroy(): void { + if (this.pristineSubscription) this.pristineSubscription.unsubscribe(); super.ngOnDestroy(); } } diff --git a/client/src/app/instance/search-multiple/search-multiple-routing.module.ts b/client/src/app/instance/search-multiple/search-multiple-routing.module.ts index a3590eb28c7d96bbd48addb36fa15a9d00c3ff0b..7c7a014309f6bc3c9b5061493c1bb466a5d14ce7 100644 --- a/client/src/app/instance/search-multiple/search-multiple-routing.module.ts +++ b/client/src/app/instance/search-multiple/search-multiple-routing.module.ts @@ -26,6 +26,10 @@ const routes: Routes = [ } ]; +/** + * @class + * @classdesc Search multiple routing module. + */ @NgModule({ imports: [RouterModule.forChild(routes)], exports: [RouterModule] diff --git a/client/src/app/instance/search-multiple/search-multiple.component.spec.ts b/client/src/app/instance/search-multiple/search-multiple.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..bf42abc813a72e5ee20c2cae51572f95e05f3d53 --- /dev/null +++ b/client/src/app/instance/search-multiple/search-multiple.component.spec.ts @@ -0,0 +1,45 @@ +import { Component, Input } from '@angular/core'; +import { TestBed, waitForAsync, ComponentFixture } from '@angular/core/testing'; +import { RouterTestingModule } from '@angular/router/testing'; + +import { provideMockStore, MockStore } from '@ngrx/store/testing'; + +import { SearchMultipleComponent } from './search-multiple.component'; +import { Instance } from '../../metamodel/models'; +import { ConeSearch, SearchMultipleQueryParams, SearchQueryParams } from '../store/models'; + +describe('[Instance][SearchMultiple] SearchMultipleComponent', () => { + @Component({ selector: 'app-progress-bar-multiple', template: '' }) + class ProgressBarMultipleStubComponent { + @Input() instance: Instance; + @Input() currentStep: string; + @Input() positionStepChecked: boolean; + @Input() datasetsStepChecked: boolean; + @Input() resultStepChecked: boolean; + @Input() coneSearch: ConeSearch; + @Input() selectedDatasets: string[]; + @Input() queryParams: SearchMultipleQueryParams; + } + + let component: SearchMultipleComponent; + let fixture: ComponentFixture<SearchMultipleComponent>; + let store: MockStore; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [RouterTestingModule], + declarations: [ + SearchMultipleComponent, + ProgressBarMultipleStubComponent + ], + providers: [provideMockStore({ })] + }).compileComponents(); + fixture = TestBed.createComponent(SearchMultipleComponent); + component = fixture.componentInstance; + store = TestBed.inject(MockStore); + })); + + it('should create the component', () => { + expect(component).toBeDefined(); + }); +}); diff --git a/client/src/app/instance/search-multiple/search-multiple.module.ts b/client/src/app/instance/search-multiple/search-multiple.module.ts index fb571918658a6964da4044754d30fff003230838..2d155bd9c3da6134f4fa689fb0bf0f0cc50567be 100644 --- a/client/src/app/instance/search-multiple/search-multiple.module.ts +++ b/client/src/app/instance/search-multiple/search-multiple.module.ts @@ -14,6 +14,10 @@ import { ConeSearchModule } from '../cone-search/cone-search.module'; import { SearchMultipleRoutingModule, routedComponents } from './search-multiple-routing.module'; import { dummiesComponents } from './components'; +/** + * @class + * @classdesc Search multiple module. + */ @NgModule({ imports: [ SharedModule, diff --git a/client/src/test-data.ts b/client/src/test-data.ts index 4928da851991c58df45b57a7d1d9bb96137ab093..683df725204adfb4dd6fa6fb5975530dbfef8c0d 100644 --- a/client/src/test-data.ts +++ b/client/src/test-data.ts @@ -1,4 +1,175 @@ -import { Attribute, Dataset, OutputCategory } from './app/metamodel/models'; +import { Attribute, Dataset, DatasetFamily, Instance, OutputCategory, Survey } from './app/metamodel/models'; + +export const SURVEY_LIST: Survey[] = [ + { + name: 'survey-one', + label: 'First survey', + description: 'This is the description of first survey', + link: 'http://survey-one.com', + manager: 'Marylin Monroe', + id_database: 1, + nb_datasets: 1 + }, + { + name: 'survey-two', + label: 'Second survey', + description: 'This is the description of second survey', + link: 'http://survey-two.com', + manager: 'FA', + id_database: 2, + nb_datasets: 2 + } +]; + +export const INSTANCE: Instance = { + name: 'myInstance', + label: 'My Instance', + data_path: 'data/path', + config: { + design: { + design_color: 'green', + design_background_color: 'darker green', + design_logo: 'path/to/logo', + design_favicon: 'path/to/favicon' + }, + home: { + home_component: 'HomeComponent', + home_config: { + home_component_text: 'Description', + home_component_logo: 'path/to/logo' + } + }, + search: { + search_by_criteria_allowed: false, + search_by_criteria_label: 'Search', + search_multiple_allowed: false, + search_multiple_label: 'Search multiple', + search_multiple_all_datasets_selected: false + }, + documentation: { + documentation_allowed: false, + documentation_label: 'Documentation' + } + }, + nb_dataset_families: 1, + nb_datasets: 2 +}; + +export const DATASET_FAMILY_LIST: DatasetFamily[] = [ + { id: 2, label: 'My second dataset family', display: 2, opened: false }, + { id: 1, label: 'My first dataset family', display: 1, opened: true } +]; + +export const DATASET_LIST: Dataset[] = [ + { + name: 'myDataset', + table_ref: 'table', + label: 'my dataset', + description: 'This is my dataset', + display: 1, + data_path: 'path', + survey_name: 'mySurvey', + id_dataset_family: 1, + public: true, + full_data_path: '/data/path', + config: { + images: ['image'], + survey: { + survey_enabled: true, + survey_label: 'More about this survey' + }, + cone_search: { + cone_search_enabled: true, + cone_search_opened: true, + cone_search_column_ra: 1, + cone_search_column_dec: 2, + cone_search_plot_enabled: true, + cone_search_sdss_enabled: true, + cone_search_sdss_display: 1, + cone_search_background: [{ id: 1, enabled: true, display: 1 }] + }, + download: { + download_enabled: true, + download_opened: true, + download_csv: true, + download_ascii: true, + download_vo: true, + download_archive: true + }, + summary: { + summary_enabled: true, + summary_opened: true + }, + server_link: { + server_link_enabled: true, + server_link_opened: true + }, + samp: { + samp_enabled: true, + samp_opened: true + }, + datatable: { + datatable_enabled: true, + datatable_opened: true, + datatable_selectable_rows: true + } + } + }, + { + name: 'anotherDataset', + table_ref: 'table', + label: 'amother dataset', + description: 'This is another dataset', + display: 2, + data_path: 'path', + survey_name: 'mySurvey', + id_dataset_family: 1, + public: true, + full_data_path: '/data/path', + config: { + images: ['image'], + survey: { + survey_enabled: true, + survey_label: 'More about this survey' + }, + cone_search: { + cone_search_enabled: true, + cone_search_opened: true, + cone_search_column_ra: 1, + cone_search_column_dec: 2, + cone_search_plot_enabled: true, + cone_search_sdss_enabled: true, + cone_search_sdss_display: 1, + cone_search_background: [{ id: 1, enabled: true, display: 1 }] + }, + download: { + download_enabled: true, + download_opened: true, + download_csv: true, + download_ascii: true, + download_vo: true, + download_archive: true + }, + summary: { + summary_enabled: true, + summary_opened: true + }, + server_link: { + server_link_enabled: true, + server_link_opened: true + }, + samp: { + samp_enabled: true, + samp_opened: true + }, + datatable: { + datatable_enabled: true, + datatable_opened: true, + datatable_selectable_rows: true + } + } + }, +]; export const DATASET: Dataset = { name: 'myDataset',