Skip to content

Commit

Permalink
Frontend tests
Browse files Browse the repository at this point in the history
  • Loading branch information
asanchezr committed Sep 30, 2023
1 parent c927737 commit 8f3339f
Show file tree
Hide file tree
Showing 8 changed files with 875 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { FormikProps } from 'formik';
import { createMemoryHistory } from 'history';
import { forwardRef } from 'react';

import { mockLookups } from '@/mocks/lookups.mock';
import { getMockApiPropertyManagement } from '@/mocks/propertyManagement.mock';
import { Api_PropertyManagement } from '@/models/api/Property';
import { lookupCodesSlice } from '@/store/slices/lookupCodes';
import { render, RenderOptions } from '@/utils/test-utils';

import {
IPropertyManagementUpdateContainerProps,
PropertyManagementUpdateContainer,
} from './PropertyManagementUpdateContainer';
import { IPropertyManagementUpdateFormProps } from './PropertyManagementUpdateForm';

const history = createMemoryHistory();
const storeState = {
[lookupCodesSlice.name]: { lookupCodes: mockLookups },
};

const mockGetApi = {
error: undefined,
response: undefined,
execute: jest.fn(),
loading: false,
};

const mockUpdateApi = {
error: undefined,
response: undefined,
execute: jest.fn(),
loading: false,
};

jest.mock('@/hooks/repositories/usePropertyManagementRepository', () => ({
usePropertyManagementRepository: () => {
return {
getPropertyManagement: mockGetApi,
updatePropertyManagement: mockUpdateApi,
};
},
}));

