import { TestBed } from '@angular/core/testing'; import { provideMockActions } from '@ngrx/effects/testing'; import { EffectsMetadata, getEffectsMetadata } from '@ngrx/effects'; import { MockStore, provideMockStore } from '@ngrx/store/testing'; import { Observable } from 'rxjs'; import { cold, hot } from 'jasmine-marbles'; import { ToastrService } from 'ngx-toastr'; import { DetailEffects } from './detail.effects'; import { DetailService } from '../services/detail.service'; import * as detailActions from '../actions/detail.actions'; import * as detailSelector from '../selectors/detail.selector'; import * as attributeSelector from 'src/app/metamodel/selectors/attribute.selector'; import * as datasetSelector from 'src/app/metamodel/selectors/dataset.selector'; import * as fromDetail from '../reducers/detail.reducer'; import * as fromMetamodel from '../../../metamodel/metamodel.reducer'; describe('DetailEffects', () => { let actions = new Observable(); let effects: DetailEffects; let metadata: EffectsMetadata<DetailEffects>; let detailService: DetailService; let store: MockStore; let toastr: ToastrService; let mockDatasetSelectorSelectDatasetNameByRoute; let mockAttributeSelectorSelectAllAttributes; let mockDetailSelectorSelectIdByRoute; const initialState = { metamodel: { ...fromMetamodel.getMetamodelState }, instance: { detail: { ...fromDetail.initialState } } }; beforeEach(() => { TestBed.configureTestingModule({ providers: [ DetailEffects, { provide: DetailService, useValue: { retrieveObject: jest.fn(), retrieveSpectra: jest.fn() }}, { provide: ToastrService, useValue: { error: jest.fn() }}, provideMockActions(() => actions), provideMockStore({ initialState }), ] }).compileComponents(); effects = TestBed.inject(DetailEffects); metadata = getEffectsMetadata(effects); detailService = TestBed.inject(DetailService); store = TestBed.inject(MockStore); toastr = TestBed.inject(ToastrService); mockDatasetSelectorSelectDatasetNameByRoute = store.overrideSelector( datasetSelector.selectDatasetNameByRoute,'' ); mockAttributeSelectorSelectAllAttributes = store.overrideSelector( attributeSelector.selectAllAttributes,[] ); mockDetailSelectorSelectIdByRoute = store.overrideSelector( detailSelector.selectIdByRoute,1 ); }); it('should be created', () => { expect(effects).toBeTruthy(); }); describe('retrieveObject$ effect', () => { it('should dispatch the retrieveObjectSuccess action on success', () => { mockDatasetSelectorSelectDatasetNameByRoute = store.overrideSelector( datasetSelector.selectDatasetNameByRoute, 'myDatasetName' ); mockAttributeSelectorSelectAllAttributes = store.overrideSelector( attributeSelector.selectAllAttributes, [{ id: 1, name: 'myFirstAttribute', label: 'My First Attribute', form_label: 'My First Attribute', output_display: 1, criteria_display: 1, type: 'type', display_detail: 1, order_by: true, detail: true }] ); mockDetailSelectorSelectIdByRoute = store.overrideSelector( detailSelector.selectIdByRoute, 1 ); const action = detailActions.retrieveObject(); const outcome = detailActions.retrieveObjectSuccess({ object: 'myObject' }); actions = hot('-a', { a: action }); const response = cold('-b|', { b: ['myObject'] }); const expected = cold('--c', { c: outcome }); detailService.retrieveObject = jest.fn(() => response); expect(effects.retrieveObject$).toBeObservable(expected); }); it('should dispatch the retrieveObjectFail action on failure', () => { mockDatasetSelectorSelectDatasetNameByRoute = store.overrideSelector( datasetSelector.selectDatasetNameByRoute, 'myDatasetName' ); mockAttributeSelectorSelectAllAttributes = store.overrideSelector( attributeSelector.selectAllAttributes, [{ id: 1, name: 'myFirstAttribute', label: 'My First Attribute', form_label: 'My First Attribute', output_display: 1, criteria_display: 1, type: 'type', display_detail: 1, order_by: true, detail: true }] ); mockDetailSelectorSelectIdByRoute = store.overrideSelector( detailSelector.selectIdByRoute, 1 ); const action = detailActions.retrieveObject(); const error = new Error(); const outcome = detailActions.retrieveObjectFail(); actions = hot('-a', { a: action }); const response = cold('-#|', {}, error); const expected = cold('--b', { b: outcome }); detailService.retrieveObject = jest.fn(() => response); expect(effects.retrieveObject$).toBeObservable(expected); }); }); describe('retrieveObjectFail$ effect', () => { it('should not dispatch', () => { expect(metadata.retrieveObjectFail$).toEqual( expect.objectContaining({ dispatch: false }) ); }); it('should display an error notification', () => { const spy = jest.spyOn(toastr, 'error'); const action = detailActions.retrieveObjectFail(); actions = hot('a', { a: action }); const expected = cold('a', { a: action }); expect(effects.retrieveObjectFail$).toBeObservable(expected); expect(spy).toHaveBeenCalledTimes(1); expect(spy).toHaveBeenCalledWith('Loading Failed!', 'Unable to load the object'); }); }); describe('retrieveSpectra$ effect', () => { it('should dispatch the retrieveSpectraSuccess action on success', () => { mockDatasetSelectorSelectDatasetNameByRoute = store.overrideSelector( datasetSelector.selectDatasetNameByRoute, 'myDatasetName' ); const action = detailActions.retrieveSpectra({ filename: 'mySpectraFilename' }); const outcome = detailActions.retrieveSpectraSuccess({ spectraCSV: 'mySpectraFile' }); actions = hot('-a', { a: action }); const response = cold('-b|', { b: 'mySpectraFile' }); const expected = cold('--c', { c: outcome }); detailService.retrieveSpectra = jest.fn(() => response); expect(effects.retrieveSpectra$).toBeObservable(expected); }); it('should dispatch the retrieveSpectraFail action on failure', () => { mockDatasetSelectorSelectDatasetNameByRoute = store.overrideSelector( datasetSelector.selectDatasetNameByRoute, 'myDatasetName' ); const action = detailActions.retrieveSpectra({ filename: 'mySpectraFilename' }); const error = new Error(); const outcome = detailActions.retrieveSpectraFail(); actions = hot('-a', { a: action }); const response = cold('-#|', {}, error); const expected = cold('--b', { b: outcome }); detailService.retrieveSpectra = jest.fn(() => response); expect(effects.retrieveSpectra$).toBeObservable(expected); }); }); describe('retrieveSpectraFail$ effect', () => { it('should not dispatch', () => { expect(metadata.retrieveSpectraFail$).toEqual( expect.objectContaining({ dispatch: false }) ); }); it('should display an error notification', () => { const spy = jest.spyOn(toastr, 'error'); const action = detailActions.retrieveSpectraFail(); actions = hot('a', { a: action }); const expected = cold('a', { a: action }); expect(effects.retrieveSpectraFail$).toBeObservable(expected); expect(spy).toHaveBeenCalledTimes(1); expect(spy).toHaveBeenCalledWith('Loading Failed!', 'Unable to load spectra'); }); }); });