Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
bda5c8e
[PRMP-1409] feat: add Document Version History feature
lillie-dae Feb 20, 2026
2c0a1ba
[PRMP-1409] feat: Add FHIR R4 Bundle and DocumentReference resources
lillie-dae Mar 4, 2026
bfcd66c
[PRMP-1409] feat: add Document Version History feature
lillie-dae Feb 20, 2026
90fabd9
[PRMP-1409] feat: Add FHIR R4 Bundle and DocumentReference resources
lillie-dae Mar 4, 2026
e5b75cc
[PRMP-1409] feat: add Document Version History feature
lillie-dae Feb 20, 2026
4f6b697
[PRMP-1410] Document version history view
lillie-dae Mar 4, 2026
bd40ddf
minor fix to tests
lillie-dae Mar 20, 2026
46fece7
code comment change
lillie-dae Mar 23, 2026
6fc6d82
bring it fixs from 1411
lillie-dae Mar 24, 2026
e19895a
add test coverage
lillie-dae Mar 24, 2026
f0df472
[PRMP-1409] feat: add Document Version History feature
lillie-dae Feb 20, 2026
93754a8
[PRMP-1409] feat: Add FHIR R4 Bundle and DocumentReference resources
lillie-dae Mar 4, 2026
a3761b2
[PRMP-1409] feat: add Document Version History feature
lillie-dae Feb 20, 2026
ee4500a
[PRMP-1410] Document version history view
lillie-dae Mar 4, 2026
88ca6ea
[PRMP-1411] add document version restore functionality
lillie-dae Feb 20, 2026
28529b1
ci fixes
lillie-dae Mar 19, 2026
4e69ecd
minor ci fix
lillie-dae Mar 19, 2026
c0eeaf9
refactor: rename RestoreVersionCompletePage to DocumentVersionRestore…
lillie-dae Mar 20, 2026
befb8b1
movies files to DocumentVersionRestore
lillie-dae Mar 23, 2026
776ee89
code comment fixes
lillie-dae Mar 23, 2026
156ed5b
minor fix for tests
lillie-dae Mar 24, 2026
49cc95f
code comment change
lillie-dae Mar 24, 2026
ad24cf0
fix complete page not showing version
lillie-dae Mar 24, 2026
58646c3
skip tests for now
lillie-dae Mar 24, 2026
6e5598b
fixed core test and debugged smoke test
lillie-dae Mar 25, 2026
ed7a348
merge fixes
lillie-dae Mar 25, 2026
3ef1109
skip test again
lillie-dae Mar 25, 2026
4a3e3b3
Merge branch 'main' into PRMP-1411
lillie-dae Mar 25, 2026
09e379b
update BackButton to navigate to patient documents
lillie-dae Mar 26, 2026
3b18df2
Merge branch 'main' into PRMP-1411
lillie-dae Mar 27, 2026
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
@@ -0,0 +1,330 @@
import searchPatientPayload from '../../../fixtures/requests/GET_SearchPatient.json';
import versionHistoryPayload from '../../../fixtures/requests/GET_DocumentVersionHistory.json';
import { Roles } from '../../../support/roles';

const baseUrl = Cypress.config('baseUrl');

const searchResults = [
{
fileName: 'Scanned paper notes.pdf',
created: '2025-12-15T10:30:00Z',
virusScannerResult: 'Clean',
author: 'Y12345',
id: '2a7a270e-aa1d-532e-8648-d5d8e3defb82',
fileSize: 3072,
version: '3',
documentSnomedCodeType: '16521000000101',
contentType: 'application/pdf',
},
];

const featureFlags = {
uploadLloydGeorgeWorkflowEnabled: true,
uploadArfWorkflowEnabled: true,
uploadLambdaEnabled: true,
uploadDocumentIteration2Enabled: true,
uploadDocumentIteration3Enabled: true,
documentCorrectEnabled: true,
versionHistoryEnabled: true,
};

const bucketUrlIdentifier = 'document-store.s3.amazonaws.com';