describe('PropertyManagementUpdateContainer component', () => {
let viewProps: IPropertyManagementUpdateFormProps;

const View = forwardRef<FormikProps<any>, IPropertyManagementUpdateFormProps>((props, ref) => {
viewProps = props;
return <></>;
});

const onSuccess = jest.fn();

const setup = (
renderOptions?: RenderOptions & { props?: Partial<IPropertyManagementUpdateContainerProps> },
) => {
renderOptions = renderOptions ?? {};
const utils = render(
<PropertyManagementUpdateContainer
{...renderOptions.props}
propertyId={renderOptions.props?.propertyId ?? 1}
View={View}
onSuccess={onSuccess}
/>,
{
...renderOptions,
store: storeState,
history,
},
);

return {
...utils,
};
};

afterEach(() => {
jest.clearAllMocks();
});

it('renders as expected', () => {
const { asFragment } = setup();
expect(asFragment()).toMatchSnapshot();
});

it('fetches property management info from the api', () => {
mockGetApi.execute.mockResolvedValue(getMockApiPropertyManagement(1));
setup({ props: { propertyId: 1 } });
expect(mockGetApi.execute).toBeCalled();
});

it('calls onSuccess when onSave method is called', async () => {
mockUpdateApi.execute.mockResolvedValue({ id: 1 } as Api_PropertyManagement);
setup();
await viewProps.onSave(getMockApiPropertyManagement());
expect(mockUpdateApi.execute).toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Api_PropertyManagement } from '@/models/api/Property';
import { PropertyManagementFormModel } from './models';
import { IPropertyManagementUpdateFormProps } from './PropertyManagementUpdateForm';

interface IPropertyManagementUpdateContainerProps {
export interface IPropertyManagementUpdateContainerProps {
propertyId: number;
onSuccess: () => void;
View: React.ForwardRefExoticComponent<
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import { FormikProps } from 'formik';
import { createMemoryHistory } from 'history';
import React from 'react';

import { mockLookups } from '@/mocks/lookups.mock';
import {
getMockApiPropertyManagement,
getMockApiPropertyManagementPurpose,
} from '@/mocks/propertyManagement.mock';
import { Api_PropertyManagementPurpose } from '@/models/api/Property';
import { lookupCodesSlice } from '@/store/slices/lookupCodes';
import { fakeText, render, RenderOptions, userEvent, waitFor } from '@/utils/test-utils';

import { PropertyManagementFormModel } from './models';
import {
IPropertyManagementUpdateFormProps,
PropertyManagementUpdateForm,
} from './PropertyManagementUpdateForm';

const history = createMemoryHistory();
const storeState = {
[lookupCodesSlice.name]: { lookupCodes: mockLookups },
};

const onSave = jest.fn();

describe('PropertyManagementUpdateForm component', () => {
const setup = (
renderOptions?: RenderOptions & { props?: Partial<IPropertyManagementUpdateFormProps> },
) => {
renderOptions = renderOptions ?? {};
const formikRef = React.createRef<FormikProps<PropertyManagementFormModel>>();
const utils = render(
<PropertyManagementUpdateForm
{...renderOptions.props}
onSave={onSave}
propertyManagement={
renderOptions.props?.propertyManagement ?? getMockApiPropertyManagement()
}
isLoading={renderOptions.props?.isLoading ?? false}
ref={formikRef}
/>,
{
...renderOptions,
store: storeState,
history,
},
);

return {
...utils,
getFormikRef: () => formikRef,
getAdditionalDetailsTextArea: () =>
utils.container.querySelector(`textarea[name="additionalDetails"]`) as HTMLTextAreaElement,
};
};

afterEach(() => {
jest.clearAllMocks();
});

it('renders as expected', () => {
const { asFragment } = setup();
expect(asFragment()).toMatchSnapshot();
});

it('displays a loading spinner when loading', () => {
const { getByTestId } = setup({ props: { isLoading: true } });
const spinner = getByTestId('filter-backdrop-loading');
expect(spinner).toBeVisible();
});

it('displays existing values if they exist', () => {
const { getByText } = setup({
props: {
propertyManagement: {
...getMockApiPropertyManagement(),
managementPurposes: [getMockApiPropertyManagementPurpose()],
},
},
});
expect(getByText('BC Ferries')).toBeVisible();
});

it('calls onSave when form is submitted', async () => {
const { getFormikRef } = setup({
props: {
propertyManagement: {
...getMockApiPropertyManagement(),
managementPurposes: [getMockApiPropertyManagementPurpose()],
},
},
});
await waitFor(() => getFormikRef()?.current?.submitForm());
expect(onSave).toHaveBeenCalled();
});

it('should validate required field Additional Details when purpose type is Other', async () => {
const otherPurpose: Api_PropertyManagementPurpose = {
...getMockApiPropertyManagementPurpose(),
propertyPurposeTypeCode: {
id: 'OTHER',
description: 'test',
},
};
const { getFormikRef, findByText, getAdditionalDetailsTextArea } = setup({
props: {
propertyManagement: {
...getMockApiPropertyManagement(),
managementPurposes: [otherPurpose],
},
},
});

const textArea = getAdditionalDetailsTextArea();
await waitFor(() => userEvent.clear(textArea));

// submit form to trigger validation check
await waitFor(() => getFormikRef()?.current?.submitForm());

expect(
await findByText(/Additional details are required when Other purpose is selected/i),
).toBeVisible();
});

it('should validate character limits', async () => {
const otherPurpose: Api_PropertyManagementPurpose = {
...getMockApiPropertyManagementPurpose(),
};
const { getFormikRef, findByText, getAdditionalDetailsTextArea } = setup({
props: {
propertyManagement: {
...getMockApiPropertyManagement(),
managementPurposes: [otherPurpose],
},
},
});

// additional details cannot exceed 4000 characters and it's required when OTHER purpose is selected
const textArea = getAdditionalDetailsTextArea();
await waitFor(() => userEvent.paste(textArea, fakeText(4200)));

// submit form to trigger validation check
await waitFor(() => getFormikRef()?.current?.submitForm());

expect(await findByText(/Additional details must be at most 4000 characters/i)).toBeVisible();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`PropertyManagementUpdateContainer component renders as expected 1`] = `
<DocumentFragment>
<div
class="Toastify"
/>
<div />
</DocumentFragment>
`;
Loading

0 comments on commit 8f3339f

Please sign in to comment.