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 }));
});
});
});