Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -349,11 +349,24 @@ describe('DocumentView', () => {
it('calls removeDocument when remove action is triggered', () => {
renderComponent();

// Assuming the first record link is remove action
// assume first link is remove
const removeRecordLink = screen.getByTestId(lloydGeorgeRecordLinks[0].key);
fireEvent.click(removeRecordLink);
expect(mockRemoveDocument).toHaveBeenCalled();
});

it('navigates to download success page when download action is triggered', () => {
vi.useFakeTimers();
renderComponent();

// assume second link is download
const downloadRecordLink = screen.getByTestId(lloydGeorgeRecordLinks[1].key);
fireEvent.click(downloadRecordLink);

vi.advanceTimersByTime(5000000);
expect(mockUseNavigate).toHaveBeenCalledWith(routes.DOWNLOAD_COMPLETE);
vi.useRealTimers();
});
});

describe('Role-based rendering', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,12 @@ const DocumentView = ({

const details = (): React.JSX.Element => {
return (
<div className="lloydgeorge_record-details">
<div className="lloydgeorge_record-details_details">
<div className="lloydgeorge_record-details_details--last-updated mt-3">
<div className="document_record-details">
<div className="document_record-details_details">
<div className="document_record-details_details--last-updated mt-3">
Filename: {documentReference.fileName}
</div>
<div className="lloydgeorge_record-details_details--last-updated mt-3">
<div className="document_record-details_details--last-updated mt-3">
Last updated: {getFormattedDate(new Date(documentReference.created))}
</div>
</div>
Expand All @@ -85,12 +85,18 @@ const DocumentView = ({

const downloadClicked = (): void => {
if (documentReference.url) {
const estimatedDownloadDuration =
Math.floor(documentReference.fileSize / 5000000 * 1000); // Estimate 5MB/s download speed
const anchor = document.createElement('a');
anchor.href = documentReference.url;
anchor.download = documentReference.fileName;
document.body.appendChild(anchor);
anchor.click();
anchor.remove();

setTimeout(() => {
navigate(routes.DOWNLOAD_COMPLETE);
}, estimatedDownloadDuration);
}
};

Expand Down Expand Up @@ -182,10 +188,10 @@ const DocumentView = ({
return session.isFullscreen ? (
card
) : (
<div className="lloydgeorge_record-stage_flex">
<div className="document_record-stage_flex">
<div
data-testid="record-card-container"
className={`lloydgeorge_record-stage_flex-row lloydgeorge_record-stage_flex-row${showMenu ? '--menu' : '--upload'}`}
className={`document_record-stage_flex-row document_record-stage_flex-row${showMenu ? '--menu' : '--upload'}`}
>
{card}
</div>
Expand All @@ -200,7 +206,7 @@ const DocumentView = ({
(role === REPOSITORY_ROLE.GP_ADMIN || role === REPOSITORY_ROLE.GP_CLINICAL);

return (
<div className="lloydgeorge_record-stage">
<div className="document_record-stage">
{session.isFullscreen && (
<div className="header">
<div className="header-items">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { buildPatientDetails } from '../../helpers/test/testBuilders';
import { render, screen } from '@testing-library/react';
import { runAxeTest } from '../../helpers/test/axeTestHelper';
import { afterEach, beforeEach, describe, expect, it, vi, Mock } from 'vitest';
import DownloadCompletePage from './DownloadCompletePage';
import userEvent from '@testing-library/user-event';
import { routes } from '../../types/generic/routes';
import usePatient from '../../helpers/hooks/usePatient';

vi.mock('../../helpers/hooks/usePatient');

const mockedUseNavigate = vi.fn();
const mockUsePatient = usePatient as Mock;

vi.mock('react-router-dom', () => ({
useNavigate: () => mockedUseNavigate,
}));

describe('DownloadCompletePage', () => {
const mockPatient = buildPatientDetails();

beforeEach(() => {
import.meta.env.VITE_ENVIRONMENT = 'vitest';
mockUsePatient.mockReturnValue(mockPatient);
});
afterEach(() => {
vi.clearAllMocks();
});

it('renders the download complete screen', () => {
render(<DownloadCompletePage />);

expect(screen.getByTestId('page-title')).toBeInTheDocument();
expect(
screen.getByText(`Patient name: ${mockPatient.familyName}, ${mockPatient.givenName}`),
).toBeInTheDocument();
expect(screen.getByText('Your responsibilities with this record')).toBeInTheDocument();
expect(
screen.getByText('Follow the Record Management Code of Practice'),
).toBeInTheDocument();
expect(
screen.getByRole('button', {
name: 'Go to home',
}),
).toBeInTheDocument();
});

it('navigates to the home screen when go to home is clicked', async () => {
render(<DownloadCompletePage />);

await userEvent.click(screen.getByRole('button', {name: 'Go to home'}));

expect(mockedUseNavigate).toHaveBeenCalledWith(routes.HOME);
});

it('navigates to the home screen if patient details are undefined', async () => {
mockUsePatient.mockReturnValue(undefined);
render(<DownloadCompletePage />);

expect(mockedUseNavigate).toHaveBeenCalledWith(routes.HOME);
});

describe('Accessibility', () => {
it('passes accessibility checks', async () => {
render(<DownloadCompletePage />);
const results = await runAxeTest(document.body);
expect(results).toHaveNoViolations();
});
});
});
68 changes: 68 additions & 0 deletions app/src/pages/downloadCompletePage/DownloadCompletePage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React from 'react';
import { Button } from 'nhsuk-react-components';
import useTitle from '../../helpers/hooks/useTitle';
import { useNavigate } from 'react-router-dom';
import { routes } from '../../types/generic/routes';
import usePatient from '../../helpers/hooks/usePatient';
import { formatNhsNumber } from '../../helpers/utils/formatNhsNumber';
import { getFormattedDateFromString } from '../../helpers/utils/formatDate';
import { getFormattedPatientFullName } from '../../helpers/utils/formatPatientFullName';

const DownloadCompletePage = (): React.JSX.Element => {
const navigate = useNavigate();
const patient = usePatient();

const pageHeader = 'Download complete';
useTitle({ pageTitle: pageHeader });

if (!patient) {
navigate(routes.HOME);
return <></>;
}

return (
<div className="document_download-complete">
<div className="nhsuk-panel" data-testid="download-complete-card">
<h1 data-testid="page-title" className="nhsuk-panel__title">
Download complete
</h1>
<br />
<div className="nhsuk-panel__body">
<strong data-testid="patient-name">Patient name: {getFormattedPatientFullName(patient)}</strong>
<br />
<span data-testid="nhs-number">NHS number: {formatNhsNumber(patient.nhsNumber)}</span>
<br />
<span data-testid="dob">Date of birth: {getFormattedDateFromString(patient.birthDate)}</span>
</div>
</div>

<h2 className="nhsuk-heading-l">Your responsibilities with this record</h2>
<p>
Everyone in a health and care organisation is responsible for managing records
appropriately. It is important all general practice staff understand their
responsibilities for creating, maintaining, and disposing of records appropriately.
</p>

<h3 className="nhsuk-heading-m">Follow the Record Management Code of Practice</h3>
<p>
The{' '}
<a href="https://transform.england.nhs.uk/information-governance/guidance/records-management-code">
Record Management Code of Practice
</a>{' '}
provides a framework for consistent and effective records management, based on
established standards.
</p>

<Button
data-testid="go-to-home-button"
onClick={(): void => {
navigate(routes.HOME);
}}
>
Go to home
</Button>
</div>
);
};

export default DownloadCompletePage;
8 changes: 7 additions & 1 deletion app/src/router/AppRouter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import PatientAccessAuditPage from '../pages/patientAccessAuditPage/PatientAcces
import MockLoginPage from '../pages/mockLoginPage/MockLoginPage';
import DocumentUploadPage from '../pages/documentUploadPage/DocumentUploadPage';
import AdminRoutesPage from '../pages/adminRoutesPage/AdminRoutesPage';
import DownloadCompletePage from '../pages/downloadCompletePage/DownloadCompletePage';

const {
START,
Expand Down Expand Up @@ -58,6 +59,7 @@ const {
DOCUMENT_UPLOAD_WILDCARD,
ADMIN_ROUTE,
ADMIN_ROUTE_WILDCARD,
DOWNLOAD_COMPLETE,
} = routes;

type Routes = {
Expand Down Expand Up @@ -247,7 +249,7 @@ export const routeMap: Routes = {
type: ROUTE_TYPE.PRIVATE,
},

// App guard routes
// Patient guard routes
[VERIFY_PATIENT]: {
page: <PatientResultPage />,
type: ROUTE_TYPE.PATIENT,
Expand Down Expand Up @@ -286,6 +288,10 @@ export const routeMap: Routes = {
page: <DocumentUploadPage />,
type: ROUTE_TYPE.PATIENT,
},
[DOWNLOAD_COMPLETE]: {
page: <DownloadCompletePage />,
type: ROUTE_TYPE.PATIENT,
},
};

const createRoutesFromType = (routeType: ROUTE_TYPE): Array<React.JSX.Element> =>
Expand Down
7 changes: 7 additions & 0 deletions app/src/styles/App.scss
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ $hunit: '%';
}

// Lloyd George
.document,
.lloydgeorge {
&_record-stage {
&_links {
Expand Down Expand Up @@ -571,6 +572,7 @@ $hunit: '%';
}

.lloydgeorge,
.document,
.report {
&_download-complete {
max-width: 711px;
Expand Down Expand Up @@ -618,18 +620,21 @@ $hunit: '%';

@media (max-width: 685px) {
.nhsuk-card__heading.report_download-complete_details-content_header,
.nhsuk-card__heading.document_download-complete_details-content_header,
.nhsuk-card__heading.lloydgeorge_download-complete_details-content_header {
font-size: 2rem;
}
}

@media (max-width: 435px) {
.nhsuk-card__heading.report_download-complete_details-content_header,
.nhsuk-card__heading.document_download-complete_details-content_header,
.nhsuk-card__heading.lloydgeorge_download-complete_details-content_header {
font-size: 1.5rem;
}

.nhsuk-card__description.report_download-complete_details-content_description,
.nhsuk-card__description.document_download-complete_details-content_description,
.nhsuk-card__description.lloydgeorge_download-complete_details-content_description {
font-size: 1.2rem !important;
}
Expand Down Expand Up @@ -929,6 +934,7 @@ $hunit: '%';
margin-bottom: 50px;
}

.document_drag-and-drop,
.lloydgeorge_drag-and-drop {
border-color: $nhsuk-error-color;
}
Expand Down Expand Up @@ -975,6 +981,7 @@ $hunit: '%';
padding: 0;
}

.document_record-stage,
.lloydgeorge_record-stage {
height: calc(100vh - 93px);
position: relative;
Expand Down
2 changes: 2 additions & 0 deletions app/src/types/generic/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ export enum routes {

ADMIN_ROUTE = '/admin',
ADMIN_ROUTE_WILDCARD = '/admin/*',

DOWNLOAD_COMPLETE = '/download-complete',
}

export enum routeChildren {
Expand Down
Loading