-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ASAP-542] - submit compliance report (#4407)
* add compliance report model to cms * fix types * backend updates * frontend updates * add tests * update fixture * update getManuscriptCreateDataObject * update tests * update schema * add more tests for code coverage * update tests * update props for ManuscriptCard * minor changes * updates from code review * update test to wait for enabled share button * allow validation onBlur * conditional onBlur for older forms
- Loading branch information
Showing
56 changed files
with
2,014 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
60 changes: 60 additions & 0 deletions
60
apps/crn-frontend/src/network/teams/TeamComplianceReport.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import { Frame } from '@asap-hub/frontend-utils'; | ||
import { | ||
ComplianceReportForm, | ||
ComplianceReportHeader, | ||
NotFoundPage, | ||
usePushFromHere, | ||
} from '@asap-hub/react-components'; | ||
import { network } from '@asap-hub/routing'; | ||
import { FormProvider, useForm } from 'react-hook-form'; | ||
import { useParams } from 'react-router-dom'; | ||
import { useSetRecoilState } from 'recoil'; | ||
import { | ||
refreshTeamState, | ||
useManuscriptById, | ||
usePostComplianceReport, | ||
} from './state'; | ||
import { useManuscriptToast } from './useManuscriptToast'; | ||
|
||
type TeamComplianceReportProps = { | ||
teamId: string; | ||
}; | ||
const TeamComplianceReport: React.FC<TeamComplianceReportProps> = ({ | ||
teamId, | ||
}) => { | ||
const { manuscriptId } = useParams<{ manuscriptId: string }>(); | ||
const manuscript = useManuscriptById(manuscriptId); | ||
const { setFormType } = useManuscriptToast(); | ||
|
||
const pushFromHere = usePushFromHere(); | ||
|
||
const setRefreshTeamState = useSetRecoilState(refreshTeamState(teamId)); | ||
const form = useForm(); | ||
const createComplianceReport = usePostComplianceReport(); | ||
|
||
if (manuscript && manuscript.versions[0]) { | ||
const onSuccess = () => { | ||
const path = network({}).teams({}).team({ teamId }).workspace({}).$; | ||
setFormType('compliance-report'); | ||
setRefreshTeamState((value) => value + 1); | ||
pushFromHere(path); | ||
}; | ||
|
||
return ( | ||
<FormProvider {...form}> | ||
<Frame title="Create Compliance Report"> | ||
<ComplianceReportHeader /> | ||
<ComplianceReportForm | ||
onSuccess={onSuccess} | ||
onSave={createComplianceReport} | ||
manuscriptTitle={manuscript.title} | ||
manuscriptVersionId={manuscript.versions[0].id} | ||
/> | ||
</Frame> | ||
</FormProvider> | ||
); | ||
} | ||
|
||
return <NotFoundPage />; | ||
}; | ||
export default TeamComplianceReport; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
150 changes: 150 additions & 0 deletions
150
apps/crn-frontend/src/network/teams/__tests__/TeamComplianceReport.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
import { | ||
Auth0Provider, | ||
WhenReady, | ||
} from '@asap-hub/crn-frontend/src/auth/test-utils'; | ||
import { network } from '@asap-hub/routing'; | ||
import { | ||
render, | ||
screen, | ||
waitFor, | ||
waitForElementToBeRemoved, | ||
} from '@testing-library/react'; | ||
import userEvent from '@testing-library/user-event'; | ||
import { createMemoryHistory } from 'history'; | ||
import { ComponentProps, Suspense } from 'react'; | ||
import { Route, Router } from 'react-router-dom'; | ||
import { RecoilRoot } from 'recoil'; | ||
|
||
import { createComplianceReport, getManuscript } from '../api'; | ||
import { ManuscriptToastProvider } from '../ManuscriptToastProvider'; | ||
import { refreshTeamState } from '../state'; | ||
import TeamComplianceReport from '../TeamComplianceReport'; | ||
|
||
const manuscriptResponse = { | ||
id: 'manuscript-1', | ||
title: 'The Manuscript', | ||
versions: [{ id: 'manuscript-version-1' }], | ||
}; | ||
const complianceReportResponse = { id: 'compliance-report-1' }; | ||
|
||
const teamId = '42'; | ||
|
||
jest.mock('../api', () => ({ | ||
createComplianceReport: jest.fn().mockResolvedValue(complianceReportResponse), | ||
getManuscript: jest.fn().mockResolvedValue(manuscriptResponse), | ||
})); | ||
|
||
const mockGetManuscript = getManuscript as jest.MockedFunction< | ||
typeof getManuscript | ||
>; | ||
|
||
beforeEach(() => { | ||
jest.resetModules(); | ||
}); | ||
|
||
const renderPage = async ( | ||
user: ComponentProps<typeof Auth0Provider>['user'] = {}, | ||
history = createMemoryHistory({ | ||
initialEntries: [ | ||
network({}) | ||
.teams({}) | ||
.team({ teamId }) | ||
.workspace({}) | ||
.createComplianceReport({ manuscriptId: manuscriptResponse.id }).$, | ||
], | ||
}), | ||
) => { | ||
const path = | ||
network.template + | ||
network({}).teams.template + | ||
network({}).teams({}).team.template + | ||
network({}).teams({}).team({ teamId }).workspace.template + | ||
network({}).teams({}).team({ teamId }).workspace({}).createComplianceReport | ||
.template; | ||
|
||
const { container } = render( | ||
<RecoilRoot | ||
initializeState={({ set }) => { | ||
set(refreshTeamState(teamId), Math.random()); | ||
}} | ||
> | ||
<Suspense fallback="loading"> | ||
<Auth0Provider user={user}> | ||
<WhenReady> | ||
<Router history={history}> | ||
<Route path={path}> | ||
<ManuscriptToastProvider> | ||
<TeamComplianceReport teamId={teamId} /> | ||
</ManuscriptToastProvider> | ||
</Route> | ||
</Router> | ||
</WhenReady> | ||
</Auth0Provider> | ||
</Suspense> | ||
</RecoilRoot>, | ||
); | ||
await waitForElementToBeRemoved(() => screen.queryByText(/loading/i)); | ||
return { container }; | ||
}; | ||
|
||
it('renders compliance report form page', async () => { | ||
const { container } = await renderPage(); | ||
|
||
expect(container).toHaveTextContent( | ||
'Share the compliance report associated with this manuscript.', | ||
); | ||
expect(container).toHaveTextContent('Title of Manuscript'); | ||
}); | ||
|
||
it('can publish a form when the data is valid and navigates to team workspace', async () => { | ||
const url = 'https://compliancereport.com'; | ||
const description = 'compliance report description'; | ||
const history = createMemoryHistory({ | ||
initialEntries: [ | ||
network({}) | ||
.teams({}) | ||
.team({ teamId }) | ||
.workspace({}) | ||
.createComplianceReport({ manuscriptId: manuscriptResponse.id }).$, | ||
], | ||
}); | ||
|
||
await renderPage({}, history); | ||
|
||
userEvent.type(screen.getByRole('textbox', { name: /url/i }), url); | ||
|
||
userEvent.type( | ||
screen.getByRole('textbox', { | ||
name: /Compliance Report Description/i, | ||
}), | ||
description, | ||
); | ||
|
||
const shareButton = screen.getByRole('button', { name: /Share/i }); | ||
await waitFor(() => expect(shareButton).toBeEnabled()); | ||
|
||
userEvent.click(shareButton); | ||
|
||
await waitFor(() => { | ||
expect(createComplianceReport).toHaveBeenCalledWith( | ||
{ | ||
url, | ||
description, | ||
manuscriptVersionId: manuscriptResponse.versions[0]!.id, | ||
}, | ||
expect.anything(), | ||
); | ||
expect(history.location.pathname).toBe( | ||
`/network/teams/${teamId}/workspace`, | ||
); | ||
}); | ||
}); | ||
|
||
it('renders not found when the manuscript hook does not return a manuscript with a version', async () => { | ||
mockGetManuscript.mockResolvedValue(undefined); | ||
await renderPage(); | ||
|
||
expect(screen.getByRole('heading').textContent).toContain( | ||
'Sorry! We can’t seem to find that page.', | ||
); | ||
}); |
Oops, something went wrong.