Skip to content

Commit

Permalink
BHBC-865: Create project workflow updates based on permits + misc (#107)
Browse files Browse the repository at this point in the history
* BHBC-865: Create project workflow updates based on permits + misc

* BHBC-865: Test updates

* BHBC-865: Update button styling on final create project step
  • Loading branch information
NickPhura authored Mar 10, 2021
1 parent 10aa974 commit 1bf9d01
Show file tree
Hide file tree
Showing 20 changed files with 3,942 additions and 2,202 deletions.
2 changes: 1 addition & 1 deletion api/src/models/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ export class PostCoordinatorData {
}

export interface IPostPermit {
permit_number: string;
permit_number: number;
sampling_conducted: boolean;
}

Expand Down
2 changes: 1 addition & 1 deletion api/src/openapi/schemas/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export const projectPostBody = {
type: 'object',
properties: {
permit_number: {
type: 'string'
type: 'number'
},
sampling_conducted: {
type: 'string'
Expand Down
19 changes: 19 additions & 0 deletions app/src/__mocks__/popper.js.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// __mocks__/popper.js.js

// mocks will be picked up by Jest and applied automatically.
// Required to make the material-ui select/autocomplete components work during unit tests
// See https://stackoverflow.com/questions/60333156/how-to-fix-typeerror-document-createrange-is-not-a-function-error-while-testi

import PopperJs from 'popper.js';

export default class Popper {
constructor() {
this.placements = PopperJs.placements;

return {
update: () => {},
destroy: () => {},
scheduleUpdate: () => {}
};
}
}
19 changes: 1 addition & 18 deletions app/src/components/fields/AutocompleteField.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { MenuItem, TextField } from '@material-ui/core';
import { TextField } from '@material-ui/core';
import Autocomplete, { createFilterOptions } from '@material-ui/lab/Autocomplete';
import { useFormikContext } from 'formik';
import React from 'react';
Expand All @@ -16,14 +16,6 @@ export interface IAutocompleteField {
const AutocompleteField: React.FC<IAutocompleteField> = (props) => {
const { touched, errors, setFieldValue } = useFormikContext<string>();

const handleGetOptionSelected = (option: string, value: string): boolean => {
if (!option || !value) {
return false;
}

return option === value;
};

return (
<Autocomplete
freeSolo
Expand All @@ -35,19 +27,10 @@ const AutocompleteField: React.FC<IAutocompleteField> = (props) => {
value={props.value}
options={props.options}
getOptionLabel={(option) => option}
getOptionSelected={handleGetOptionSelected}
filterOptions={createFilterOptions({ limit: props.filterLimit })}
onChange={(event, option) => {
setFieldValue(props.id, option);
}}
renderOption={(option, { selected }) => {
return (
<>
<MenuItem style={{ marginRight: 8 }} value={option} selected={selected} />
{option}
</>
);
}}
renderInput={(params) => (
<TextField
{...params}
Expand Down
179 changes: 107 additions & 72 deletions app/src/features/projects/CreateProjectPage.test.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import { cleanup, findByText as rawFindByText, fireEvent, render } from '@testing-library/react';
import { cleanup, findByText as rawFindByText, fireEvent, render, waitFor } from '@testing-library/react';
import { createMemoryHistory } from 'history';
import { useBiohubApi } from 'hooks/useBioHubApi';
import { ICreateProjectResponse } from 'interfaces/useBioHubApi-interfaces';
import React from 'react';
import { act } from 'react-dom/test-utils';
import { Router } from 'react-router';
import CreateProjectPage from './CreateProjectPage';

const history = createMemoryHistory();

jest.mock('../../hooks/useBioHubApi');
const mockUseBiohubApi = {
createProject: jest.fn<Promise<ICreateProjectResponse>, []>(),
getAllCodes: jest.fn<Promise<object>, []>()
};

Expand All @@ -30,96 +27,134 @@ const renderContainer = () => {
describe('CreateProjectPage', () => {
beforeEach(() => {
// clear mocks before each test
mockBiohubApi().createProject.mockClear();
mockBiohubApi().getAllCodes.mockClear();
});

afterEach(() => {
cleanup();
});

it('shows the page title', async () => {
await act(async () => {
mockBiohubApi().createProject.mockResolvedValue({
id: 100
});
mockBiohubApi().getAllCodes.mockResolvedValue({
code_set: []
});
const { findByText } = renderContainer();
const PageTitle = await findByText('Create Project');
it('renders the initial default page correctly', async () => {
mockBiohubApi().getAllCodes.mockResolvedValue({
code_set: []
});
const { getByText, asFragment } = renderContainer();

expect(PageTitle).toBeVisible();
await waitFor(() => {
expect(getByText('Project Coordinator')).toBeVisible();

expect(getByText('Permits')).toBeVisible();

expect(asFragment()).toMatchSnapshot();
});
});

it('adds the extra create project steps if at least 1 permit is marked as having conducted sampling', async () => {
mockBiohubApi().getAllCodes.mockResolvedValue({
coordinator_agency: [{ id: 1, name: 'code 1' }]
});
const { findByText, asFragment, getByText, getByTestId, getByLabelText } = renderContainer();

// wait for project coordinator form to load
expect(await findByText('First Name')).toBeVisible();

fireEvent.change(getByLabelText('First Name *'), { target: { value: 'first name' } });
fireEvent.change(getByLabelText('Last Name *'), { target: { value: 'last name' } });
fireEvent.change(getByLabelText('Business Email Address *'), { target: { value: '[email protected]' } });
fireEvent.change(getByLabelText('Coordinator Agency *'), { target: { value: 'agency name' } });

fireEvent.click(getByText('Next'));

// wait for permit form to load
expect(await findByText('Add Another')).toBeVisible();

fireEvent.change(getByLabelText('Permit Number *'), { target: { value: 12345 } });
fireEvent.change(getByTestId('sampling_conducted'), { target: { value: 'true' } });

// wait for forms to load
await waitFor(() => {
expect(getByText('General Information')).toBeVisible();

expect(getByText('Project Coordinator')).toBeVisible();

expect(getByText('Permits')).toBeVisible();

expect(getByText('General Information')).toBeVisible();

expect(getByText('Objectives')).toBeVisible();

expect(getByText('Location')).toBeVisible();

expect(getByText('Species')).toBeVisible();

expect(getByText('Funding and Partnerships')).toBeVisible();

expect(asFragment()).toMatchSnapshot();
});
});

it('shows the page title', async () => {
mockBiohubApi().getAllCodes.mockResolvedValue({
code_set: []
});
const { findByText } = renderContainer();
const PageTitle = await findByText('Create Project');

expect(PageTitle).toBeVisible();
});

describe('Are you sure? Dialog', () => {
it('shows warning dialog if the user clicks the `Cancel and Exit` button', async () => {
await act(async () => {
mockBiohubApi().createProject.mockResolvedValue({
id: 100
});
mockBiohubApi().getAllCodes.mockResolvedValue({
code_set: []
});
history.push('/home');
history.push('/projects/create');
const { findByText, getByRole } = renderContainer();
const BackToProjectsButton = await findByText('Cancel and Exit', { exact: false });

fireEvent.click(BackToProjectsButton);
const AreYouSureTitle = await findByText('Cancel Create Project');
const AreYouSureText = await findByText('Are you sure you want to cancel?');
const AreYouSureYesButton = await rawFindByText(getByRole('dialog'), 'Yes', { exact: false });

expect(AreYouSureTitle).toBeVisible();
expect(AreYouSureText).toBeVisible();
expect(AreYouSureYesButton).toBeVisible();
mockBiohubApi().getAllCodes.mockResolvedValue({
code_set: []
});
history.push('/home');
history.push('/projects/create');
const { findByText, getByRole } = renderContainer();
const BackToProjectsButton = await findByText('Cancel and Exit', { exact: false });

fireEvent.click(BackToProjectsButton);
const AreYouSureTitle = await findByText('Cancel Create Project');
const AreYouSureText = await findByText('Are you sure you want to cancel?');
const AreYouSureYesButton = await rawFindByText(getByRole('dialog'), 'Yes', { exact: false });

expect(AreYouSureTitle).toBeVisible();
expect(AreYouSureText).toBeVisible();
expect(AreYouSureYesButton).toBeVisible();
});

it('it calls history.push() if the user clicks `Yes`', async () => {
await act(async () => {
mockBiohubApi().createProject.mockResolvedValue({
id: 100
});
mockBiohubApi().getAllCodes.mockResolvedValue({
code_set: []
});
history.push('/home');
history.push('/projects/create');
const { findByText, getByRole } = renderContainer();
const BackToProjectsButton = await findByText('Cancel and Exit', { exact: false });

fireEvent.click(BackToProjectsButton);
const AreYouSureYesButton = await rawFindByText(getByRole('dialog'), 'Yes', { exact: false });

expect(history.location.pathname).toEqual('/projects/create');
fireEvent.click(AreYouSureYesButton);
expect(history.location.pathname).toEqual('/projects');
mockBiohubApi().getAllCodes.mockResolvedValue({
code_set: []
});
history.push('/home');
history.push('/projects/create');
const { findByText, getByRole } = renderContainer();
const BackToProjectsButton = await findByText('Cancel and Exit', { exact: false });

fireEvent.click(BackToProjectsButton);
const AreYouSureYesButton = await rawFindByText(getByRole('dialog'), 'Yes', { exact: false });

expect(history.location.pathname).toEqual('/projects/create');
fireEvent.click(AreYouSureYesButton);
expect(history.location.pathname).toEqual('/projects');
});

it('it does nothing if the user clicks `No`', async () => {
await act(async () => {
mockBiohubApi().createProject.mockResolvedValue({
id: 100
});
mockBiohubApi().getAllCodes.mockResolvedValue({
code_set: []
});
history.push('/home');
history.push('/projects/create');
const { findByText, getByRole } = renderContainer();
const BackToProjectsButton = await findByText('Cancel and Exit', { exact: false });

fireEvent.click(BackToProjectsButton);
const AreYouSureNoButton = await rawFindByText(getByRole('dialog'), 'No', { exact: false });

expect(history.location.pathname).toEqual('/projects/create');
fireEvent.click(AreYouSureNoButton);
expect(history.location.pathname).toEqual('/projects/create');
mockBiohubApi().getAllCodes.mockResolvedValue({
code_set: []
});
history.push('/home');
history.push('/projects/create');
const { findByText, getByRole } = renderContainer();
const BackToProjectsButton = await findByText('Cancel and Exit', { exact: false });

fireEvent.click(BackToProjectsButton);
const AreYouSureNoButton = await rawFindByText(getByRole('dialog'), 'No', { exact: false });

expect(history.location.pathname).toEqual('/projects/create');
fireEvent.click(AreYouSureNoButton);
expect(history.location.pathname).toEqual('/projects/create');
});
});
});
Loading

0 comments on commit 1bf9d01

Please sign in to comment.