import { fireEvent } from '@testing-library/react'; import React from 'react'; import { combineReducers } from 'redux'; import { renderConnectedComponent } from '../../test-utils/dist/js'; import { abortRequest, reduxAjaxMiddleware, reduxAjaxReducer, reduxAjaxReducerKey, setRequestParams, submitFailure, submitPending, submitRequest, submitReset, submitResponseReset, submitSuccess, useReduxAjax } from './index'; import { RequestMethod } from './redux-ajax.type'; const requestId = 'test-request'; const setupTest = () => { const Test = () => { const { isRequestPending, isRequestSuccessful, isRequestFailed, isRequestComplete, isRequestAborted, hasError, error, hasResponse, response } = useReduxAjax(requestId); return (
{isRequestPending &&
pending
} {isRequestSuccessful &&
success
} {isRequestFailed &&
failure
} {isRequestComplete &&
complete
} {isRequestAborted &&
aborted
} {hasResponse &&
{response.message}
} {hasError &&
{error.message}
}
); }; return renderConnectedComponent({ rootReducer: combineReducers({ [reduxAjaxReducerKey]: reduxAjaxReducer }), middlewareList: [reduxAjaxMiddleware({ fetchFn: jest.fn() })] })(); }; describe('withAjaxRequest container', () => { describe('mapped props', () => { afterEach(() => { jest.restoreAllMocks(); }); it('provides request status functions', async () => { expect.assertions(1); const { findByText, getByText, store } = setupTest(); store.dispatch(submitPending({ requestId })); await findByText('pending'); store.dispatch(submitSuccess({ requestId })); await findByText('success'); expect(getByText('complete')).toBeInTheDocument(); }); it('provides functions to get the error in case of failure', async () => { expect.assertions(2); const { findByText, getByText, store } = setupTest(); store.dispatch(submitFailure({ requestId, error: { message: 'test-error' } })); await findByText('failure'); expect(getByText('complete')).toBeInTheDocument(); expect(getByText('test-error')).toBeInTheDocument(); }); it('provides functions to get the response in case of success', async () => { expect.assertions(2); const { findByText, getByText, store } = setupTest(); store.dispatch(submitSuccess({ requestId, response: { message: 'test-success' } })); await findByText('success'); expect(getByText('complete')).toBeInTheDocument(); expect(getByText('test-success')).toBeInTheDocument(); }); it('provides functions to know if the request has been aborted', async () => { expect.assertions(2); const spy = jest.fn(); const { getByText, findByText, store } = setupTest(); store.dispatch( submitRequest({ requestId, requestContent: { url: '/test' }, onRequestAborted: spy }) ); store.dispatch(abortRequest({ requestId })); await findByText('aborted'); expect(getByText('complete')).toBeInTheDocument(); expect(spy).toHaveBeenCalledWith(expect.any(Event)); }); }); describe('dispatchable actions', () => { let dispatchSpy; afterEach(() => { jest.restoreAllMocks(); }); const setupTest = () => { dispatchSpy = jest.fn(); const Test = () => { const { setRequestParams, resetRequest, resetResponse, submitRequest, abortRequest } = useReduxAjax(requestId); return (
{ setRequestParams({ url: 'test', method: RequestMethod.post, body: { test: value } }); }} />
); }; return renderConnectedComponent({ dispatch: dispatchSpy })(); }; it('provides functions to build and submit ajax request', () => { expect.assertions(4); const { getByLabelText, getByText } = setupTest(); fireEvent.input(getByLabelText('test-input'), { target: { value: 'new-value' } }); fireEvent.click(getByText('try again')); fireEvent.click(getByText('reset')); fireEvent.click(getByText('fetch data')); expect(dispatchSpy).toHaveBeenCalledWith( setRequestParams({ requestId, url: 'test', method: RequestMethod.post, body: { test: 'new-value' } }) ); expect(dispatchSpy).toHaveBeenCalledWith(submitReset({ requestId })); expect(dispatchSpy).toHaveBeenCalledWith(submitResponseReset({ requestId })); expect(dispatchSpy).toHaveBeenCalledWith( submitRequest({ requestId, requestContent: { url: 'test', method: RequestMethod.get } }) ); }); it('provides functions to abort a submitted request', async () => { expect.assertions(2); const { getByText } = setupTest(); await fireEvent.click(getByText('fetch data')); await fireEvent.click(getByText('abort')); expect(dispatchSpy).toHaveBeenCalledWith( submitRequest({ requestId, requestContent: { url: 'test', method: RequestMethod.get } }) ); expect(dispatchSpy).toHaveBeenCalledWith(abortRequest({ requestId })); }); it('can send prepared request', () => { expect.assertions(1); const spy = jest.fn(); const mock = jest.fn(); const Test = () => { const { submitRequest } = useReduxAjax(requestId); return (
); }; const requestContent = { url: 'test', method: RequestMethod.post, body: { test: 'test' } }; const { getByText } = renderConnectedComponent({ dispatch: spy, getState: () => ({ ajax: { [requestId]: requestContent } }) })(); fireEvent.click(getByText('submit')); expect(spy).toHaveBeenCalledWith(submitRequest({ requestId, transformData: mock })); }); }); });