From c3b66904b92f6b37a82219908a909107d812496b Mon Sep 17 00:00:00 2001 From: Alejandro Sanchez Date: Tue, 3 Oct 2023 21:07:19 -0700 Subject: [PATCH] Remove mock-axios from outdated test file --- .../leases/add/AddLeaseContainer.test.tsx | 146 ++++++++++-------- source/frontend/src/utils/test-utils.tsx | 9 ++ 2 files changed, 89 insertions(+), 66 deletions(-) diff --git a/source/frontend/src/features/leases/add/AddLeaseContainer.test.tsx b/source/frontend/src/features/leases/add/AddLeaseContainer.test.tsx index 215c16d2e4..de5e3f0a85 100644 --- a/source/frontend/src/features/leases/add/AddLeaseContainer.test.tsx +++ b/source/frontend/src/features/leases/add/AddLeaseContainer.test.tsx @@ -1,9 +1,6 @@ import { useKeycloak } from '@react-keycloak/web'; import userEvent from '@testing-library/user-event'; -import axios from 'axios'; -import MockAdapter from 'axios-mock-adapter'; import { createMemoryHistory } from 'history'; -import { noop } from 'lodash'; import { useMapStateMachine } from '@/components/common/mapFSM/MapStateMachineContext'; import { useUserInfoRepository } from '@/hooks/repositories/useUserInfoRepository'; @@ -12,8 +9,17 @@ import { mapMachineBaseMock } from '@/mocks/mapFSM.mock'; import { Api_Lease } from '@/models/api/Lease'; import { UserOverrideCode } from '@/models/api/UserOverrideCode'; import { lookupCodesSlice } from '@/store/slices/lookupCodes'; -import { act, fillInput, renderAsync, RenderOptions, screen, waitFor } from '@/utils/test-utils'; +import { + act, + createAxiosError, + fillInput, + renderAsync, + RenderOptions, + screen, + selectOptions, +} from '@/utils/test-utils'; +import { useAddLease } from '../hooks/useAddLease'; import AddLeaseContainer, { IAddLeaseContainerProps } from './AddLeaseContainer'; jest.mock('@react-keycloak/web'); @@ -48,6 +54,18 @@ jest.mock('@/hooks/repositories/useUserInfoRepository'); }, }); +const addLease = jest.fn(); +jest.mock('../hooks/useAddLease'); +(useAddLease as jest.MockedFunction).mockReturnValue({ + addLease: { + execute: addLease, + error: undefined, + loading: false, + response: undefined, + status: 200, + }, +}); + // Need to mock this library for unit tests jest.mock('react-visibility-sensor', () => { return jest.fn().mockImplementation(({ children }) => { @@ -64,12 +82,13 @@ const history = createMemoryHistory(); const storeState = { [lookupCodesSlice.name]: { lookupCodes: mockLookups }, }; -const mockAxios = new MockAdapter(axios); + +const onClose = jest.fn(); describe('AddLeaseContainer component', () => { const setup = async (renderOptions: RenderOptions & Partial = {}) => { // render component under test - const component = await renderAsync(, { + const component = await renderAsync(, { ...renderOptions, store: storeState, history, @@ -81,12 +100,13 @@ describe('AddLeaseContainer component', () => { }; beforeEach(() => { - mockAxios.resetHistory(); - mockAxios.resetHandlers(); - (useMapStateMachine as jest.Mock).mockImplementation(() => mapMachineBaseMock); }); + afterEach(() => { + jest.clearAllMocks(); + }); + it('renders as expected', async () => { const { component } = await setup({}); expect(component.asFragment()).toMatchSnapshot(); @@ -98,103 +118,97 @@ describe('AddLeaseContainer component', () => { } = await setup({}); userEvent.click(getAllByText('Cancel')[0]); expect(history.location.pathname).toBe('/'); + expect(onClose).toBeCalled(); }); it('saves the form with minimal data', async () => { const { component: { getByText, container }, } = await setup({}); - await act(async () => { - await fillInput(container, 'statusTypeCode', 'DRAFT', 'select'); - await fillInput(container, 'paymentReceivableTypeCode', 'RCVBL', 'select'); - await fillInput(container, 'startDate', '01/01/2020', 'datepicker'); - await fillInput(container, 'expiryDate', '01/02/2020', 'datepicker'); - await fillInput(container, 'regionId', '1', 'select'); - await fillInput(container, 'programTypeCode', 'BCFERRIES', 'select'); - await fillInput(container, 'leaseTypeCode', 'LICONSTRC', 'select'); - await fillInput(container, 'purposeTypeCode', 'BCFERRIES', 'select'); - }); - /* - await act(async () => { - userEvent.click(getByText('Remove')); - }); - */ + await act(() => selectOptions('statusTypeCode', 'DRAFT')); + await act(() => selectOptions('paymentReceivableTypeCode', 'RCVBL')); + await act(() => selectOptions('regionId', '1')); + await act(() => selectOptions('programTypeCode', 'BCFERRIES')); + await act(() => selectOptions('leaseTypeCode', 'LIOCCTTLD')); + await act(() => selectOptions('purposeTypeCode', 'BCFERRIES')); + await act(() => fillInput(container, 'startDate', '01/01/2020', 'datepicker')); + await act(() => fillInput(container, 'expiryDate', '01/02/2020', 'datepicker')); + await act(async () => userEvent.click(getByText(/Save/i))); - mockAxios.onPost().reply(200, {}); - await act(async () => { - userEvent.click(getByText(/Save/i)); - }); - await waitFor(() => { - expect(JSON.parse(mockAxios.history.post[0].data)).toEqual(leaseData); - }); - - expect(JSON.parse(mockAxios.history.post[0].data)).toEqual(leaseData); + expect(addLease).toBeCalledWith(leaseData, []); }); it('triggers the confirm popup', async () => { + addLease.mockRejectedValue( + createAxiosError(409, 'test message', { + errorCode: UserOverrideCode.ADD_LOCATION_TO_PROPERTY, + }), + ); + const { component: { getByText, findByText, container }, } = await setup({}); - await act(async () => { - await fillInput(container, 'statusTypeCode', 'DRAFT', 'select'); - await fillInput(container, 'paymentReceivableTypeCode', 'RCVBL', 'select'); - await fillInput(container, 'startDate', '01/01/2020', 'datepicker'); - await fillInput(container, 'expiryDate', '01/02/2020', 'datepicker'); - await fillInput(container, 'regionId', '1', 'select'); - await fillInput(container, 'programTypeCode', 'BCFERRIES', 'select'); - await fillInput(container, 'leaseTypeCode', 'LICONSTRC', 'select'); - await fillInput(container, 'purposeTypeCode', 'BCFERRIES', 'select'); - }); - mockAxios - .onPost() - .reply(409, { error: 'test message', errorCode: UserOverrideCode.ADD_LOCATION_TO_PROPERTY }); - act(() => userEvent.click(getByText(/Save/i))); + await act(() => selectOptions('statusTypeCode', 'DRAFT')); + await act(() => selectOptions('paymentReceivableTypeCode', 'RCVBL')); + await act(() => selectOptions('regionId', '1')); + await act(() => selectOptions('programTypeCode', 'BCFERRIES')); + await act(() => selectOptions('leaseTypeCode', 'LIOCCTTLD')); + await act(() => selectOptions('purposeTypeCode', 'BCFERRIES')); + await act(() => fillInput(container, 'startDate', '01/01/2020', 'datepicker')); + await act(() => fillInput(container, 'expiryDate', '01/02/2020', 'datepicker')); + await act(async () => userEvent.click(getByText(/Save/i))); + expect(await findByText('test message')).toBeVisible(); }); it('clicking on the save anyways popup saves the form', async () => { + // simulate api error + addLease.mockRejectedValue( + createAxiosError(409, 'test message', { + errorCode: UserOverrideCode.ADD_LOCATION_TO_PROPERTY, + }), + ); + const { component: { getByText, container }, } = await setup({}); - await act(async () => { - await fillInput(container, 'statusTypeCode', 'DRAFT', 'select'); - await fillInput(container, 'paymentReceivableTypeCode', 'RCVBL', 'select'); - await fillInput(container, 'startDate', '01/01/2020', 'datepicker'); - await fillInput(container, 'expiryDate', '01/02/2020', 'datepicker'); - await fillInput(container, 'regionId', '1', 'select'); - await fillInput(container, 'programTypeCode', 'BCFERRIES', 'select'); - await fillInput(container, 'leaseTypeCode', 'LICONSTRC', 'select'); - await fillInput(container, 'purposeTypeCode', 'BCFERRIES', 'select'); - }); + await act(() => selectOptions('statusTypeCode', 'DRAFT')); + await act(() => selectOptions('paymentReceivableTypeCode', 'RCVBL')); + await act(() => selectOptions('regionId', '1')); + await act(() => selectOptions('programTypeCode', 'BCFERRIES')); + await act(() => selectOptions('leaseTypeCode', 'LIOCCTTLD')); + await act(() => selectOptions('purposeTypeCode', 'BCFERRIES')); + await act(() => fillInput(container, 'startDate', '01/01/2020', 'datepicker')); + await act(() => fillInput(container, 'expiryDate', '01/02/2020', 'datepicker')); + await act(async () => userEvent.click(getByText(/Save/i))); - mockAxios - .onPost() - .reply(409, { error: 'test message', errorCode: UserOverrideCode.ADD_LOCATION_TO_PROPERTY }); - act(() => userEvent.click(getByText(/Save/i))); - await waitFor(() => { - expect(JSON.parse(mockAxios.history.post[0].data)).toEqual(leaseData); - }); + expect(addLease).toBeCalledWith(leaseData, []); const popup = await screen.findByText(/test message/i); expect(popup).toBeVisible(); + // simulate api success + addLease.mockResolvedValue({ ...leaseData, id: 1 }); + await act(async () => { userEvent.click(await screen.findByText('Acknowledge & Continue')); }); - expect(JSON.parse(mockAxios.history.post[0].data)).toEqual(leaseData); + expect(addLease).toBeCalledWith(leaseData, []); + expect(history.location.pathname).toBe('/mapview/sidebar/lease/1'); }); }); + const leaseData: Api_Lease = { startDate: '2020-01-01', amount: 0, paymentReceivableType: { id: 'RCVBL' }, purposeType: { id: 'BCFERRIES' }, statusType: { id: 'DRAFT' }, - type: { id: 'LICONSTRC' }, + type: { id: 'LIOCCTTLD' }, region: { id: 1 }, programType: { id: 'BCFERRIES' }, returnNotes: '', diff --git a/source/frontend/src/utils/test-utils.tsx b/source/frontend/src/utils/test-utils.tsx index df2e9c61d6..5e0154a798 100644 --- a/source/frontend/src/utils/test-utils.tsx +++ b/source/frontend/src/utils/test-utils.tsx @@ -5,6 +5,7 @@ import { RenderOptions as RtlRenderOptions, RenderResult, } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import { AxiosError, AxiosResponse } from 'axios'; import { createMemoryHistory, MemoryHistory } from 'history'; import noop from 'lodash/noop'; @@ -55,6 +56,14 @@ export function fakeText(length = 50): string { return 'x'.repeat(length); } +export const selectOptions = async (elementName: string, values: string[] | string) => { + const element: HTMLSelectElement | null = document.querySelector(`select[name="${elementName}"]`); + if (!element) { + throw new Error(`Could not find element with name: ${elementName}`); + } + return userEvent.selectOptions(element, values); +}; + export const fillInput = async ( container: HTMLElement, name: string,