import axios, { AxiosError, AxiosInterceptorManager, AxiosResponse } from 'axios'; import { initAjaxHandlersUnauthorized } from '../ajax-handlers-unauthorized'; jest.mock('axios', () => ({ interceptors: { response: { use: jest.fn() } }, isCancel: jest.fn(), })); interface Handlers { response: { onFulfilled?: Parameters['use']>[0]; onRejected?: Parameters['use']>[1]; }; } type DeepPartial = T extends object ? { [P in keyof T]?: DeepPartial; } : T; describe(`[ajax-handlers] ${initAjaxHandlersUnauthorized.name}`, () => { const originalLocation = window.location; let options: Parameters[0]; let handlers: Handlers; beforeAll(() => { Object.defineProperty(window, 'location', { configurable: true, value: { ...originalLocation, reload: jest.fn() }, }); }); beforeEach(() => { jest.clearAllMocks(); sessionStorage.clear(); options = undefined; }); const subject = () => { initAjaxHandlersUnauthorized(options); const [onFulfilled, onRejected] = jest.mocked(axios.interceptors.response.use).mock .calls[0]; handlers = { response: { onFulfilled, onRejected }, }; }; test('initializes response interceptor', () => { subject(); expect(axios.interceptors.response.use).toHaveBeenLastCalledWith( undefined, expect.any(Function) ); }); describe('onRejected handler', () => { const response401: DeepPartial = { status: 401, config: { url: '/foo' }, data: 'foo', }; const response500: DeepPartial = { status: 500, config: { url: '/foo' }, data: 'foo', }; const onRejectedSubject = (error: DeepPartial) => { subject(); handlers.response.onRejected?.(error).catch(() => {}); }; test.each([ { response: response401, reload: true }, { response: response500, reload: false }, ])('Status: $response.status --> Reloads: $reload', ({ response, reload }) => { onRejectedSubject({ response }); expect(window.location.reload).toHaveBeenCalledTimes(reload ? 1 : 0); }); describe('with custom isUnauthorized', () => { beforeEach(() => { options = { isUnauthorized: (response, defaultHandler) => defaultHandler() && response.data === response401.data, }; }); test.each([ { response: response401, reload: true }, { response: { ...response401, data: 'bar' }, reload: false }, { response: response500, reload: false }, ])( 'Status: $response.status Data: $response.data --> Reloads: $reload', ({ response, reload }) => { onRejectedSubject({ response }); expect(window.location.reload).toHaveBeenCalledTimes(reload ? 1 : 0); } ); }); describe('with custom unauthorizedHandler', () => { beforeEach(() => { options = { unauthorizedHandler: jest.fn(), }; }); test('calls passed handler', () => { onRejectedSubject({ response: response401 }); expect(window.location.reload).not.toHaveBeenCalled(); expect(options?.unauthorizedHandler).toHaveBeenCalled(); }); }); }); });