From e6e772a63264d6745d9c6e6572796100208f7676 Mon Sep 17 00:00:00 2001 From: RachelHowellNHS Date: Thu, 4 Jan 2024 13:39:53 +0000 Subject: [PATCH 01/43] [PRMDR-414] add warning callout and text --- .../LloydGeorgeRecordDetails.tsx | 90 ++++++++++--------- .../LloydGeorgeRecordStage.tsx | 33 ++++++- 2 files changed, 81 insertions(+), 42 deletions(-) diff --git a/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.tsx b/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.tsx index 1879e61e9..8afa4baa4 100644 --- a/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.tsx @@ -13,6 +13,7 @@ export type Props = { numberOfFiles: number; totalFileSizeInByte: number; setStage: Dispatch>; + userIsGpAdminNonBsol?: boolean; }; function LloydGeorgeRecordDetails({ @@ -20,6 +21,7 @@ function LloydGeorgeRecordDetails({ numberOfFiles, totalFileSizeInByte, setStage, + userIsGpAdminNonBsol, }: Props) { const [showActionsMenu, setShowActionsMenu] = useState(false); const actionsRef = useRef(null); @@ -45,52 +47,58 @@ function LloydGeorgeRecordDetails({ {' |'} -
-
+ {userIsGpAdminNonBsol ? ( +
test
+ ) : ( +
- - Select an action... - - -
- {showActionsMenu && ( -
- - -
    - {actionLinks.map((link) => - role && !link.unauthorised?.includes(role) ? ( -
  1. - { - e.preventDefault(); - setStage(link.stage); - }} - > - {link.label} - -
  2. - ) : null, - )} -
-
-
+ onClick={handleMoreActions} + > +
+ + Select an action... + +
- )} -
+ {showActionsMenu && ( +
+ + +
    + {actionLinks.map((link) => + role && !link.unauthorised?.includes(role) ? ( +
  1. + { + e.preventDefault(); + setStage(link.stage); + }} + > + {link.label} + +
  2. + ) : null, + )} +
+
+
+
+ )} +
+ )}
); } diff --git a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx index 15b57cc4d..dbe8b6666 100644 --- a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx @@ -1,5 +1,5 @@ import React, { Dispatch, SetStateAction, useState } from 'react'; -import { BackLink, Card, Details } from 'nhsuk-react-components'; +import { BackLink, Card, Details, WarningCallout } from 'nhsuk-react-components'; import { getFormattedDate } from '../../../helpers/utils/formatDate'; import { DOWNLOAD_STAGE } from '../../../types/generic/downloadStage'; import PdfViewer from '../../generic/pdfViewer/PdfViewer'; @@ -8,6 +8,9 @@ import { formatNhsNumber } from '../../../helpers/utils/formatNhsNumber'; import { LG_RECORD_STAGE } from '../../../types/blocks/lloydGeorgeStages'; import usePatient from '../../../helpers/hooks/usePatient'; import LloydGeorgeRecordError from '../lloydGeorgeRecordError/LloydGeorgeRecordError'; +import useRole from '../../../helpers/hooks/useRole'; +import { useSessionContext } from '../../../providers/sessionProvider/SessionProvider'; +import { REPOSITORY_ROLE } from '../../../types/generic/authRole'; export type Props = { downloadStage: DOWNLOAD_STAGE; @@ -37,6 +40,11 @@ function LloydGeorgeRecordStage({ const nhsNumber: string = patientDetails?.nhsNumber || ''; const formattedNhsNumber = formatNhsNumber(nhsNumber); + const role = useRole(); + // const [session] = useSessionContext(); + // const userIsGpAdminNonBsol = role === REPOSITORY_ROLE.GP_ADMIN && session.auth?.isBSOL; + const userIsGpAdminNonBsol = true; + const PdfCardDescription = () => { if (downloadStage === DOWNLOAD_STAGE.PENDING) { return Loading...; @@ -46,6 +54,7 @@ function LloydGeorgeRecordStage({ numberOfFiles, totalFileSizeInByte, setStage, + userIsGpAdminNonBsol, }; return ; } else { @@ -66,6 +75,28 @@ function LloydGeorgeRecordStage({ Go back )} + {!fullScreen && userIsGpAdminNonBsol && ( +
+ + + Before downloading + +

+ If you download this record it removes from our storage. You will not be + able to access it here. +

+

+ Once downloaded, you are responsible for this patient's information and + should follow data protection principles as outlined in UK General Data + Protection Regulation (GDPR). +

+
+

Available records

+
+ )}

{`${patientDetails?.givenName} ${patientDetails?.familyName}`} From d54d1900e49b9a91f223a8710bc74bb5ad4e244a Mon Sep 17 00:00:00 2001 From: RachelHowellNHS Date: Thu, 4 Jan 2024 15:17:30 +0000 Subject: [PATCH 02/43] [PRMDR-414] add download and remove record button --- .../lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.tsx | 6 ++++-- app/src/styles/App.scss | 5 +++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.tsx b/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.tsx index 8afa4baa4..3e0767817 100644 --- a/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.tsx @@ -2,7 +2,7 @@ import React, { Dispatch, SetStateAction, useRef, useState } from 'react'; import { ReactComponent as Chevron } from '../../../styles/down-chevron.svg'; import formatFileSize from '../../../helpers/utils/formatFileSize'; import { useOnClickOutside } from 'usehooks-ts'; -import { Card } from 'nhsuk-react-components'; +import { Card, Button } from 'nhsuk-react-components'; import { Link } from 'react-router-dom'; import useRole from '../../../helpers/hooks/useRole'; import { actionLinks } from '../../../types/blocks/lloydGeorgeActions'; @@ -48,7 +48,9 @@ function LloydGeorgeRecordDetails({

{userIsGpAdminNonBsol ? ( -
test
+ ) : (
Date: Thu, 4 Jan 2024 15:31:06 +0000 Subject: [PATCH 03/43] [PRMDR-414] increase space above button --- app/src/styles/App.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/styles/App.scss b/app/src/styles/App.scss index 2896710d4..401d940fb 100644 --- a/app/src/styles/App.scss +++ b/app/src/styles/App.scss @@ -190,7 +190,7 @@ $govuk-compatibility-govukelements: true; } &_download-remove-button { position: absolute; - top: 32px; + top: 80px; right: 32px; } &_actions { From 8e667bef8571feb4bad1f1c1541e9861a005d7d3 Mon Sep 17 00:00:00 2001 From: RachelHowellNHS Date: Thu, 4 Jan 2024 15:35:35 +0000 Subject: [PATCH 04/43] [PRMDR-414] wrap button in div --- .../lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.tsx | 8 +++++--- app/src/styles/App.scss | 3 +++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.tsx b/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.tsx index 3e0767817..0bb9829a1 100644 --- a/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.tsx @@ -48,9 +48,11 @@ function LloydGeorgeRecordDetails({
{userIsGpAdminNonBsol ? ( - +
+ +
) : (
Date: Thu, 4 Jan 2024 15:51:50 +0000 Subject: [PATCH 05/43] [PRMDR-414] remove unused id --- .../blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx index dbe8b6666..253933cc6 100644 --- a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx @@ -76,10 +76,7 @@ function LloydGeorgeRecordStage({ )} {!fullScreen && userIsGpAdminNonBsol && ( -
+
Before downloading From 8460f948264b8b3eea1aaade045876c8eed992f0 Mon Sep 17 00:00:00 2001 From: RachelHowellNHS Date: Thu, 4 Jan 2024 15:59:42 +0000 Subject: [PATCH 06/43] [PRMDR-414] change role to gp clinical for testing and create useIsBSOL hook --- .../lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx | 6 +++--- app/src/helpers/hooks/useIsBSOL.tsx | 10 ++++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 app/src/helpers/hooks/useIsBSOL.tsx diff --git a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx index 253933cc6..99e41300f 100644 --- a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx @@ -11,6 +11,7 @@ import LloydGeorgeRecordError from '../lloydGeorgeRecordError/LloydGeorgeRecordE import useRole from '../../../helpers/hooks/useRole'; import { useSessionContext } from '../../../providers/sessionProvider/SessionProvider'; import { REPOSITORY_ROLE } from '../../../types/generic/authRole'; +import useIsBSOL from '../../../helpers/hooks/useIsBSOL'; export type Props = { downloadStage: DOWNLOAD_STAGE; @@ -41,9 +42,8 @@ function LloydGeorgeRecordStage({ const formattedNhsNumber = formatNhsNumber(nhsNumber); const role = useRole(); - // const [session] = useSessionContext(); - // const userIsGpAdminNonBsol = role === REPOSITORY_ROLE.GP_ADMIN && session.auth?.isBSOL; - const userIsGpAdminNonBsol = true; + const isBSOL = useIsBSOL(); + const userIsGpAdminNonBsol = role === REPOSITORY_ROLE.GP_CLINICAL && !isBSOL; const PdfCardDescription = () => { if (downloadStage === DOWNLOAD_STAGE.PENDING) { diff --git a/app/src/helpers/hooks/useIsBSOL.tsx b/app/src/helpers/hooks/useIsBSOL.tsx new file mode 100644 index 000000000..75c51b8c3 --- /dev/null +++ b/app/src/helpers/hooks/useIsBSOL.tsx @@ -0,0 +1,10 @@ +import { useSessionContext } from '../../providers/sessionProvider/SessionProvider'; + +function useIsBSOL() { + const [session] = useSessionContext(); + + const isBSOL = session.auth ? session.auth.isBSOL : null; + return isBSOL; +} + +export default useIsBSOL; From a87c545dfbb17574e1bb56bd014b104229251dbe Mon Sep 17 00:00:00 2001 From: RachelHowellNHS Date: Thu, 4 Jan 2024 16:43:51 +0000 Subject: [PATCH 07/43] [PRMDR-414] fix tests --- .../lloydGeorgeRecordStage/LloydGeorgeRecordStage.test.tsx | 1 + .../blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx | 1 - .../pages/lloydGeorgeRecordPage/LloydGeorgeRecordPage.test.tsx | 1 + 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.test.tsx b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.test.tsx index feeddcd8f..e95244092 100644 --- a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.test.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.test.tsx @@ -14,6 +14,7 @@ const mockPatientDetails = buildPatientDetails(); jest.mock('../../../helpers/hooks/useRole'); jest.mock('../../../helpers/hooks/usePatient'); +jest.mock('../../../helpers/hooks/useIsBSOL'); const mockedUsePatient = usePatient as jest.Mock; const mockNavigate = jest.fn(); diff --git a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx index 99e41300f..7a1e26cc5 100644 --- a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx @@ -9,7 +9,6 @@ import { LG_RECORD_STAGE } from '../../../types/blocks/lloydGeorgeStages'; import usePatient from '../../../helpers/hooks/usePatient'; import LloydGeorgeRecordError from '../lloydGeorgeRecordError/LloydGeorgeRecordError'; import useRole from '../../../helpers/hooks/useRole'; -import { useSessionContext } from '../../../providers/sessionProvider/SessionProvider'; import { REPOSITORY_ROLE } from '../../../types/generic/authRole'; import useIsBSOL from '../../../helpers/hooks/useIsBSOL'; diff --git a/app/src/pages/lloydGeorgeRecordPage/LloydGeorgeRecordPage.test.tsx b/app/src/pages/lloydGeorgeRecordPage/LloydGeorgeRecordPage.test.tsx index 0ebb4cbce..2e797c277 100644 --- a/app/src/pages/lloydGeorgeRecordPage/LloydGeorgeRecordPage.test.tsx +++ b/app/src/pages/lloydGeorgeRecordPage/LloydGeorgeRecordPage.test.tsx @@ -11,6 +11,7 @@ jest.mock('../../helpers/hooks/usePatient'); jest.mock('../../helpers/hooks/useBaseAPIHeaders'); jest.mock('../../helpers/hooks/useBaseAPIUrl'); jest.mock('../../helpers/hooks/useRole'); +jest.mock('../../helpers/hooks/useIsBSOL'); const mockAxios = axios as jest.Mocked; const mockPatientDetails = buildPatientDetails(); const mockedUsePatient = usePatient as jest.Mock; From c7e6918baf8b479f526bee03650cea49b7a47371 Mon Sep 17 00:00:00 2001 From: RachelHowellNHS Date: Thu, 4 Jan 2024 16:53:20 +0000 Subject: [PATCH 08/43] [PRMDR-414] change role back to gp admin --- .../blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx index 7a1e26cc5..621e4ed8c 100644 --- a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx @@ -42,7 +42,7 @@ function LloydGeorgeRecordStage({ const role = useRole(); const isBSOL = useIsBSOL(); - const userIsGpAdminNonBsol = role === REPOSITORY_ROLE.GP_CLINICAL && !isBSOL; + const userIsGpAdminNonBsol = role === REPOSITORY_ROLE.GP_ADMIN && !isBSOL; const PdfCardDescription = () => { if (downloadStage === DOWNLOAD_STAGE.PENDING) { From 190b631c7a9eefe09c041ca5a8e42fd1ea7ff26a Mon Sep 17 00:00:00 2001 From: RachelHowellNHS Date: Fri, 5 Jan 2024 11:03:36 +0000 Subject: [PATCH 09/43] [PRMDR-414] unit tests --- .../LloydGeorgeRecordDetails.test.tsx | 33 ++++++++++- .../LloydGeorgeRecordDetails.tsx | 6 +- .../LloydGeorgeRecordStage.test.tsx | 57 +++++++++++++++++++ .../LloydGeorgeRecordStage.tsx | 6 +- app/src/helpers/hooks/useIsBSOL.test.tsx | 42 ++++++++++++++ 5 files changed, 135 insertions(+), 9 deletions(-) create mode 100644 app/src/helpers/hooks/useIsBSOL.test.tsx diff --git a/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.test.tsx b/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.test.tsx index 5af09ea71..17075cd48 100644 --- a/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.test.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.test.tsx @@ -12,7 +12,7 @@ jest.mock('../../../helpers/hooks/useRole'); const mockedUseNavigate = jest.fn(); const mockPdf = buildLgSearchResult(); -const mockSetStaqe = jest.fn(); +const mockSetStage = jest.fn(); const mockedUseRole = useRole as jest.Mock; jest.mock('react-router', () => ({ useNavigate: () => mockedUseNavigate, @@ -96,7 +96,7 @@ describe('LloydGeorgeRecordDetails', () => { userEvent.click(screen.getByText(action.label)); }); await waitFor(async () => { - expect(mockSetStaqe).toHaveBeenCalledWith(action.stage); + expect(mockSetStage).toHaveBeenCalledWith(action.stage); }); }, ); @@ -132,10 +132,37 @@ describe('LloydGeorgeRecordDetails', () => { }, ); }); + + describe('GP admin non BSOL user', () => { + it('renders the record details component with button', () => { + render( + , + ); + + expect(screen.getByText(`Last updated: ${mockPdf.last_updated}`)).toBeInTheDocument(); + expect(screen.getByText(`${mockPdf.number_of_files} files`)).toBeInTheDocument(); + expect( + screen.getByText(`File size: ${formatFileSize(mockPdf.total_file_size_in_byte)}`), + ).toBeInTheDocument(); + expect(screen.getByText('File format: PDF')).toBeInTheDocument(); + expect( + screen.getByRole('button', { name: 'Download and remove record' }), + ).toBeInTheDocument(); + + expect(screen.queryByText(`Select an action...`)).not.toBeInTheDocument(); + expect(screen.queryByTestId('actions-menu')).not.toBeInTheDocument(); + }); + }); }); const TestApp = (props: Omit) => { - return ; + return ; }; const renderComponent = (propsOverride?: Partial) => { diff --git a/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.tsx b/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.tsx index 0bb9829a1..854d3a3c8 100644 --- a/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.tsx @@ -13,7 +13,7 @@ export type Props = { numberOfFiles: number; totalFileSizeInByte: number; setStage: Dispatch>; - userIsGpAdminNonBsol?: boolean; + userIsGpAdminNonBSOL?: boolean; }; function LloydGeorgeRecordDetails({ @@ -21,7 +21,7 @@ function LloydGeorgeRecordDetails({ numberOfFiles, totalFileSizeInByte, setStage, - userIsGpAdminNonBsol, + userIsGpAdminNonBSOL, }: Props) { const [showActionsMenu, setShowActionsMenu] = useState(false); const actionsRef = useRef(null); @@ -47,7 +47,7 @@ function LloydGeorgeRecordDetails({ {' |'}
- {userIsGpAdminNonBsol ? ( + {userIsGpAdminNonBSOL ? (
diff --git a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx index 0d4fa1161..7918fa560 100644 --- a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx @@ -1,5 +1,5 @@ import React, { Dispatch, SetStateAction, useState } from 'react'; -import { BackLink, Card, Details, WarningCallout } from 'nhsuk-react-components'; +import { BackLink, Card, Details, WarningCallout, InsetText } from 'nhsuk-react-components'; import { getFormattedDate } from '../../../helpers/utils/formatDate'; import { DOWNLOAD_STAGE } from '../../../types/generic/downloadStage'; import PdfViewer from '../../generic/pdfViewer/PdfViewer'; @@ -32,6 +32,7 @@ function LloydGeorgeRecordStage({ stage, }: Props) { const [fullScreen, setFullScreen] = useState(false); + const [downloadRemoveButtonClicked, setDownloadRemoveButtonClicked] = useState(false); const patientDetails = usePatient(); const dob: String = patientDetails?.birthDate ? getFormattedDate(new Date(patientDetails.birthDate)) @@ -53,7 +54,8 @@ function LloydGeorgeRecordStage({ numberOfFiles, totalFileSizeInByte, setStage, - userIsGpAdminNonBSOL: userIsGpAdminNonBSOL, + userIsGpAdminNonBSOL, + setDownloadRemoveButtonClicked, }; return ; } else { @@ -89,6 +91,7 @@ function LloydGeorgeRecordStage({ should follow data protection principles as outlined in UK General Data Protection Regulation (GDPR).

+ {downloadRemoveButtonClicked && Test}

Available records

From 9e4852f98a25101325e526347d8318157c70ffa7 Mon Sep 17 00:00:00 2001 From: RachelHowellNHS Date: Fri, 5 Jan 2024 17:25:48 +0000 Subject: [PATCH 13/43] [PRMDR-417] fix unit tests props --- .../LloydGeorgeRecordDetails.test.tsx | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.test.tsx b/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.test.tsx index 17075cd48..6325ff871 100644 --- a/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.test.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.test.tsx @@ -13,6 +13,7 @@ jest.mock('../../../helpers/hooks/useRole'); const mockedUseNavigate = jest.fn(); const mockPdf = buildLgSearchResult(); const mockSetStage = jest.fn(); +const mockSetDownloadRemoveButtonClicked = jest.fn(); const mockedUseRole = useRole as jest.Mock; jest.mock('react-router', () => ({ useNavigate: () => mockedUseNavigate, @@ -142,6 +143,7 @@ describe('LloydGeorgeRecordDetails', () => { totalFileSizeInByte={mockPdf.total_file_size_in_byte} setStage={mockSetStage} userIsGpAdminNonBSOL={true} + setDownloadRemoveButtonClicked={mockSetDownloadRemoveButtonClicked} />, ); @@ -161,12 +163,18 @@ describe('LloydGeorgeRecordDetails', () => { }); }); -const TestApp = (props: Omit) => { - return ; +const TestApp = (props: Omit) => { + return ( + + ); }; const renderComponent = (propsOverride?: Partial) => { - const props: Omit = { + const props: Omit = { lastUpdated: mockPdf.last_updated, numberOfFiles: mockPdf.number_of_files, totalFileSizeInByte: mockPdf.total_file_size_in_byte, From cf1065bba619f52b2e8ef1a8663bd4e990da7fb1 Mon Sep 17 00:00:00 2001 From: RachelHowellNHS Date: Mon, 8 Jan 2024 13:47:15 +0000 Subject: [PATCH 14/43] [PRMDR-417] add content to inset text --- .../LloydGeorgeRecordStage.tsx | 42 +++++++++++++++++-- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx index 7918fa560..4de95a1c5 100644 --- a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx @@ -1,5 +1,14 @@ import React, { Dispatch, SetStateAction, useState } from 'react'; -import { BackLink, Card, Details, WarningCallout, InsetText } from 'nhsuk-react-components'; +import { + BackLink, + Card, + Details, + WarningCallout, + InsetText, + Checkboxes, + Button, + ButtonLink, +} from 'nhsuk-react-components'; import { getFormattedDate } from '../../../helpers/utils/formatDate'; import { DOWNLOAD_STAGE } from '../../../types/generic/downloadStage'; import PdfViewer from '../../generic/pdfViewer/PdfViewer'; @@ -78,7 +87,7 @@ function LloydGeorgeRecordStage({ )} {!fullScreen && userIsGpAdminNonBSOL && (
- + Before downloading @@ -91,7 +100,34 @@ function LloydGeorgeRecordStage({ should follow data protection principles as outlined in UK General Data Protection Regulation (GDPR).

- {downloadRemoveButtonClicked && Test} + {downloadRemoveButtonClicked && ( + +

Are you sure you want to download and remove this record?

+

+ If you download this record, it will remove from our storage. + You must keep the patient's record safe. +

+ + + + + + + + + Cancel + +
+ )}

Available records

From be548556223a9713c6da644ddc77f5d3d16a2e45 Mon Sep 17 00:00:00 2001 From: RachelHowellNHS Date: Mon, 8 Jan 2024 14:12:09 +0000 Subject: [PATCH 15/43] [PRMDR-417] fix checkbox --- .../lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx index 4de95a1c5..6f62e4f9e 100644 --- a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx @@ -107,13 +107,10 @@ function LloydGeorgeRecordStage({ If you download this record, it will remove from our storage. You must keep the patient's record safe.

- - - - + + + I understand that downloading this record removes it from + storage. Cancel diff --git a/app/src/styles/App.scss b/app/src/styles/App.scss index 0f1dd3994..fc3d6b02a 100644 --- a/app/src/styles/App.scss +++ b/app/src/styles/App.scss @@ -160,6 +160,15 @@ $govuk-compatibility-govukelements: true; top: 30px; } } + &_gp-admin-non-bsol { + &_inset-text { + padding-bottom: 0; + padding-top: 0; + &_yes-download-remove-button { + background-color: #d5281b; + } + } + } } &_downloadall-stage { &_header { From 6752210ed35afdfe9a4a588d9f2cbaa2fbf1e83d Mon Sep 17 00:00:00 2001 From: RachelHowellNHS Date: Mon, 8 Jan 2024 15:12:29 +0000 Subject: [PATCH 17/43] [PRMDR-417] amend styling --- .../LloydGeorgeRecordStage.tsx | 14 +++++++++++--- app/src/styles/App.scss | 2 +- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx index 04a45d359..ad34923be 100644 --- a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx @@ -72,6 +72,8 @@ function LloydGeorgeRecordStage({ } }; + const handleConfirmDownloadAndRemoveButton = () => {}; + return (
{fullScreen && ( @@ -107,13 +109,19 @@ function LloydGeorgeRecordStage({ If you download this record, it will remove from our storage. You must keep the patient's record safe.

- - + + I understand that downloading this record removes it from storage. - Date: Mon, 8 Jan 2024 16:00:53 +0000 Subject: [PATCH 18/43] [PRMDR-417] add warning icon --- .../lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx index ad34923be..a2a381218 100644 --- a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx @@ -20,6 +20,7 @@ import LloydGeorgeRecordError from '../lloydGeorgeRecordError/LloydGeorgeRecordE import useRole from '../../../helpers/hooks/useRole'; import { REPOSITORY_ROLE } from '../../../types/generic/authRole'; import useIsBSOL from '../../../helpers/hooks/useIsBSOL'; +import WarningText from '../../generic/warningText/WarningText'; export type Props = { downloadStage: DOWNLOAD_STAGE; @@ -105,10 +106,10 @@ function LloydGeorgeRecordStage({ {downloadRemoveButtonClicked && (

Are you sure you want to download and remove this record?

-

- If you download this record, it will remove from our storage. - You must keep the patient's record safe. -

+ Date: Mon, 8 Jan 2024 16:35:59 +0000 Subject: [PATCH 19/43] [PRMDR-417] fix button colour --- app/src/styles/App.scss | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/styles/App.scss b/app/src/styles/App.scss index 68bf89c59..7e36315a0 100644 --- a/app/src/styles/App.scss +++ b/app/src/styles/App.scss @@ -166,7 +166,11 @@ $govuk-compatibility-govukelements: true; padding-bottom: 0; padding-top: 0; &_confirm-download-remove-button { - background-color: #d5281b; + background-color: #b61105; + box-shadow: #9a0c02; + &:hover { + background-color: #9a0c02; + } } } } From 9c6f42d48ecd7b5cb6039ff1dab453559db8b6ea Mon Sep 17 00:00:00 2001 From: RachelHowellNHS Date: Mon, 8 Jan 2024 18:00:15 +0000 Subject: [PATCH 20/43] [PRMDR-417] amend button submit, change id --- .../blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx index 5c6f56920..321b729d7 100644 --- a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx @@ -126,7 +126,7 @@ function LloydGeorgeRecordStage({ {downloadRemoveButtonClicked && (
{ + setDownloadRemoveButtonClicked(false); + }} className="nhsuk-button nhsuk-button--secondary" style={{ marginLeft: 30 }} role="button" From 6be1164d7317619166c4f183de52e0e72af6671d Mon Sep 17 00:00:00 2001 From: RachelHowellNHS Date: Tue, 9 Jan 2024 10:26:45 +0000 Subject: [PATCH 23/43] [PRMDR-417] add condition to stop error showing after cancel button has been clicked --- .../blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx index 01196a2a9..e80d1b18a 100644 --- a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx @@ -93,9 +93,9 @@ function LloydGeorgeRecordStage({ return (
- {formState.errors.confirmDownloadRemove && ( + {formState.errors.confirmDownloadRemove && downloadRemoveButtonClicked && ( From 131443ad2fe5b58f7592c8b4c8fc51653417335a Mon Sep 17 00:00:00 2001 From: RachelHowellNHS Date: Tue, 9 Jan 2024 10:40:15 +0000 Subject: [PATCH 24/43] [PRMDR-417] add clearErrors hook --- .../LloydGeorgeRecordStage.tsx | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx index e80d1b18a..f22e3b41c 100644 --- a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx @@ -52,7 +52,7 @@ function LloydGeorgeRecordStage({ ? getFormattedDate(new Date(patientDetails.birthDate)) : ''; - const { register, handleSubmit, formState, getFieldState } = useForm({ + const { register, handleSubmit, formState, getFieldState, clearErrors } = useForm({ reValidateMode: 'onSubmit', }); const { ref: inputRef, ...checkboxProps } = register('confirmDownloadRemove', { @@ -91,9 +91,14 @@ function LloydGeorgeRecordStage({ } }; + const handleCancelButton = () => { + setDownloadRemoveButtonClicked(false); + clearErrors('confirmDownloadRemove'); + }; + return (
- {formState.errors.confirmDownloadRemove && downloadRemoveButtonClicked && ( + {formState.errors.confirmDownloadRemove && ( { - setDownloadRemoveButtonClicked(false); - }} + onClick={handleCancelButton} className="nhsuk-button nhsuk-button--secondary" style={{ marginLeft: 30 }} role="button" From 832678ab01d9c0a46342c3ff64d3124cca5b791a Mon Sep 17 00:00:00 2001 From: RachelHowellNHS Date: Tue, 9 Jan 2024 11:34:46 +0000 Subject: [PATCH 25/43] [PRMDR-417] add setError hook --- .../lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.tsx | 8 ++++++++ .../lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx | 4 +++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.tsx b/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.tsx index 2d4be9024..af4469951 100644 --- a/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.tsx @@ -7,6 +7,7 @@ import { Link } from 'react-router-dom'; import useRole from '../../../helpers/hooks/useRole'; import { actionLinks } from '../../../types/blocks/lloydGeorgeActions'; import { LG_RECORD_STAGE } from '../../../types/blocks/lloydGeorgeStages'; +import { FieldValues, UseFormSetError } from 'react-hook-form'; export type Props = { lastUpdated: string; @@ -15,6 +16,8 @@ export type Props = { setStage: Dispatch>; userIsGpAdminNonBSOL?: boolean; setDownloadRemoveButtonClicked: Dispatch>; + downloadRemoveButtonClicked: boolean; + setError: UseFormSetError; }; function LloydGeorgeRecordDetails({ @@ -24,6 +27,8 @@ function LloydGeorgeRecordDetails({ setStage, userIsGpAdminNonBSOL, setDownloadRemoveButtonClicked, + downloadRemoveButtonClicked, + setError, }: Props) { const [showActionsMenu, setShowActionsMenu] = useState(false); const actionsRef = useRef(null); @@ -36,6 +41,9 @@ function LloydGeorgeRecordDetails({ }); const handleDownloadAndRemoveRecordButton = () => { + if (downloadRemoveButtonClicked) { + setError('confirmDownloadRemove', { type: 'custom', message: 'true' }); + } setDownloadRemoveButtonClicked(true); }; diff --git a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx index f22e3b41c..543206393 100644 --- a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx @@ -52,7 +52,7 @@ function LloydGeorgeRecordStage({ ? getFormattedDate(new Date(patientDetails.birthDate)) : ''; - const { register, handleSubmit, formState, getFieldState, clearErrors } = useForm({ + const { register, handleSubmit, formState, getFieldState, clearErrors, setError } = useForm({ reValidateMode: 'onSubmit', }); const { ref: inputRef, ...checkboxProps } = register('confirmDownloadRemove', { @@ -78,6 +78,8 @@ function LloydGeorgeRecordStage({ setStage, userIsGpAdminNonBSOL, setDownloadRemoveButtonClicked, + downloadRemoveButtonClicked, + setError, }; return ; } else { From bb0ef48e46ab83971539519f0c4741210a13f841 Mon Sep 17 00:00:00 2001 From: RachelHowellNHS Date: Tue, 9 Jan 2024 11:38:20 +0000 Subject: [PATCH 26/43] [PRMDR-417] add setError hook --- .../LloydGeorgeRecordDetails.test.tsx | 373 +++++++++--------- 1 file changed, 189 insertions(+), 184 deletions(-) diff --git a/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.test.tsx b/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.test.tsx index 6325ff871..09f08a57e 100644 --- a/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.test.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.test.tsx @@ -1,185 +1,190 @@ -import { render, screen, waitFor } from '@testing-library/react'; -import LgRecordDetails, { Props } from './LloydGeorgeRecordDetails'; -import { buildLgSearchResult } from '../../../helpers/test/testBuilders'; -import formatFileSize from '../../../helpers/utils/formatFileSize'; -import userEvent from '@testing-library/user-event'; -import { act } from 'react-dom/test-utils'; -import { REPOSITORY_ROLE } from '../../../types/generic/authRole'; -import useRole from '../../../helpers/hooks/useRole'; -import { actionLinks } from '../../../types/blocks/lloydGeorgeActions'; -import { LinkProps } from 'react-router-dom'; -jest.mock('../../../helpers/hooks/useRole'); - -const mockedUseNavigate = jest.fn(); -const mockPdf = buildLgSearchResult(); -const mockSetStage = jest.fn(); -const mockSetDownloadRemoveButtonClicked = jest.fn(); -const mockedUseRole = useRole as jest.Mock; -jest.mock('react-router', () => ({ - useNavigate: () => mockedUseNavigate, -})); -jest.mock('react-router-dom', () => ({ - __esModule: true, - Link: (props: LinkProps) => , -})); - -describe('LloydGeorgeRecordDetails', () => { - beforeEach(() => { - mockedUseRole.mockReturnValue(REPOSITORY_ROLE.PCSE); - process.env.REACT_APP_ENVIRONMENT = 'jest'; - }); - afterEach(() => { - jest.clearAllMocks(); - }); - describe('Rendering', () => { - it('renders the record details component', () => { - renderComponent(); - - expect(screen.getByText(`Last updated: ${mockPdf.last_updated}`)).toBeInTheDocument(); - expect(screen.getByText(`${mockPdf.number_of_files} files`)).toBeInTheDocument(); - expect( - screen.getByText(`File size: ${formatFileSize(mockPdf.total_file_size_in_byte)}`), - ).toBeInTheDocument(); - expect(screen.getByText('File format: PDF')).toBeInTheDocument(); - }); - - it('renders record details actions menu', async () => { - renderComponent(); - - expect(screen.getByText(`Select an action...`)).toBeInTheDocument(); - expect(screen.getByTestId('actions-menu')).toBeInTheDocument(); - actionLinks.forEach((action) => { - expect(screen.queryByText(action.label)).not.toBeInTheDocument(); - }); - - act(() => { - userEvent.click(screen.getByTestId('actions-menu')); - }); - await waitFor(async () => { - actionLinks.forEach((action) => { - expect(screen.getByText(action.label)).toBeInTheDocument(); - }); - }); - }); - - it.each(actionLinks)("renders actionLink '$label'", async (action) => { - renderComponent(); - - expect(screen.getByText(`Select an action...`)).toBeInTheDocument(); - expect(screen.getByTestId('actions-menu')).toBeInTheDocument(); - - act(() => { - userEvent.click(screen.getByTestId('actions-menu')); - }); - await waitFor(async () => { - expect(screen.getByText(action.label)).toBeInTheDocument(); - }); - }); - }); - - describe('Navigation', () => { - it.each(actionLinks)( - "navigates to '$stage' when action '$label' is clicked", - async (action) => { - renderComponent(); - - expect(screen.getByText(`Select an action...`)).toBeInTheDocument(); - expect(screen.getByTestId('actions-menu')).toBeInTheDocument(); - - act(() => { - userEvent.click(screen.getByTestId('actions-menu')); - }); - await waitFor(async () => { - expect(screen.getByText(action.label)).toBeInTheDocument(); - }); - - act(() => { - userEvent.click(screen.getByText(action.label)); - }); - await waitFor(async () => { - expect(mockSetStage).toHaveBeenCalledWith(action.stage); - }); - }, - ); - }); - - describe('Unauthorised', () => { - const unauthorisedLinks = actionLinks.filter((a) => Array.isArray(a.unauthorised)); - - it.each(unauthorisedLinks)( - "does not render actionLink '$label' if role is unauthorised", - async (action) => { - const [unauthorisedRole] = action.unauthorised ?? []; - mockedUseRole.mockReturnValue(unauthorisedRole); - - renderComponent(); - - expect(screen.getByText(`Select an action...`)).toBeInTheDocument(); - expect(screen.getByTestId('actions-menu')).toBeInTheDocument(); - - act(() => { - userEvent.click(screen.getByTestId('actions-menu')); - }); - await waitFor(async () => { - expect(screen.queryByText(action.label)).not.toBeInTheDocument(); - }); - }, - ); - - it.each(unauthorisedLinks)( - "does not render actionLink '$label' for GP Clinical Role", - async (action) => { - expect(action.unauthorised).toContain(REPOSITORY_ROLE.GP_CLINICAL); - }, - ); - }); - - describe('GP admin non BSOL user', () => { - it('renders the record details component with button', () => { - render( - , - ); - - expect(screen.getByText(`Last updated: ${mockPdf.last_updated}`)).toBeInTheDocument(); - expect(screen.getByText(`${mockPdf.number_of_files} files`)).toBeInTheDocument(); - expect( - screen.getByText(`File size: ${formatFileSize(mockPdf.total_file_size_in_byte)}`), - ).toBeInTheDocument(); - expect(screen.getByText('File format: PDF')).toBeInTheDocument(); - expect( - screen.getByRole('button', { name: 'Download and remove record' }), - ).toBeInTheDocument(); - - expect(screen.queryByText(`Select an action...`)).not.toBeInTheDocument(); - expect(screen.queryByTestId('actions-menu')).not.toBeInTheDocument(); - }); - }); +describe('test', () => { + it('renders the record details component', () => {}); }); - -const TestApp = (props: Omit) => { - return ( - - ); -}; - -const renderComponent = (propsOverride?: Partial) => { - const props: Omit = { - lastUpdated: mockPdf.last_updated, - numberOfFiles: mockPdf.number_of_files, - totalFileSizeInByte: mockPdf.total_file_size_in_byte, - - ...propsOverride, - }; - return render(); -}; +export {}; + +// import { render, screen, waitFor } from '@testing-library/react'; +// import LgRecordDetails, { Props } from './LloydGeorgeRecordDetails'; +// import { buildLgSearchResult } from '../../../helpers/test/testBuilders'; +// import formatFileSize from '../../../helpers/utils/formatFileSize'; +// import userEvent from '@testing-library/user-event'; +// import { act } from 'react-dom/test-utils'; +// import { REPOSITORY_ROLE } from '../../../types/generic/authRole'; +// import useRole from '../../../helpers/hooks/useRole'; +// import { actionLinks } from '../../../types/blocks/lloydGeorgeActions'; +// import { LinkProps } from 'react-router-dom'; +// jest.mock('../../../helpers/hooks/useRole'); +// +// const mockedUseNavigate = jest.fn(); +// const mockPdf = buildLgSearchResult(); +// const mockSetStage = jest.fn(); +// const mockSetDownloadRemoveButtonClicked = jest.fn(); +// const mockedUseRole = useRole as jest.Mock; +// jest.mock('react-router', () => ({ +// useNavigate: () => mockedUseNavigate, +// })); +// jest.mock('react-router-dom', () => ({ +// __esModule: true, +// Link: (props: LinkProps) => , +// })); +// +// describe('LloydGeorgeRecordDetails', () => { +// beforeEach(() => { +// mockedUseRole.mockReturnValue(REPOSITORY_ROLE.PCSE); +// process.env.REACT_APP_ENVIRONMENT = 'jest'; +// }); +// afterEach(() => { +// jest.clearAllMocks(); +// }); +// describe('Rendering', () => { +// it('renders the record details component', () => { +// renderComponent(); +// +// expect(screen.getByText(`Last updated: ${mockPdf.last_updated}`)).toBeInTheDocument(); +// expect(screen.getByText(`${mockPdf.number_of_files} files`)).toBeInTheDocument(); +// expect( +// screen.getByText(`File size: ${formatFileSize(mockPdf.total_file_size_in_byte)}`), +// ).toBeInTheDocument(); +// expect(screen.getByText('File format: PDF')).toBeInTheDocument(); +// }); +// +// it('renders record details actions menu', async () => { +// renderComponent(); +// +// expect(screen.getByText(`Select an action...`)).toBeInTheDocument(); +// expect(screen.getByTestId('actions-menu')).toBeInTheDocument(); +// actionLinks.forEach((action) => { +// expect(screen.queryByText(action.label)).not.toBeInTheDocument(); +// }); +// +// act(() => { +// userEvent.click(screen.getByTestId('actions-menu')); +// }); +// await waitFor(async () => { +// actionLinks.forEach((action) => { +// expect(screen.getByText(action.label)).toBeInTheDocument(); +// }); +// }); +// }); +// +// it.each(actionLinks)("renders actionLink '$label'", async (action) => { +// renderComponent(); +// +// expect(screen.getByText(`Select an action...`)).toBeInTheDocument(); +// expect(screen.getByTestId('actions-menu')).toBeInTheDocument(); +// +// act(() => { +// userEvent.click(screen.getByTestId('actions-menu')); +// }); +// await waitFor(async () => { +// expect(screen.getByText(action.label)).toBeInTheDocument(); +// }); +// }); +// }); +// +// describe('Navigation', () => { +// it.each(actionLinks)( +// "navigates to '$stage' when action '$label' is clicked", +// async (action) => { +// renderComponent(); +// +// expect(screen.getByText(`Select an action...`)).toBeInTheDocument(); +// expect(screen.getByTestId('actions-menu')).toBeInTheDocument(); +// +// act(() => { +// userEvent.click(screen.getByTestId('actions-menu')); +// }); +// await waitFor(async () => { +// expect(screen.getByText(action.label)).toBeInTheDocument(); +// }); +// +// act(() => { +// userEvent.click(screen.getByText(action.label)); +// }); +// await waitFor(async () => { +// expect(mockSetStage).toHaveBeenCalledWith(action.stage); +// }); +// }, +// ); +// }); +// +// describe('Unauthorised', () => { +// const unauthorisedLinks = actionLinks.filter((a) => Array.isArray(a.unauthorised)); +// +// it.each(unauthorisedLinks)( +// "does not render actionLink '$label' if role is unauthorised", +// async (action) => { +// const [unauthorisedRole] = action.unauthorised ?? []; +// mockedUseRole.mockReturnValue(unauthorisedRole); +// +// renderComponent(); +// +// expect(screen.getByText(`Select an action...`)).toBeInTheDocument(); +// expect(screen.getByTestId('actions-menu')).toBeInTheDocument(); +// +// act(() => { +// userEvent.click(screen.getByTestId('actions-menu')); +// }); +// await waitFor(async () => { +// expect(screen.queryByText(action.label)).not.toBeInTheDocument(); +// }); +// }, +// ); +// +// it.each(unauthorisedLinks)( +// "does not render actionLink '$label' for GP Clinical Role", +// async (action) => { +// expect(action.unauthorised).toContain(REPOSITORY_ROLE.GP_CLINICAL); +// }, +// ); +// }); +// +// describe('GP admin non BSOL user', () => { +// it('renders the record details component with button', () => { +// render( +// , +// ); +// +// expect(screen.getByText(`Last updated: ${mockPdf.last_updated}`)).toBeInTheDocument(); +// expect(screen.getByText(`${mockPdf.number_of_files} files`)).toBeInTheDocument(); +// expect( +// screen.getByText(`File size: ${formatFileSize(mockPdf.total_file_size_in_byte)}`), +// ).toBeInTheDocument(); +// expect(screen.getByText('File format: PDF')).toBeInTheDocument(); +// expect( +// screen.getByRole('button', { name: 'Download and remove record' }), +// ).toBeInTheDocument(); +// +// expect(screen.queryByText(`Select an action...`)).not.toBeInTheDocument(); +// expect(screen.queryByTestId('actions-menu')).not.toBeInTheDocument(); +// }); +// }); +// }); +// +// const TestApp = (props: Omit) => { +// return ( +// +// ); +// }; +// +// const renderComponent = (propsOverride?: Partial) => { +// const props: Omit = { +// lastUpdated: mockPdf.last_updated, +// numberOfFiles: mockPdf.number_of_files, +// totalFileSizeInByte: mockPdf.total_file_size_in_byte, +// +// ...propsOverride, +// }; +// return render(); +// }; From 193d4a58d16eb53542f9d612ee2e597dd207918f Mon Sep 17 00:00:00 2001 From: RachelHowellNHS Date: Tue, 9 Jan 2024 12:00:48 +0000 Subject: [PATCH 27/43] [PRMDR-417] add setFocus hook --- .../lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.tsx | 6 +++--- .../lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.tsx b/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.tsx index af4469951..e0aa9a904 100644 --- a/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.tsx @@ -7,7 +7,7 @@ import { Link } from 'react-router-dom'; import useRole from '../../../helpers/hooks/useRole'; import { actionLinks } from '../../../types/blocks/lloydGeorgeActions'; import { LG_RECORD_STAGE } from '../../../types/blocks/lloydGeorgeStages'; -import { FieldValues, UseFormSetError } from 'react-hook-form'; +import { FieldValues, useForm, UseFormSetError } from 'react-hook-form'; export type Props = { lastUpdated: string; @@ -17,7 +17,6 @@ export type Props = { userIsGpAdminNonBSOL?: boolean; setDownloadRemoveButtonClicked: Dispatch>; downloadRemoveButtonClicked: boolean; - setError: UseFormSetError; }; function LloydGeorgeRecordDetails({ @@ -28,11 +27,11 @@ function LloydGeorgeRecordDetails({ userIsGpAdminNonBSOL, setDownloadRemoveButtonClicked, downloadRemoveButtonClicked, - setError, }: Props) { const [showActionsMenu, setShowActionsMenu] = useState(false); const actionsRef = useRef(null); const role = useRole(); + const { setFocus, setError } = useForm(); const handleMoreActions = () => { setShowActionsMenu(!showActionsMenu); }; @@ -43,6 +42,7 @@ function LloydGeorgeRecordDetails({ const handleDownloadAndRemoveRecordButton = () => { if (downloadRemoveButtonClicked) { setError('confirmDownloadRemove', { type: 'custom', message: 'true' }); + setFocus('confirmDownloadRemove'); } setDownloadRemoveButtonClicked(true); }; diff --git a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx index 543206393..aeb093483 100644 --- a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx @@ -52,7 +52,7 @@ function LloydGeorgeRecordStage({ ? getFormattedDate(new Date(patientDetails.birthDate)) : ''; - const { register, handleSubmit, formState, getFieldState, clearErrors, setError } = useForm({ + const { register, handleSubmit, formState, getFieldState, clearErrors } = useForm({ reValidateMode: 'onSubmit', }); const { ref: inputRef, ...checkboxProps } = register('confirmDownloadRemove', { @@ -79,7 +79,6 @@ function LloydGeorgeRecordStage({ userIsGpAdminNonBSOL, setDownloadRemoveButtonClicked, downloadRemoveButtonClicked, - setError, }; return ; } else { From d98467222520fe39b39093401e780261c1396d70 Mon Sep 17 00:00:00 2001 From: RachelHowellNHS Date: Tue, 9 Jan 2024 12:12:26 +0000 Subject: [PATCH 28/43] [PRMDR-417] add setFocus hook --- .../LloydGeorgeRecordDetails.tsx | 7 +++++-- .../lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx | 9 ++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.tsx b/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.tsx index e0aa9a904..c18905dfd 100644 --- a/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.tsx @@ -7,7 +7,7 @@ import { Link } from 'react-router-dom'; import useRole from '../../../helpers/hooks/useRole'; import { actionLinks } from '../../../types/blocks/lloydGeorgeActions'; import { LG_RECORD_STAGE } from '../../../types/blocks/lloydGeorgeStages'; -import { FieldValues, useForm, UseFormSetError } from 'react-hook-form'; +import { FieldValues, useForm, UseFormSetError, UseFormSetFocus } from 'react-hook-form'; export type Props = { lastUpdated: string; @@ -17,6 +17,8 @@ export type Props = { userIsGpAdminNonBSOL?: boolean; setDownloadRemoveButtonClicked: Dispatch>; downloadRemoveButtonClicked: boolean; + setError: UseFormSetError; + setFocus: UseFormSetFocus; }; function LloydGeorgeRecordDetails({ @@ -27,11 +29,12 @@ function LloydGeorgeRecordDetails({ userIsGpAdminNonBSOL, setDownloadRemoveButtonClicked, downloadRemoveButtonClicked, + setError, + setFocus, }: Props) { const [showActionsMenu, setShowActionsMenu] = useState(false); const actionsRef = useRef(null); const role = useRole(); - const { setFocus, setError } = useForm(); const handleMoreActions = () => { setShowActionsMenu(!showActionsMenu); }; diff --git a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx index aeb093483..d5e57e366 100644 --- a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx @@ -52,9 +52,10 @@ function LloydGeorgeRecordStage({ ? getFormattedDate(new Date(patientDetails.birthDate)) : ''; - const { register, handleSubmit, formState, getFieldState, clearErrors } = useForm({ - reValidateMode: 'onSubmit', - }); + const { register, handleSubmit, formState, getFieldState, clearErrors, setError, setFocus } = + useForm({ + reValidateMode: 'onSubmit', + }); const { ref: inputRef, ...checkboxProps } = register('confirmDownloadRemove', { required: true, }); @@ -79,6 +80,8 @@ function LloydGeorgeRecordStage({ userIsGpAdminNonBSOL, setDownloadRemoveButtonClicked, downloadRemoveButtonClicked, + setError, + setFocus, }; return ; } else { From 3b9f81ba5f6b348283f976c6fa1e6734744dfb41 Mon Sep 17 00:00:00 2001 From: RachelHowellNHS Date: Tue, 9 Jan 2024 13:58:23 +0000 Subject: [PATCH 29/43] [PRMDR-417] styling --- .../lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx | 1 + app/src/styles/App.scss | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx index d5e57e366..e950cb962 100644 --- a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx @@ -164,6 +164,7 @@ function LloydGeorgeRecordStage({ } > Date: Tue, 9 Jan 2024 14:10:01 +0000 Subject: [PATCH 30/43] [PRMDR-417] styling --- .../blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx index e950cb962..36b56b40c 100644 --- a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx @@ -155,6 +155,7 @@ function LloydGeorgeRecordStage({ You must keep the patient's record safe." /> Date: Tue, 9 Jan 2024 14:30:23 +0000 Subject: [PATCH 31/43] [PRMDR-417] Add unit tests for download and remove button at LloydGeorgeRecordDetails.test.tsx --- .../LloydGeorgeRecordDetails.test.tsx | 397 +++++++++--------- 1 file changed, 208 insertions(+), 189 deletions(-) diff --git a/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.test.tsx b/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.test.tsx index 09f08a57e..96d9e7b94 100644 --- a/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.test.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordDetails/LloydGeorgeRecordDetails.test.tsx @@ -1,190 +1,209 @@ -describe('test', () => { - it('renders the record details component', () => {}); +import { render, screen, waitFor } from '@testing-library/react'; +import LgRecordDetails, { Props } from './LloydGeorgeRecordDetails'; +import { buildLgSearchResult } from '../../../helpers/test/testBuilders'; +import formatFileSize from '../../../helpers/utils/formatFileSize'; +import userEvent from '@testing-library/user-event'; +import { act } from 'react-dom/test-utils'; +import { REPOSITORY_ROLE } from '../../../types/generic/authRole'; +import useRole from '../../../helpers/hooks/useRole'; +import { actionLinks } from '../../../types/blocks/lloydGeorgeActions'; +import { LinkProps } from 'react-router-dom'; + +jest.mock('../../../helpers/hooks/useRole'); + +const mockedUseNavigate = jest.fn(); +const mockPdf = buildLgSearchResult(); +const mockSetStage = jest.fn(); +const mockSetDownloadRemoveButtonClicked = jest.fn(); +const mockSetError = jest.fn(); +const mockSetFocus = jest.fn(); +const mockedUseRole = useRole as jest.Mock; +jest.mock('react-router', () => ({ + useNavigate: () => mockedUseNavigate, +})); +jest.mock('react-router-dom', () => ({ + __esModule: true, + Link: (props: LinkProps) => , +})); + +describe('LloydGeorgeRecordDetails', () => { + beforeEach(() => { + mockedUseRole.mockReturnValue(REPOSITORY_ROLE.PCSE); + process.env.REACT_APP_ENVIRONMENT = 'jest'; + }); + afterEach(() => { + jest.clearAllMocks(); + }); + describe('Rendering', () => { + it('renders the record details component', () => { + renderComponent(); + + expect(screen.getByText(`Last updated: ${mockPdf.last_updated}`)).toBeInTheDocument(); + expect(screen.getByText(`${mockPdf.number_of_files} files`)).toBeInTheDocument(); + expect( + screen.getByText(`File size: ${formatFileSize(mockPdf.total_file_size_in_byte)}`), + ).toBeInTheDocument(); + expect(screen.getByText('File format: PDF')).toBeInTheDocument(); + }); + + it('renders record details actions menu', async () => { + renderComponent(); + + expect(screen.getByText(`Select an action...`)).toBeInTheDocument(); + expect(screen.getByTestId('actions-menu')).toBeInTheDocument(); + actionLinks.forEach((action) => { + expect(screen.queryByText(action.label)).not.toBeInTheDocument(); + }); + + act(() => { + userEvent.click(screen.getByTestId('actions-menu')); + }); + await waitFor(async () => { + actionLinks.forEach((action) => { + expect(screen.getByText(action.label)).toBeInTheDocument(); + }); + }); + }); + + it.each(actionLinks)("renders actionLink '$label'", async (action) => { + renderComponent(); + + expect(screen.getByText(`Select an action...`)).toBeInTheDocument(); + expect(screen.getByTestId('actions-menu')).toBeInTheDocument(); + + act(() => { + userEvent.click(screen.getByTestId('actions-menu')); + }); + await waitFor(async () => { + expect(screen.getByText(action.label)).toBeInTheDocument(); + }); + }); + }); + + describe('Navigation', () => { + it.each(actionLinks)( + "navigates to '$stage' when action '$label' is clicked", + async (action) => { + renderComponent(); + + expect(screen.getByText(`Select an action...`)).toBeInTheDocument(); + expect(screen.getByTestId('actions-menu')).toBeInTheDocument(); + + act(() => { + userEvent.click(screen.getByTestId('actions-menu')); + }); + await waitFor(async () => { + expect(screen.getByText(action.label)).toBeInTheDocument(); + }); + + act(() => { + userEvent.click(screen.getByText(action.label)); + }); + await waitFor(async () => { + expect(mockSetStage).toHaveBeenCalledWith(action.stage); + }); + }, + ); + }); + + describe('Unauthorised', () => { + const unauthorisedLinks = actionLinks.filter((a) => Array.isArray(a.unauthorised)); + + it.each(unauthorisedLinks)( + "does not render actionLink '$label' if role is unauthorised", + async (action) => { + const [unauthorisedRole] = action.unauthorised ?? []; + mockedUseRole.mockReturnValue(unauthorisedRole); + + renderComponent(); + + expect(screen.getByText(`Select an action...`)).toBeInTheDocument(); + expect(screen.getByTestId('actions-menu')).toBeInTheDocument(); + + act(() => { + userEvent.click(screen.getByTestId('actions-menu')); + }); + await waitFor(async () => { + expect(screen.queryByText(action.label)).not.toBeInTheDocument(); + }); + }, + ); + + it.each(unauthorisedLinks)( + "does not render actionLink '$label' for GP Clinical Role", + async (action) => { + expect(action.unauthorised).toContain(REPOSITORY_ROLE.GP_CLINICAL); + }, + ); + }); + + describe('GP admin non BSOL user', () => { + it('renders the record details component with button', () => { + renderComponent({ userIsGpAdminNonBSOL: true }); + + expect(screen.getByText(`Last updated: ${mockPdf.last_updated}`)).toBeInTheDocument(); + expect(screen.getByText(`${mockPdf.number_of_files} files`)).toBeInTheDocument(); + expect( + screen.getByText(`File size: ${formatFileSize(mockPdf.total_file_size_in_byte)}`), + ).toBeInTheDocument(); + expect(screen.getByText('File format: PDF')).toBeInTheDocument(); + expect( + screen.getByRole('button', { name: 'Download and remove record' }), + ).toBeInTheDocument(); + + expect(screen.queryByText(`Select an action...`)).not.toBeInTheDocument(); + expect(screen.queryByTestId('actions-menu')).not.toBeInTheDocument(); + }); + + it('set downloadRemoveButtonClicked to true when button is clicked', () => { + renderComponent({ userIsGpAdminNonBSOL: true }); + + const button = screen.getByRole('button', { name: 'Download and remove record' }); + + button.click(); + + expect(mockSetDownloadRemoveButtonClicked).toHaveBeenCalledWith(true); + }); + + it('calls setFocus and setError when the button is clicked again after warning box shown up', () => { + renderComponent({ userIsGpAdminNonBSOL: true, downloadRemoveButtonClicked: true }); + + const button = screen.getByRole('button', { name: 'Download and remove record' }); + + button.click(); + + expect(mockSetError).toHaveBeenCalledWith('confirmDownloadRemove', { + type: 'custom', + message: 'true', + }); + expect(mockSetFocus).toHaveBeenCalledWith('confirmDownloadRemove'); + }); + }); }); -export {}; - -// import { render, screen, waitFor } from '@testing-library/react'; -// import LgRecordDetails, { Props } from './LloydGeorgeRecordDetails'; -// import { buildLgSearchResult } from '../../../helpers/test/testBuilders'; -// import formatFileSize from '../../../helpers/utils/formatFileSize'; -// import userEvent from '@testing-library/user-event'; -// import { act } from 'react-dom/test-utils'; -// import { REPOSITORY_ROLE } from '../../../types/generic/authRole'; -// import useRole from '../../../helpers/hooks/useRole'; -// import { actionLinks } from '../../../types/blocks/lloydGeorgeActions'; -// import { LinkProps } from 'react-router-dom'; -// jest.mock('../../../helpers/hooks/useRole'); -// -// const mockedUseNavigate = jest.fn(); -// const mockPdf = buildLgSearchResult(); -// const mockSetStage = jest.fn(); -// const mockSetDownloadRemoveButtonClicked = jest.fn(); -// const mockedUseRole = useRole as jest.Mock; -// jest.mock('react-router', () => ({ -// useNavigate: () => mockedUseNavigate, -// })); -// jest.mock('react-router-dom', () => ({ -// __esModule: true, -// Link: (props: LinkProps) => , -// })); -// -// describe('LloydGeorgeRecordDetails', () => { -// beforeEach(() => { -// mockedUseRole.mockReturnValue(REPOSITORY_ROLE.PCSE); -// process.env.REACT_APP_ENVIRONMENT = 'jest'; -// }); -// afterEach(() => { -// jest.clearAllMocks(); -// }); -// describe('Rendering', () => { -// it('renders the record details component', () => { -// renderComponent(); -// -// expect(screen.getByText(`Last updated: ${mockPdf.last_updated}`)).toBeInTheDocument(); -// expect(screen.getByText(`${mockPdf.number_of_files} files`)).toBeInTheDocument(); -// expect( -// screen.getByText(`File size: ${formatFileSize(mockPdf.total_file_size_in_byte)}`), -// ).toBeInTheDocument(); -// expect(screen.getByText('File format: PDF')).toBeInTheDocument(); -// }); -// -// it('renders record details actions menu', async () => { -// renderComponent(); -// -// expect(screen.getByText(`Select an action...`)).toBeInTheDocument(); -// expect(screen.getByTestId('actions-menu')).toBeInTheDocument(); -// actionLinks.forEach((action) => { -// expect(screen.queryByText(action.label)).not.toBeInTheDocument(); -// }); -// -// act(() => { -// userEvent.click(screen.getByTestId('actions-menu')); -// }); -// await waitFor(async () => { -// actionLinks.forEach((action) => { -// expect(screen.getByText(action.label)).toBeInTheDocument(); -// }); -// }); -// }); -// -// it.each(actionLinks)("renders actionLink '$label'", async (action) => { -// renderComponent(); -// -// expect(screen.getByText(`Select an action...`)).toBeInTheDocument(); -// expect(screen.getByTestId('actions-menu')).toBeInTheDocument(); -// -// act(() => { -// userEvent.click(screen.getByTestId('actions-menu')); -// }); -// await waitFor(async () => { -// expect(screen.getByText(action.label)).toBeInTheDocument(); -// }); -// }); -// }); -// -// describe('Navigation', () => { -// it.each(actionLinks)( -// "navigates to '$stage' when action '$label' is clicked", -// async (action) => { -// renderComponent(); -// -// expect(screen.getByText(`Select an action...`)).toBeInTheDocument(); -// expect(screen.getByTestId('actions-menu')).toBeInTheDocument(); -// -// act(() => { -// userEvent.click(screen.getByTestId('actions-menu')); -// }); -// await waitFor(async () => { -// expect(screen.getByText(action.label)).toBeInTheDocument(); -// }); -// -// act(() => { -// userEvent.click(screen.getByText(action.label)); -// }); -// await waitFor(async () => { -// expect(mockSetStage).toHaveBeenCalledWith(action.stage); -// }); -// }, -// ); -// }); -// -// describe('Unauthorised', () => { -// const unauthorisedLinks = actionLinks.filter((a) => Array.isArray(a.unauthorised)); -// -// it.each(unauthorisedLinks)( -// "does not render actionLink '$label' if role is unauthorised", -// async (action) => { -// const [unauthorisedRole] = action.unauthorised ?? []; -// mockedUseRole.mockReturnValue(unauthorisedRole); -// -// renderComponent(); -// -// expect(screen.getByText(`Select an action...`)).toBeInTheDocument(); -// expect(screen.getByTestId('actions-menu')).toBeInTheDocument(); -// -// act(() => { -// userEvent.click(screen.getByTestId('actions-menu')); -// }); -// await waitFor(async () => { -// expect(screen.queryByText(action.label)).not.toBeInTheDocument(); -// }); -// }, -// ); -// -// it.each(unauthorisedLinks)( -// "does not render actionLink '$label' for GP Clinical Role", -// async (action) => { -// expect(action.unauthorised).toContain(REPOSITORY_ROLE.GP_CLINICAL); -// }, -// ); -// }); -// -// describe('GP admin non BSOL user', () => { -// it('renders the record details component with button', () => { -// render( -// , -// ); -// -// expect(screen.getByText(`Last updated: ${mockPdf.last_updated}`)).toBeInTheDocument(); -// expect(screen.getByText(`${mockPdf.number_of_files} files`)).toBeInTheDocument(); -// expect( -// screen.getByText(`File size: ${formatFileSize(mockPdf.total_file_size_in_byte)}`), -// ).toBeInTheDocument(); -// expect(screen.getByText('File format: PDF')).toBeInTheDocument(); -// expect( -// screen.getByRole('button', { name: 'Download and remove record' }), -// ).toBeInTheDocument(); -// -// expect(screen.queryByText(`Select an action...`)).not.toBeInTheDocument(); -// expect(screen.queryByTestId('actions-menu')).not.toBeInTheDocument(); -// }); -// }); -// }); -// -// const TestApp = (props: Omit) => { -// return ( -// -// ); -// }; -// -// const renderComponent = (propsOverride?: Partial) => { -// const props: Omit = { -// lastUpdated: mockPdf.last_updated, -// numberOfFiles: mockPdf.number_of_files, -// totalFileSizeInByte: mockPdf.total_file_size_in_byte, -// -// ...propsOverride, -// }; -// return render(); -// }; + +type mockedProps = Omit< + Props, + 'setStage' | 'stage' | 'setDownloadRemoveButtonClicked' | 'setError' | 'setFocus' +>; +const TestApp = (props: mockedProps) => { + return ( + + ); +}; + +const renderComponent = (propsOverride?: Partial) => { + const props: mockedProps = { + lastUpdated: mockPdf.last_updated, + numberOfFiles: mockPdf.number_of_files, + totalFileSizeInByte: mockPdf.total_file_size_in_byte, + downloadRemoveButtonClicked: false, + ...propsOverride, + }; + return render(); +}; From 4aedb6eff39b14ec83f2560cd447732cc190f6f6 Mon Sep 17 00:00:00 2001 From: Joe Fong Date: Tue, 9 Jan 2024 14:34:43 +0000 Subject: [PATCH 32/43] [PRMDR-417] Fix the issue of checkbox not working right when clicked twice --- .../lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx index 36b56b40c..a48c787fc 100644 --- a/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx +++ b/app/src/components/blocks/lloydGeorgeRecordStage/LloydGeorgeRecordStage.tsx @@ -59,7 +59,6 @@ function LloydGeorgeRecordStage({ const { ref: inputRef, ...checkboxProps } = register('confirmDownloadRemove', { required: true, }); - const { isDirty: isCheckboxDirty } = getFieldState('confirmDownloadRemove', formState); const nhsNumber: string = patientDetails?.nhsNumber || ''; const formattedNhsNumber = formatNhsNumber(nhsNumber); @@ -90,9 +89,7 @@ function LloydGeorgeRecordStage({ }; const handleConfirmDownloadAndRemoveButton = () => { - if (isCheckboxDirty) { - setStage(LG_RECORD_STAGE.DOWNLOAD_ALL); - } + setStage(LG_RECORD_STAGE.DOWNLOAD_ALL); }; const handleCancelButton = () => { @@ -177,7 +174,7 @@ function LloydGeorgeRecordStage({