import DataUnit from "../../src/dataunit/DataUnit"; import { DUActionInterceptor, LoadDataParams } from "../../src/dataunit/interfaces/dataUnit"; import { PaginationInfo } from "../../src/dataunit/loading/PaginationInfo"; import { Action, ExecutionContext } from "../../src/dataunit/state/action/DataUnitAction"; import ErrorException from "../../src/exceptions/ErrorException"; import { createDataUnitMock } from "./loader/utils/createDataUnitMock"; import { metadata } from "./resources/metadata"; import { recordsTest } from "./resources/records"; describe('Load data and metadata', () => { let dataUnit: DataUnit; let dataLoaderMock = jest.fn(); let metadataLoaderMock = jest.fn(); beforeEach(() => { jest.clearAllMocks(); window.requestAnimationFrame = (functionCallback: Function) => functionCallback(); ({ dataUnit, dataLoaderMock, metadataLoaderMock } = createDataUnitMock()); }); describe('gotoPage', () => { it('should not call loader when pageSize is not defined', async () => { await dataUnit.gotoPage(2); expect(dataLoaderMock).not.toHaveBeenCalled(); }); it('should pass limit size and offset on request when pageSize is bigger than 0', async () => { dataUnit.pageSize = 1; const dataLoaderMock = jest.fn().mockResolvedValue({ records: recordsTest }); dataUnit.dataLoader = dataLoaderMock; await dataUnit.loadData(); await dataUnit.gotoPage(2); expect(dataLoaderMock).toHaveBeenCalledWith(dataUnit, expect.objectContaining({ limit: 1, offset: 0 })); }); it('should call loadData when have a next page', async () => { dataUnit.pageSize = 1; const dataLoaderMock = jest.fn().mockResolvedValue({ records: recordsTest }); dataUnit.dataLoader = dataLoaderMock; await dataUnit.updatePagination({ currentPage: 0, firstRecord: 0, hasMore: true, lastRecord: 4, total: 5 }); const response = await dataUnit.gotoPage(2); expect(dataLoaderMock).toHaveBeenCalled(); expect(response).toStrictEqual({ records: recordsTest }); }); it('should return undefined when not have any next page', async () => { dataUnit.pageSize = 1; const dataLoaderMock = jest.fn().mockResolvedValue({ records: recordsTest }); dataUnit.dataLoader = dataLoaderMock; await dataUnit.updatePagination({ currentPage: 5, firstRecord: 0, hasMore: false, lastRecord: 4, total: 5 }); const response = await dataUnit.gotoPage(6); expect(dataLoaderMock).not.toHaveBeenCalled(); expect(response).toBeUndefined(); }); }); describe('nextPage', () => { it('should call loadData for the next page', async () => { const dataUnit = new DataUnit(); dataUnit.pageSize = 1; const dataLoaderMock = jest.fn().mockResolvedValue({ records: recordsTest }); dataUnit.dataLoader = dataLoaderMock; await dataUnit.updatePagination({ currentPage: 0, firstRecord: 0, hasMore: true, lastRecord: 4, total: 5 }); const response = await dataUnit.nextPage(); expect(dataLoaderMock).toHaveBeenCalledWith(dataUnit, expect.objectContaining({ offset: 1 })); expect(response).toStrictEqual({ records: recordsTest }); }); }); describe('previousPage', () => { it('should call loadData for the previous page', async () => { const dataUnit = new DataUnit(); dataUnit.pageSize = 1; const dataLoaderMock = jest.fn().mockResolvedValue({ records: recordsTest }); dataUnit.dataLoader = dataLoaderMock; await dataUnit.updatePagination({ currentPage: 1, firstRecord: 0, hasMore: true, lastRecord: 4, total: 5 }); const response = await dataUnit.previousPage(); expect(dataLoaderMock).toHaveBeenCalledWith(dataUnit, expect.objectContaining({ offset: 0 })); expect(response).toStrictEqual({ records: recordsTest }); }); }); describe('dataLoader', () => { it('should return records from dataLoader', async () => { const result = await dataUnit.loadData(); expect(result.records).toStrictEqual(recordsTest); }); it('should call dataLoader when loadData is invoked', async () => { dataLoaderMock.mockResolvedValue({ records: [] }); dataUnit.dataLoader = dataLoaderMock; const result = await dataUnit.loadData(); expect(dataLoaderMock).toHaveBeenCalled(); expect(result).toEqual({ records: [] }); }); it('should clear dataUnit when parent record is undefined', async () => { dataUnit.selectFirst(); const childDataUnit = new DataUnit('child', dataUnit); const result = await childDataUnit.loadData(); expect(childDataUnit.records).toEqual([]); expect(result).toEqual({ records: [] }); }); it('should clear dataUnit when parent record is new', async () => { dataUnit.addRecord(); const childDataUnit = new DataUnit('child', dataUnit); const result = await childDataUnit.loadData(); expect(childDataUnit.records).toEqual([]); expect(result).toEqual({ records: [] }); }); it('should pass quickFilter on request', async () => { const quickFilter = { term: 'test' }; await dataUnit.loadData(quickFilter); expect(dataLoaderMock).toHaveBeenCalledWith(dataUnit, expect.objectContaining({ quickFilter })); }); it('should pass limit size and offset on request when pageSize is bigger than 0', async () => { dataUnit.pageSize = 1; await dataUnit.loadData(); expect(dataLoaderMock).toHaveBeenCalledWith(dataUnit, expect.objectContaining({ limit: 1, offset: 0 })); }); it('should avoid call dataLoader when request is the same at the last', async () => { const paginationInfo: PaginationInfo = { currentPage: 0, firstRecord: 0, hasMore: true, lastRecord: 4, }; jest.spyOn(dataUnit, 'getPaginationInfo').mockReturnValue(paginationInfo); const response1 = await dataUnit.loadData(undefined, undefined, true, undefined, true); const response2 = await dataUnit.loadData(undefined, undefined, true, undefined, true); const selectedRecord = dataUnit.getSelectedRecord(); expect(selectedRecord).toStrictEqual(recordsTest[0]); expect(dataLoaderMock).toHaveBeenCalledTimes(1); expect(response1.records).toStrictEqual(response2.records); }); it('should select first record when propertie selectFirstRecord is true', async () => { await dataUnit.loadData(undefined, undefined, undefined, undefined, true); const selectedRecord = dataUnit.getSelectedRecord(); expect(selectedRecord).toStrictEqual(recordsTest[0]); }); it('should handle error dataLoader', async () => { dataLoaderMock.mockRejectedValue(new Error("Error test")); const loadData = async () => await dataUnit.loadData(); await expect(loadData()).rejects.toBeInstanceOf(ErrorException); }); }); describe('loadDataWithParams', () => { it('should pass params to loadData correctly', async () => { const loadDataMock = jest.spyOn(dataUnit, 'loadData'); const executionCtx: ExecutionContext = { before: jest.fn((value) => value), after: jest.fn((value) => value), } const params: LoadDataParams = { checkLastFilter: true, executionCtx, keepSelection: true, quickFilter: { term: 'test' }, selectFirstRecord: true, source: 'test' } dataUnit.loadDataWithParams(params); expect(loadDataMock).toHaveBeenCalledWith( params.quickFilter, params.executionCtx, params.checkLastFilter, params.source, params.selectFirstRecord, params.keepSelection ); }); }); describe('loadMetadata', () => { it('should return metadata', async () => { const response = await dataUnit.loadMetadata(); expect(response).toStrictEqual(metadata); }); it('should handle error metadataLoader', async () => { metadataLoaderMock.mockRejectedValue(new Error("Error test")); const loadMetadata = async () => await dataUnit.loadMetadata(); await expect(loadMetadata()).rejects.toBeInstanceOf(ErrorException); }); it('should call executionCtx methods', async () => { const executionCtx: ExecutionContext = { before: jest.fn((value) => value), after: jest.fn((value) => value), } await dataUnit.loadMetadata(executionCtx); expect(executionCtx.before).toHaveBeenCalled(); expect(executionCtx.after).toHaveBeenCalled(); }); it('should call interceptors', async () => { const loadingMetadata = jest.fn(); const metadataLoaded = jest.fn(); const interceptor: DUActionInterceptor = { interceptAction: (action) => { switch (action.type) { case Action.LOADING_METADATA: loadingMetadata(action.payload); break; case Action.METADATA_LOADED: metadataLoaded(action.payload); break; } return action; } } dataUnit.addInterceptor(interceptor); const promiseLoadMetadata = dataUnit.loadMetadata(); expect(loadingMetadata).toHaveBeenCalled(); expect(metadataLoaded).not.toHaveBeenCalled(); await promiseLoadMetadata; expect(metadataLoaded).toHaveBeenCalledWith(metadata); }); it('should interrupt by executionCtx', async () => { const executionCtx: ExecutionContext = { before: jest.fn(), after: jest.fn(), } await dataUnit.loadMetadata(executionCtx); expect(executionCtx.before).toHaveBeenCalled(); expect(executionCtx.after).not.toHaveBeenCalled(); expect(dataUnit.metadataLoader).not.toHaveBeenCalled(); }); }); });