describe.skip('GP Workflow: Restore document version', () => {
const beforeEachConfiguration = (role) => {
cy.login(role, featureFlags);
cy.navigateToPatientSearchPage();

cy.intercept('GET', '/SearchPatient*', {
statusCode: 200,
body: { ...searchPatientPayload, canManageRecord: true },
}).as('search');

cy.getByTestId('nhs-number-input').type(searchPatientPayload.nhsNumber);
cy.getByTestId('search-submit-btn').click();
cy.wait('@search');
};

const navigateToDocumentSearchResults = () => {
cy.intercept('GET', '/SearchDocumentReferences*', {
statusCode: 200,
body: { references: searchResults },
}).as('searchDocumentReferences');

cy.intercept('GET', '/DocumentReview*', {
statusCode: 200,
body: { count: 0, results: [] },
}).as('reviews');

cy.get('#verify-submit').click();
cy.wait('@searchDocumentReferences');
};

const navigateToDocumentView = () => {
navigateToDocumentSearchResults();

cy.intercept(
{
method: 'GET',
url: '/DocumentReference/2a7a270e-aa1d-532e-8648-d5d8e3defb82',
},
{
statusCode: 200,
body: {
url: baseUrl + '/browserconfig.xml',
contentType: 'application/pdf',
},
},
).as('getDocument');

cy.getByTestId('view-0-link').click();
};

const navigateToVersionHistory = () => {
navigateToDocumentView();

cy.intercept('GET', '/DocumentReference/2a7a270e-aa1d-532e-8648-d5d8e3defb82/_history*', {
statusCode: 200,
body: versionHistoryPayload,
}).as('getVersionHistory');

cy.getByTestId('view-document-history-link').click();
cy.wait('@getVersionHistory');
};

const navigateToRestoreConfirm = () => {
navigateToVersionHistory();

cy.getByTestId('restore-version-2').click();
};

context('Version history page', () => {
it(
'GP_ADMIN can view the version history timeline for a document',
{ tags: 'regression' },
() => {
beforeEachConfiguration(Roles.GP_ADMIN);
navigateToVersionHistory();

// Assert version history page is shown
cy.contains('Version history').should('be.visible');

// Assert all 3 versions are displayed
cy.getByTestId('view-version-3').should('exist');
cy.getByTestId('view-version-2').should('exist');
cy.getByTestId('view-version-1').should('exist');

// Assert active version (v3) shows "This is the current version"
cy.contains("This is the current version shown in this patient's record").should(
'be.visible',
);

// Assert inactive versions have "Restore version" links
cy.getByTestId('restore-version-2').should('exist');
cy.getByTestId('restore-version-1').should('exist');
},
);

it(
'GP_ADMIN cannot see restore links for the active version',
{ tags: 'regression' },
() => {
beforeEachConfiguration(Roles.GP_ADMIN);
navigateToVersionHistory();

// The active version (v3) should not have a restore link
cy.getByTestId('restore-version-3').should('not.exist');
},
);
});

context('Restore version confirmation page', () => {
it(
'GP_ADMIN can navigate to the restore confirmation page from version history',
{ tags: 'regression' },
() => {
beforeEachConfiguration(Roles.GP_ADMIN);
navigateToRestoreConfirm();

// Assert restore confirm page is shown
cy.contains(
'Are you sure you want to restore this version of these scanned paper notes?',
).should('be.visible');

// Assert radio options are present
cy.getByTestId('yes-radio-btn').should('exist');
cy.getByTestId('no-radio-btn').should('exist');
cy.getByTestId('continue-button').should('exist');

// Assert help and guidance link exists
cy.getByTestId('help-and-guidance-link').should('exist');
},
);

it(
'shows validation error when submitting without selecting an option',
{ tags: 'regression' },
() => {
beforeEachConfiguration(Roles.GP_ADMIN);
navigateToRestoreConfirm();

cy.getByTestId('continue-button').click();

// Assert error summary is shown
cy.getByTestId('error-summary').should('be.visible');
cy.contains('Select whether you want to restore this version').should('be.visible');
},
);

it(
'navigates back when "No" is selected and continue is clicked',
{ tags: 'regression' },
() => {
beforeEachConfiguration(Roles.GP_ADMIN);
navigateToRestoreConfirm();

cy.getByTestId('no-radio-btn').click();
cy.getByTestId('continue-button').click();

// Should navigate back to version history
cy.contains('Version history').should('be.visible');
},
);

it('navigates back when go back link is clicked', { tags: 'regression' }, () => {
beforeEachConfiguration(Roles.GP_ADMIN);
navigateToRestoreConfirm();

cy.getByTestId('go-back-link').click();

// Should navigate back to version history
cy.contains('Version history').should('be.visible');
});
});

context('Restore version uploading and completion', () => {
it(
'GP_ADMIN can successfully restore a previous version of a document',
{ tags: 'regression' },
() => {
beforeEachConfiguration(Roles.GP_ADMIN);
navigateToRestoreConfirm();

// Intercept the upload session / document reference call
cy.intercept('POST', '/DocumentReference*', {
statusCode: 200,
body: {
url: 'http://' + bucketUrlIdentifier,
fields: {
key: 'test-key',
'x-amz-algorithm': 'xxxx-xxxx-SHA256',
'x-amz-credential': 'xxxxxxxxxxx/20230904/eu-west-2/s3/aws4_request',
'x-amz-date': '20230904T125954Z',
'x-amz-security-token': 'xxxxxxxxx',
'x-amz-signature': '9xxxxxxxx',
},
},
}).as('uploadSession');

// Intercept the S3 upload
cy.intercept('POST', '**' + bucketUrlIdentifier + '**', {
statusCode: 204,
}).as('s3Upload');

// Intercept virus scan / document status polling
cy.intercept('GET', '/DocumentStatus*', {
statusCode: 200,
body: {
'2a7a270e-aa1d-532e-8648-d5d8e3defb82': {
status: 'succeeded',
},
},
}).as('documentStatus');

// Intercept the upload confirmation
cy.intercept('POST', '/UploadConfirm*', {
statusCode: 204,
}).as('uploadConfirm');

// Select "Yes" and continue
cy.getByTestId('yes-radio-btn').click();
cy.getByTestId('continue-button').click();

// Wait for restore to complete and navigate to success page
cy.getByTestId('restore-complete-panel', { timeout: 30000 }).should('be.visible');

// Assert restore complete page content
cy.contains('Version restored').should('be.visible');
cy.getByTestId('patient-name').should('be.visible');
cy.getByTestId('nhs-number').should('be.visible');
cy.getByTestId('dob').should('be.visible');
cy.getByTestId('restore-version-description').should('be.visible');

// Assert "go to version history" link exists
cy.getByTestId('version-history-link').should('exist');

// Assert "Go to Lloyd George records" button exists
cy.getByTestId('go-to-records-button').should('exist');
},
);

it(
'navigates to Lloyd George records from restore complete page',
{ tags: 'regression' },
() => {
beforeEachConfiguration(Roles.GP_ADMIN);
navigateToRestoreConfirm();

// Set up intercepts for the upload flow
cy.intercept('POST', '/DocumentReference*', {
statusCode: 200,
body: {
url: 'http://' + bucketUrlIdentifier,
fields: {
key: 'test-key',
'x-amz-algorithm': 'xxxx-xxxx-SHA256',
'x-amz-credential': 'xxxxxxxxxxx/20230904/eu-west-2/s3/aws4_request',
'x-amz-date': '20230904T125954Z',
'x-amz-security-token': 'xxxxxxxxx',
'x-amz-signature': '9xxxxxxxx',
},
},
}).as('uploadSession');

cy.intercept('POST', '**' + bucketUrlIdentifier + '**', {
statusCode: 204,
}).as('s3Upload');

cy.intercept('GET', '/DocumentStatus*', {
statusCode: 200,
body: {
'2a7a270e-aa1d-532e-8648-d5d8e3defb82': {
status: 'succeeded',
},
},
}).as('documentStatus');

cy.intercept('POST', '/UploadConfirm*', {
statusCode: 204,
}).as('uploadConfirm');

// Complete the restore
cy.getByTestId('yes-radio-btn').click();
cy.getByTestId('continue-button').click();
cy.getByTestId('restore-complete-panel', { timeout: 30000 }).should('be.visible');

// Click "Go to Lloyd George records" button
cy.intercept('GET', '/SearchDocumentReferences*', {
statusCode: 200,
body: { references: searchResults },
}).as('searchDocumentReferencesAfterRestore');

cy.getByTestId('go-to-records-button').click();

// Should be back on the patient documents page
cy.url().should('contain', '/patient/documents');
cy.getByTestId('available-files-table-title').should('be.visible');
},
);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { Roles } from '../../../support/roles';
import dbItem from '../../../fixtures/dynamo-db-items/active-patient-h81109.json';

const workspace = Cypress.env('WORKSPACE');
dbItem.FileLocation = dbItem.FileLocation.replace('{env}', workspace);
const activePatient = 9730154708; //9730154708,9730154376
const bucketName = `${workspace}-lloyd-george-store`;
const tableName = `${workspace}_LloydGeorgeReferenceMetadata`;
const fileName = `${activePatient}/e4a6d7f7-01f3-44be-8964-515b2c0ec180`;

const patientVerifyUrl = '/patient/verify';
const documentViewUrl = '/patient/documents';

// inital test works if you prepopulate the data need to sort out populating database
describe.skip('GP Workflow: restore version history', () => {
context('Version history button is visible on document view page', () => {
beforeEach(() => {
cy.deleteFileFromS3(bucketName, fileName);
cy.deleteItemFromDynamoDb(tableName, dbItem.ID);
cy.addPdfFileToS3(bucketName, fileName, 'test_patient_record.pdf');
cy.addItemToDynamoDb(tableName, dbItem);
});

afterEach(() => {
cy.deleteFileFromS3(bucketName, fileName);
cy.deleteItemFromDynamoDb(tableName, dbItem.ID);
});

it(
'[Smoke] GP ADMIN user can see the version history button on the document view page',
{ tags: 'smoke', defaultCommandTimeout: 20000 },
() => {
cy.smokeLogin(Roles.SMOKE_GP_ADMIN, 'H81109');
cy.get('.nhsuk-navigation-container').should('exist');
cy.navigateToPatientSearchPage();
cy.get('#nhs-number-input').click();
cy.get('#nhs-number-input').type(activePatient);
cy.getByTestId('search-submit-btn').should('exist');
cy.getByTestId('search-submit-btn').click();

cy.url({ timeout: 15000 }).should('contain', patientVerifyUrl);
cy.get('#verify-submit').should('exist');
cy.get('#verify-submit').click();

cy.url().should('contain', documentViewUrl);

cy.getByTestId('view-0-link', { timeout: 30000 }).should('exist');
cy.getByTestId('view-0-link').click();

cy.getByTestId('pdf-viewer', { timeout: 30000 }).should('be.visible');

cy.getByTestId('view-document-history-link').should('exist');
cy.getByTestId('view-document-history-link').click();

cy.url({ timeout: 15000 }).should('contain', '/patient/documents/version-history');
},
);
});
});
Loading
Loading