Skip to content

Commit

Permalink
Remove mock-axios from outdated test file
Browse files Browse the repository at this point in the history
  • Loading branch information
asanchezr committed Oct 4, 2023
1 parent 89c36e9 commit 55818fe
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 66 deletions.
146 changes: 80 additions & 66 deletions source/frontend/src/features/leases/add/AddLeaseContainer.test.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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');
Expand Down Expand Up @@ -48,6 +54,18 @@ jest.mock('@/hooks/repositories/useUserInfoRepository');
},
});

const addLease = jest.fn();
jest.mock('../hooks/useAddLease');
(useAddLease as jest.MockedFunction<typeof useAddLease>).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 }) => {
Expand All @@ -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<IAddLeaseContainerProps> = {}) => {
// render component under test
const component = await renderAsync(<AddLeaseContainer onClose={noop} />, {
const component = await renderAsync(<AddLeaseContainer onClose={onClose} />, {
...renderOptions,
store: storeState,
history,
Expand All @@ -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();
Expand All @@ -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: '',
Expand Down
9 changes: 9 additions & 0 deletions source/frontend/src/utils/test-utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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}`);

Check warning on line 62 in source/frontend/src/utils/test-utils.tsx

View check run for this annotation

Codecov / codecov/patch

source/frontend/src/utils/test-utils.tsx#L62

Added line #L62 was not covered by tests
}
return userEvent.selectOptions(element, values);
};

export const fillInput = async (
container: HTMLElement,
name: string,
Expand Down

0 comments on commit 55818fe

Please sign in to comment.