Skip to content

Commit

Permalink
PSP-5500 Limit project regions to those the user has access to (#2897)
Browse files Browse the repository at this point in the history
  • Loading branch information
asanchezr authored Feb 24, 2023
1 parent a6beaa0 commit a2ea0f3
Show file tree
Hide file tree
Showing 14 changed files with 150 additions and 101 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ import MockAdapter from 'axios-mock-adapter';
import { MapStateContextProvider } from 'components/maps/providers/MapStateContext';
import { Feature, GeoJsonProperties, Geometry } from 'geojson';
import { createMemoryHistory } from 'history';
import { useUserInfoRepository } from 'hooks/repositories/useUserInfoRepository';
import { mockLookups } from 'mocks/mockLookups';
import { mockProjectPostResponse } from 'mocks/mockProjects';
import { getUserMock } from 'mocks/userMock';
import { Api_Project } from 'models/api/Project';
import { lookupCodesSlice } from 'store/slices/lookupCodes';
import { act, render, RenderOptions, userEvent, waitFor } from 'utils/test-utils';
Expand Down Expand Up @@ -33,6 +35,29 @@ jest.mock('react-visibility-sensor', () => {
});
});

jest.mock('hooks/repositories/useUserInfoRepository');
(useUserInfoRepository as jest.MockedFunction<typeof useUserInfoRepository>).mockReturnValue({
retrieveUserInfo: jest.fn(),
retrieveUserInfoLoading: true,
retrieveUserInfoResponse: {
...getUserMock(),
userRegions: [
{
id: 1,
userId: 5,
regionCode: 1,
region: { id: 1 },
},
{
id: 2,
userId: 5,
regionCode: 2,
region: { id: 2 },
},
],
},
});

