Skip to content

Commit c61f357

Browse files
check letter queue; fix lock file
1 parent 1c54f65 commit c61f357

3 files changed

Lines changed: 110 additions & 12 deletions

File tree

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/component-tests/integration-tests/urgent-letter-priority.spec.ts

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,23 @@ import { sendSnsEvent } from "tests/helpers/send-sns-event";
33
import { createPreparedV1Event } from "tests/helpers/event-fixtures";
44
import { randomUUID } from "node:crypto";
55
import { logger } from "tests/helpers/pino-logger";
6-
import { createValidRequestHeaders } from "tests/constants/request-headers";
6+
// import { createValidRequestHeaders } from "tests/constants/request-headers";
77
import getRestApiGatewayBaseUrl from "tests/helpers/aws-gateway-helper";
8-
import { SUPPLIER_LETTERS } from "tests/constants/api-constants";
8+
// import { SUPPLIER_LETTERS } from "tests/constants/api-constants";
99
import { pollForLetterStatus } from "tests/helpers/poll-for-letters-helper";
1010
import { pollSupplierAllocatorLogForResolvedSpec } from "tests/helpers/aws-cloudwatch-helper";
11-
import {
12-
GetLettersResponse,
13-
GetLettersResponseSchema,
14-
} from "../../../lambdas/api-handler/src/contracts/letters";
11+
import { getLettersFromQueueViaIndex } from "tests/helpers/generate-fetch-test-data";
12+
// import {
13+
// GetLettersResponse,
14+
// GetLettersResponseSchema,
15+
// } from "../../../lambdas/api-handler/src/contracts/letters";
1516
import {
1617
AllocatedLetter,
1718
AllocatedLetterSchema,
1819
} from "../../../lambdas/upsert-letter/src/handler/schemas";
1920

