Skip to content

Commit ed17066

Browse files
committed
Fixes
1 parent 08d5f3d commit ed17066

6 files changed

Lines changed: 31 additions & 80 deletions

File tree

infrastructure/terraform/components/api/locals.tf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ locals {
2222
common_lambda_env_vars = {
2323
LETTERS_TABLE_NAME = aws_dynamodb_table.letters.name,
2424
LETTER_QUEUE_TABLE_NAME = aws_dynamodb_table.letter_queue.name,
25-
LETTER_QUEUE_VISIBILITY_TIMEOUT = 600, # 1O minutes * 60 seconds
25+
LETTER_QUEUE_VISIBILITY_TIMEOUT = 600, # 10 minutes * 60 seconds
2626
MI_TABLE_NAME = aws_dynamodb_table.mi.name,
2727
LETTER_TTL_HOURS = 12960, # 18 months * 30 days * 24 hours
28-
LETTER_QUEUE_TTL_HOURS = 168 # 7 days * 24 days
28+
LETTER_QUEUE_TTL_HOURS = 168 # 7 days * 24 hours
2929
MI_TTL_HOURS = 2160 # 90 days * 24 hours
3030
SUPPLIER_ID_HEADER = "nhsd-supplier-id",
3131
APIM_CORRELATION_HEADER = "nhsd-correlation-id",

internal/datastore/src/__test__/letter-queue-repository.test.ts

Lines changed: 11 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -159,44 +159,28 @@ describe("LetterQueueRepository", () => {
159159

160160
describe("updateLetterTimestamp", () => {
161161
it("updates the queueTimestamp on an existing letter", async () => {
162-
jest.useFakeTimers().setSystemTime(new Date("2026-03-04T13:15:45.000Z"));
163-
await letterQueueRepository.putLetter(createLetter());
162+
const pendingLetter =
163+
await letterQueueRepository.putLetter(createLetter());
164164

165165
await letterQueueRepository.updateLetterTimestamp(
166-
"supplier1",
167-
"letter1",
168-
600,
166+
pendingLetter,
167+
new Date("2026-03-04T13:15:45.000Z"),
169168
);
170169

171170
const letter = await getLetter(db, "supplier1", "letter1");
172-
expect(letter?.queueTimestamp).toBe("2026-03-04T13:25:45.000Z");
173-
});
174-
175-
it("throws LetterDoesNotExistError when the letter does not exist", async () => {
176-
await expect(
177-
letterQueueRepository.updateLetterTimestamp("supplier1", "letter1", 60),
178-
).rejects.toThrow(LetterDoesNotExistError);
171+
expect(letter?.queueTimestamp).toBe("2026-03-04T13:15:45.000Z");
179172
});
180173

181-
it("does nothing when the letter is deleted before it can be updated", async () => {
182-
jest.spyOn(db.docClient, "send").mockImplementationOnce((_) => ({
183-
// Fake the existence of the letter for the GetCommand
184-
Item: {
185-
...createLetter(),
186-
queueTimestamp: "2026-03-04T13:15:45.000Z",
187-
},
188-
}));
189-
174+
it("does nothing when the letter does not exist", async () => {
190175
await letterQueueRepository.updateLetterTimestamp(
191-
"supplier1",
192-
"letter1",
193-
60,
176+
createLetter(),
177+
new Date(),
194178
);
195179

196180
expect(await letterExists(db, "supplier1", "letter1")).toBe(false);
197181
});
198182

199-
it("rethrows errors from DynamoDB when getting the letter", async () => {
183+
it("rethrows errors from DynamoDB when updating the letter", async () => {
200184
const misconfiguredRepository = new LetterQueueRepository(
201185
db.docClient,
202186
logger,
@@ -207,27 +191,11 @@ describe("LetterQueueRepository", () => {
207191
);
208192
await expect(
209193
misconfiguredRepository.updateLetterTimestamp(
210-
"supplier1",
211-
"letter1",
212-
60,
194+
createLetter(),
195+
new Date(),
213196
),
214197
).rejects.toThrow("Cannot do operations on a non-existent table");
215198
});
216-
217-
it("rethrows errors from DynamoDB when updating the error", async () => {
218-
await letterQueueRepository.putLetter(createLetter());
219-
const originalSend = db.docClient.send.bind(db.docClient);
220-
jest
221-
.spyOn(db.docClient, "send")
222-
.mockImplementationOnce(originalSend)
223-
.mockImplementationOnce((_) => {
224-
throw new Error("error");
225-
});
226-
227-
await expect(
228-
letterQueueRepository.updateLetterTimestamp("supplier1", "letter1", 60),
229-
).rejects.toThrow("error");
230-
});
231199
});
232200
});
233201

internal/datastore/src/letter-queue-repository.ts

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import {
22
DeleteCommand,
33
DynamoDBDocumentClient,
4-
GetCommand,
54
PutCommand,
65
QueryCommand,
76
UpdateCommand,
@@ -98,35 +97,21 @@ export default class LetterQueueRepository {
9897
}
9998

10099
async updateLetterTimestamp(
101-
supplierId: string,
102-
letterId: string,
103-
seconds: number,
100+
pendingLetter: PendingLetterBase,
101+
timestamp: Date,
104102
): Promise<void> {
105-
const item = await this.ddbClient.send(
106-
new GetCommand({
107-
TableName: this.config.letterQueueTableName,
108-
Key: { supplierId, letterId },
109-
}),
110-
);
111-
112-
if (!item.Item) {
113-
throw new LetterDoesNotExistError(supplierId, letterId);
114-
}
115-
116-
const currentTimestamp = new Date(item.Item.queueTimestamp).getTime();
117-
const updatedTimestamp = new Date(
118-
currentTimestamp + seconds * 1000,
119-
).toISOString();
120-
121103
try {
122104
await this.ddbClient.send(
123105
new UpdateCommand({
124106
TableName: this.config.letterQueueTableName,
125-
Key: { supplierId, letterId },
107+
Key: {
108+
supplierId: pendingLetter.supplierId,
109+
letterId: pendingLetter.letterId,
110+
},
126111
UpdateExpression: "SET queueTimestamp = :ts",
127112
ConditionExpression: "attribute_exists(letterId)",
128113
ExpressionAttributeValues: {
129-
":ts": updatedTimestamp,
114+
":ts": timestamp.toISOString(),
130115
},
131116
}),
132117
);

lambdas/api-handler/src/config/__tests__/env.test.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ describe("lambdaEnv", () => {
2121
process.env.LETTERS_TABLE_NAME = "letters-table";
2222
process.env.LETTER_QUEUE_TABLE_NAME = "letter-queue-table";
2323
process.env.MI_TABLE_NAME = "mi-table";
24-
process.env.LETTER_QUEUE_TABLE_NAME = "letter-queue-table";
25-
process.env.MI_TABLE_NAME = "mi-table";
2624
process.env.LETTER_TTL_HOURS = "12960";
2725
process.env.LETTER_QUEUE_TTL_HOURS = "240";
2826
process.env.MI_TTL_HOURS = "2160";

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

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,17 @@ function makeLetter(id: string, status: Letter["status"]): Letter {
4444
};
4545
}
4646

47+
afterEach(async () => {
48+
jest.useRealTimers();
49+
});
50+
4751
describe("getPendingLetters", () => {
4852
beforeEach(() => {
4953
jest.clearAllMocks();
5054
});
5155

5256
it("returns letters from the letter queue repository", async () => {
57+
jest.useFakeTimers().setSystemTime(new Date("2026-03-04T13:15:45.000Z"));
5358
const mockRepo = {
5459
getLetters: jest.fn().mockResolvedValue([
5560
{
@@ -78,15 +83,13 @@ describe("getPendingLetters", () => {
7883
expect(mockRepo.getLetters).toHaveBeenCalledWith("supplier1", 10);
7984
expect(mockRepo.updateLetterTimestamp).toHaveBeenNthCalledWith(
8085
1,
81-
"supplier1",
82-
"id1",
83-
600,
86+
expect.objectContaining({ supplierId: "supplier1", letterId: "id1" }),
87+
new Date("2026-03-04T13:25:45.000Z"),
8488
);
8589
expect(mockRepo.updateLetterTimestamp).toHaveBeenNthCalledWith(
8690
2,
87-
"supplier1",
88-
"id2",
89-
600,
91+
expect.objectContaining({ supplierId: "supplier1", letterId: "id2" }),
92+
new Date("2026-03-04T13:25:45.000Z"),
9093
);
9194
expect(result).toEqual([
9295
{ id: "id1", status: "PENDING", specificationId: "s1", groupId: "g1" },

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

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,9 @@ export const getPendingLetters = async (
5252
visibilityTimeout: number,
5353
): Promise<LetterBase[]> => {
5454
const pendingLetters = await letterQueueRepo.getLetters(supplierId, limit);
55+
const timestamp = new Date(Date.now() + visibilityTimeout * 1000);
5556
for (const letter of pendingLetters) {
56-
await letterQueueRepo.updateLetterTimestamp(
57-
letter.supplierId,
58-
letter.letterId,
59-
visibilityTimeout,
60-
);
57+
await letterQueueRepo.updateLetterTimestamp(letter, timestamp);
6158
}
6259
return pendingLetters.map((letter) => mapPendingLetterToLetterBase(letter));
6360
};

0 commit comments

Comments
 (0)