@@ -494,6 +494,7 @@ describe("LetterRepository", () => {
494494 await checkLetterStatus ( "supplier1" , "letter59" , "PENDING" ) ;
495495 } ) ;
496496
497+ // eslint-disable-next-line jest/expect-expect
497498 test ( "should skip array gaps" , async ( ) => {
498499 const letters = [ ] ;
499500 letters [ 0 ] = createLetter ( "supplier1" , "letter1" ) ;
@@ -516,4 +517,71 @@ describe("LetterRepository", () => {
516517 ] ) ,
517518 ) . rejects . toThrow ( "Cannot do operations on a non-existent table" ) ;
518519 } ) ;
520+
521+ test ( "should paginate through multiple pages when fetching letters by supplier" , async ( ) => {
522+ const mockSend = jest
523+ . fn ( )
524+ // first call returns 30 items with a LastEvaluatedKey
525+ . mockResolvedValueOnce ( {
526+ Items : Array . from ( { length : 30 } , ( _ , i ) => ( {
527+ id : `letter${ ( i + 1 ) . toString ( ) . padStart ( 3 , "0" ) } ` ,
528+ status : "PENDING" ,
529+ specificationId : "specification1" ,
530+ groupId : "group1" ,
531+ } ) ) ,
532+ LastEvaluatedKey : { id : "letter030" , supplierId : "supplier1" } ,
533+ } )
534+ // second call returns remaining 20 items without LastEvaluatedKey
535+ . mockResolvedValueOnce ( {
536+ Items : Array . from ( { length : 20 } , ( _ , i ) => ( {
537+ id : `letter${ ( i + 31 ) . toString ( ) . padStart ( 3 , "0" ) } ` ,
538+ status : "PENDING" ,
539+ specificationId : "specification1" ,
540+ groupId : "group1" ,
541+ } ) ) ,
542+ LastEvaluatedKey : undefined ,
543+ } ) ;
544+
545+ const mockDdbClient = { send : mockSend } as any ;
546+ const repo = new LetterRepository ( mockDdbClient , logger , db . config ) ;
547+
548+ // request 50 letters - should require 2 DynamoDB queries due to mocked pagination
549+ const letters = await repo . getLettersBySupplier ( "supplier1" , "PENDING" , 50 ) ;
550+
551+ // verify all 50 letters were returned
552+ expect ( letters ) . toHaveLength ( 50 ) ;
553+
554+ // verify two send calls were made (2 pages)
555+ expect ( mockSend ) . toHaveBeenCalledTimes ( 2 ) ;
556+
557+ // verify the second call included the ExclusiveStartKey from first response
558+ const secondCallInput = mockSend . mock . calls [ 1 ] [ 0 ] . input ;
559+ expect ( secondCallInput . ExclusiveStartKey ) . toEqual ( {
560+ id : "letter030" ,
561+ supplierId : "supplier1" ,
562+ } ) ;
563+ } ) ;
564+
565+ test ( "should respect limit when fewer items available than requested" , async ( ) => {
566+ // create only 10 letters
567+ for ( let i = 1 ; i <= 10 ; i ++ ) {
568+ await letterRepository . putLetter (
569+ createLetter (
570+ "supplier1" ,
571+ `letter${ i . toString ( ) . padStart ( 2 , "0" ) } ` ,
572+ "PENDING" ,
573+ ) ,
574+ ) ;
575+ }
576+
577+ // request 50 letters but only 10 exist
578+ const letters = await letterRepository . getLettersBySupplier (
579+ "supplier1" ,
580+ "PENDING" ,
581+ 50 ,
582+ ) ;
583+
584+ expect ( letters ) . toHaveLength ( 10 ) ;
585+ expect ( letters . every ( ( l ) => l . status === "PENDING" ) ) . toBe ( true ) ;
586+ } ) ;
519587} ) ;
0 commit comments