From 740bc69c6d5f33731b6757f3f9a3e1155ae1f279 Mon Sep 17 00:00:00 2001 From: David Wass Date: Tue, 11 Nov 2025 14:21:47 +0000 Subject: [PATCH 1/4] CCM-12590 - Update failure reason code to string --- docs/assets/diagrams/types.md | 2 +- .../datastore/src/__test__/letter-repository.test.ts | 4 ++-- internal/datastore/src/types.md | 2 +- internal/datastore/src/types.ts | 2 +- lambdas/api-handler/src/contracts/letters.ts | 6 +++--- .../src/handlers/__tests__/get-letter.test.ts | 4 ++-- .../src/handlers/__tests__/get-letters.test.ts | 2 +- .../src/handlers/__tests__/patch-letter.test.ts | 4 ++-- .../src/mappers/__tests__/letter-mapper.test.ts | 10 +++++----- .../src/services/__tests__/letter-operations.test.ts | 4 ++-- postman/Sandbox.postman_collection.json | 6 +++--- .../apiGateway-tests/testCases/UpdateLetterStatus.ts | 6 +++--- tests/sandbox/testCases/getLetterStatus_testCases.ts | 6 +++--- .../sandbox/testCases/updateLetterStatus_testCases.ts | 4 ++-- .../testCases/updateMultipleStatus_testCases.ts | 10 +++++----- 15 files changed, 36 insertions(+), 36 deletions(-) diff --git a/docs/assets/diagrams/types.md b/docs/assets/diagrams/types.md index 42e62db7..5c541c75 100644 --- a/docs/assets/diagrams/types.md +++ b/docs/assets/diagrams/types.md @@ -13,7 +13,7 @@ erDiagram string status "enum: PENDING, ACCEPTED, REJECTED, PRINTED, ENCLOSED, CANCELLED, DISPATCHED, FAILED, RETURNED, FORWARDED, DELIVERED" string specificationId string groupId - number reasonCode + string reasonCode string reasonText string supplierId string url "url" diff --git a/internal/datastore/src/__test__/letter-repository.test.ts b/internal/datastore/src/__test__/letter-repository.test.ts index 6e336468..d1714f90 100644 --- a/internal/datastore/src/__test__/letter-repository.test.ts +++ b/internal/datastore/src/__test__/letter-repository.test.ts @@ -111,14 +111,14 @@ describe('LetterRepository', () => { id: 'letter1', supplierId: 'supplier1', status: 'REJECTED', - reasonCode: 1, + reasonCode: 'R01', reasonText: 'Reason text' }; await letterRepository.updateLetterStatus(letterDto); const updatedLetter = await letterRepository.getLetterById('supplier1', 'letter1'); expect(updatedLetter.status).toBe('REJECTED'); - expect(updatedLetter.reasonCode).toBe(1); + expect(updatedLetter.reasonCode).toBe('R01'); expect(updatedLetter.reasonText).toBe('Reason text'); }); diff --git a/internal/datastore/src/types.md b/internal/datastore/src/types.md index 25fde561..83246072 100644 --- a/internal/datastore/src/types.md +++ b/internal/datastore/src/types.md @@ -13,7 +13,7 @@ erDiagram string status "enum: PENDING, ACCEPTED, REJECTED, PRINTED, ENCLOSED, CANCELLED, DISPATCHED, FAILED, RETURNED, FORWARDED, DELIVERED" string specificationId string groupId - number reasonCode + string reasonCode string reasonText string supplierId string url "url" diff --git a/internal/datastore/src/types.ts b/internal/datastore/src/types.ts index 2f2aa810..0d428a4e 100644 --- a/internal/datastore/src/types.ts +++ b/internal/datastore/src/types.ts @@ -24,7 +24,7 @@ export const LetterSchemaBase = z.object({ status: LetterStatus, specificationId: z.string(), groupId: z.string(), - reasonCode: z.number().optional(), + reasonCode: z.string().optional(), reasonText: z.string().optional() }); diff --git a/lambdas/api-handler/src/contracts/letters.ts b/lambdas/api-handler/src/contracts/letters.ts index a6c0789b..1cc33a37 100644 --- a/lambdas/api-handler/src/contracts/letters.ts +++ b/lambdas/api-handler/src/contracts/letters.ts @@ -7,7 +7,7 @@ export type LetterDto = { supplierId: string, specificationId?: string, groupId?: string, - reasonCode?: number, + reasonCode?: string, reasonText?: string }; @@ -30,7 +30,7 @@ export const PatchLetterRequestResourceSchema = z.object({ type: z.literal('Letter'), attributes: z.object({ status: LetterStatusSchema, - reasonCode: z.number().optional(), + reasonCode: z.string().optional(), reasonText: z.string().optional(), }).strict() }).strict(); @@ -42,7 +42,7 @@ export const GetLetterResponseResourceSchema = z.object({ status: LetterStatusSchema, specificationId: z.string(), groupId: z.string().optional(), - reasonCode: z.number().optional(), + reasonCode: z.string().optional(), reasonText: z.string().optional(), }).strict() }).strict(); diff --git a/lambdas/api-handler/src/handlers/__tests__/get-letter.test.ts b/lambdas/api-handler/src/handlers/__tests__/get-letter.test.ts index 742bf274..bd9b329e 100644 --- a/lambdas/api-handler/src/handlers/__tests__/get-letter.test.ts +++ b/lambdas/api-handler/src/handlers/__tests__/get-letter.test.ts @@ -78,7 +78,7 @@ describe('API Lambda handler', () => { specificationId: 'spec1', groupId: 'group1', status: 'FAILED', - reasonCode: 100, + reasonCode: 'R01', reasonText: 'failed validation' }); @@ -97,7 +97,7 @@ describe('API Lambda handler', () => { status: 'FAILED', specificationId: 'spec1', groupId: 'group1', - reasonCode: 100, + reasonCode: 'R01', reasonText: 'failed validation' } } diff --git a/lambdas/api-handler/src/handlers/__tests__/get-letters.test.ts b/lambdas/api-handler/src/handlers/__tests__/get-letters.test.ts index 292538da..581e3960 100644 --- a/lambdas/api-handler/src/handlers/__tests__/get-letters.test.ts +++ b/lambdas/api-handler/src/handlers/__tests__/get-letters.test.ts @@ -65,7 +65,7 @@ describe('API Lambda handler', () => { specificationId: 's1', groupId: 'g1', status: 'PENDING', - reasonCode: 123, // shouldn't be returned if present + reasonCode: 'R02', // shouldn't be returned if present reasonText: 'Reason text' // shouldn't be returned if present }, ]); diff --git a/lambdas/api-handler/src/handlers/__tests__/patch-letter.test.ts b/lambdas/api-handler/src/handlers/__tests__/patch-letter.test.ts index 72737e4b..6ec92111 100644 --- a/lambdas/api-handler/src/handlers/__tests__/patch-letter.test.ts +++ b/lambdas/api-handler/src/handlers/__tests__/patch-letter.test.ts @@ -32,7 +32,7 @@ const updateLetterStatusRequest : PatchLetterRequest = { type: 'Letter', attributes: { status: 'REJECTED', - reasonCode: 123, + reasonCode: 'R01', reasonText: 'Reason text', } } @@ -81,7 +81,7 @@ describe('patchLetter API Handler', () => { status: 'REJECTED', specificationId: 'spec1', groupId: 'group1', - reasonCode: 123, + reasonCode: 'R01', reasonText: 'Reason text', } } diff --git a/lambdas/api-handler/src/mappers/__tests__/letter-mapper.test.ts b/lambdas/api-handler/src/mappers/__tests__/letter-mapper.test.ts index f6f8e3dc..f3111b1f 100644 --- a/lambdas/api-handler/src/mappers/__tests__/letter-mapper.test.ts +++ b/lambdas/api-handler/src/mappers/__tests__/letter-mapper.test.ts @@ -46,7 +46,7 @@ describe('letter-mapper', () => { supplierStatus: 'supplier1#PENDING', supplierStatusSk: Date.now().toString(), ttl: 123, - reasonCode: 123, + reasonCode: 'R01', reasonText: 'Reason text' }; @@ -60,7 +60,7 @@ describe('letter-mapper', () => { specificationId: 'spec123', status: 'PENDING', groupId: 'group123', - reasonCode: 123, + reasonCode: 'R01', reasonText: 'Reason text', } } @@ -111,7 +111,7 @@ describe('letter-mapper', () => { supplierStatus: 'supplier1#PENDING', supplierStatusSk: Date.now().toString(), ttl: 123, - reasonCode: 123, + reasonCode: 'R01', reasonText: 'Reason text' }; @@ -125,7 +125,7 @@ describe('letter-mapper', () => { specificationId: 'spec123', status: 'PENDING', groupId: 'group123', - reasonCode: 123, + reasonCode: 'R01', reasonText: 'Reason text', } } @@ -145,7 +145,7 @@ describe('letter-mapper', () => { supplierStatus: 'supplier1#PENDING', supplierStatusSk: Date.now().toString(), ttl: 123, - reasonCode: 123, + reasonCode: 'R01', reasonText: 'Reason text' }; diff --git a/lambdas/api-handler/src/services/__tests__/letter-operations.test.ts b/lambdas/api-handler/src/services/__tests__/letter-operations.test.ts index 1016061c..d8dd0a35 100644 --- a/lambdas/api-handler/src/services/__tests__/letter-operations.test.ts +++ b/lambdas/api-handler/src/services/__tests__/letter-operations.test.ts @@ -102,7 +102,7 @@ describe('patchLetterStatus function', () => { id: 'letter1', supplierId: 'supplier1', status: 'REJECTED', - reasonCode: 123, + reasonCode: 'R01', reasonText: 'Reason text' }; @@ -223,7 +223,7 @@ function makeLetter(id: string, status: Letter['status']) : Letter { supplierStatus: `supplier1#${status}`, supplierStatusSk: Date.now().toString(), ttl: 123, - reasonCode: 123, + reasonCode: 'R01', reasonText: "Reason text" }; } diff --git a/postman/Sandbox.postman_collection.json b/postman/Sandbox.postman_collection.json index b4aabdb2..4279bb4a 100644 --- a/postman/Sandbox.postman_collection.json +++ b/postman/Sandbox.postman_collection.json @@ -754,7 +754,7 @@ "language": "json" } }, - "raw": "\n{\n \"data\": {\n \"attributes\": {\n \"reasonCode\": 100,\n \"reasonText\": \"failed validation\",\n \"status\": \"CANCELLED\"\n },\n \"id\": \"2WL5eYSWGzCHlGmzNxuqVusPxDg\",\n \"type\": \"Letter\"\n }\n}" + "raw": "\n{\n \"data\": {\n \"attributes\": {\n \"reasonCode\": 'R01',\n \"reasonText\": \"failed validation\",\n \"status\": \"CANCELLED\"\n },\n \"id\": \"2WL5eYSWGzCHlGmzNxuqVusPxDg\",\n \"type\": \"Letter\"\n }\n}" }, "header": [ { @@ -1014,7 +1014,7 @@ "language": "json" } }, - "raw": "{\n \"data\": {\n \"attributes\": {\n \"reasonCode\": 100,\n \"reasonText\": \"failed validation\",\n \"status\": \"FAILED\"\n },\n \"id\": \"2WL5eYSWGzCHlGmzNxuqVusPxDg\",\n \"type\": \"Letter\"\n }\n}" + "raw": "{\n \"data\": {\n \"attributes\": {\n \"reasonCode\": 'R01',\n \"reasonText\": \"failed validation\",\n \"status\": \"FAILED\"\n },\n \"id\": \"2WL5eYSWGzCHlGmzNxuqVusPxDg\",\n \"type\": \"Letter\"\n }\n}" }, "header": [ { @@ -1451,7 +1451,7 @@ "language": "json" } }, - "raw": "{\n \"data\": [\n {\n \"attributes\": {\n \"status\": \"PENDING\"\n },\n \"id\": \"2WL5eYSWGzCHlGmzNxuqVusPxDg\",\n \"type\": \"Letter\"\n },\n {\n \"attributes\": {\n \"status\": \"ACCEPTED\"\n },\n \"id\": \"2WL5eYSWGzCHlGmzNxuqVusPxDg\",\n \"type\": \"Letter\"\n },\n {\n \"attributes\": {\n \"status\": \"PRINTED\"\n },\n \"id\": \"2WL5eYSWGzCHlGmzNxuqVusPxDg\",\n \"type\": \"Letter\"\n },\n {\n \"attributes\": {\n \"status\": \"ENCLOSED\"\n },\n \"id\": \"2WL5eYSWGzCHlGmzNxuqVusPxDg\",\n \"type\": \"Letter\"\n },\n {\n \"attributes\": {\n \"status\": \"DISPATCHED\"\n },\n \"id\": \"2WL5eYSWGzCHlGmzNxuqVusPxDg\",\n \"type\": \"Letter\"\n },\n {\n \"attributes\": {\n \"status\": \"DELIVERED\"\n },\n \"id\": \"2WL5eYSWGzCHlGmzNxuqVusPxDg\",\n \"type\": \"Letter\"\n },\n {\n \"attributes\": {\n \"reasonCode\": 100,\n \"reasonText\": \"failed validation\",\n \"status\": \"RETURNED\"\n },\n \"id\": \"2WL5eYSWGzCHlGmzNxuqVusPxDg\",\n \"type\": \"Letter\"\n },\n {\n \"attributes\": {\n \"reasonCode\": 100,\n \"reasonText\": \"failed validation\",\n \"status\": \"CANCELLED\"\n },\n \"id\": \"2WL5eYSWGzCHlGmzNxuqVusPxDg\",\n \"type\": \"Letter\"\n },\n {\n \"attributes\": {\n \"reasonCode\": 100,\n \"reasonText\": \"failed validation\",\n \"status\": \"FAILED\"\n },\n \"id\": \"2WL5eYSWGzCHlGmzNxuqVusPxDg\",\n \"type\": \"Letter\"\n },\n {\n \"attributes\": {\n \"reasonCode\": 100,\n \"reasonText\": \"failed validation\",\n \"status\": \"RETURNED\"\n },\n \"id\": \"2WL5eYSWGzCHlGmzNxuqVusPxDg\",\n \"type\": \"Letter\"\n }\n ]\n}" + "raw": "{\n \"data\": [\n {\n \"attributes\": {\n \"status\": \"PENDING\"\n },\n \"id\": \"2WL5eYSWGzCHlGmzNxuqVusPxDg\",\n \"type\": \"Letter\"\n },\n {\n \"attributes\": {\n \"status\": \"ACCEPTED\"\n },\n \"id\": \"2WL5eYSWGzCHlGmzNxuqVusPxDg\",\n \"type\": \"Letter\"\n },\n {\n \"attributes\": {\n \"status\": \"PRINTED\"\n },\n \"id\": \"2WL5eYSWGzCHlGmzNxuqVusPxDg\",\n \"type\": \"Letter\"\n },\n {\n \"attributes\": {\n \"status\": \"ENCLOSED\"\n },\n \"id\": \"2WL5eYSWGzCHlGmzNxuqVusPxDg\",\n \"type\": \"Letter\"\n },\n {\n \"attributes\": {\n \"status\": \"DISPATCHED\"\n },\n \"id\": \"2WL5eYSWGzCHlGmzNxuqVusPxDg\",\n \"type\": \"Letter\"\n },\n {\n \"attributes\": {\n \"status\": \"DELIVERED\"\n },\n \"id\": \"2WL5eYSWGzCHlGmzNxuqVusPxDg\",\n \"type\": \"Letter\"\n },\n {\n \"attributes\": {\n \"reasonCode\": 'R01',\n \"reasonText\": \"failed validation\",\n \"status\": \"RETURNED\"\n },\n \"id\": \"2WL5eYSWGzCHlGmzNxuqVusPxDg\",\n \"type\": \"Letter\"\n },\n {\n \"attributes\": {\n \"reasonCode\": 'R01',\n \"reasonText\": \"failed validation\",\n \"status\": \"CANCELLED\"\n },\n \"id\": \"2WL5eYSWGzCHlGmzNxuqVusPxDg\",\n \"type\": \"Letter\"\n },\n {\n \"attributes\": {\n \"reasonCode\": 'R01',\n \"reasonText\": \"failed validation\",\n \"status\": \"FAILED\"\n },\n \"id\": \"2WL5eYSWGzCHlGmzNxuqVusPxDg\",\n \"type\": \"Letter\"\n },\n {\n \"attributes\": {\n \"reasonCode\": 'R01',\n \"reasonText\": \"failed validation\",\n \"status\": \"RETURNED\"\n },\n \"id\": \"2WL5eYSWGzCHlGmzNxuqVusPxDg\",\n \"type\": \"Letter\"\n }\n ]\n}" }, "header": [ { diff --git a/tests/component-tests/apiGateway-tests/testCases/UpdateLetterStatus.ts b/tests/component-tests/apiGateway-tests/testCases/UpdateLetterStatus.ts index 875541b1..1dc60d4d 100644 --- a/tests/component-tests/apiGateway-tests/testCases/UpdateLetterStatus.ts +++ b/tests/component-tests/apiGateway-tests/testCases/UpdateLetterStatus.ts @@ -8,7 +8,7 @@ export type PatchMessageRequestBody = { type: string; id: string; attributes: { - reasonCode?: string | number; + reasonCode?: string; reasonText?: string; status: string; }; @@ -20,7 +20,7 @@ export type PatchMessageResponseBody = { type: string; id: string; attributes: { - reasonCode?: number; + reasonCode?: string; reasonText?: string; status: string; specificationId:string; @@ -64,7 +64,7 @@ export function patchFailureRequestBody (id: string, status: string) : PatchMess data: { attributes: { status: status, - reasonCode: 123, + reasonCode: 'R01', reasonText: 'Test Reason' }, type: 'Letter', diff --git a/tests/sandbox/testCases/getLetterStatus_testCases.ts b/tests/sandbox/testCases/getLetterStatus_testCases.ts index 54333de1..6e52bf4c 100644 --- a/tests/sandbox/testCases/getLetterStatus_testCases.ts +++ b/tests/sandbox/testCases/getLetterStatus_testCases.ts @@ -37,7 +37,7 @@ type RejectedLetterData = specificationId: string; groupId: string; status: string; - reasonCode: number; + reasonCode: string; reasonText: string; } }; @@ -90,7 +90,7 @@ export const apiSandboxGetLetterStatusTestData: ApiSandboxGetLetterStatusTestCas specificationId: '2WL5eYSWGzCHlGmzNxuqVusPxDg', groupId: 'c5d93f917f5546d08beccf770a915d96', status: 'REJECTED', - reasonCode: 100, + reasonCode: 'R01', reasonText: "failed validation", }, } @@ -110,7 +110,7 @@ export const apiSandboxGetLetterStatusTestData: ApiSandboxGetLetterStatusTestCas specificationId: '2WL5eYSWGzCHlGmzNxuqVusPxDg', groupId: 'c5d93f917f5546d08beccf770a915d96', status: 'CANCELLED', - reasonCode: 100 + reasonCode: 'R01' }, } } diff --git a/tests/sandbox/testCases/updateLetterStatus_testCases.ts b/tests/sandbox/testCases/updateLetterStatus_testCases.ts index 816a6e83..a22f3675 100644 --- a/tests/sandbox/testCases/updateLetterStatus_testCases.ts +++ b/tests/sandbox/testCases/updateLetterStatus_testCases.ts @@ -51,7 +51,7 @@ export const apiSandboxUpdateLetterStatusTestData: ApiSandboxUpdateLetterStatusT id: '2WL5eYSWGzCHlGmzNxuqVusPxDg', attributes: { status: 'REJECTED', - reasonCode: 100, + reasonCode: 'R01', reasonText: 'failed validation', }, } @@ -62,7 +62,7 @@ export const apiSandboxUpdateLetterStatusTestData: ApiSandboxUpdateLetterStatusT type: 'Letter', id: '2WL5eYSWGzCHlGmzNxuqVusPxDg', attributes: { - reasonCode: 100, + reasonCode: 'R01', reasonText: 'failed validation', status: 'REJECTED', specificationId:'2WL5eYSWGzCHlGmzNxuqVusPxDg', diff --git a/tests/sandbox/testCases/updateMultipleStatus_testCases.ts b/tests/sandbox/testCases/updateMultipleStatus_testCases.ts index f94a17e7..dd6fdc7b 100644 --- a/tests/sandbox/testCases/updateMultipleStatus_testCases.ts +++ b/tests/sandbox/testCases/updateMultipleStatus_testCases.ts @@ -15,7 +15,7 @@ type postRequest = { type: string; id: string; attributes: { - reasonCode?: string | number; + reasonCode?: string; reasonText?: string; status: string; } @@ -71,7 +71,7 @@ export const apiSandboxMultipleLetterStatusTestData: ApiSandboxUpdateLetterStatu }, { attributes: { - reasonCode: 100, + reasonCode: 'R01', reasonText: 'failed validation', status: 'RETURNED' }, @@ -80,7 +80,7 @@ export const apiSandboxMultipleLetterStatusTestData: ApiSandboxUpdateLetterStatu }, { attributes: { - reasonCode: 100, + reasonCode: 'R01', reasonText: 'failed validation', status: 'CANCELLED' }, @@ -89,7 +89,7 @@ export const apiSandboxMultipleLetterStatusTestData: ApiSandboxUpdateLetterStatu }, { attributes: { - reasonCode: 100, + reasonCode: 'R01', reasonText: 'failed validation', status: 'FAILED' }, @@ -98,7 +98,7 @@ export const apiSandboxMultipleLetterStatusTestData: ApiSandboxUpdateLetterStatu }, { attributes: { - reasonCode: 100, + reasonCode: 'R01', reasonText: 'failed validation', status: 'RETURNED' }, From 0a083aaf9232e4041ae929407cedb7d4c0766036 Mon Sep 17 00:00:00 2001 From: David Wass Date: Thu, 13 Nov 2025 09:58:23 +0000 Subject: [PATCH 2/4] Update sandbox and OAS descriptions --- .../requests/patchLetter_CANCELLED.json | 4 ++-- .../requests/patchLetter_FAILED.json | 4 ++-- .../requests/patchLetter_REJECTED.json | 4 ++-- .../requests/patchLetter_RETURNED.json | 2 +- .../responses/patchLetter_CANCELLED.json | 4 ++-- .../responses/patchLetter_FAILED.json | 4 ++-- .../responses/patchLetter_REJECTED.json | 4 ++-- .../responses/patchLetter_RETURNED.json | 2 +- .../components/documentation/getLetterStatus.md | 17 +++++++++++++++++ .../api/components/documentation/patchLetter.md | 17 +++++++++++++++++ .../api/components/documentation/postLetters.md | 17 +++++++++++++++++ 11 files changed, 65 insertions(+), 14 deletions(-) diff --git a/sandbox/data/examples/patchLetter/requests/patchLetter_CANCELLED.json b/sandbox/data/examples/patchLetter/requests/patchLetter_CANCELLED.json index 7106a2f5..945cb1d6 100644 --- a/sandbox/data/examples/patchLetter/requests/patchLetter_CANCELLED.json +++ b/sandbox/data/examples/patchLetter/requests/patchLetter_CANCELLED.json @@ -1,8 +1,8 @@ { "data": { "attributes": { - "reasonCode": "R01", - "reasonText": "failed validation", + "reasonCode": "R10", + "reasonText": "Miscellaneous", "status": "CANCELLED" }, "id": "2WL5eYSWGzCHlGmzNxuqVusPxDg", diff --git a/sandbox/data/examples/patchLetter/requests/patchLetter_FAILED.json b/sandbox/data/examples/patchLetter/requests/patchLetter_FAILED.json index 359d9bc3..2e0721ea 100644 --- a/sandbox/data/examples/patchLetter/requests/patchLetter_FAILED.json +++ b/sandbox/data/examples/patchLetter/requests/patchLetter_FAILED.json @@ -1,8 +1,8 @@ { "data": { "attributes": { - "reasonCode": "R01", - "reasonText": "failed validation", + "reasonCode": "R10", + "reasonText": "Miscellaneous", "status": "FAILED" }, "id": "2WL5eYSWGzCHlGmzNxuqVusPxDg", diff --git a/sandbox/data/examples/patchLetter/requests/patchLetter_REJECTED.json b/sandbox/data/examples/patchLetter/requests/patchLetter_REJECTED.json index c44c0558..fc11dd2c 100644 --- a/sandbox/data/examples/patchLetter/requests/patchLetter_REJECTED.json +++ b/sandbox/data/examples/patchLetter/requests/patchLetter_REJECTED.json @@ -1,8 +1,8 @@ { "data": { "attributes": { - "reasonCode": "R01", - "reasonText": "failed validation", + "reasonCode": "R07", + "reasonText": "No such address", "status": "REJECTED" }, "id": "2WL5eYSWGzCHlGmzNxuqVusPxDg", diff --git a/sandbox/data/examples/patchLetter/requests/patchLetter_RETURNED.json b/sandbox/data/examples/patchLetter/requests/patchLetter_RETURNED.json index c44c0558..fc20aa5a 100644 --- a/sandbox/data/examples/patchLetter/requests/patchLetter_RETURNED.json +++ b/sandbox/data/examples/patchLetter/requests/patchLetter_RETURNED.json @@ -2,7 +2,7 @@ "data": { "attributes": { "reasonCode": "R01", - "reasonText": "failed validation", + "reasonText": "Addressee gone away", "status": "REJECTED" }, "id": "2WL5eYSWGzCHlGmzNxuqVusPxDg", diff --git a/sandbox/data/examples/patchLetter/responses/patchLetter_CANCELLED.json b/sandbox/data/examples/patchLetter/responses/patchLetter_CANCELLED.json index a0509519..b7724000 100644 --- a/sandbox/data/examples/patchLetter/responses/patchLetter_CANCELLED.json +++ b/sandbox/data/examples/patchLetter/responses/patchLetter_CANCELLED.json @@ -1,8 +1,8 @@ { "data": { "attributes": { - "reasonCode": "R01", - "reasonText": "failed validation", + "reasonCode": "R10", + "reasonText": "Miscellaneous", "specificationId": "2WL5eYSWGzCHlGmzNxuqVusPxDg", "status": "CANCELLED" }, diff --git a/sandbox/data/examples/patchLetter/responses/patchLetter_FAILED.json b/sandbox/data/examples/patchLetter/responses/patchLetter_FAILED.json index b2c2f902..208a9459 100644 --- a/sandbox/data/examples/patchLetter/responses/patchLetter_FAILED.json +++ b/sandbox/data/examples/patchLetter/responses/patchLetter_FAILED.json @@ -1,8 +1,8 @@ { "data": { "attributes": { - "reasonCode": "R01", - "reasonText": "failed validation", + "reasonCode": "R10", + "reasonText": "Miscellaneous", "specificationId": "2WL5eYSWGzCHlGmzNxuqVusPxDg", "status": "FAILED" }, diff --git a/sandbox/data/examples/patchLetter/responses/patchLetter_REJECTED.json b/sandbox/data/examples/patchLetter/responses/patchLetter_REJECTED.json index 98a205e5..c628b4bb 100644 --- a/sandbox/data/examples/patchLetter/responses/patchLetter_REJECTED.json +++ b/sandbox/data/examples/patchLetter/responses/patchLetter_REJECTED.json @@ -1,8 +1,8 @@ { "data": { "attributes": { - "reasonCode": "R01", - "reasonText": "failed validation", + "reasonCode": "R07", + "reasonText": "No such address", "specificationId": "2WL5eYSWGzCHlGmzNxuqVusPxDg", "status": "REJECTED" }, diff --git a/sandbox/data/examples/patchLetter/responses/patchLetter_RETURNED.json b/sandbox/data/examples/patchLetter/responses/patchLetter_RETURNED.json index eb3a70a0..9224419e 100644 --- a/sandbox/data/examples/patchLetter/responses/patchLetter_RETURNED.json +++ b/sandbox/data/examples/patchLetter/responses/patchLetter_RETURNED.json @@ -2,7 +2,7 @@ "data": { "attributes": { "reasonCode": "R01", - "reasonText": "failed validation", + "reasonText": "Addressee gone away", "specificationId": "2WL5eYSWGzCHlGmzNxuqVusPxDg", "status": "RETURNED" }, diff --git a/specification/api/components/documentation/getLetterStatus.md b/specification/api/components/documentation/getLetterStatus.md index cf4474d1..b1815343 100644 --- a/specification/api/components/documentation/getLetterStatus.md +++ b/specification/api/components/documentation/getLetterStatus.md @@ -20,3 +20,20 @@ You can test the following scenarios in our sandbox environment | Retrieve a CANCELLED letter status | `2XL5eYSWGzCHlGmzNxuqVusPxDg`| | Retrieve a FAILED letter status | `2YL5eYSWGzCHlGmzNxuqVusPxDg`| | Retrieve a RETURNED letter status | `2ZL5eYSWGzCHlGmzNxuqVusPxDg`| + +### Example Error Codes + +Examples of reason codes and text that may be returned include (but are not limited to) + +| Reason Code | Reason Text | +|-------------|----------------------------| +|R01 |Addressee gone away | +|R02 |Address incomplete | +|R03 |Address inaccessible | +|R04 |Addressee unknown | +|R05 |Addressee gone away/Refused | +|R06 |Not called for | +|R07 |No such address | +|R08 |No reason given | +|R09 |Deceased | +|R10 |Miscellaneous | diff --git a/specification/api/components/documentation/patchLetter.md b/specification/api/components/documentation/patchLetter.md index 4958c9fd..e29b229d 100644 --- a/specification/api/components/documentation/patchLetter.md +++ b/specification/api/components/documentation/patchLetter.md @@ -24,3 +24,20 @@ Allowed `status` values that can be used to are: It is not possible to update a letter to status of `PENDING`. Optionally a `reasonCode` and `reasonText` explaining the status (for example, validation failures) can be included in the request body. + +### Example Error Codes + +Examples of reason codes and text that may be returned include (but are not limited to) + +| Reason Code | Reason Text | +|-------------|----------------------------| +|R01 |Addressee gone away | +|R02 |Address incomplete | +|R03 |Address inaccessible | +|R04 |Addressee unknown | +|R05 |Addressee gone away/Refused | +|R06 |Not called for | +|R07 |No such address | +|R08 |No reason given | +|R09 |Deceased | +|R10 |Miscellaneous | diff --git a/specification/api/components/documentation/postLetters.md b/specification/api/components/documentation/postLetters.md index f968ac6d..b067b688 100644 --- a/specification/api/components/documentation/postLetters.md +++ b/specification/api/components/documentation/postLetters.md @@ -26,3 +26,20 @@ Allowed `status` values that can be used to are: It is not possible to update a letter to status of `PENDING`. Optionally a `reasonCode` and `reasonText` explaining the status (for example, validation failures) can be included in the request body for each update. + +### Example Error Codes + +Examples of reason codes and text that may be returned include (but are not limited to) + +| Reason Code | Reason Text | +|-------------|----------------------------| +|R01 |Addressee gone away | +|R02 |Address incomplete | +|R03 |Address inaccessible | +|R04 |Addressee unknown | +|R05 |Addressee gone away/Refused | +|R06 |Not called for | +|R07 |No such address | +|R08 |No reason given | +|R09 |Deceased | +|R10 |Miscellaneous | From 144f1a22252a09c9a29a6e113a50697b2d0b38bd Mon Sep 17 00:00:00 2001 From: "namitha.prabhu" Date: Fri, 14 Nov 2025 12:20:35 +0000 Subject: [PATCH 3/4] tests --- tests/helpers/generate_fetch_testData.ts | 1 + tests/helpers/pnpmHelpers.ts | 4 ++++ tests/sandbox/testCases/updateLetterStatus_testCases.ts | 4 ++-- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/helpers/generate_fetch_testData.ts b/tests/helpers/generate_fetch_testData.ts index 2fd63aa6..069e7886 100644 --- a/tests/helpers/generate_fetch_testData.ts +++ b/tests/helpers/generate_fetch_testData.ts @@ -29,6 +29,7 @@ export async function createTestData(supplierId: string): Promise { supplierId: supplierId, environment: envName, awsAccountId: '820178564574', + letterId: 'letterId', groupId: 'TestGroupID', specificationId: 'TestSpecificationID', status: 'PENDING', diff --git a/tests/helpers/pnpmHelpers.ts b/tests/helpers/pnpmHelpers.ts index e0e748c0..4a55ca9e 100644 --- a/tests/helpers/pnpmHelpers.ts +++ b/tests/helpers/pnpmHelpers.ts @@ -11,6 +11,7 @@ export async function runCreateLetter(options: { supplierId: string; environment: string; awsAccountId: string; + letterId: string; groupId: string; specificationId: string; status: string; @@ -21,6 +22,7 @@ export async function runCreateLetter(options: { supplierId, environment, awsAccountId, + letterId, groupId, specificationId, status, @@ -46,6 +48,8 @@ export async function runCreateLetter(options: { environment, '--awsAccountId', awsAccountId, + '--letter-id', + letterId, '--group-id', groupId, '--specification-id', diff --git a/tests/sandbox/testCases/updateLetterStatus_testCases.ts b/tests/sandbox/testCases/updateLetterStatus_testCases.ts index 816a6e83..35765676 100644 --- a/tests/sandbox/testCases/updateLetterStatus_testCases.ts +++ b/tests/sandbox/testCases/updateLetterStatus_testCases.ts @@ -112,10 +112,10 @@ export const apiSandboxUpdateLetterStatusTestData: ApiSandboxUpdateLetterStatusT }, expectedStatus: 400, expectedResponse: { - message: 'request.body.data.attributes.status should be equal to one of the allowed values: PENDING, ACCEPTED, REJECTED, PRINTED, ENCLOSED, CANCELLED, DISPATCHED, DELIVERED, FAILED, RETURNED, FORWARDED', + message: 'request.body.data.attributes.status should be equal to one of the allowed values: PENDING, ACCEPTED, REJECTED, PRINTED, ENCLOSED, CANCELLED, DISPATCHED, DELIVERED, FAILED, RETURNED, DESTROYED, FORWARDED', errors: [{ path: '.body.data.attributes.status', - message: 'should be equal to one of the allowed values: PENDING, ACCEPTED, REJECTED, PRINTED, ENCLOSED, CANCELLED, DISPATCHED, DELIVERED, FAILED, RETURNED, FORWARDED', + message: 'should be equal to one of the allowed values: PENDING, ACCEPTED, REJECTED, PRINTED, ENCLOSED, CANCELLED, DISPATCHED, DELIVERED, FAILED, RETURNED, DESTROYED, FORWARDED', errorCode: 'enum.openapi.validation' }] }, From aae412a18e240037e7a1eacd5388078aef8179e4 Mon Sep 17 00:00:00 2001 From: "namitha.prabhu" Date: Mon, 17 Nov 2025 13:48:11 +0000 Subject: [PATCH 4/4] tests --- tests/constants/api_constants.ts | 11 ++++- .../testCases/updateLetterStatus_testCases.ts | 42 +++++-------------- .../updateMultipleStatus_testCases.ts | 4 +- tests/sandbox/updateLetterStatus.spec.ts | 10 +++-- 4 files changed, 28 insertions(+), 39 deletions(-) diff --git a/tests/constants/api_constants.ts b/tests/constants/api_constants.ts index 53e1d703..e90c1d14 100644 --- a/tests/constants/api_constants.ts +++ b/tests/constants/api_constants.ts @@ -1,8 +1,17 @@ export const SUPPLIER_LETTERS = 'letters'; -export const SUPPLIER_API_URL_SANDBOX = 'https://internal-dev-sandbox.api.service.nhs.uk/nhs-notify-supplier'; export const AWS_REGION = 'eu-west-2'; export const envName = process.env.PR_NUMBER ?? 'main'; export const API_NAME = `nhs-${envName}-supapi`; export const LETTERSTABLENAME = `nhs-${envName}-supapi-letters`; export const SUPPLIERID = 'TestSupplier1'; export const MI_ENDPOINT = 'mi'; + +const formattedPr = process.env.PR_NUMBER + ? process.env.PR_NUMBER.replace(/^pr(\d+)$/i, "PR-$1") + : null; + +// Build sandbox environment name +const sandboxEnv = formattedPr + ? `nhs-notify-supplier-${formattedPr}` + : "nhs-notify-supplier"; +export const SUPPLIER_API_URL_SANDBOX = `https://internal-dev-sandbox.api.service.nhs.uk/${sandboxEnv}`; diff --git a/tests/sandbox/testCases/updateLetterStatus_testCases.ts b/tests/sandbox/testCases/updateLetterStatus_testCases.ts index f27ecb35..b81ca167 100644 --- a/tests/sandbox/testCases/updateLetterStatus_testCases.ts +++ b/tests/sandbox/testCases/updateLetterStatus_testCases.ts @@ -16,8 +16,8 @@ export type ApiSandboxUpdateLetterStatusTestData = { export const apiSandboxUpdateLetterStatusTestData: ApiSandboxUpdateLetterStatusTestData[] = [ { - testCase: '200 response if record is updated with status PENDING', - id: '2WL5eYSWGzCHlGmzNxuqVusPxDg', + testCase: '202 response if record is updated with status PENDING', + id: '24L5eYSWGzCHlGmzNxuqVusPxDg', header: sandBoxHeader, body: { data: { @@ -28,22 +28,12 @@ export const apiSandboxUpdateLetterStatusTestData: ApiSandboxUpdateLetterStatusT }, } }, - expectedStatus: 200, - expectedResponse: { - data: { - type: 'Letter', - id: '2WL5eYSWGzCHlGmzNxuqVusPxDg', - attributes: { - status: 'PENDING', - specificationId:'2WL5eYSWGzCHlGmzNxuqVusPxDg', - }, - } - }, + expectedStatus: 202, }, { - testCase: '200 response if record is updated with status REJECTED', - id: '2WL5eYSWGzCHlGmzNxuqVusPxDg', + testCase: '202 response if record is updated with status REJECTED', + id: '24L5eYSWGzCHlGmzNxuqVusPxDg', header: sandBoxHeader, body: { data: { @@ -51,24 +41,12 @@ export const apiSandboxUpdateLetterStatusTestData: ApiSandboxUpdateLetterStatusT id: '2WL5eYSWGzCHlGmzNxuqVusPxDg', attributes: { status: 'REJECTED', - reasonCode: 'R01', - reasonText: 'failed validation', - }, - } - }, - expectedStatus: 200, - expectedResponse: { - data: { - type: 'Letter', - id: '2WL5eYSWGzCHlGmzNxuqVusPxDg', - attributes: { - reasonCode: 'R01', - reasonText: 'failed validation', - status: 'REJECTED', - specificationId:'2WL5eYSWGzCHlGmzNxuqVusPxDg', + reasonCode: 'R07', + reasonText: 'No such address', }, } }, + expectedStatus: 202, }, { testCase: '404 response if no resource is found for the given id', @@ -112,10 +90,10 @@ export const apiSandboxUpdateLetterStatusTestData: ApiSandboxUpdateLetterStatusT }, expectedStatus: 400, expectedResponse: { - message: 'request.body.data.attributes.status should be equal to one of the allowed values: PENDING, ACCEPTED, REJECTED, PRINTED, ENCLOSED, CANCELLED, DISPATCHED, DELIVERED, FAILED, RETURNED, DESTROYED, FORWARDED', + message: 'request.body.data.attributes.status should be equal to one of the allowed values: PENDING, ACCEPTED, REJECTED, PRINTED, ENCLOSED, CANCELLED, DISPATCHED, DELIVERED, FAILED, RETURNED, FORWARDED', errors: [{ path: '.body.data.attributes.status', - message: 'should be equal to one of the allowed values: PENDING, ACCEPTED, REJECTED, PRINTED, ENCLOSED, CANCELLED, DISPATCHED, DELIVERED, FAILED, RETURNED, DESTROYED, FORWARDED', + message: 'should be equal to one of the allowed values: PENDING, ACCEPTED, REJECTED, PRINTED, ENCLOSED, CANCELLED, DISPATCHED, DELIVERED, FAILED, RETURNED, FORWARDED', errorCode: 'enum.openapi.validation' }] }, diff --git a/tests/sandbox/testCases/updateMultipleStatus_testCases.ts b/tests/sandbox/testCases/updateMultipleStatus_testCases.ts index dd6fdc7b..c312a334 100644 --- a/tests/sandbox/testCases/updateMultipleStatus_testCases.ts +++ b/tests/sandbox/testCases/updateMultipleStatus_testCases.ts @@ -23,7 +23,7 @@ type postRequest = { export const apiSandboxMultipleLetterStatusTestData: ApiSandboxUpdateLetterStatusTestData[] = [{ - testCase: '200 response if records are updated', + testCase: '202 response if records are updated', header: sandBoxHeader, body:{ data : @@ -106,7 +106,7 @@ export const apiSandboxMultipleLetterStatusTestData: ApiSandboxUpdateLetterStatu type: 'Letter' } ]}, - expectedStatus: 200 + expectedStatus: 202 }, { testCase: '404 response if invalid request is passed', diff --git a/tests/sandbox/updateLetterStatus.spec.ts b/tests/sandbox/updateLetterStatus.spec.ts index 9e0d9a4d..02d9d9b7 100644 --- a/tests/sandbox/updateLetterStatus.spec.ts +++ b/tests/sandbox/updateLetterStatus.spec.ts @@ -7,16 +7,18 @@ test.describe('Sandbox Tests To Update Letter Status', () => { apiSandboxUpdateLetterStatusTestData.forEach(({ testCase, header, id, body, expectedStatus, expectedResponse }) => { test(`Patch /Letters endpoint returns ${testCase}`, async ({ request }) => { - const response = await request.patch(`${SUPPLIER_API_URL_SANDBOX}/${SUPPLIER_LETTERS}/${id}` ,{ headers: header, data: body }); - const res = await response.json(); - expect(response.status()).toBe(expectedStatus); - expect(res).toEqual(expectedResponse); + console.log("URL", `${SUPPLIER_API_URL_SANDBOX}/${SUPPLIER_LETTERS}/${id}`); + expect(response.status()).toBe(expectedStatus); + if (response.status() != 202){ + const res = await response.json(); + expect(res).toEqual(expectedResponse); + } }); }); });