|
| 1 | +import { renderHook } from '@testing-library/react'; |
| 2 | +import { useActionType } from '../actionType'; |
| 3 | +import { useFiles } from '../files'; |
| 4 | +import { useLocation } from '../location'; |
| 5 | +import { useLocationItems } from '../locationItems'; |
| 6 | +import { HandleStoreAction, useStore } from '../useStore'; |
| 7 | +import { FileItem } from '../../../actions'; |
| 8 | + |
| 9 | +jest.mock('../../../controls/context'); |
| 10 | +jest.mock('../actionType'); |
| 11 | +jest.mock('../files'); |
| 12 | +jest.mock('../location'); |
| 13 | +jest.mock('../locationItems'); |
| 14 | + |
| 15 | +describe('useStore', () => { |
| 16 | + const locationData = { |
| 17 | + bucket: 'bucket', |
| 18 | + id: 'id', |
| 19 | + permissions: ['write' as const], |
| 20 | + prefix: '', |
| 21 | + type: 'PREFIX' as const, |
| 22 | + }; |
| 23 | + const actionTypeState = 'action-type'; |
| 24 | + const filesState: FileItem[] = []; |
| 25 | + const locationState = { current: locationData, path: '', key: '' }; |
| 26 | + const locationItemsState = { fileDataItems: [] }; |
| 27 | + |
| 28 | + const mockUseActionType = jest.mocked(useActionType); |
| 29 | + const mocktUseFiles = jest.mocked(useFiles); |
| 30 | + const mocktUseLocation = jest.mocked(useLocation); |
| 31 | + const mocktUseLocationItems = jest.mocked(useLocationItems); |
| 32 | + const mockDispatchActionType = jest.fn(); |
| 33 | + const mockDispatchFilesAction = jest.fn(); |
| 34 | + const mockDispatchLocationAction = jest.fn(); |
| 35 | + const mockDispatchLocationItemsAction = jest.fn(); |
| 36 | + |
| 37 | + const expectActions = (actions: Parameters<HandleStoreAction>[number][]) => { |
| 38 | + const { result } = renderHook(() => useStore()); |
| 39 | + const [, dispatchStoreAction] = result.current; |
| 40 | + return { |
| 41 | + toHaveBeenDispatchedBy: (dispatcher: HandleStoreAction) => { |
| 42 | + actions.forEach((action, index) => { |
| 43 | + // dispatch each action as a store action |
| 44 | + dispatchStoreAction(action); |
| 45 | + // assert that that the correct sub-dispatcher was invoked |
| 46 | + expect(dispatcher).toHaveBeenNthCalledWith(index + 1, action); |
| 47 | + }); |
| 48 | + }, |
| 49 | + }; |
| 50 | + }; |
| 51 | + |
| 52 | + beforeEach(() => { |
| 53 | + mockUseActionType.mockReturnValue([ |
| 54 | + actionTypeState, |
| 55 | + mockDispatchActionType, |
| 56 | + ]); |
| 57 | + mocktUseFiles.mockReturnValue([filesState, mockDispatchFilesAction]); |
| 58 | + mocktUseLocation.mockReturnValue([ |
| 59 | + locationState, |
| 60 | + mockDispatchLocationAction, |
| 61 | + ]); |
| 62 | + mocktUseLocationItems.mockReturnValue([ |
| 63 | + locationItemsState, |
| 64 | + mockDispatchLocationItemsAction, |
| 65 | + ]); |
| 66 | + }); |
| 67 | + |
| 68 | + afterEach(() => { |
| 69 | + mockUseActionType.mockClear(); |
| 70 | + mocktUseFiles.mockClear(); |
| 71 | + mocktUseLocation.mockClear(); |
| 72 | + mocktUseLocationItems.mockClear(); |
| 73 | + }); |
| 74 | + |
| 75 | + it('returns store state', () => { |
| 76 | + const { result } = renderHook(() => useStore()); |
| 77 | + |
| 78 | + expect(result.current).toStrictEqual([ |
| 79 | + { |
| 80 | + actionType: actionTypeState, |
| 81 | + files: filesState, |
| 82 | + location: locationState, |
| 83 | + locationItems: locationItemsState, |
| 84 | + }, |
| 85 | + expect.any(Function), |
| 86 | + ]); |
| 87 | + }); |
| 88 | + |
| 89 | + it('dispatches actionType action', () => { |
| 90 | + expectActions([ |
| 91 | + { type: 'SET_ACTION_TYPE', actionType: 'new-action-type' }, |
| 92 | + { type: 'RESET_ACTION_TYPE' }, |
| 93 | + ]).toHaveBeenDispatchedBy(mockDispatchActionType); |
| 94 | + }); |
| 95 | + |
| 96 | + it('dispatches files action', () => { |
| 97 | + expectActions([ |
| 98 | + { type: 'ADD_FILE_ITEMS' }, |
| 99 | + { type: 'REMOVE_FILE_ITEM', id: 'file-id' }, |
| 100 | + { type: 'SELECT_FILES' }, |
| 101 | + { type: 'RESET_FILE_ITEMS' }, |
| 102 | + ]).toHaveBeenDispatchedBy(mockDispatchFilesAction); |
| 103 | + }); |
| 104 | + |
| 105 | + it('dispatches location action', () => { |
| 106 | + expectActions([ |
| 107 | + { type: 'NAVIGATE', location: locationData }, |
| 108 | + { type: 'RESET_LOCATION' }, |
| 109 | + ]).toHaveBeenDispatchedBy(mockDispatchLocationAction); |
| 110 | + }); |
| 111 | + |
| 112 | + it('dispatches locationItems action', () => { |
| 113 | + expectActions([ |
| 114 | + { type: 'SET_LOCATION_ITEMS' }, |
| 115 | + { type: 'REMOVE_LOCATION_ITEM', id: 'file-id' }, |
| 116 | + { type: 'RESET_LOCATION_ITEMS' }, |
| 117 | + ]).toHaveBeenDispatchedBy(mockDispatchLocationItemsAction); |
| 118 | + }); |
| 119 | +}); |
0 commit comments