20-
// See group_nhs-notify-supplier-api-dev.tfvars in nhs-notify-internal
21+
// Values for CI/CD are kept in group_nhs-notify-supplier-api-dev.tfvars in the nhs-notify-internal repo
22+
// If running locally see default of variant_map in infrastructure/terraform/components/api/variables.tf
2123
const variantUrgencyMap: Record<string, number> = {
2224
"digitrials-aspiring": 0,
2325
"digitrials-dmapp": 1,
@@ -39,8 +41,6 @@ const variantUrgencyMap: Record<string, number> = {
3941
"notify-standard": 98,
4042
"notify-standard-colour": 99,
4143
};
42-
43-
// See group_nhs-notify-supplier-api-dev.tfvars in nhs-notify-internal
4444
const supplier = "supplier1";
4545

4646
let baseUrl: string;
@@ -68,6 +68,17 @@ test.describe("Urgent Letter Priority Tests", () => {
6868
await verifyAllocationLogsContainPriority(urgencyNineLetterIds, 9);
6969
await verifyAllocationLogsContainPriority(urgencyTenLetterIds, 10);
7070

71+
const lettersFromQueue = await getLettersFromQueueViaIndex(supplier);
72+
const letterIdsFromQueue = lettersFromQueue.map(
73+
(letter) => letter.letterId,
74+
);
75+
76+
verifyIndexPositionOfLetterVariants(
77+
letterIdsFromQueue,
78+
urgencyNineLetterIds,
79+
urgencyTenLetterIds,
80+
);
81+
7182
// TODO: CCM-15185 should call the endpoint directly to verify the order of letters
7283
// const header = createValidRequestHeaders(supplier);
7384
// const response = await request.get(`${baseUrl}/${SUPPLIER_LETTERS}`, {
@@ -81,6 +92,8 @@ test.describe("Urgent Letter Priority Tests", () => {
8192
// const getLettersResponse: GetLettersResponse =
8293
// GetLettersResponseSchema.parse(responseBody);
8394

95+
// const letterIds = getLettersResponse.data.map((letter) => letter.id);
96+
8497
// verifyIndexPositionOfLetterVariants(
8598
// getLettersResponse,
8699
// urgencyNineLetterIds,
@@ -120,11 +133,10 @@ async function sendEventsForVariants(variants: string[]) {
120133
}
121134

122135
function verifyIndexPositionOfLetterVariants(
123-
getLettersResponse: GetLettersResponse,
136+
letterIds: string[],
124137
letterIdsLeastUrgency: string[],
125138
letterIdsHigherUrgency: string[],
126139
) {
127-
const letterIds = getLettersResponse.data.map((letter) => letter.id);
128140
for (const leastUrgencyLetterId of letterIdsLeastUrgency) {
129141
expect(letterIds).toContain(leastUrgencyLetterId); // in case limit param is hit
130142
const indexToTest = letterIds.indexOf(leastUrgencyLetterId);

tests/helpers/generate-fetch-test-data.ts

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,21 @@ import {
1313
} from "../constants/api-constants";
1414
import { createSupplierData, runCreateLetter } from "./pnpm-helpers";
1515
import { logger } from "./pino-logger";
16+
import z from "zod";
1617

1718
const ddb = new DynamoDBClient({});
1819
const docClient = DynamoDBDocumentClient.from(ddb);
1920

21+
export const PendingLetterSchema = z.object({
22+
supplierId: z.string(),
23+
letterId: z.string(),
24+
queueTimestamp: z.string(),
25+
visibilityTimestamp: z.string(),
26+
queueSortOrderSk: z.string().describe("Secondary index SK"),
27+
priority: z.int().min(0).max(99).optional(),
28+
});
29+
export type PendingLetter = z.infer<typeof PendingLetterSchema>;
30+
2031
export interface SupplierApiLetters {
2132
supplierId: string;
2233
specificationId: string;
@@ -211,3 +222,78 @@ export async function checkLetterQueueTable(
211222
return [false];
212223
}
213224
}
225+
226+
export async function getLettersFromQueueViaIndex(
227+
supplierId: string,
228+
): Promise<PendingLetter[]> {
229+
const MAX_ATTEMPTS = 5;
230+
const RETRY_DELAY_MS = 10_000;
231+
232+
try {
233+
const params = {
234+
TableName: LETTERQUEUE_TABLENAME,
235+
IndexName: "queueSortOrder-index",
236+
KeyConditionExpression:
237+
"supplierId = :supplierId",
238+
ExpressionAttributeValues: {
239+
":supplierId": supplierId
240+
},
241+
};
242+
243+
for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
244+
const { Items } = await docClient.send(new QueryCommand(params));
245+
246+
if (Items !== undefined && Items.length > 0) {
247+
logger.info(
248+
`Queried letter queue table to verify existence for supplier ${supplierId} and found items.`,
249+
);
250+
251+
return z.array(PendingLetterSchema).parse(Items);
252+
}
253+
if (attempt < MAX_ATTEMPTS) {
254+
logger.info(
255+
`Retrying get letters from queue for supplierId ${supplierId} in ${RETRY_DELAY_MS}ms`,
256+
);
257+
await delay(RETRY_DELAY_MS);
258+
}
259+
}
260+
return [];
261+
} catch (error) {
262+
logger.error({ supplierId, error }, "Letter queue query failed");
263+
return [];
264+
}
265+
}
266+
267+
// async getLetters(
268+
// supplierId: string,
269+
// limit: number,
270+
// ): Promise<PendingLetter[]> {
271+
// const letters: PendingLetter[] = [];
272+
// let lastEvaluatedKey: Record<string, unknown> | undefined;
273+
274+
// do {
275+
// const result = await this.ddbClient.send(
276+
// new QueryCommand({
277+
// TableName: this.config.letterQueueTableName,
278+
// IndexName: "queueSortOrder-index",
279+
// KeyConditionExpression: "supplierId = :supplierId",
280+
// FilterExpression: "visibilityTimestamp < :now",
281+
// ExpressionAttributeValues: {
282+
// ":supplierId": supplierId,
283+
// ":now": new Date().toISOString(),
284+
// },
285+
// // 1000 is a compromise - a smaller number might result in a lot of round trips, a larger one might
286+
// // entail fetching and then throwing away a lot of data
287+
// Limit: this.config.queryPageSize ?? 1000,
288+
// ExclusiveStartKey: lastEvaluatedKey,
289+
// }),
290+
// );
291+
292+
// const page = z.array(PendingLetterSchema).parse(result.Items);
293+
// letters.push(...page);
294+
295+
// lastEvaluatedKey = result.LastEvaluatedKey;
296+
// } while (lastEvaluatedKey !== undefined && letters.length < limit);
297+
298+
// return letters.slice(0, limit);
299+
// }

0 commit comments

Comments
 (0)