Skip to content

Commit 2e515aa

Browse files
CCM-12875: Updated package.json and headers
1 parent 94a66c1 commit 2e515aa

File tree

5 files changed

+191
-28
lines changed

5 files changed

+191
-28
lines changed

lambdas/pdm-mock-api/README.md

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ The PDM Mock API simulates two key PDM endpoints following the FHIR R4 DocumentR
99
- **POST /patient-data-manager/FHIR/R4/DocumentReference** - Create a new DocumentReference
1010
- **GET /patient-data-manager/FHIR/R4/DocumentReference/{id}** - Retrieve a specific DocumentReference
1111

12-
The mock includes the same authentication mechanism used in the PDS mock, requiring a Bearer token in the Authorization header.
13-
1412
## API Endpoints
1513

1614
### POST /patient-data-manager/FHIR/R4/DocumentReference
@@ -22,19 +20,26 @@ Creates a new PDM DocumentReference.
2220
```bash
2321
curl -X POST https://<api-gateway-url>/patient-data-manager/FHIR/R4/DocumentReference \
2422
-H "Authorization: Bearer <token>" \
25-
-H "Content-Type: application/json" \
26-
-d '{"id": "custom-id"}'
23+
-H "Content-Type: application/fhir+json" \
24+
-H "X-Request-ID: 4a0e5f18-1747-4438-ac52-5ba2c21575f5" \
25+
-d '{}'
2726
```
2827

28+
**Headers:**
29+
30+
- `Authorization: Bearer <token>` - Required authentication token (default: `mock-pdm-token`)
31+
- `Content-Type: application/fhir+json` - Required content type
32+
- `X-Request-ID: <UUID>` - This uuid will be used as the DocumentReference `id` in the response.
33+
2934
**Response (201 Created):**
3035

3136
```json
3237
{
3338
"resourceType": "DocumentReference",
34-
"id": "c7a74264-cf34-31b1-a395-811fa375cec6",
39+
"id": "4a0e5f18-1747-4438-ac52-5ba2c21575f5",
3540
"meta": {
3641
"versionId": "1",
37-
"lastUpdated": "2025-11-26T16:50:48.338244Z"
42+
"lastUpdated": "2025-11-27T16:50:48.338244Z"
3843
},
3944
"status": "current",
4045
"subject": {
@@ -54,6 +59,8 @@ curl -X POST https://<api-gateway-url>/patient-data-manager/FHIR/R4/DocumentRefe
5459
}
5560
```
5661

62+
**Note:** The `id` in the response matches the `X-Request-ID` header value.
63+
5764
### GET /patient-data-manager/FHIR/R4/DocumentReference/{id}
5865

5966
Retrieves a specific PDM DocumentReference by ID.
@@ -62,9 +69,17 @@ Retrieves a specific PDM DocumentReference by ID.
6269

6370
```bash
6471
curl https://<api-gateway-url>/patient-data-manager/FHIR/R4/DocumentReference/test-id \
65-
-H "Authorization: Bearer <token>"
72+
-H "Authorization: Bearer <token>" \
73+
-H "Content-Type: application/fhir+json" \
74+
-H "X-Request-ID: 848b67ea-eeaa-3620-a388-e4e8594ff2e3"
6675
```
6776

77+
**Headers:**
78+
79+
- `Authorization: Bearer <token>` - Required authentication token (default: `mock-pdm-token`)
80+
- `Content-Type: application/fhir+json` - Required content type
81+
- `X-Request-ID: <uuid>` - Used for request tracking and correlation.
82+
6883
**Response (200 OK):**
6984

