@@ -483,7 +483,8 @@ describe("supplier-config service", () => {
483483
484484 expect ( result ) . toEqual ( [ "spec1" ] ) ;
485485 } ) ;
486- it ( "throws when no eligible packs found for letter" , async ( ) => {
486+
487+ it ( "throws when no eligible packs found for letter based on sheets" , async ( ) => {
487488 const deps = makeDeps ( ) ;
488489 deps . supplierConfigRepo . getPackSpecification = jest
489490 . fn ( )
@@ -505,11 +506,15 @@ describe("supplier-config service", () => {
505506 "No eligible pack specifications found for letter variant id undefined and pack specification ids spec1" ,
506507 ) ;
507508 expect ( deps . logger . info ) . toHaveBeenCalledWith ( {
508- description : "Pack specification filtered out based on constraints" ,
509+ description : "Pack specification spec1 filtered out based on pageCount constraints" ,
509510 packSpecId : "spec1" ,
510511 pageCount : 3 ,
511- constraintValue : 2 ,
512- constraintOperator : "LESS_THAN" ,
512+ violatedConstraints : expect . arrayContaining ( [ expect . objectContaining ( {
513+ actualValue : 3 ,
514+ constraint : "sheets" ,
515+ constraintValue : 2 ,
516+ operator : "LESS_THAN" ,
517+ } ) ] ) ,
513518 } ) ;
514519 expect ( deps . logger . error ) . toHaveBeenCalledWith (
515520 expect . objectContaining ( {
@@ -519,6 +524,158 @@ describe("supplier-config service", () => {
519524 } ) ,
520525 ) ;
521526 } ) ;
527+
528+ it ( "does not filter pack specification when duplex reduces sheets and constraint is LESS_THAN_OR_EQUAL" , async ( ) => {
529+ const deps = makeDeps ( ) ;
530+ deps . supplierConfigRepo . getPackSpecification = jest
531+ . fn ( )
532+ . mockResolvedValue ( {
533+ id : "spec1" ,
534+ assembly : { duplex : true } ,
535+ constraints : {
536+ sheets : { operator : "LESS_THAN_OR_EQUAL" , value : 2 } ,
537+ } ,
538+ } as any ) ;
539+
540+ const letterEvent = {
541+ data : {
542+ pageCount : 3 ,
543+ letterVariantId : "variant-1" ,
544+ } ,
545+ } as any ;
546+
547+ const result = await filterPacksForLetter ( letterEvent , [ "spec1" ] , deps ) ;
548+
549+ expect ( result ) . toEqual ( [ "spec1" ] ) ;
550+ expect ( deps . logger . info ) . not . toHaveBeenCalled ( ) ;
551+ } ) ;
552+
553+ it ( "filters pack specification when sides fail LESS_THAN_OR_EQUAL" , async ( ) => {
554+ const deps = makeDeps ( ) ;
555+ deps . supplierConfigRepo . getPackSpecification = jest . fn ( ) . mockResolvedValue ( {
556+ id : "spec1" ,
557+ constraints : {
558+ sides : { operator : "LESS_THAN_OR_EQUAL" , value : 2 } ,
559+ } ,
560+ } as any ) ;
561+
562+ const letterEvent = {
563+ data : {
564+ pageCount : 3 ,
565+ letterVariantId : "variant-1" ,
566+ } ,
567+ } as any ;
568+
569+ await expect (
570+ filterPacksForLetter ( letterEvent , [ "spec1" ] , deps ) ,
571+ ) . rejects . toThrow ( / N o e l i g i b l e p a c k s p e c i f i c a t i o n s f o u n d / ) ;
572+
573+ expect ( deps . logger . info ) . toHaveBeenCalledWith ( {
574+ description :
575+ "Pack specification spec1 filtered out based on pageCount constraints" ,
576+ packSpecId : "spec1" ,
577+ pageCount : 3 ,
578+ violatedConstraints : expect . arrayContaining ( [
579+ expect . objectContaining ( {
580+ constraint : "sides" ,
581+ actualValue : 3 ,
582+ constraintValue : 2 ,
583+ operator : "LESS_THAN_OR_EQUAL" ,
584+ } ) ,
585+ ] ) ,
586+ } ) ;
587+ } ) ;
588+
589+ it ( "filters by sides using page count even when duplex is enabled" , async ( ) => {
590+ const deps = makeDeps ( ) ;
591+ deps . supplierConfigRepo . getPackSpecification = jest . fn ( ) . mockResolvedValue ( {
592+ id : "spec1" ,
593+ assembly : { duplex : true } ,
594+ constraints : {
595+ sheets : { operator : "LESS_THAN_OR_EQUAL" , value : 2 } ,
596+ sides : { operator : "LESS_THAN_OR_EQUAL" , value : 2 } ,
597+ } ,
598+ } as any ) ;
599+
600+ const letterEvent = {
601+ data : {
602+ pageCount : 3 ,
603+ letterVariantId : "variant-1" ,
604+ } ,
605+ } as any ;
606+
607+ await expect (
608+ filterPacksForLetter ( letterEvent , [ "spec1" ] , deps ) ,
609+ ) . rejects . toThrow ( / N o e l i g i b l e p a c k s p e c i f i c a t i o n s f o u n d / ) ;
610+
611+ expect ( deps . logger . info ) . toHaveBeenCalledWith ( {
612+ description :
613+ "Pack specification spec1 filtered out based on pageCount constraints" ,
614+ packSpecId : "spec1" ,
615+ pageCount : 3 ,
616+ violatedConstraints : expect . arrayContaining ( [
617+ expect . objectContaining ( {
618+ constraint : "sides" ,
619+ actualValue : 3 ,
620+ constraintValue : 2 ,
621+ operator : "LESS_THAN_OR_EQUAL" ,
622+ } ) ,
623+ ] ) ,
624+ } ) ;
625+ } ) ;
626+
627+ it ( "does not filter pack specification when sides is valid" , async ( ) => {
628+ const deps = makeDeps ( ) ;
629+ deps . supplierConfigRepo . getPackSpecification = jest
630+ . fn ( )
631+ . mockResolvedValue ( {
632+ id : "spec1" ,
633+ assembly : { duplex : true } ,
634+ constraints : {
635+ sheets : { operator : "LESS_THAN_OR_EQUAL" , value : 4 } ,
636+ } ,
637+ } as any ) ;
638+
639+ const letterEvent = {
640+ data : {
641+ pageCount : 3 ,
642+ letterVariantId : "variant-1" ,
643+ } ,
644+ } as any ;
645+
646+ const result = await filterPacksForLetter ( letterEvent , [ "spec1" ] , deps ) ;
647+
648+ expect ( result ) . toEqual ( [ "spec1" ] ) ;
649+ expect ( deps . logger . info ) . not . toHaveBeenCalled ( ) ;
650+ } ) ;
651+
652+ it ( "keeps pack specification when sides constraint passes" , async ( ) => {
653+ const deps = makeDeps ( ) ;
654+ deps . supplierConfigRepo . getPackSpecification = jest
655+ . fn ( )
656+ . mockResolvedValue ( {
657+ id : "spec1" ,
658+ constraints : {
659+ sides : { operator : "LESS_THAN_OR_EQUAL" , value : 3 } ,
660+ } ,
661+ } as any ) ;
662+
663+ const letterEvent = {
664+ data : {
665+ pageCount : 3 ,
666+ letterVariantId : "variant-1" ,
667+ } ,
668+ } as any ;
669+
670+ const result = await filterPacksForLetter ( letterEvent , [ "spec1" ] , deps ) ;
671+
672+ expect ( result ) . toEqual ( [ "spec1" ] ) ;
673+ expect ( deps . logger . info ) . not . toHaveBeenCalled ( ) ;
674+ expect ( deps . logger . error ) . not . toHaveBeenCalled ( ) ;
675+ } ) ;
676+
677+
678+
522679 it ( "returns eligible packs for all constraint types" , async ( ) => {
523680 const deps = makeDeps ( ) ;
524681 const constraints : { operator : string ; value : number } [ ] = [
0 commit comments