diff --git a/app/cypress/e2e/1-ndr-smoke-tests/gp_user_workflows/review_reassign_happy_workflow.cy.js b/app/cypress/e2e/1-ndr-smoke-tests/gp_user_workflows/review_reassign_happy_workflow.cy.js
new file mode 100644
index 000000000..c142954a3
--- /dev/null
+++ b/app/cypress/e2e/1-ndr-smoke-tests/gp_user_workflows/review_reassign_happy_workflow.cy.js
@@ -0,0 +1,80 @@
+import { Roles } from '../../../support/roles';
+import dbItem from '../../../fixtures/dynamo-db-items/example-review-h81109.json';
+
+const workspace = Cypress.env('WORKSPACE');
+const tableName = `${workspace}_DocumentUploadReview`;
+const path = `9730155348/e3e4f62e-6f95-4d8c-8870-5212b6353ae9/test_patient_record.pdf`;
+const bucketName = `${workspace}-document-pending-review-store`;
+
+describe('GP Workflow: Review and Reassign', () => {
+ context('Review and Reassign', () => {
+ beforeEach(() => {
+ cy.addItemToDynamoDb(tableName, dbItem);
+ cy.addPdfFileToS3(bucketName, path, 'test_patient_record.pdf');
+ });
+
+ afterEach(() => {
+ cy.deleteItemFromDynamoDb(tableName, dbItem.ID, 1);
+ cy.deleteItemFromDynamoDb(tableName, dbItem.ID, 2);
+ cy.deleteFileFromS3(bucketName, path);
+ });
+
+ it(
+ '[Smoke] GP ADMIN user can review and reassign a document to the correct patient',
+ { tags: 'smoke', defaultCommandTimeout: 20000 },
+ () => {
+ cy.smokeLogin(Roles.SMOKE_GP_ADMIN);
+
+ // click admin console
+ cy.navigateToHomePage();
+ cy.getByTestId('admin-hub-btn').should('exist').click();
+
+ // click review docs
+ cy.getByTestId('admin-reviews-btn').should('exist').click();
+
+ // find the example review item by nhs number and view it
+ cy.getByTestId('view-record-link-e3e4f62e-6f95-4d8c-8870-5212b6353ae9')
+ .should('exist')
+ .click();
+
+ // click "dont accept the record" and continue
+ cy.getByTestId('reject-record-option').should('exist').check();
+ cy.getByTestId('reject-record-option').should('be.checked');
+ cy.getByTestId('continue-btn').should('exist').click();
+
+ // find the textbox and search for the correct nhs number to reassign to
+ cy.getByTestId('nhs-number-input').should('exist').click();
+ cy.getByTestId('nhs-number-input').type('9730788197');
+ cy.getByTestId('continue-button').should('exist').click();
+
+ // confirm demographics of the new patient and continue
+ cy.getByTestId('confirm-patient-details-btn').should('exist').click();
+
+ // assert reassignment success message and path
+ cy.contains('This document has been matched to the correct patient').should(
+ 'be.visible',
+ );
+ cy.url().should('contain', '/admin/reviews/:reviewId/complete/patient-matched');
+
+ // assert the review is no longer in our review queue
+ cy.getByTestId('review-another-btn').should('exist').click();
+ cy.getByTestId('view-record-link-e3e4f62e-6f95-4d8c-8870-5212b6353ae9').should(
+ 'not.exist',
+ );
+
+ // logout
+ cy.getByTestId('logout-btn').click();
+
+ // login as new ods code to verify the document is now in their review queue
+ cy.getByTestId('start-btn').should('exist'); // wait for login button to appear after logout
+ cy.smokeLogin(Roles.SMOKE_GP_ADMIN, 'M85143');
+ cy.navigateToHomePage();
+ cy.getByTestId('admin-hub-btn').should('exist').click();
+ cy.getByTestId('admin-reviews-btn').should('exist').click();
+ cy.getByTestId('view-record-link-e3e4f62e-6f95-4d8c-8870-5212b6353ae9').should(
+ 'exist',
+ );
+ },
+ );
+ });
+});
diff --git a/app/cypress/fixtures/dynamo-db-items/example-review-h81109.json b/app/cypress/fixtures/dynamo-db-items/example-review-h81109.json
new file mode 100644
index 000000000..1732abe94
--- /dev/null
+++ b/app/cypress/fixtures/dynamo-db-items/example-review-h81109.json
@@ -0,0 +1,17 @@
+{
+ "ID": "e3e4f62e-6f95-4d8c-8870-5212b6353ae9",
+ "Version": 1,
+ "Author": "H81109",
+ "Custodian": "H81109",
+ "DocumentSnomedCodeType": "16521000000101",
+ "Files": [
+ {
+ "FileLocation": "s3://ndrk-document-pending-review-store/9730155348/e3e4f62e-6f95-4d8c-8870-5212b6353ae9/test_patient_record.pdf",
+ "FileName": "test_patient_record.pdf"
+ }
+ ],
+ "NhsNumber": "9730155348",
+ "ReviewReason": "Unsuccessful upload",
+ "ReviewStatus": "PENDING_REVIEW",
+ "UploadDate": 1768728372
+}
\ No newline at end of file
diff --git a/app/cypress/support/aws.commands.ts b/app/cypress/support/aws.commands.ts
index 364fcf3d9..05dd472dd 100644
--- a/app/cypress/support/aws.commands.ts
+++ b/app/cypress/support/aws.commands.ts
@@ -91,26 +91,35 @@ Cypress.Commands.add('deleteFileFromS3', (bucketName: string, fileName: string)
);
});
-Cypress.Commands.add('deleteItemFromDynamoDb', (tableName: string, itemId: string) => {
- const params: DeleteItemCommandInput = {
- TableName: tableName,
- Key: {
+Cypress.Commands.add(
+ 'deleteItemFromDynamoDb',
+ (tableName: string, itemId: string, version?: number) => {
+ const key: DeleteItemCommandInput['Key'] = {
ID: { S: itemId },
- },
- };
+ };
- return cy.wrap(
- dynamo
- .send(new DeleteItemCommand(params))
- .then((data) => data)
- .catch((err) => {
- const message = 'Error deleting item from Dynamo: ' + tableName;
- // eslint-disable-next-line no-console
- console.error(message, err);
- throw new Error(message);
- }),
- );
-});
+ if (version !== undefined) {
+ key.Version = { N: version.toString() };
+ }
+
+ const params: DeleteItemCommandInput = {
+ TableName: tableName,
+ Key: key,
+ };
+
+ return cy.wrap(
+ dynamo
+ .send(new DeleteItemCommand(params))
+ .then((data) => data)
+ .catch((err) => {
+ const message = 'Error deleting item from Dynamo: ' + tableName;
+ // eslint-disable-next-line no-console
+ console.error(message, err);
+ throw new Error(message);
+ }),
+ );
+ },
+);
Cypress.Commands.add(
'deleteItemsBySecondaryKeyFromDynamoDb',
diff --git a/app/src/components/blocks/_admin/reviewsDetailsStage/ReviewsDetailsStage.tsx b/app/src/components/blocks/_admin/reviewsDetailsStage/ReviewsDetailsStage.tsx
index 78001edb1..c2c47e118 100644
--- a/app/src/components/blocks/_admin/reviewsDetailsStage/ReviewsDetailsStage.tsx
+++ b/app/src/components/blocks/_admin/reviewsDetailsStage/ReviewsDetailsStage.tsx
@@ -357,12 +357,17 @@ const ReviewsDetailsStage = ({