7085
```json
@@ -96,6 +111,29 @@ curl https://<api-gateway-url>/patient-data-manager/FHIR/R4/DocumentReference/te
96111

97112
## Error Scenarios
98113

114+
### Missing X-Request-ID Header
115+
116+
Both GET and POST endpoints require the `X-Request-ID` header. If it's missing, a 400 error is returned:
117+
118+
**Response (400 Bad Request):**
119+
120+
```json
121+
{
122+
"resourceType": "OperationOutcome",
123+
"issue": [
124+
{
125+
"severity": "error",
126+
"code": "required",
127+
"details": {
128+
"text": "Missing X-Request-ID header"
129+
}
130+
}
131+
]
132+
}
133+
```
134+
135+
### Error Scenarios
136+
99137
The mock API supports triggering specific error responses for testing. Use these special resource IDs:
100138

101139
| Resource ID | Status Code | Error Code | Description |

lambdas/pdm-mock-api/package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,10 @@
1414
"jest-mock-extended": "^3.0.7",
1515
"typescript": "^5.9.3"
1616
},
17-
"main": "dist/index.js",
18-
"name": "pdm-mock-api",
17+
"name": "nhs-notify-digital-letters-pdm-mock-api",
1918
"private": true,
2019
"scripts": {
21-
"build": "rm -rf dist && npx esbuild --bundle --minify --sourcemap --target=es2020 --platform=node --loader:.node=file --entry-names=[name] --outdir=dist src/index.ts",
20+
"lambda-build": "rm -rf dist && npx esbuild --bundle --minify --sourcemap --target=es2020 --platform=node --loader:.node=file --entry-names=[name] --outdir=dist src/index.ts",
2221
"lint": "eslint .",
2322
"lint:fix": "eslint . --fix",
2423
"test:unit": "jest",

lambdas/pdm-mock-api/src/__tests__/container.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ describe('Container', () => {
5858
const mockEvent = {
5959
pathParameters: { id: 'test-id' },
6060
requestContext: { requestId: 'test-request' },
61+
headers: {
62+
'X-Request-ID': 'container-test-1234-5678-9abc-def012345678',
63+
},
6164
};
6265

6366
const result = await container.getResourceHandler(mockEvent as never);

lambdas/pdm-mock-api/src/__tests__/handlers.test.ts

Lines changed: 81 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,11 @@ describe('GET Resource Handler', () => {
5656

5757
it('should return a mock resource for valid resource ID', async () => {
5858
const handler = createGetResourceHandler(mockLogger);
59-
const event = createMockEvent();
59+
const event = createMockEvent({
60+
headers: {
61+
'X-Request-ID': 'get-test-1234-5678-9abc-def012345678',
62+
},
63+
});
6064

6165
const response = await handler(event);
6266

@@ -81,7 +85,12 @@ describe('GET Resource Handler', () => {
8185

8286
it('should return 400 error when resource ID is missing', async () => {
8387
const handler = createGetResourceHandler(mockLogger);
84-
const event = createMockEvent({ pathParameters: null });
88+
const event = createMockEvent({
89+
pathParameters: null,
90+
headers: {
91+
'X-Request-ID': 'missing-id-test-1234-5678-9abc-def012345678',
92+
},
93+
});
8594

8695
const response = await handler(event);
8796

@@ -93,7 +102,12 @@ describe('GET Resource Handler', () => {
93102

94103
it('should return empty response for empty-response scenario', async () => {
95104
const handler = createGetResourceHandler(mockLogger);
96-
const event = createMockEvent({ pathParameters: { id: 'empty-response' } });
105+
const event = createMockEvent({
106+
pathParameters: { id: 'empty-response' },
107+
headers: {
108+
'X-Request-ID': 'empty-response-test-1234-5678-9abc-def012345678',
109+
},
110+
});
97111

98112
const response = await handler(event);
99113

@@ -143,7 +157,12 @@ describe('GET Resource Handler', () => {
143157
for (const { expectedCode, expectedStatus, id } of errorCases) {
144158
it(`should return ${expectedStatus} error for ${id}`, async () => {
145159
const handler = createGetResourceHandler(mockLogger);
146-
const event = createMockEvent({ pathParameters: { id } });
160+
const event = createMockEvent({
161+
pathParameters: { id },
162+
headers: {
163+
'X-Request-ID': `${id}-test-1234-5678-9abc-def012345678`,
164+
},
165+
});
147166

148167
const response = await handler(event);
149168

@@ -154,6 +173,20 @@ describe('GET Resource Handler', () => {
154173
});
155174
}
156175
});
176+
177+
it('should return 400 error when X-Request-ID header is missing', async () => {
178+
const handler = createGetResourceHandler(mockLogger);
179+
const event = createMockEvent();
180+
181+
const response = await handler(event);
182+
183+
expect(response.statusCode).toBe(400);
184+
const body = JSON.parse(response.body);
185+
expect(body.resourceType).toBe('OperationOutcome');
186+
expect(body.issue[0].severity).toBe('error');
187+
expect(body.issue[0].code).toBe('required');
188+
expect(body.issue[0].details.text).toBe('Missing X-Request-ID header');
189+
});
157190
});
158191

159192
describe('POST Create Resource Handler', () => {
@@ -163,9 +196,13 @@ describe('POST Create Resource Handler', () => {
163196

164197
it('should create a new resource with provided ID', async () => {
165198
const handler = createCreateResourceHandler(mockLogger);
199+
const xRequestId = 'custom-id-1234-5678-9abc-def012345678';
166200
const event = createMockEvent({
167201
httpMethod: 'POST',
168202
body: JSON.stringify({ id: 'custom-id' }),
203+
headers: {
204+
'X-Request-ID': xRequestId,
205+
},
169206
});
170207

171208
const response = await handler(event);
@@ -175,54 +212,76 @@ describe('POST Create Resource Handler', () => {
175212

176213
const body = JSON.parse(response.body);
177214
expect(body.resourceType).toBe('DocumentReference');
178-
expect(body.id).toBeDefined();
179-
expect(body.id).toMatch(
180-
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,
181-
);
215+
expect(body.id).toBe(xRequestId);
182216
expect(body.status).toBe('current');
183217
expect(body.meta).toBeDefined();
184218
expect(body.meta.versionId).toBe('1');
185219
expect(body.meta.lastUpdated).toBeDefined();
186220
});
187221

188-
it('should create a new resource with generated ID when not provided', async () => {
222+
it('should use X-Request-ID header as resource ID when provided', async () => {
189223
const handler = createCreateResourceHandler(mockLogger);
224+
const xRequestId = '4a0e5f18-1747-4438-ac52-5ba2c21575f5';
190225
const event = createMockEvent({
191226
httpMethod: 'POST',
192227
body: JSON.stringify({}),
228+
headers: {
229+
'X-Request-ID': xRequestId,
230+
'Content-Type': 'application/fhir+json',
231+
},
193232
});
194233

195234
const response = await handler(event);
196235

197236
expect(response.statusCode).toBe(201);
237+
const body = JSON.parse(response.body);
238+
expect(body.id).toBe(xRequestId);
239+
});
240+
241+
it('should return 400 error when X-Request-ID header is missing', async () => {
242+
const handler = createCreateResourceHandler(mockLogger);
243+
const event = createMockEvent({
244+
httpMethod: 'POST',
245+
body: JSON.stringify({}),
246+
headers: {},
247+
});
198248

249+
const response = await handler(event);
250+
251+
expect(response.statusCode).toBe(400);
199252
const body = JSON.parse(response.body);
200-
expect(body.id).toMatch(
201-
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,
202-
);
253+
expect(body.resourceType).toBe('OperationOutcome');
254+
expect(body.issue[0].severity).toBe('error');
255+
expect(body.issue[0].code).toBe('required');
256+
expect(body.issue[0].details.text).toBe('Missing X-Request-ID header');
203257
});
204258

205-
it('should handle empty body', async () => {
259+
it('should handle empty body with X-Request-ID header', async () => {
206260
const handler = createCreateResourceHandler(mockLogger);
261+
const xRequestId = 'aabbccdd-1111-2222-3333-444455556666';
207262
const event = createMockEvent({
208263
httpMethod: 'POST',
209264
body: null,
265+
headers: {
266+
'X-Request-ID': xRequestId,
267+
},
210268
});
211269

212270
const response = await handler(event);
213271

214272
expect(response.statusCode).toBe(201);
215273
const body = JSON.parse(response.body);
216-
expect(body.id).toMatch(
217-
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,
218-
);
274+
expect(body.id).toBe(xRequestId);
219275
});
220276

221277
it('should return 400 error for invalid JSON', async () => {
222278
const handler = createCreateResourceHandler(mockLogger);
223279
const event = createMockEvent({
224280
httpMethod: 'POST',
225281
body: 'invalid-json{',
282+
headers: {
283+
'X-Request-ID': 'invalid-json-test-1234-5678-9abc-def012345678',
284+
},
226285
});
227286

228287
const response = await handler(event);
@@ -238,6 +297,9 @@ describe('POST Create Resource Handler', () => {
238297
const event = createMockEvent({
239298
httpMethod: 'POST',
240299
body: JSON.stringify({ emptyResponse: true }),
300+
headers: {
301+
'X-Request-ID': 'empty-test-1234-5678-9abc-def012345678',
302+
},
241303
});
242304

243305
const response = await handler(event);
@@ -251,6 +313,9 @@ describe('POST Create Resource Handler', () => {
251313
const event = createMockEvent({
252314
httpMethod: 'POST',
253315
body: JSON.stringify({ triggerError: 'error-409-conflict' }),
316+
headers: {
317+
'X-Request-ID': 'error-test-1234-5678-9abc-def012345678',
318+
},
254319
});
255320

256321
const response = await handler(event);

0 commit comments

Comments
 (0)