import { TestBed } from '@angular/core/testing'; import { provideMockActions } from '@ngrx/effects/testing'; import { EffectsMetadata, getEffectsMetadata } from '@ngrx/effects'; import { Observable } from 'rxjs'; import { cold, hot } from 'jasmine-marbles'; import { ToastrService } from 'ngx-toastr'; import { ConeSearchEffects } from './cone-search.effects'; import { ConeSearchService } from '../services/cone-search.service'; import * as coneSearchActions from '../actions/cone-search.actions'; import { Resolver } from '../models'; describe('ConeSearchEffects', () => { let actions = new Observable(); let effects: ConeSearchEffects; let metadata: EffectsMetadata<ConeSearchEffects>; let coneSearchService: ConeSearchService; let toastr: ToastrService; beforeEach(() => { TestBed.configureTestingModule({ providers: [ ConeSearchEffects, { provide: ConeSearchService, useValue: { retrieveCoordinates: jest.fn() }}, { provide: ToastrService, useValue: { error: jest.fn() } }, provideMockActions(() => actions) ] }).compileComponents(); effects = TestBed.inject(ConeSearchEffects); metadata = getEffectsMetadata(effects); coneSearchService = TestBed.inject(ConeSearchService); toastr = TestBed.inject(ToastrService); }); it('should be created', () => { expect(effects).toBeTruthy(); }); describe('retrieveCoordinates$ effect', () => { it('should dispatch the retrieveCoordinatesSuccess action on success', () => { const name: string = 'myObjectName'; const apiResponse = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<Sesame xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" + " xsi:noNamespaceSchemaLocation=\"http://vizier.u-strasbg.fr/xml/sesame_4x.xsd\">\n" + "<Target option=\"NSV\">\n" + " <name>myObjectName</name>\n" + " <!-- Q1525761 #1 -->\n" + " <Resolver name=\"N=NED\"><!--delay: 989ms [2] -->\n" + " <otype>!*</otype>\n" + " <jpos>06:45:09.24 -16:42:47.3</jpos>\n" + " <jradeg>1</jradeg>\n" + " <jdedeg>2</jdedeg>\n" + " <refPos>2007A&A...474..653V</refPos>\n" + " <errRAmas>50</errRAmas><errDEmas>500</errDEmas>\n" + " <oname>Sirius</oname>\n" + " </Resolver>\n" + "</Target>\n" + "</Sesame>\n" + "<!--- ====Done (2021-Aug-04,15:00:56z)==== -->\n"; const resolver: Resolver = { name: 'myObjectName', ra: 1, dec: 2 }; const action = coneSearchActions.retrieveCoordinates({ name }); const outcome = coneSearchActions.retrieveCoordinatesSuccess({ resolver }); actions = hot('-a', { a: action }); const response = cold('-a|', { a: apiResponse }); const expected = cold('--b', { b: outcome }); coneSearchService.retrieveCoordinates = jest.fn(() => response); expect(effects.retrieveCoordinates$).toBeObservable(expected); }); it('should dispatch the retrieveCoordinatesFail action on HTTP failure', () => { const name: string = 'myObjectName'; const action = coneSearchActions.retrieveCoordinates({ name }); const error = new Error(); const outcome = coneSearchActions.retrieveCoordinatesFail(); actions = hot('-a', { a: action }); const response = cold('-#|', {}, error); const expected = cold('--b', { b: outcome }); coneSearchService.retrieveCoordinates = jest.fn(() => response); expect(effects.retrieveCoordinates$).toBeObservable(expected); }); it('should dispatch the retrieveCoordinatesFail action on process failure', () => { const name: string = 'myObjectName'; const apiResponse = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<Sesame xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" + " xsi:noNamespaceSchemaLocation=\"http://vizier.u-strasbg.fr/xml/sesame_4x.xsd\">\n" + "<Target option=\"NSV\">\n" + " <name>myObjectName</name>\n" + " <!-- Q1525761 #1 -->\n" + "</Target>\n" + "</Sesame>\n" + "<!--- ====Done (2021-Aug-04,15:00:56z)==== -->\n"; const action = coneSearchActions.retrieveCoordinates({ name }); const outcome = coneSearchActions.retrieveCoordinatesFail(); actions = hot('-a', { a: action }); const response = cold('-a|', { a: apiResponse }); const expected = cold('--b', { b: outcome }); coneSearchService.retrieveCoordinates = jest.fn(() => response); expect(effects.retrieveCoordinates$).toBeObservable(expected); }); }); describe('retrieveCoordinatesFail$ effect', () => { it('should not dispatch', () => { expect(metadata.retrieveCoordinatesFail$).toEqual( expect.objectContaining({ dispatch: false }) ); }); it('should display an error notification', () => { const spy = jest.spyOn(toastr, 'error'); const action = coneSearchActions.retrieveCoordinatesFail(); actions = hot('a', { a: action }); const expected = cold('a', { a: action }); expect(effects.retrieveCoordinatesFail$).toBeObservable(expected); expect(spy).toHaveBeenCalledTimes(1); expect(spy).toHaveBeenCalledWith('Failure to retrieve coordinates', 'The coordinates could not be retrieved'); }); }); });