1+ import { GetCommand } from "@aws-sdk/lib-dynamodb" ;
12import { Logger } from "pino" ;
23import {
34 DBContext ,
78} from "./db" ;
89import LetterQueueRepository from "../letter-queue-repository" ;
910import { InsertPendingLetter } from "../types" ;
10- import { LetterAlreadyExistsError } from "../errors " ;
11+ import { LetterAlreadyExistsError } from "../letter-already-exists-error " ;
1112import { createTestLogger } from "./logs" ;
13+ import { LetterDoesNotExistError } from "../letter-does-not-exist-error" ;
1214
1315function createLetter ( letterId = "letter1" ) : InsertPendingLetter {
1416 return {
@@ -51,32 +53,19 @@ describe("LetterQueueRepository", () => {
5153 await db . container . stop ( ) ;
5254 } ) ;
5355
54- function assertTtl ( ttl : number , before : number , after : number ) {
55- const expectedLower = Math . floor (
56- before / 1000 + 60 * 60 * db . config . letterQueueTtlHours ,
57- ) ;
58- const expectedUpper = Math . floor (
59- after / 1000 + 60 * 60 * db . config . lettersTtlHours ,
60- ) ;
61- expect ( ttl ) . toBeGreaterThanOrEqual ( expectedLower ) ;
62- expect ( ttl ) . toBeLessThanOrEqual ( expectedUpper ) ;
63- }
64-
6556 describe ( "putLetter" , ( ) => {
6657 it ( "adds a letter to the database" , async ( ) => {
67- const before = Date . now ( ) ;
58+ jest . useFakeTimers ( ) . setSystemTime ( new Date ( "2026-03-04T13:15:45.000Z" ) ) ;
6859
6960 const pendingLetter =
7061 await letterQueueRepository . putLetter ( createLetter ( ) ) ;
7162
72- const after = Date . now ( ) ;
73-
74- const timestampInMillis = new Date (
75- pendingLetter . queueTimestamp ,
76- ) . valueOf ( ) ;
77- expect ( timestampInMillis ) . toBeGreaterThanOrEqual ( before ) ;
78- expect ( timestampInMillis ) . toBeLessThanOrEqual ( after ) ;
79- assertTtl ( pendingLetter . ttl , before , after ) ;
63+ expect ( pendingLetter . queueTimestamp ) . toBe ( "2026-03-04T13:15:45.000Z" ) ;
64+ expect ( pendingLetter . visibilityTimestamp ) . toBe (
65+ "2026-03-04T13:15:45.000Z" ,
66+ ) ;
67+ expect ( pendingLetter . ttl ) . toBe ( 1_772_633_745 ) ;
68+ expect ( await letterExists ( db , "supplier1" , "letter1" ) ) . toBe ( true ) ;
8069 } ) ;
8170
8271 it ( "throws LetterAlreadyExistsError when creating a letter which already exists" , async ( ) => {
@@ -101,4 +90,48 @@ describe("LetterQueueRepository", () => {
10190 ) . rejects . toThrow ( "Cannot do operations on a non-existent table" ) ;
10291 } ) ;
10392 } ) ;
93+
94+ describe ( "deleteLetter" , ( ) => {
95+ it ( "deletes a letter from the database" , async ( ) => {
96+ await letterQueueRepository . putLetter ( createLetter ( ) ) ;
97+
98+ await letterQueueRepository . deleteLetter ( "supplier1" , "letter1" ) ;
99+
100+ expect ( await letterExists ( db , "supplier1" , "letter1" ) ) . toBe ( false ) ;
101+ } ) ;
102+
103+ it ( "throws an error when the letter does not exist" , async ( ) => {
104+ await expect (
105+ letterQueueRepository . deleteLetter ( "supplier1" , "letter1" ) ,
106+ ) . rejects . toThrow ( LetterDoesNotExistError ) ;
107+ } ) ;
108+
109+ it ( "rethrows errors from DynamoDB when deleting a letter" , async ( ) => {
110+ const misconfiguredRepository = new LetterQueueRepository (
111+ db . docClient ,
112+ logger ,
113+ {
114+ ...db . config ,
115+ letterQueueTableName : "nonexistent-table" ,
116+ } ,
117+ ) ;
118+ await expect (
119+ misconfiguredRepository . deleteLetter ( "supplier1" , "letter1" ) ,
120+ ) . rejects . toThrow ( "Cannot do operations on a non-existent table" ) ;
121+ } ) ;
122+ } ) ;
104123} ) ;
124+
125+ async function letterExists (
126+ db : DBContext ,
127+ supplierId : string ,
128+ letterId : string ,
129+ ) : Promise < boolean > {
130+ const result = await db . docClient . send (
131+ new GetCommand ( {
132+ TableName : db . config . letterQueueTableName ,
133+ Key : { supplierId, letterId } ,
134+ } ) ,
135+ ) ;
136+ return result . Item !== undefined ;
137+ }
0 commit comments