diff --git a/client/src/app/metamodel/effects/select-option.effects.spec.ts b/client/src/app/metamodel/effects/select-option.effects.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..cc5c965c2516ed70c9a2f3dbc4eb2e819575cd97 --- /dev/null +++ b/client/src/app/metamodel/effects/select-option.effects.spec.ts @@ -0,0 +1,288 @@ +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 { SelectOptionEffects } from './select-option.effects'; +import { SelectOptionService } from '../services/select-option.service'; +import * as selectOptionActions from '../actions/select-option.actions'; +import { SELECT_OPTION, SELECT_OPTION_LIST } from '../../../test-data'; + +describe('[Metamodel][Effects] SelectOptionEffects', () => { + let actions = new Observable(); + let effects: SelectOptionEffects; + let metadata: EffectsMetadata<SelectOptionEffects>; + let service: SelectOptionService; + let toastr: ToastrService; + + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [ + SelectOptionEffects, + { provide: SelectOptionService, useValue: { retrieveCoordinates: jest.fn() }}, + { provide: ToastrService, useValue: { + success: jest.fn(), + error: jest.fn() + }}, + provideMockActions(() => actions) + ] + }).compileComponents(); + effects = TestBed.inject(SelectOptionEffects); + metadata = getEffectsMetadata(effects); + service = TestBed.inject(SelectOptionService); + toastr = TestBed.inject(ToastrService); + }); + + it('should be created', () => { + expect(effects).toBeTruthy(); + }); + + describe('loadSelectOptions$ effect', () => { + it('should dispatch the loadSelectOptionListSuccess action on success', () => { + const action = selectOptionActions.loadSelectOptionList(); + const outcome = selectOptionActions.loadSelectOptionListSuccess({ selectOptions: SELECT_OPTION_LIST }); + + actions = hot('-a', { a: action }); + const response = cold('-a|', { a: SELECT_OPTION_LIST }); + const expected = cold('--b', { b: outcome }); + service.retrieveSelectOptionList = jest.fn(() => response); + + expect(effects.loadSelectOptions$).toBeObservable(expected); + }); + + it('should dispatch the loadSelectOptionListFail action on HTTP failure', () => { + const action = selectOptionActions.loadSelectOptionList(); + const error = new Error(); + const outcome = selectOptionActions.loadSelectOptionListFail(); + + actions = hot('-a', { a: action }); + const response = cold('-#|', { }, error); + const expected = cold('--b', { b: outcome }); + service.retrieveSelectOptionList = jest.fn(() => response); + + expect(effects.loadSelectOptions$).toBeObservable(expected); + }); + }); + + describe('addSelectOption$ effect', () => { + it('should dispatch the addSelectOptionSuccess action on success', () => { + const action = selectOptionActions.addSelectOption({ selectOption: SELECT_OPTION }); + const outcome = selectOptionActions.addSelectOptionSuccess({ selectOption: SELECT_OPTION}); + + actions = hot('-a', { a: action }); + const response = cold('-a|', { a: SELECT_OPTION }); + const expected = cold('--b', { b: outcome }); + service.addSelectOption = jest.fn(() => response); + + expect(effects.addSelectOption$).toBeObservable(expected); + }); + + it('should dispatch the addSelectOptionFail action on HTTP failure', () => { + const action = selectOptionActions.addSelectOption({ selectOption: SELECT_OPTION }); + const error = new Error(); + const outcome = selectOptionActions.addSelectOptionFail(); + + actions = hot('-a', { a: action }); + const response = cold('-#|', { }, error); + const expected = cold('--b', { b: outcome }); + service.addSelectOption = jest.fn(() => response); + + expect(effects.addSelectOption$).toBeObservable(expected); + }); + }); + + describe('addSelectOptionSuccess$ effect', () => { + it('should not dispatch', () => { + expect(metadata.addSelectOptionSuccess$).toEqual( + expect.objectContaining({ dispatch: false }) + ); + }); + + it('should display a success notification', () => { + const toastrSpy = jest.spyOn(toastr, 'success'); + const action = selectOptionActions.addSelectOptionSuccess({ selectOption: SELECT_OPTION }); + + actions = hot('a', { a: action }); + const expected = cold('a', { a: action }); + + expect(effects.addSelectOptionSuccess$).toBeObservable(expected); + expect(toastrSpy).toHaveBeenCalledTimes(1); + expect(toastrSpy).toHaveBeenCalledWith( + 'Select option successfully added', + 'The new select option was added into the database' + ); + }); + }); + + describe('addSelectOptionFail$ effect', () => { + it('should not dispatch', () => { + expect(metadata.addSelectOptionFail$).toEqual( + expect.objectContaining({ dispatch: false }) + ); + }); + + it('should display an error notification', () => { + const spy = jest.spyOn(toastr, 'error'); + const action = selectOptionActions.addSelectOptionFail(); + + actions = hot('a', { a: action }); + const expected = cold('a', { a: action }); + + expect(effects.addSelectOptionFail$).toBeObservable(expected); + expect(spy).toHaveBeenCalledTimes(1); + expect(spy).toHaveBeenCalledWith( + 'Failure to add select option', + 'The new select option could not be added into the database' + ); + }); + }); + + describe('editSelectOption$ effect', () => { + it('should dispatch the editSelectOptionSuccess action on success', () => { + const action = selectOptionActions.editSelectOption({ selectOption: SELECT_OPTION }); + const outcome = selectOptionActions.editSelectOptionSuccess({ selectOption: SELECT_OPTION}); + + actions = hot('-a', { a: action }); + const response = cold('-a|', { a: SELECT_OPTION }); + const expected = cold('--b', { b: outcome }); + service.editSelectOption = jest.fn(() => response); + + expect(effects.editSelectOption$).toBeObservable(expected); + }); + + it('should dispatch the editSelectOptionFail action on HTTP failure', () => { + const action = selectOptionActions.editSelectOption({ selectOption: SELECT_OPTION }); + const error = new Error(); + const outcome = selectOptionActions.editSelectOptionFail(); + + actions = hot('-a', { a: action }); + const response = cold('-#|', { }, error); + const expected = cold('--b', { b: outcome }); + service.editSelectOption = jest.fn(() => response); + + expect(effects.editSelectOption$).toBeObservable(expected); + }); + }); + + describe('editSelectOptionSuccess$ effect', () => { + it('should not dispatch', () => { + expect(metadata.editSelectOptionSuccess$).toEqual( + expect.objectContaining({ dispatch: false }) + ); + }); + + it('should display a success notification', () => { + const toastrSpy = jest.spyOn(toastr, 'success'); + const action = selectOptionActions.editSelectOptionSuccess({ selectOption: SELECT_OPTION }); + + actions = hot('a', { a: action }); + const expected = cold('a', { a: action }); + + expect(effects.editSelectOptionSuccess$).toBeObservable(expected); + expect(toastrSpy).toHaveBeenCalledTimes(1); + expect(toastrSpy).toHaveBeenCalledWith( + 'Select option successfully edited', + 'The existing select option has been edited into the database' + ); + }); + }); + + describe('editSelectOptionFail$ effect', () => { + it('should not dispatch', () => { + expect(metadata.editSelectOptionFail$).toEqual( + expect.objectContaining({ dispatch: false }) + ); + }); + + it('should display an error notification', () => { + const spy = jest.spyOn(toastr, 'error'); + const action = selectOptionActions.editSelectOptionFail(); + + actions = hot('a', { a: action }); + const expected = cold('a', { a: action }); + + expect(effects.editSelectOptionFail$).toBeObservable(expected); + expect(spy).toHaveBeenCalledTimes(1); + expect(spy).toHaveBeenCalledWith( + 'Failure to edit select option', + 'The existing select option could not be edited into the database' + ); + }); + }); + + describe('deleteSelectOption$ effect', () => { + it('should dispatch the deleteSelectOptionSuccess action on success', () => { + const action = selectOptionActions.deleteSelectOption({ selectOption: SELECT_OPTION }); + const outcome = selectOptionActions.deleteSelectOptionSuccess({ selectOption: SELECT_OPTION}); + + actions = hot('-a', { a: action }); + const response = cold('-a|', { a: SELECT_OPTION }); + const expected = cold('--b', { b: outcome }); + service.deleteSelectOption = jest.fn(() => response); + + expect(effects.deleteSelectOption$).toBeObservable(expected); + }); + + it('should dispatch the deleteSelectOptionFail action on HTTP failure', () => { + const action = selectOptionActions.deleteSelectOption({ selectOption: SELECT_OPTION }); + const error = new Error(); + const outcome = selectOptionActions.deleteSelectOptionFail(); + + actions = hot('-a', { a: action }); + const response = cold('-#|', { }, error); + const expected = cold('--b', { b: outcome }); + service.deleteSelectOption = jest.fn(() => response); + + expect(effects.deleteSelectOption$).toBeObservable(expected); + }); + }); + + describe('deleteSelectOptionSuccess$ effect', () => { + it('should not dispatch', () => { + expect(metadata.deleteSelectOptionSuccess$).toEqual( + expect.objectContaining({ dispatch: false }) + ); + }); + + it('should display a success notification', () => { + const toastrSpy = jest.spyOn(toastr, 'success'); + const action = selectOptionActions.deleteSelectOptionSuccess({ selectOption: SELECT_OPTION }); + + actions = hot('a', { a: action }); + const expected = cold('a', { a: action }); + + expect(effects.deleteSelectOptionSuccess$).toBeObservable(expected); + expect(toastrSpy).toHaveBeenCalledTimes(1); + expect(toastrSpy).toHaveBeenCalledWith( + 'Select option successfully deleted', + 'The existing select option has been deleted' + ); + }); + }); + + describe('deleteSelectOptionFail$ effect', () => { + it('should not dispatch', () => { + expect(metadata.deleteSelectOptionFail$).toEqual( + expect.objectContaining({ dispatch: false }) + ); + }); + + it('should display an error notification', () => { + const spy = jest.spyOn(toastr, 'error'); + const action = selectOptionActions.deleteSelectOptionFail(); + + actions = hot('a', { a: action }); + const expected = cold('a', { a: action }); + + expect(effects.deleteSelectOptionFail$).toBeObservable(expected); + expect(spy).toHaveBeenCalledTimes(1); + expect(spy).toHaveBeenCalledWith( + 'Failure to delete select option', + 'The existing select option could not be deleted from the database' + ); + }); + }); +}); diff --git a/client/src/app/metamodel/effects/select-option.effects.ts b/client/src/app/metamodel/effects/select-option.effects.ts index eb98f8546f0da591b95a8f7827ba69492926a885..2beaf5ae6a83a22aa6e589f4f79a1081c6c3ae7e 100644 --- a/client/src/app/metamodel/effects/select-option.effects.ts +++ b/client/src/app/metamodel/effects/select-option.effects.ts @@ -16,11 +16,18 @@ import { ToastrService } from 'ngx-toastr'; import * as selectOptionActions from '../actions/select-option.actions'; import { SelectOptionService } from '../services/select-option.service'; - + +/** + * @class + * @classdesc Select option effects. + */ @Injectable() export class SelectOptionEffects { - - loadSelectOptions$ = createEffect(() => + + /** + * Calls action to retrieve select option list. + */ + loadSelectOptions$ = createEffect((): any => this.actions$.pipe( ofType(selectOptionActions.loadSelectOptionList), mergeMap(() => this.selectOptionService.retrieveSelectOptionList() @@ -31,8 +38,11 @@ export class SelectOptionEffects { ) ) ); - - addSelectOption$ = createEffect(() => + + /** + * Calls action to add a select option. + */ + addSelectOption$ = createEffect((): any => this.actions$.pipe( ofType(selectOptionActions.addSelectOption), mergeMap(action => this.selectOptionService.addSelectOption(action.selectOption) @@ -44,21 +54,30 @@ export class SelectOptionEffects { ) ); - addSelectOptionSuccess$ = createEffect(() => + /** + * Displays add select option success notification. + */ + addSelectOptionSuccess$ = createEffect(() => this.actions$.pipe( ofType(selectOptionActions.addSelectOptionSuccess), tap(() => this.toastr.success('Select option successfully added', 'The new select option was added into the database')) - ), { dispatch: false} + ), { dispatch: false } ); - addSelectOptionFail$ = createEffect(() => + /** + * Displays add select option error notification. + */ + addSelectOptionFail$ = createEffect(() => this.actions$.pipe( ofType(selectOptionActions.addSelectOptionFail), tap(() => this.toastr.error('Failure to add select option', 'The new select option could not be added into the database')) - ), { dispatch: false} + ), { dispatch: false } ); - editSelectOption$ = createEffect(() => + /** + * Calls action to modify a select option. + */ + editSelectOption$ = createEffect((): any => this.actions$.pipe( ofType(selectOptionActions.editSelectOption), mergeMap(action => this.selectOptionService.editSelectOption(action.selectOption) @@ -70,21 +89,30 @@ export class SelectOptionEffects { ) ); - editSelectOptionSuccess$ = createEffect(() => + /** + * Displays edit select option success notification. + */ + editSelectOptionSuccess$ = createEffect(() => this.actions$.pipe( ofType(selectOptionActions.editSelectOptionSuccess), tap(() => this.toastr.success('Select option successfully edited', 'The existing select option has been edited into the database')) - ), { dispatch: false} + ), { dispatch: false } ); - editSelectOptionFail$ = createEffect(() => + /** + * Displays edit select option error notification. + */ + editSelectOptionFail$ = createEffect(() => this.actions$.pipe( ofType(selectOptionActions.editSelectOptionFail), tap(() => this.toastr.error('Failure to edit select option', 'The existing select option could not be edited into the database')) - ), { dispatch: false} + ), { dispatch: false } ); - deleteSelectOption$ = createEffect(() => + /** + * Calls action to remove a select option. + */ + deleteSelectOption$ = createEffect(():any => this.actions$.pipe( ofType(selectOptionActions.deleteSelectOption), mergeMap(action => this.selectOptionService.deleteSelectOption(action.selectOption.id) @@ -96,18 +124,24 @@ export class SelectOptionEffects { ) ); - deleteSelectOptionSuccess$ = createEffect(() => + /** + * Displays delete select option success notification. + */ + deleteSelectOptionSuccess$ = createEffect(() => this.actions$.pipe( ofType(selectOptionActions.deleteSelectOptionSuccess), tap(() => this.toastr.success('Select option successfully deleted', 'The existing select option has been deleted')) - ), { dispatch: false} + ), { dispatch: false } ); - deleteSelectOptionFail$ = createEffect(() => + /** + * Displays delete select option error notification. + */ + deleteSelectOptionFail$ = createEffect(() => this.actions$.pipe( ofType(selectOptionActions.deleteSelectOptionFail), tap(() => this.toastr.error('Failure to delete select option', 'The existing select option could not be deleted from the database')) - ), { dispatch: false} + ), { dispatch: false } ); constructor( diff --git a/client/src/app/metamodel/effects/select.effects.spec.ts b/client/src/app/metamodel/effects/select.effects.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..3032179c724aac54a4319b184eb75d4f11511213 --- /dev/null +++ b/client/src/app/metamodel/effects/select.effects.spec.ts @@ -0,0 +1,290 @@ +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 { SelectEffects } from './select.effects'; +import { SelectService } from '../services/select.service'; +import * as selectActions from '../actions/select.actions'; +import { SELECT, SELECT_LIST } from '../../../test-data'; + +describe('[Metamodel][Effects] SelectEffects', () => { + let actions = new Observable(); + let effects: SelectEffects; + let metadata: EffectsMetadata<SelectEffects>; + let service: SelectService; + let toastr: ToastrService; + + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [ + SelectEffects, + {provide: SelectService, useValue: {retrieveCoordinates: jest.fn()}}, + { + provide: ToastrService, useValue: { + success: jest.fn(), + error: jest.fn() + } + }, + provideMockActions(() => actions) + ] + }).compileComponents(); + effects = TestBed.inject(SelectEffects); + metadata = getEffectsMetadata(effects); + service = TestBed.inject(SelectService); + toastr = TestBed.inject(ToastrService); + }); + + it('should be created', () => { + expect(effects).toBeTruthy(); + }); + + describe('loadSelects$ effect', () => { + it('should dispatch the loadSelectListSuccess action on success', () => { + const action = selectActions.loadSelectList(); + const outcome = selectActions.loadSelectListSuccess({ selects: SELECT_LIST }); + + actions = hot('-a', { a: action }); + const response = cold('-a|', { a: SELECT_LIST }); + const expected = cold('--b', { b: outcome }); + service.retrieveSelectList = jest.fn(() => response); + + expect(effects.loadSelects$).toBeObservable(expected); + }); + + it('should dispatch the loadSelectListFail action on HTTP failure', () => { + const action = selectActions.loadSelectList(); + const error = new Error(); + const outcome = selectActions.loadSelectListFail(); + + actions = hot('-a', { a: action }); + const response = cold('-#|', { }, error); + const expected = cold('--b', { b: outcome }); + service.retrieveSelectList = jest.fn(() => response); + + expect(effects.loadSelects$).toBeObservable(expected); + }); + }); + + describe('addSelect$ effect', () => { + it('should dispatch the addSelectSuccess action on success', () => { + const action = selectActions.addSelect({ select: SELECT }); + const outcome = selectActions.addSelectSuccess({ select: SELECT}); + + actions = hot('-a', { a: action }); + const response = cold('-a|', { a: SELECT }); + const expected = cold('--b', { b: outcome }); + service.addSelect = jest.fn(() => response); + + expect(effects.addSelect$).toBeObservable(expected); + }); + + it('should dispatch the addSelectFail action on HTTP failure', () => { + const action = selectActions.addSelect({ select: SELECT }); + const error = new Error(); + const outcome = selectActions.addSelectFail(); + + actions = hot('-a', { a: action }); + const response = cold('-#|', { }, error); + const expected = cold('--b', { b: outcome }); + service.addSelect = jest.fn(() => response); + + expect(effects.addSelect$).toBeObservable(expected); + }); + }); + + describe('addSelectSuccess$ effect', () => { + it('should not dispatch', () => { + expect(metadata.addSelectSuccess$).toEqual( + expect.objectContaining({ dispatch: false }) + ); + }); + + it('should display a success notification', () => { + const toastrSpy = jest.spyOn(toastr, 'success'); + const action = selectActions.addSelectSuccess({ select: SELECT }); + + actions = hot('a', { a: action }); + const expected = cold('a', { a: action }); + + expect(effects.addSelectSuccess$).toBeObservable(expected); + expect(toastrSpy).toHaveBeenCalledTimes(1); + expect(toastrSpy).toHaveBeenCalledWith( + 'Select successfully added', + 'The new select was added into the database' + ); + }); + }); + + describe('addSelectFail$ effect', () => { + it('should not dispatch', () => { + expect(metadata.addSelectFail$).toEqual( + expect.objectContaining({ dispatch: false }) + ); + }); + + it('should display an error notification', () => { + const spy = jest.spyOn(toastr, 'error'); + const action = selectActions.addSelectFail(); + + actions = hot('a', { a: action }); + const expected = cold('a', { a: action }); + + expect(effects.addSelectFail$).toBeObservable(expected); + expect(spy).toHaveBeenCalledTimes(1); + expect(spy).toHaveBeenCalledWith( + 'Failure to add select', + 'The new select could not be added into the database' + ); + }); + }); + + describe('editSelect$ effect', () => { + it('should dispatch the editSelectSuccess action on success', () => { + const action = selectActions.editSelect({ select: SELECT }); + const outcome = selectActions.editSelectSuccess({ select: SELECT}); + + actions = hot('-a', { a: action }); + const response = cold('-a|', { a: SELECT }); + const expected = cold('--b', { b: outcome }); + service.editSelect = jest.fn(() => response); + + expect(effects.editSelect$).toBeObservable(expected); + }); + + it('should dispatch the editSelectFail action on HTTP failure', () => { + const action = selectActions.editSelect({ select: SELECT }); + const error = new Error(); + const outcome = selectActions.editSelectFail(); + + actions = hot('-a', { a: action }); + const response = cold('-#|', { }, error); + const expected = cold('--b', { b: outcome }); + service.editSelect = jest.fn(() => response); + + expect(effects.editSelect$).toBeObservable(expected); + }); + }); + + describe('editSelectSuccess$ effect', () => { + it('should not dispatch', () => { + expect(metadata.editSelectSuccess$).toEqual( + expect.objectContaining({ dispatch: false }) + ); + }); + + it('should display a success notification', () => { + const toastrSpy = jest.spyOn(toastr, 'success'); + const action = selectActions.editSelectSuccess({ select: SELECT }); + + actions = hot('a', { a: action }); + const expected = cold('a', { a: action }); + + expect(effects.editSelectSuccess$).toBeObservable(expected); + expect(toastrSpy).toHaveBeenCalledTimes(1); + expect(toastrSpy).toHaveBeenCalledWith( + 'Select successfully edited', + 'The existing select has been edited into the database' + ); + }); + }); + + describe('editSelectFail$ effect', () => { + it('should not dispatch', () => { + expect(metadata.editSelectFail$).toEqual( + expect.objectContaining({ dispatch: false }) + ); + }); + + it('should display an error notification', () => { + const spy = jest.spyOn(toastr, 'error'); + const action = selectActions.editSelectFail(); + + actions = hot('a', { a: action }); + const expected = cold('a', { a: action }); + + expect(effects.editSelectFail$).toBeObservable(expected); + expect(spy).toHaveBeenCalledTimes(1); + expect(spy).toHaveBeenCalledWith( + 'Failure to edit select', + 'The existing select could not be edited into the database' + ); + }); + }); + + describe('deleteSelect$ effect', () => { + it('should dispatch the deleteSelectSuccess action on success', () => { + const action = selectActions.deleteSelect({ select: SELECT }); + const outcome = selectActions.deleteSelectSuccess({ select: SELECT}); + + actions = hot('-a', { a: action }); + const response = cold('-a|', { a: SELECT }); + const expected = cold('--b', { b: outcome }); + service.deleteSelect = jest.fn(() => response); + + expect(effects.deleteSelect$).toBeObservable(expected); + }); + + it('should dispatch the deleteSelectFail action on HTTP failure', () => { + const action = selectActions.deleteSelect({ select: SELECT }); + const error = new Error(); + const outcome = selectActions.deleteSelectFail(); + + actions = hot('-a', { a: action }); + const response = cold('-#|', { }, error); + const expected = cold('--b', { b: outcome }); + service.deleteSelect = jest.fn(() => response); + + expect(effects.deleteSelect$).toBeObservable(expected); + }); + }); + + describe('deleteSelectSuccess$ effect', () => { + it('should not dispatch', () => { + expect(metadata.deleteSelectSuccess$).toEqual( + expect.objectContaining({ dispatch: false }) + ); + }); + + it('should display a success notification', () => { + const toastrSpy = jest.spyOn(toastr, 'success'); + const action = selectActions.deleteSelectSuccess({ select: SELECT }); + + actions = hot('a', { a: action }); + const expected = cold('a', { a: action }); + + expect(effects.deleteSelectSuccess$).toBeObservable(expected); + expect(toastrSpy).toHaveBeenCalledTimes(1); + expect(toastrSpy).toHaveBeenCalledWith( + 'Select successfully deleted', + 'The existing select has been deleted' + ); + }); + }); + + describe('deleteSelectFail$ effect', () => { + it('should not dispatch', () => { + expect(metadata.deleteSelectFail$).toEqual( + expect.objectContaining({ dispatch: false }) + ); + }); + + it('should display an error notification', () => { + const spy = jest.spyOn(toastr, 'error'); + const action = selectActions.deleteSelectFail(); + + actions = hot('a', { a: action }); + const expected = cold('a', { a: action }); + + expect(effects.deleteSelectFail$).toBeObservable(expected); + expect(spy).toHaveBeenCalledTimes(1); + expect(spy).toHaveBeenCalledWith( + 'Failure to delete select', + 'The existing select could not be deleted from the database' + ); + }); + }); +}); diff --git a/client/src/app/metamodel/effects/select.effects.ts b/client/src/app/metamodel/effects/select.effects.ts index b3f53c9151a0cc5aa412113297b53150c800183f..c4a21e361d5b0bc916e862217c1604c05048eae0 100644 --- a/client/src/app/metamodel/effects/select.effects.ts +++ b/client/src/app/metamodel/effects/select.effects.ts @@ -16,10 +16,18 @@ import { ToastrService } from 'ngx-toastr'; import * as selectActions from '../actions/select.actions'; import { SelectService } from '../services/select.service'; - + +/** + * @class + * @classdesc Select effects. + */ @Injectable() export class SelectEffects { - loadSelects$ = createEffect(() => + + /** + * Calls action to retrieve select list. + */ + loadSelects$ = createEffect((): any => this.actions$.pipe( ofType(selectActions.loadSelectList), mergeMap(() => this.selectService.retrieveSelectList() @@ -31,7 +39,10 @@ export class SelectEffects { ) ); - addSelect$ = createEffect(() => + /** + * Calls action to add a select. + */ + addSelect$ = createEffect((): any => this.actions$.pipe( ofType(selectActions.addSelect), mergeMap(action => this.selectService.addSelect(action.select) @@ -43,21 +54,30 @@ export class SelectEffects { ) ); - addSelectSuccess$ = createEffect(() => + /** + * Displays add select success notification. + */ + addSelectSuccess$ = createEffect(() => this.actions$.pipe( ofType(selectActions.addSelectSuccess), tap(() => this.toastr.success('Select successfully added', 'The new select was added into the database')) - ), { dispatch: false} + ), { dispatch: false } ); - addSelectFail$ = createEffect(() => + /** + * Displays add select error notification. + */ + addSelectFail$ = createEffect(() => this.actions$.pipe( ofType(selectActions.addSelectFail), tap(() => this.toastr.error('Failure to add select', 'The new select could not be added into the database')) - ), { dispatch: false} + ), { dispatch: false } ); - editSelect$ = createEffect(() => + /** + * Calls action to modify a select. + */ + editSelect$ = createEffect((): any => this.actions$.pipe( ofType(selectActions.editSelect), mergeMap(action => this.selectService.editSelect(action.select) @@ -69,21 +89,30 @@ export class SelectEffects { ) ); - editSelectSuccess$ = createEffect(() => + /** + * Displays edit select success notification. + */ + editSelectSuccess$ = createEffect(() => this.actions$.pipe( ofType(selectActions.editSelectSuccess), tap(() => this.toastr.success('Select successfully edited', 'The existing select has been edited into the database')) - ), { dispatch: false} + ), { dispatch: false } ); - editSelectFail$ = createEffect(() => + /** + * Displays edit select success notification. + */ + editSelectFail$ = createEffect(() => this.actions$.pipe( ofType(selectActions.editSelectFail), tap(() => this.toastr.error('Failure to edit select', 'The existing select could not be edited into the database')) - ), { dispatch: false} + ), { dispatch: false } ); - deleteSelect$ = createEffect(() => + /** + * Calls action to remove a select. + */ + deleteSelect$ = createEffect((): any => this.actions$.pipe( ofType(selectActions.deleteSelect), mergeMap(action => this.selectService.deleteSelect(action.select.name) @@ -95,20 +124,26 @@ export class SelectEffects { ) ); - deleteSelectSuccess$ = createEffect(() => + /** + * Displays delete select success notification. + */ + deleteSelectSuccess$ = createEffect(() => this.actions$.pipe( ofType(selectActions.deleteSelectSuccess), tap(() => this.toastr.success('Select successfully deleted', 'The existing select has been deleted')) - ), { dispatch: false} + ), { dispatch: false } ); - deleteSelectFail$ = createEffect(() => + /** + * Displays delete select error notification. + */ + deleteSelectFail$ = createEffect(() => this.actions$.pipe( ofType(selectActions.deleteSelectFail), tap(() => this.toastr.error('Failure to delete select', 'The existing select could not be deleted from the database')) - ), { dispatch: false} + ), { dispatch: false } ); - + constructor( private actions$: Actions, private selectService: SelectService, diff --git a/client/src/app/metamodel/effects/table.effects.spec.ts b/client/src/app/metamodel/effects/table.effects.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..ce9ea6595e9836e35c34711bb210571ef6c466a8 --- /dev/null +++ b/client/src/app/metamodel/effects/table.effects.spec.ts @@ -0,0 +1,61 @@ +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 { TableEffects } from './table.effects'; +import { TableService } from '../services/table.service'; +import * as tableActions from '../actions/table.actions'; + +describe('[Metamodel][Effects] TableEffects', () => { + let actions = new Observable(); + let effects: TableEffects; + let metadata: EffectsMetadata<TableEffects>; + let service: TableService; + + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [ + TableEffects, + { provide: TableService, useValue: { retrieveCoordinates: jest.fn() }}, + provideMockActions(() => actions) + ] + }).compileComponents(); + effects = TestBed.inject(TableEffects); + metadata = getEffectsMetadata(effects); + service = TestBed.inject(TableService); + }); + + it('should be created', () => { + expect(effects).toBeTruthy(); + }); + + describe('loadTables$ effect', () => { + it('should dispatch the loadTableListSuccess action on success', () => { + const action = tableActions.loadTableList({ idDatabase: 1 }); + const outcome = tableActions.loadTableListSuccess({ tables: ['table1', 'table2'] }); + + actions = hot('-a', { a: action }); + const response = cold('-a|', { a: ['table1', 'table2'] }); + const expected = cold('--b', { b: outcome }); + service.retrieveTableList = jest.fn(() => response); + + expect(effects.loadTables$).toBeObservable(expected); + }); + + it('should dispatch the loadTableListFail action on HTTP failure', () => { + const action = tableActions.loadTableList({ idDatabase: 1 }); + const error = new Error(); + const outcome = tableActions.loadTableListFail(); + + actions = hot('-a', { a: action }); + const response = cold('-#|', { }, error); + const expected = cold('--b', { b: outcome }); + service.retrieveTableList = jest.fn(() => response); + + expect(effects.loadTables$).toBeObservable(expected); + }); + }); +}); diff --git a/client/src/app/metamodel/effects/table.effects.ts b/client/src/app/metamodel/effects/table.effects.ts index 669c08feb9a6fbe8ce5b8b83fd061f50f4955144..9a507ce2be574c5d480e6ee67fc286a82b82cc16 100644 --- a/client/src/app/metamodel/effects/table.effects.ts +++ b/client/src/app/metamodel/effects/table.effects.ts @@ -22,6 +22,7 @@ import { TableService } from '../services/table.service'; */ @Injectable() export class TableEffects { + /** * Calls action to retrieve table list. */