Skip to content

Commit 494068b

Browse files
committed
Fixes following merge from main
1 parent f55ac54 commit 494068b

File tree

4 files changed

+49
-38
lines changed

4 files changed

+49
-38
lines changed

infrastructure/terraform/components/api/README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ No requirements.
3535
| <a name="module_authorizer_lambda"></a> [authorizer\_lambda](#module\_authorizer\_lambda) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-lambda.zip | n/a |
3636
| <a name="module_domain_truststore"></a> [domain\_truststore](#module\_domain\_truststore) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.20/terraform-s3bucket.zip | n/a |
3737
| <a name="module_get_letter"></a> [get\_letter](#module\_get\_letter) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-lambda.zip | n/a |
38-
| <a name="module_get_letters"></a> [get\_letters](#module\_get\_letters) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.20/terraform-lambda.zip | n/a |
3938
| <a name="module_get_letter_data"></a> [get\_letter\_data](#module\_get\_letter\_data) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-lambda.zip | n/a |
4039
| <a name="module_get_letters"></a> [get\_letters](#module\_get\_letters) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-lambda.zip | n/a |
4140
| <a name="module_kms"></a> [kms](#module\_kms) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.20/terraform-kms.zip | n/a |

lambdas/api-handler/src/handlers/__tests__/get-letter.test.ts

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,34 @@ import { Context } from 'aws-lambda';
22
import { mockDeep } from 'jest-mock-extended';
33
import * as letterService from '../../services/letter-operations';
44
import { makeApiGwEvent } from './utils/test-utils';
5-
import { getLetter } from '../../index';
65
import { ApiErrorDetail } from '../../contracts/errors';
76
import { NotFoundError } from '../../errors';
7+
import { S3Client } from '@aws-sdk/client-s3';
8+
import pino from 'pino';
9+
import { LetterRepository } from '../../../../../internal/datastore/src';
10+
import { Deps } from '../../config/deps';
11+
import { EnvVars } from '../../config/env';
12+
import { createGetLetterHandler } from '../get-letter';
813

914
jest.mock('../../services/letter-operations');
1015

11-
jest.mock('../../config/lambda-config', () => ({
12-
lambdaConfig: {
13-
SUPPLIER_ID_HEADER: 'nhsd-supplier-id',
14-
APIM_CORRELATION_HEADER: 'nhsd-correlation-id'
15-
}
16-
}));
1716

1817
describe('API Lambda handler', () => {
1918

19+
const mockedDeps: jest.Mocked<Deps> = {
20+
s3Client: {} as unknown as S3Client,
21+
letterRepo: {} as unknown as LetterRepository,
22+
logger: { info: jest.fn(), error: jest.fn() } as unknown as pino.Logger,
23+
env: {
24+
SUPPLIER_ID_HEADER: 'nhsd-supplier-id',
25+
APIM_CORRELATION_HEADER: 'nhsd-correlation-id',
26+
LETTERS_TABLE_NAME: 'LETTERS_TABLE_NAME',
27+
LETTER_TTL_HOURS: 12960,
28+
DOWNLOAD_URL_TTL_SECONDS: 60,
29+
MAX_LIMIT: 2500
30+
} as unknown as EnvVars
31+
};
32+
2033
beforeEach(() => {
2134
jest.clearAllMocks();
2235
jest.resetModules();
@@ -33,9 +46,10 @@ describe('API Lambda handler', () => {
3346
});
3447

3548
const event = makeApiGwEvent({path: '/letters/id1',
36-
headers: {'nhsd-supplier-id': 'supplier1', 'nhsd-correlation-id': 'correlationId'},
49+
headers: {'nhsd-supplier-id': 'supplier1', 'nhsd-correlation-id': 'correlationId', 'x-request-id': 'requestId'},
3750
pathParameters: {id: 'id1'}});
3851

52+
const getLetter = createGetLetterHandler(mockedDeps);
3953
const result = await getLetter(event, mockDeep<Context>(), jest.fn());
4054

4155
const expected = {
@@ -69,12 +83,12 @@ describe('API Lambda handler', () => {
6983
});
7084

7185
const event = makeApiGwEvent({path: '/letters/id1',
72-
headers: {'nhsd-supplier-id': 'supplier1', 'nhsd-correlation-id': 'correlationId'},
86+
headers: {'nhsd-supplier-id': 'supplier1', 'nhsd-correlation-id': 'correlationId', 'x-request-id': 'requestId'},
7387
pathParameters: {id: 'id1'}});
7488

89+
const getLetter = createGetLetterHandler(mockedDeps);
7590
const result = await getLetter(event, mockDeep<Context>(), jest.fn());
7691

77-
7892
const expected = {
7993
data: {
8094
id: 'id1',
@@ -103,9 +117,10 @@ describe('API Lambda handler', () => {
103117
});
104118

105119
const event = makeApiGwEvent({path: '/letters/id1',
106-
headers: {'nhsd-supplier-id': 'supplier1', 'nhsd-correlation-id': 'correlationId'},
120+
headers: {'nhsd-supplier-id': 'supplier1', 'nhsd-correlation-id': 'correlationId', 'x-request-id': 'requestId'},
107121
pathParameters: {id: 'id1'}});
108122

123+
const getLetter = createGetLetterHandler(mockedDeps);
109124
const result = await getLetter(event, mockDeep<Context>(), jest.fn());
110125

111126
expect(result).toEqual(expect.objectContaining({
@@ -115,33 +130,36 @@ describe('API Lambda handler', () => {
115130

116131
it ('returns 500 when correlation id is missing from header', async() => {
117132
const event = makeApiGwEvent({path: '/letters/id1',
118-
headers: {'nhsd-supplier-id': 'supplier1'},
133+
headers: {'nhsd-supplier-id': 'supplier1', 'x-request-id': 'requestId'},
119134
pathParameters: {id: 'id1'}});
120135

136+
const getLetter = createGetLetterHandler(mockedDeps);
121137
const result = await getLetter(event, mockDeep<Context>(), jest.fn());
122138

123139
expect(result).toEqual(expect.objectContaining({
124140
statusCode: 500,
125141
}));
126142
});
127143

128-
it ('returns 400 when supplier id is missing from header', async() => {
144+
it ('returns 500 when supplier id is missing from header', async() => {
129145
const event = makeApiGwEvent({path: '/letters/id1',
130-
headers: {'nhsd-correlation-id': 'correlationId'},
146+
headers: {'nhsd-correlation-id': 'correlationId', 'x-request-id': 'requestId'},
131147
pathParameters: {id: 'id1'}});
132148

149+
const getLetter = createGetLetterHandler(mockedDeps);
133150
const result = await getLetter(event, mockDeep<Context>(), jest.fn());
134151

135152
expect(result).toEqual(expect.objectContaining({
136-
statusCode: 400,
153+
statusCode: 500,
137154
}));
138155
});
139156

140157

141158
it ('returns 400 when letter id is missing from path', async() => {
142159
const event = makeApiGwEvent({path: '/letters/id1',
143-
headers: {'nhsd-supplier-id': 'supplier1', 'nhsd-correlation-id': 'correlationId'}});
160+
headers: {'nhsd-supplier-id': 'supplier1', 'nhsd-correlation-id': 'correlationId', 'x-request-id': 'requestId'}});
144161

162+
const getLetter = createGetLetterHandler(mockedDeps);
145163
const result = await getLetter(event, mockDeep<Context>(), jest.fn());
146164

147165
expect(result).toEqual(expect.objectContaining({
Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,33 @@
1-
import pino from "pino";
2-
import { createLetterRepository } from "../infrastructure/letter-repo-factory";
31
import { APIGatewayProxyHandler } from "aws-lambda";
4-
import { assertNotEmpty, lowerCaseKeys } from "../utils/validation";
5-
import { lambdaConfig } from "../config/lambda-config";
2+
import { assertNotEmpty, validateCommonHeaders } from "../utils/validation";
63
import { ValidationError } from "../errors";
74
import { ApiErrorDetail } from "../contracts/errors";
85
import { getLetterById } from "../services/letter-operations";
96
import { mapErrorToResponse } from "../mappers/error-mapper";
107
import { mapToGetLetterResponse } from "../mappers/letter-mapper";
8+
import { Deps } from "../config/deps";
119

1210

13-
const letterRepo = createLetterRepository();
14-
const log = pino();
11+
export function createGetLetterHandler(deps: Deps): APIGatewayProxyHandler {
1512

16-
export const getLetter: APIGatewayProxyHandler = async (event) => {
13+
return async (event) => {
1714

18-
let correlationId;
19-
try {
20-
assertNotEmpty(event.headers, new Error("The request headers are empty"));
21-
const lowerCasedHeaders = lowerCaseKeys(event.headers);
22-
23-
correlationId = assertNotEmpty(lowerCasedHeaders[lambdaConfig.APIM_CORRELATION_HEADER],
24-
new Error("The request headers don't contain the APIM correlation id"));
15+
const commonHeadersResult = validateCommonHeaders(event.headers, deps);
2516

26-
const supplierId = assertNotEmpty(lowerCasedHeaders[lambdaConfig.SUPPLIER_ID_HEADER],
27-
new ValidationError(ApiErrorDetail.InvalidRequestMissingSupplierId));
17+
if (!commonHeadersResult.ok) {
18+
return mapErrorToResponse(commonHeadersResult.error, commonHeadersResult.correlationId, deps.logger);
19+
}
2820

21+
try {
2922
const letterId = assertNotEmpty(event.pathParameters?.id, new ValidationError(ApiErrorDetail.InvalidRequestMissingLetterIdPathParameter));
3023

31-
const letter = await getLetterById(supplierId, letterId, letterRepo);
24+
const letter = await getLetterById(commonHeadersResult.value.supplierId, letterId, deps.letterRepo);
3225

3326
const response = mapToGetLetterResponse(letter);
3427

35-
log.info({
28+
deps.logger.info({
3629
description: 'Letter successfully fetched by id',
37-
supplierId,
30+
supplierId: commonHeadersResult.value.supplierId,
3831
letterId
3932
});
4033

@@ -44,6 +37,7 @@ export const getLetter: APIGatewayProxyHandler = async (event) => {
4437
};
4538
} catch (error)
4639
{
47-
return mapErrorToResponse(error, correlationId);
40+
return mapErrorToResponse(error, commonHeadersResult.value.correlationId, deps.logger);
4841
}
42+
}
4943
}

lambdas/api-handler/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { createPatchLetterHandler } from "./handlers/patch-letter";
66

77
const container = createDependenciesContainer();
88

9-
export const getLetterHandler = createGetLetterHandler(container);
9+
export const getLetter = createGetLetterHandler(container);
1010
export const getLetterData = createGetLetterDataHandler(container);
1111
export const getLetters = createGetLettersHandler(container);
1212
export const patchLetter = createPatchLetterHandler(container);

0 commit comments

Comments
 (0)