mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-31 09:37:15 +01:00
#1077 Add Unit Tests For Cancellation
This commit is contained in:
@@ -40,6 +40,7 @@ fdescribe('ShelfSearchComponent', () => {
|
||||
resetSelectedFilters: () => {},
|
||||
getProcessId: () => Promise.resolve(processId),
|
||||
getProcess$: of(process),
|
||||
cancelSearch: () => {},
|
||||
}),
|
||||
},
|
||||
WindowRef,
|
||||
@@ -69,6 +70,11 @@ fdescribe('ShelfSearchComponent', () => {
|
||||
expect(component instanceof ShelfSearchComponent).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should cancel outstanding requests on destroy', () => {
|
||||
component.ngOnDestroy();
|
||||
expect(searchFacade.cancelSearch).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should restore the initial state on page load (onInit)', () => {
|
||||
expect(component.restoreInitialState).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
@@ -2,21 +2,25 @@ import { SearchStateFacade } from './search.facade';
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { Store, StoreModule } from '@ngrx/store';
|
||||
import { Store as NgxsStore, NgxsModule } from '@ngxs/store';
|
||||
import { primaryFiltersMock, mockFilters } from 'apps/sales/src/app/modules/shelf/shared/mockdata';
|
||||
import {
|
||||
primaryFiltersMock,
|
||||
mockFilters,
|
||||
} from 'apps/sales/src/app/modules/shelf/shared/mockdata';
|
||||
import { PrimaryFilterOption } from 'apps/sales/src/app/modules/shelf/defs';
|
||||
import { of, Observable } from 'rxjs';
|
||||
import { of, Observable, Subject } from 'rxjs';
|
||||
import * as actions from './search.actions';
|
||||
import * as selectors from './search.selectors';
|
||||
import { SelectFilter } from 'apps/sales/src/app/modules/filter';
|
||||
import { first } from 'rxjs/operators';
|
||||
import { hot, cold } from 'jasmine-marbles';
|
||||
import { TypedAction } from '@ngrx/store/src/models';
|
||||
|
||||
fdescribe('SearchFacade', () => {
|
||||
let facade: SearchStateFacade;
|
||||
let store: Store<any>;
|
||||
let ngxsStore: NgxsStore;
|
||||
|
||||
const id = 123;
|
||||
|
||||
beforeEach(async () => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [StoreModule.forRoot({}), NgxsModule.forRoot()],
|
||||
@@ -28,6 +32,10 @@ fdescribe('SearchFacade', () => {
|
||||
facade = TestBed.get(SearchStateFacade);
|
||||
store = TestBed.get(Store);
|
||||
ngxsStore = TestBed.get(NgxsStore);
|
||||
|
||||
spyOn(facade, 'getProcessId').and.returnValue(
|
||||
new Promise((resolve) => resolve(id))
|
||||
);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
@@ -44,7 +52,9 @@ fdescribe('SearchFacade', () => {
|
||||
it('should dispatch setPrimary in Store', async () => {
|
||||
spyOn(store, 'dispatch').and.callThrough();
|
||||
spyOn(facade, 'setPrimaryFilters').and.callThrough();
|
||||
spyOn(facade, 'getPrimaryFilters$').and.returnValue(of(primaryFiltersMock));
|
||||
spyOn(facade, 'getPrimaryFilters$').and.returnValue(
|
||||
of(primaryFiltersMock)
|
||||
);
|
||||
|
||||
await facade.setPrimaryFilters(primaryFilterOption, id);
|
||||
|
||||
@@ -54,13 +64,17 @@ fdescribe('SearchFacade', () => {
|
||||
it('should keep the original order of filter when dispatching setPrimary in Store', async () => {
|
||||
spyOn(store, 'dispatch').and.callThrough();
|
||||
spyOn(facade, 'setPrimaryFilters').and.callThrough();
|
||||
spyOn(facade, 'getPrimaryFilters$').and.returnValue(of(primaryFiltersMock));
|
||||
spyOn(facade, 'getPrimaryFilters$').and.returnValue(
|
||||
of(primaryFiltersMock)
|
||||
);
|
||||
|
||||
await facade.setPrimaryFilters(primaryFilterOption, id);
|
||||
|
||||
const updatedFilters = [primaryFilterOption, primaryFiltersMock[1]];
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith(actions.setPrimaryFilters({ filters: updatedFilters, id }));
|
||||
expect(store.dispatch).toHaveBeenCalledWith(
|
||||
actions.setPrimaryFilters({ filters: updatedFilters, id })
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -101,8 +115,12 @@ fdescribe('SearchFacade', () => {
|
||||
selected: false,
|
||||
},
|
||||
]);
|
||||
spyOnProperty(facade, 'selectFilters$', 'get').and.returnValue(currentFilters);
|
||||
spyOnProperty(facade, 'primaryFilters$', 'get').and.returnValue(primaryFilters);
|
||||
spyOnProperty(facade, 'selectFilters$', 'get').and.returnValue(
|
||||
currentFilters
|
||||
);
|
||||
spyOnProperty(facade, 'primaryFilters$', 'get').and.returnValue(
|
||||
primaryFilters
|
||||
);
|
||||
|
||||
const result = await facade.selectedFilter$.pipe(first()).toPromise();
|
||||
|
||||
@@ -123,26 +141,40 @@ fdescribe('SearchFacade', () => {
|
||||
});
|
||||
|
||||
it('should return true if the select filters are changed', async () => {
|
||||
spyOnProperty(facade, 'primaryFilters$', 'get').and.returnValue(of(primaryFilters));
|
||||
spyOnProperty(facade, 'primaryFilters$', 'get').and.returnValue(
|
||||
of(primaryFilters)
|
||||
);
|
||||
const updatedSelectFilters = [
|
||||
...selectFilters.map((filter) =>
|
||||
filter.options
|
||||
? {
|
||||
...filter,
|
||||
options: filter.options.map((o, i) => (!i ? { ...o, selected: !o.initial_selected_state } : o)),
|
||||
options: filter.options.map((o, i) =>
|
||||
!i ? { ...o, selected: !o.initial_selected_state } : o
|
||||
),
|
||||
}
|
||||
: filter
|
||||
),
|
||||
];
|
||||
spyOnProperty(facade, 'selectFilters$', 'get').and.returnValue(of(updatedSelectFilters));
|
||||
const result = await facade.filtersChangedFromDefault$.pipe(first()).toPromise();
|
||||
spyOnProperty(facade, 'selectFilters$', 'get').and.returnValue(
|
||||
of(updatedSelectFilters)
|
||||
);
|
||||
const result = await facade.filtersChangedFromDefault$
|
||||
.pipe(first())
|
||||
.toPromise();
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
it('should return false if the select filters are unchanged', async () => {
|
||||
spyOnProperty(facade, 'primaryFilters$', 'get').and.returnValue(of(primaryFilters));
|
||||
spyOnProperty(facade, 'selectFilters$', 'get').and.returnValue(of(selectFilters));
|
||||
const result = await facade.filtersChangedFromDefault$.pipe(first()).toPromise();
|
||||
spyOnProperty(facade, 'primaryFilters$', 'get').and.returnValue(
|
||||
of(primaryFilters)
|
||||
);
|
||||
spyOnProperty(facade, 'selectFilters$', 'get').and.returnValue(
|
||||
of(selectFilters)
|
||||
);
|
||||
const result = await facade.filtersChangedFromDefault$
|
||||
.pipe(first())
|
||||
.toPromise();
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
@@ -152,8 +184,16 @@ fdescribe('SearchFacade', () => {
|
||||
const primaryFilterChangedFromDefault$ = hot('--a', { a: false });
|
||||
const expected = cold('--b', { b: false });
|
||||
|
||||
spyOnProperty(facade, 'selectedFilterChangedFromDefault$', 'get').and.returnValue(selectedFilterChangedFromDefault$);
|
||||
spyOnProperty(facade, 'primaryFilterChangedFromDefault$', 'get').and.returnValue(primaryFilterChangedFromDefault$);
|
||||
spyOnProperty(
|
||||
facade,
|
||||
'selectedFilterChangedFromDefault$',
|
||||
'get'
|
||||
).and.returnValue(selectedFilterChangedFromDefault$);
|
||||
spyOnProperty(
|
||||
facade,
|
||||
'primaryFilterChangedFromDefault$',
|
||||
'get'
|
||||
).and.returnValue(primaryFilterChangedFromDefault$);
|
||||
|
||||
expect(facade.filtersChangedFromDefault$).toBeObservable(expected);
|
||||
});
|
||||
@@ -165,8 +205,12 @@ fdescribe('SearchFacade', () => {
|
||||
});
|
||||
const expected = cold('--b', { b: true });
|
||||
|
||||
spyOnProperty(facade, 'selectFilters$', 'get').and.returnValue(selectFilters$);
|
||||
spyOnProperty(facade, 'primaryFilters$', 'get').and.returnValue(primaryFilters$);
|
||||
spyOnProperty(facade, 'selectFilters$', 'get').and.returnValue(
|
||||
selectFilters$
|
||||
);
|
||||
spyOnProperty(facade, 'primaryFilters$', 'get').and.returnValue(
|
||||
primaryFilters$
|
||||
);
|
||||
|
||||
expect(facade.filtersChangedFromDefault$).toBeObservable(expected);
|
||||
});
|
||||
@@ -184,7 +228,10 @@ fdescribe('SearchFacade', () => {
|
||||
|
||||
await facade.pendingInput$.pipe(first()).toPromise();
|
||||
expect(ngxsStore.select).toHaveBeenCalled();
|
||||
expect(store.select).toHaveBeenCalledWith(selectors.selectPendingInput, 123);
|
||||
expect(store.select).toHaveBeenCalledWith(
|
||||
selectors.selectPendingInput,
|
||||
123
|
||||
);
|
||||
});
|
||||
|
||||
it('should return the pending input for the provided id', () => {
|
||||
@@ -201,10 +248,7 @@ fdescribe('SearchFacade', () => {
|
||||
});
|
||||
|
||||
describe('setPendingInput', () => {
|
||||
const id = 123;
|
||||
|
||||
beforeEach(() => {
|
||||
spyOn(facade, 'getProcessId').and.returnValue(new Promise((resolve) => resolve(id)));
|
||||
spyOn(facade, 'setPendingInput').and.callThrough();
|
||||
spyOn(store, 'dispatch').and.callThrough();
|
||||
});
|
||||
@@ -213,14 +257,43 @@ fdescribe('SearchFacade', () => {
|
||||
await facade.setPendingInput('Input Without Id');
|
||||
|
||||
expect(facade.getProcessId).toHaveBeenCalled();
|
||||
expect(store.dispatch).toHaveBeenCalledWith(actions.setPendingInput({ id, input: pendingInput }));
|
||||
expect(store.dispatch).toHaveBeenCalledWith(
|
||||
actions.setPendingInput({ id, input: pendingInput })
|
||||
);
|
||||
});
|
||||
it('should dispach set input to the store', async () => {
|
||||
const pendingInput = 'Input With Id';
|
||||
await facade.setPendingInput(pendingInput, id);
|
||||
|
||||
expect(facade.getProcessId).not.toHaveBeenCalled();
|
||||
expect(store.dispatch).toHaveBeenCalledWith(actions.setPendingInput({ id, input: pendingInput }));
|
||||
expect(store.dispatch).toHaveBeenCalledWith(
|
||||
actions.setPendingInput({ id, input: pendingInput })
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('cancelSearch', () => {
|
||||
let sub: Subject<void>;
|
||||
|
||||
beforeEach(() => {
|
||||
sub = new Subject<void>();
|
||||
spyOn(sub, 'complete').and.callThrough();
|
||||
spyOn(facade['shouldCancelSearchRequestMap'], 'get').and.returnValue(sub);
|
||||
});
|
||||
|
||||
it('should get the current process id and get the respective cancellation subject and complete it', async () => {
|
||||
await facade.cancelSearch();
|
||||
expect(
|
||||
facade['shouldCancelSearchRequestMap']['get']
|
||||
).toHaveBeenCalledWith(id);
|
||||
expect(sub.complete).toHaveBeenCalled();
|
||||
});
|
||||
it('should get the cancellation subject for the provided id and complete it', async () => {
|
||||
await facade.cancelSearch(id);
|
||||
expect(
|
||||
facade['shouldCancelSearchRequestMap']['get']
|
||||
).toHaveBeenCalledWith(id);
|
||||
expect(sub.complete).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -164,7 +164,10 @@ export class SearchStateFacade {
|
||||
);
|
||||
}
|
||||
|
||||
shouldCancelSearchRequestMap = new Map<number, Subject<void>>();
|
||||
protected readonly shouldCancelSearchRequestMap = new Map<
|
||||
number,
|
||||
Subject<void>
|
||||
>();
|
||||
|
||||
constructor(private store: Store<any>, private ngxsStore: NgxsStore) {}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user