import { of, Subject, throwError } from 'rxjs'; import { enteredDocumentsPage } from 'app/common/store/router/router.actions'; import { documentsAddBookmarkFailure, documentsAddBookmarkRequest, documentsAddBookmarkSuccess, documentsFetchBookmarksFailure, documentsFetchBookmarksRequest, documentsFetchBookmarksSuccess, documentsFetchCollectionFailure, documentsFetchCollectionRequest, documentsFetchCollectionSuccess, documentsRemoveBookmarkFailure, documentsRemoveBookmarkRequest, documentsRemoveBookmarkSuccess, documentsSetCategories, getDocumentFile, resetDocumentsCollectionLimit, setDocumentsCollection, } from 'app/modules/documents/store/documents.actions'; import { createDocumentCategories, createDocuments, createDocumentUrlDTO, } from 'app/testUtils/mocks/document.mock'; import { MiddlewareDependencies, StoreState } from 'app/common/store/store.types'; import { DeepPartial } from 'redux'; import { ActionsObservable, StateObservable } from 'redux-observable'; import { addDocumentBookmarksEpic, enteredDocumentsPageEpic, fetchDocumentsEpic, getDocumentBookmarksEpic, getDocumentFileEpic, removeDocumentBookmarksEpic, } from './documents.epic'; import { resetAllFilters , setPoolFilter } from 'app/shared/store/filters'; import { isEmpty } from 'rxjs/operators'; describe('Documents epic tests', () => { let dependencies: MiddlewareDependencies; const bookmarksMock = [1, 2, 3]; const documentIdMock = 1; const assign = window.location.assign; beforeAll(() => { Object.defineProperty(window, 'location', { value: { assign: jest.fn() }, }); }); afterAll(() => { window.location.assign = assign; }); beforeEach(() => { dependencies = ({ documentsService: { getDocuments: jest.fn(() => of(createDocuments())), getDocumentsCategories: jest.fn(() => of(createDocumentCategories())), getDocumentUrl: jest.fn(() => of(createDocumentUrlDTO(documentIdMock))), getBookmarks: jest.fn(() => of({ bookmarks: bookmarksMock })), addBookmark: jest.fn(() => of({ bookmark: bookmarksMock[0] })), removeBookmark: jest.fn(() => of({ bookmark: bookmarksMock[0] })), }, }) as DeepPartial as MiddlewareDependencies; }); it('fetches documents\' data on page enter action', done => { const mockPoolId = 3; const action$ = ActionsObservable.of(enteredDocumentsPage({ pool: mockPoolId })); const state$ = new StateObservable(new Subject(), ({ filters: { poolId: mockPoolId, }, }) as DeepPartial as StoreState); const expectedOutputActions = [ documentsFetchCollectionRequest(mockPoolId), documentsFetchBookmarksRequest(), ]; enteredDocumentsPageEpic(action$, state$, dependencies).subscribe( (actualOutputAction) => { expect(actualOutputAction).toEqual(expectedOutputActions); done(); }, () => { done('epic is in error state'); } ); }); it('if pool changed id resets filters on entering documents page', done => { const mockPoolId = 3; const action$ = ActionsObservable.of(enteredDocumentsPage({ pool: mockPoolId })); const state$ = new StateObservable(new Subject(), ({ filters: { poolId: mockPoolId + 1, }, }) as DeepPartial as StoreState); const expectedOutputAction = resetAllFilters(); enteredDocumentsPageEpic(action$, state$, dependencies).subscribe( (actualOutputAction) => { expect(actualOutputAction).toContainEqual(expectedOutputAction); done(); }, () => { done('epic is in error state'); } ); }); it('fetches documents and categories and resets filters and limit on collection fetch request', done => { const mockPoolId = 3; const action$ = ActionsObservable.of(documentsFetchCollectionRequest(mockPoolId)); const state$ = {} as StateObservable; const expectedOutputActions = [ documentsSetCategories(createDocumentCategories()), setPoolFilter(mockPoolId), setDocumentsCollection(createDocuments()), resetDocumentsCollectionLimit(), documentsFetchCollectionSuccess(), ]; fetchDocumentsEpic(action$, state$, dependencies).subscribe( (actualOutputAction) => { expect(actualOutputAction).toEqual(expectedOutputActions); done(); }, () => { done('epic is in error state'); } ); }); it('returns error action on fetch categories failure', done => { const mockPoolId = 3; dependencies.documentsService.getDocumentsCategories = jest.fn(() => { return throwError(''); }); const action$ = ActionsObservable.of(documentsFetchCollectionRequest(mockPoolId)); const state$ = {} as StateObservable; const expectedOutputActions = documentsFetchCollectionFailure(); fetchDocumentsEpic(action$, state$, dependencies).subscribe( (actualOutputAction) => { expect(actualOutputAction).toEqual(expectedOutputActions); done(); }, () => { done('epic is in error state'); } ); }); it('returns error action on fetch documents failure', done => { const mockPoolId = 3; dependencies.documentsService.getDocuments = jest.fn(() => { return throwError(''); }); const action$ = ActionsObservable.of(documentsFetchCollectionRequest(mockPoolId)); const state$ = {} as StateObservable; const expectedOutputActions = documentsFetchCollectionFailure(); fetchDocumentsEpic(action$, state$, dependencies).subscribe( (actualOutputAction) => { expect(actualOutputAction).toEqual(expectedOutputActions); done(); }, () => { done('epic is in error state'); } ); }); it('should open document on document file fetch action', done => { const mockPoolId = 3; const action$ = ActionsObservable.of(getDocumentFile(mockPoolId)); const state$ = {} as StateObservable; getDocumentFileEpic(action$, state$, dependencies) .subscribe(undefined, () => { done('epic is in error state'); }, () => { expect(window.location.assign).toHaveBeenCalledWith(createDocumentUrlDTO(documentIdMock)); done(); }, ); }); it('should not return an action on document file fetch action', done => { const mockPoolId = 3; const action$ = ActionsObservable.of(getDocumentFile(mockPoolId)); const state$ = {} as StateObservable; getDocumentFileEpic(action$, state$, dependencies) .pipe(isEmpty()) .subscribe((isEmpty) => { expect(isEmpty).toBe(true); done(); }, () => { done('epic is in error state'); }, ); }); it('returns success action with bookmarks on fetch bookmarks request', done => { const action$ = ActionsObservable.of(documentsFetchBookmarksRequest()); const state$ = {} as StateObservable; const expectedOutputActions = documentsFetchBookmarksSuccess(bookmarksMock); getDocumentBookmarksEpic(action$, state$, dependencies).subscribe( (actualOutputAction) => { expect(actualOutputAction).toEqual(expectedOutputActions); done(); }, () => { done('epic is in error state'); } ); }); it('returns error action on fetch bookmarks failure', done => { dependencies.documentsService.getBookmarks = jest.fn(() => { return throwError(''); }); const action$ = ActionsObservable.of(documentsFetchBookmarksRequest()); const state$ = {} as StateObservable; const expectedOutputActions = documentsFetchBookmarksFailure(); getDocumentBookmarksEpic(action$, state$, dependencies).subscribe( (actualOutputAction) => { expect(actualOutputAction).toEqual(expectedOutputActions); done(); }, () => { done('epic is in error state'); } ); }); it('returns success action on successful addition of new bookmark', done => { const mockBookmark = 1; const action$ = ActionsObservable.of(documentsAddBookmarkRequest(mockBookmark)); const state$ = {} as StateObservable; const expectedOutputActions = documentsAddBookmarkSuccess(mockBookmark); addDocumentBookmarksEpic(action$, state$, dependencies).subscribe( (actualOutputAction) => { expect(actualOutputAction).toEqual(expectedOutputActions); done(); }, () => { done('epic is in error state'); } ); }); it('returns error action on bookmark addition failure', done => { const mockBookmark = 1; dependencies.documentsService.addBookmark = jest.fn(() => { return throwError(''); }); const action$ = ActionsObservable.of(documentsAddBookmarkRequest(mockBookmark)); const state$ = {} as StateObservable; const expectedOutputActions = documentsAddBookmarkFailure(); addDocumentBookmarksEpic(action$, state$, dependencies).subscribe( (actualOutputAction) => { expect(actualOutputAction).toEqual(expectedOutputActions); done(); }, () => { done('epic is in error state'); } ); }); it('returns success action on successful removal of new bookmark', done => { const mockBookmark = 1; const action$ = ActionsObservable.of(documentsRemoveBookmarkRequest(mockBookmark)); const state$ = {} as StateObservable; const expectedOutputActions = documentsRemoveBookmarkSuccess(mockBookmark); removeDocumentBookmarksEpic(action$, state$, dependencies).subscribe( (actualOutputAction) => { expect(actualOutputAction).toEqual(expectedOutputActions); done(); }, () => { done('epic is in error state'); } ); }); it('returns error action on bookmark removal failure', done => { const mockBookmark = 1; dependencies.documentsService.removeBookmark = jest.fn(() => { return throwError(''); }); const action$ = ActionsObservable.of(documentsRemoveBookmarkRequest(mockBookmark)); const state$ = {} as StateObservable; const expectedOutputActions = documentsRemoveBookmarkFailure(); removeDocumentBookmarksEpic(action$, state$, dependencies).subscribe( (actualOutputAction) => { expect(actualOutputAction).toEqual(expectedOutputActions); done(); }, () => { done('epic is in error state'); } ); }); });