describe('AddProjectContainer component', () => {
// render component under test
const setup = (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { Api_Project } from 'models/api/Project';
import { useCallback, useRef } from 'react';
import { FaBriefcase } from 'react-icons/fa';
import { useHistory } from 'react-router-dom';
import { mapLookupCode } from 'utils';

import SidebarFooter from '../../shared/SidebarFooter';
import { useAddProjectForm } from '../hooks/useAddProjectFormManagement';
Expand All @@ -23,9 +22,8 @@ const AddProjectContainer: React.FC<React.PropsWithChildren<IAddProjectContainer
const history = useHistory();
const { search } = useMapSearch();

const { getOptionsByType, getByType } = useLookupCodeHelpers();
const { getOptionsByType } = useLookupCodeHelpers();
const projectStatusTypeCodes = getOptionsByType(API.PROJECT_STATUS_TYPES);
const regionTypeCodes = getByType(API.REGION_TYPES).map(c => mapLookupCode(c));

const formikRef = useRef<FormikProps<ProjectForm>>(null);

Expand Down Expand Up @@ -55,7 +53,6 @@ const AddProjectContainer: React.FC<React.PropsWithChildren<IAddProjectContainer
ref={formikRef}
initialValues={helper.initialValues}
projectStatusOptions={projectStatusTypeCodes}
projectRegionOptions={regionTypeCodes}
onSubmit={helper.handleSubmit}
validationSchema={helper.validationSchema}
isCreating
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import { SelectOption } from 'components/common/form';
import * as API from 'constants/API';
import { FormikProps } from 'formik';
import { createMemoryHistory } from 'history';
import { GetMockLookUpsByType, mockLookups } from 'mocks/mockLookups';
import { useUserInfoRepository } from 'hooks/repositories/useUserInfoRepository';
import { getMockLookUpsByType, mockLookups } from 'mocks/mockLookups';
import { getUserMock } from 'mocks/userMock';
import { createRef } from 'react';
import { lookupCodesSlice } from 'store/slices/lookupCodes';
import { act, fakeText, fillInput, render, RenderOptions, userEvent } from 'utils/test-utils';
Expand All @@ -18,20 +20,42 @@ const onSubmit = jest.fn();
type TestProps = Pick<IAddProjectFormProps, 'initialValues'>;
jest.mock('@react-keycloak/web');

let mockRegionOptions: SelectOption[] = GetMockLookUpsByType(API.REGION_TYPES);
let mockProjectStatuses: SelectOption[] = GetMockLookUpsByType(API.PROJECT_STATUS_TYPES);
jest.mock('hooks/repositories/useUserInfoRepository');
(useUserInfoRepository as jest.MockedFunction<typeof useUserInfoRepository>).mockReturnValue({
retrieveUserInfo: jest.fn(),
retrieveUserInfoLoading: true,
retrieveUserInfoResponse: {
...getUserMock(),
userRegions: [
{
id: 1,
userId: 5,
regionCode: 1,
region: { id: 1 },
},
{
id: 2,
userId: 5,
regionCode: 2,
region: { id: 2 },
},
],
},
});

const mockStatusOptions: SelectOption[] = getMockLookUpsByType(API.PROJECT_STATUS_TYPES);

describe('AddProjectForm component', () => {
// render component under test
const setup = (props: TestProps, renderOptions: RenderOptions = {}) => {
const ref = createRef<FormikProps<ProjectForm>>();
const utils = render(
<AddProjectForm
ref={ref}
initialValues={props.initialValues}
validationSchema={validationSchema}
onSubmit={onSubmit}
projectStatusOptions={mockRegionOptions}
projectRegionOptions={mockProjectStatuses}
projectStatusOptions={mockStatusOptions}
/>,
{
...renderOptions,
Expand Down Expand Up @@ -104,7 +128,7 @@ describe('AddProjectForm component', () => {
expect(status.tagName).toBe('SELECT');
});

it.only('should validate character limits', async () => {
it('should validate character limits', async () => {
const { container, getFormikRef, findByText } = setup({
initialValues,
});
Expand All @@ -124,13 +148,27 @@ describe('AddProjectForm component', () => {
expect(await findByText(/Project summary must be at most 2000 characters/i)).toBeVisible();
});

it('should call onSubmit and save form data as expected', async () => {
const { getFormikRef, getNameTextbox, getRegionDropdown } = setup({
initialValues,
});

await act(() => userEvent.selectOptions(getRegionDropdown(), '1'));
await act(() => userEvent.paste(getNameTextbox(), `TRANS-CANADA HWY - 10`));

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

expect(onSubmit).toHaveBeenCalled();
});

it('should add a product', async () => {
const { getByText, getProductCodeTextBox } = setup({
initialValues,
});

const addProductButton = getByText('+ Add another product');
act(() => {
await act(() => {
userEvent.click(addProductButton);
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Form, Input, Select, SelectOption, TextArea } from 'components/common/form';
import { UserRegionSelectContainer } from 'components/common/form/UserRegionSelect/UserRegionSelectContainer';
import { Section } from 'features/mapSideBar/tabs/Section';
import { SectionField } from 'features/mapSideBar/tabs/SectionField';
import { Formik, FormikHelpers, FormikProps } from 'formik';
Expand All @@ -15,7 +16,6 @@ export interface IAddProjectFormProps {
/** Initial values of the form */
initialValues: ProjectForm;
projectStatusOptions: SelectOption[];
projectRegionOptions: SelectOption[];
/** A Yup Schema or a function that returns a Yup schema */
validationSchema?: any | (() => any);
/** Submission handler */
Expand All @@ -24,13 +24,7 @@ export interface IAddProjectFormProps {

const AddProjectForm = React.forwardRef<FormikProps<ProjectForm>, IAddProjectFormProps>(
(props, formikRef) => {
const {
initialValues,
projectStatusOptions,
projectRegionOptions,
validationSchema,
onSubmit,
} = props;
const { initialValues, projectStatusOptions, validationSchema, onSubmit } = props;

const handleSubmit = async (values: ProjectForm, formikHelpers: FormikHelpers<ProjectForm>) => {
await onSubmit(values, formikHelpers);
Expand Down Expand Up @@ -73,7 +67,7 @@ const AddProjectForm = React.forwardRef<FormikProps<ProjectForm>, IAddProjectFor
/>
</SectionField>
<SectionField label="MoTI region" required labelWidth="2">
<Select field="region" options={projectRegionOptions} placeholder="Select..." />
<UserRegionSelectContainer field="region" placeholder="Select region..." />
</SectionField>
<SectionField label="Project summary" labelWidth="12">
<MediumTextArea field="summary" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ exports[`AddProjectContainer component renders as expected 1`] = `
<option
value=""
>
Select...
Select region...
</option>
<option
class="option"
Expand All @@ -477,20 +477,6 @@ exports[`AddProjectContainer component renders as expected 1`] = `
>
Southern Interior Region
</option>
<option
class="option"
data-testid="select-option-3"
value="3"
>
Northern Region
</option>
<option
class="option"
data-testid="select-option-4"
value="4"
>
Cannot determine
</option>
</select>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,31 +273,45 @@ exports[`AddProjectForm component renders as expected 1`] = `
</option>
<option
class="option"
data-testid="select-option-1"
value="1"
data-testid="select-option-AC"
value="AC"
>
South Coast Region
Active (AC)
</option>
<option
class="option"
data-testid="select-option-2"
value="2"
data-testid="select-option-CA"
value="CA"
>
Southern Interior Region
Cancelled (CA)
</option>
<option
class="option"
data-testid="select-option-3"
value="3"
data-testid="select-option-CNCN"
value="CNCN"
>
Northern Region
Consolidated (CNCN)
</option>
<option
class="option"
data-testid="select-option-4"
value="4"
data-testid="select-option-CO"
value="CO"
>
Cannot determine
Completed (CO)
</option>
<option
class="option"
data-testid="select-option-HO"
value="HO"
>
On Hold (HO)
</option>
<option
class="option"
data-testid="select-option-PL"
value="PL"
>
Planning (PL)
</option>
</select>
</div>
Expand Down Expand Up @@ -329,49 +343,21 @@ exports[`AddProjectForm component renders as expected 1`] = `
<option
value=""
>
Select...
Select region...
</option>
<option
class="option"
data-testid="select-option-AC"
value="AC"
>
Active (AC)
</option>
<option
class="option"
data-testid="select-option-CA"
value="CA"
>
Cancelled (CA)
</option>
<option
class="option"
data-testid="select-option-CNCN"
value="CNCN"
>
Consolidated (CNCN)
</option>
<option
class="option"
data-testid="select-option-CO"
value="CO"
>
Completed (CO)
</option>
<option
class="option"
data-testid="select-option-HO"
value="HO"
data-testid="select-option-1"
value="1"
>
On Hold (HO)
South Coast Region
</option>
<option
class="option"
data-testid="select-option-PL"
value="PL"
data-testid="select-option-2"
value="2"
>
Planning (PL)
Southern Interior Region
</option>
</select>
</div>
Expand Down
Loading

0 comments on commit a2ea0f3

Please sign in to comment.