Skip to content

Commit 31c1fe3

Browse files
Integrate get and patch branches
1 parent 829b599 commit 31c1fe3

File tree

6 files changed

+72
-20
lines changed

6 files changed

+72
-20
lines changed

.vscode/launch.json

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,10 @@
77
],
88
"console": "integratedTerminal",
99
"cwd": "${workspaceFolder}/${input:workspace}",
10-
"disableOptimisticBPs": true,
1110
"internalConsoleOptions": "neverOpen",
1211
"name": "Debug current test file (pick workspace)",
1312
"program": "${workspaceFolder}/node_modules/.bin/jest",
1413
"request": "launch",
15-
"runtimeArgs": [
16-
"run",
17-
"test:unit",
18-
"--"
19-
],
20-
"runtimeExecutable": "npm",
2114
"type": "node"
2215
},
2316
{
@@ -29,17 +22,10 @@
2922
],
3023
"console": "integratedTerminal",
3124
"cwd": "${workspaceFolder}/${input:workspace}",
32-
"disableOptimisticBPs": true,
3325
"internalConsoleOptions": "neverOpen",
3426
"name": "Debug single test by name (pick workspace)",
3527
"program": "${workspaceFolder}/node_modules/.bin/jest",
3628
"request": "launch",
37-
"runtimeArgs": [
38-
"run",
39-
"test:unit",
40-
"--"
41-
],
42-
"runtimeExecutable": "npm",
4329
"type": "node"
4430
}
4531
],

lambdas/api-handler/src/contracts/errors.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,9 @@ export enum ApiErrorDetail {
3434
InvalidRequestMissingLetterIdPathParameter = 'The request is missing the letter id path parameter',
3535
InvalidRequestLetterIdsMismatch = 'The letter ID in the request body does not match the letter ID path parameter',
3636
InvalidRequestBody = 'The request body is invalid',
37-
InvalidRequestLimitNotANumber = "The limit parameter is not a number",
38-
InvalidRequestLimitNotPositive = "The limit parameter is not positive"
37+
InvalidRequestLimitNotANumber = 'The limit parameter is not a number',
38+
InvalidRequestLimitNotInRange = 'The limit parameter must be a positive number not greater than %s',
39+
InvalidRequestLimitOnly = "Only 'limit' query parameter is supported"
3940
}
4041

4142
export function buildApiError(params: {

lambdas/api-handler/src/mappers/__tests__/error-mapper.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ describe("mapErrorToResponse", () => {
3535
"errors": [
3636
{
3737
"code": "NOTIFY_LETTER_NOT_FOUND",
38-
"detail": "The provided letter ID does not exist",
38+
"detail": "The provided letter ID does not exist for the supplier",
3939
"id": expect.any(String),
4040
"links": {
4141
"about": "https://digital.nhs.uk/developer/api-catalogue/nhs-notify-supplier"

lambdas/api-handler/src/services/__tests__/letter-operations.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ describe('patchLetterStatus function', () => {
8484

8585
it('should throw notFoundError when letter does not exist', async () => {
8686
const mockRepo = {
87-
updateLetterStatus: jest.fn().mockRejectedValue(new Error('not found'))
87+
updateLetterStatus: jest.fn().mockRejectedValue(new Error('Letter with id l1 not found for supplier s1'))
8888
};
8989

9090
await expect(patchLetterStatus(letterResource, 'letter1', 'supplier1', mockRepo as any)).rejects.toThrow("The provided letter ID does not exist");
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { assertNotEmpty } from "../validation";
2+
import { ValidationError } from "../../errors";
3+
import { ApiErrorDetail } from "../../contracts/errors";
4+
5+
describe("assertNotEmpty", () => {
6+
const detail = ApiErrorDetail.NotFoundLetterId;
7+
8+
it("throws for null", () => {
9+
expect(() => assertNotEmpty(null, detail)).toThrow(ValidationError);
10+
});
11+
12+
it("throws for undefined", () => {
13+
expect(() => assertNotEmpty(undefined, detail)).toThrow(ValidationError);
14+
});
15+
16+
it("throws for empty string", () => {
17+
expect(() => assertNotEmpty("", detail)).toThrow(ValidationError);
18+
});
19+
20+
it("throws for whitespace string", () => {
21+
expect(() => assertNotEmpty(" ", detail)).toThrow(ValidationError);
22+
});
23+
24+
it("returns non-empty string", () => {
25+
const result = assertNotEmpty("hello", detail);
26+
expect(result).toBe("hello");
27+
});
28+
29+
it("returns number", () => {
30+
const result = assertNotEmpty(42, detail);
31+
expect(result).toBe(42);
32+
});
33+
34+
it("returns object", () => {
35+
const obj = { a: 1 };
36+
const result = assertNotEmpty(obj, detail);
37+
expect(result).toBe(obj);
38+
});
39+
40+
it("returns array", () => {
41+
const arr = [1, 2, 3];
42+
const result = assertNotEmpty(arr, detail);
43+
expect(result).toBe(arr);
44+
});
45+
46+
it("does not throw for empty array (current behavior)", () => {
47+
const arr: any[] = [];
48+
const result = assertNotEmpty(arr, detail);
49+
expect(result).toBe(arr);
50+
});
51+
52+
it("does not throw for empty object (current behavior)", () => {
53+
const obj = {};
54+
const result = assertNotEmpty(obj, detail);
55+
expect(result).toBe(obj);
56+
});
57+
});
Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
import * as errors from '../contracts/errors';
22
import { ValidationError } from '../errors';
33

4-
export function assertNotEmpty(value: string | null | undefined, detail: errors.ApiErrorDetail): string {
5-
if (!value || value.trim() === '') {
4+
export function assertNotEmpty<T>(
5+
value: T | null | undefined,
6+
detail: errors.ApiErrorDetail
7+
): T {
8+
if (value == null) {
69
throw new ValidationError(detail);
710
}
11+
12+
if (typeof value === "string" && value.trim() === "") {
13+
throw new ValidationError(detail);
14+
}
15+
816
return value;
917
}

0 commit comments

Comments
 (0)