import { store } from '@/redux/store'; import { errorMiddlewareListener } from './error.middleware'; jest.mock('../../utils/showToast'); describe('errorMiddlewareListener', () => { const dispatchSpy = jest.spyOn(store, 'dispatch'); beforeEach(() => { jest.clearAllMocks(); }); it('should handle error with message when action is rejected', async () => { const action = { type: 'action/rejected', payload: 'Error message', meta: { requestId: '421', rejectedWithValue: true, requestStatus: 'rejected', }, error: { code: 'Error 2', }, }; const { getState, dispatch } = store; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-expect-error await errorMiddlewareListener(action, { getState, dispatch }); expect(dispatchSpy).toHaveBeenCalledWith( expect.objectContaining({ type: 'modal/openErrorReportModal', payload: expect.anything(), }), ); }); it('should handle error without message when action is rejected', async () => { const action = { type: 'action/rejected', payload: null, meta: { requestId: '421', rejectedWithValue: true, requestStatus: 'rejected', }, error: { code: 'Error 3', }, }; const { getState, dispatch } = store; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-expect-error await errorMiddlewareListener(action, { getState, dispatch }); expect(dispatchSpy).toHaveBeenCalledWith( expect.objectContaining({ type: 'modal/openErrorReportModal', payload: expect.anything(), }), ); }); it('should not handle error when action is not rejected', async () => { const action = { type: 'action/loading', payload: null, meta: { requestId: '421', requestStatus: 'fulfilled', }, }; const { getState, dispatch } = store; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-expect-error await errorMiddlewareListener(action, { getState, dispatch }); expect(dispatchSpy).not.toHaveBeenCalled(); }); it('should handle error with unknown error message when action payload is not a string', async () => { const action = { type: 'action/rejected', payload: {}, meta: { requestId: '421', rejectedWithValue: true, requestStatus: 'rejected', }, error: { code: 'ERROR', message: 'Error message', }, }; const { getState, dispatch } = store; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-expect-error await errorMiddlewareListener(action, { getState, dispatch }); expect(dispatchSpy).toHaveBeenCalledWith( expect.objectContaining({ type: 'modal/openErrorReportModal', payload: expect.anything(), }), ); }); it('should handle error with custom message when action payload is a string', async () => { const action = { type: 'action/rejected', payload: 'Failed to fetch', meta: { requestId: '421', rejectedWithValue: true, requestStatus: 'rejected', }, error: { code: 'ERROR', message: 'xyz', stack: 'stack', }, }; const { getState, dispatch } = store; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-expect-error await errorMiddlewareListener(action, { getState, dispatch }); expect(dispatchSpy).toHaveBeenCalledWith( expect.objectContaining({ type: 'modal/openErrorReportModal', payload: expect.objectContaining({ stacktrace: 'stack', }), }), ); }); it('should show modal on access denied', async () => { const action = { type: 'action/rejected', payload: null, meta: { requestId: '421', rejectedWithValue: true, requestStatus: 'rejected', }, error: { code: '403', }, }; const { getState, dispatch } = store; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-expect-error await errorMiddlewareListener(action, { getState, dispatch }); expect(dispatchSpy).toHaveBeenCalledWith( expect.objectContaining({ type: 'modal/openAccessDeniedModal', }), ); }); });