@@ -55,20 +55,35 @@ describe("PDF document extractor", () => {
5555 } ) ;
5656 } ) ;
5757
58- it ( "extracts text first and renders fallback images through clawpdf" , async ( ) => {
59- pdfDocument . extract . mockResolvedValueOnce ( { text : "" , images : [ ] } ) . mockResolvedValueOnce ( {
60- text : "" ,
61- images : [
62- {
63- type : "image" ,
64- bytes : Uint8Array . from ( Buffer . from ( "png" ) ) ,
65- mimeType : "image/png" ,
66- page : 1 ,
67- width : 10 ,
68- height : 10 ,
69- } ,
70- ] ,
71- } ) ;
58+ it ( "extracts text first and renders each fallback page with its own pixel budget" , async ( ) => {
59+ pdfDocument . extract
60+ . mockResolvedValueOnce ( { text : "" , images : [ ] } )
61+ . mockResolvedValueOnce ( {
62+ text : "" ,
63+ images : [
64+ {
65+ type : "image" ,
66+ bytes : Uint8Array . from ( Buffer . from ( "png1" ) ) ,
67+ mimeType : "image/png" ,
68+ page : 1 ,
69+ width : 10 ,
70+ height : 10 ,
71+ } ,
72+ ] ,
73+ } )
74+ . mockResolvedValueOnce ( {
75+ text : "" ,
76+ images : [
77+ {
78+ type : "image" ,
79+ bytes : Uint8Array . from ( Buffer . from ( "png2" ) ) ,
80+ mimeType : "image/png" ,
81+ page : 2 ,
82+ width : 10 ,
83+ height : 10 ,
84+ } ,
85+ ] ,
86+ } ) ;
7287 const extractor = createPdfDocumentExtractor ( ) ;
7388
7489 const result = await extractor . extract ( request ( ) ) ;
@@ -82,18 +97,24 @@ describe("PDF document extractor", () => {
8297 maxPages : 2 ,
8398 maxTextChars : 200_000 ,
8499 } ) ;
100+ // Each page renders in its own extract() call so clawpdf's pixel budget is not
101+ // shared across pages (which would starve later pages down to 1x1 images).
85102 expect ( pdfDocument . extract ) . toHaveBeenNthCalledWith ( 2 , {
86103 mode : "images" ,
87- maxPages : 2 ,
88- image : {
89- maxDimension : 10_000 ,
90- maxPixels : 100 ,
91- forms : true ,
92- } ,
104+ pages : [ 1 ] ,
105+ image : { maxDimension : 10_000 , maxPixels : 100 , forms : true } ,
106+ } ) ;
107+ expect ( pdfDocument . extract ) . toHaveBeenNthCalledWith ( 3 , {
108+ mode : "images" ,
109+ pages : [ 2 ] ,
110+ image : { maxDimension : 10_000 , maxPixels : 100 , forms : true } ,
93111 } ) ;
94112 expect ( result ) . toEqual ( {
95113 text : "" ,
96- images : [ { type : "image" , data : "cG5n" , mimeType : "image/png" } ] ,
114+ images : [
115+ { type : "image" , data : "cG5nMQ==" , mimeType : "image/png" } ,
116+ { type : "image" , data : "cG5nMg==" , mimeType : "image/png" } ,
117+ ] ,
97118 } ) ;
98119 expect ( pdfDocument . destroy ) . toHaveBeenCalledTimes ( 1 ) ;
99120 } ) ;
@@ -131,8 +152,9 @@ describe("PDF document extractor", () => {
131152 expect ( pdfDocument . destroy ) . not . toHaveBeenCalled ( ) ;
132153 } ) ;
133154
134- it ( "filters selected pages before passing them to clawpdf " , async ( ) => {
155+ it ( "filters selected pages and renders them one page per image call " , async ( ) => {
135156 pdfDocument . extract
157+ . mockResolvedValueOnce ( { text : "" , images : [ ] } )
136158 . mockResolvedValueOnce ( { text : "" , images : [ ] } )
137159 . mockResolvedValueOnce ( { text : "" , images : [ ] } ) ;
138160 const extractor = createPdfDocumentExtractor ( ) ;
@@ -141,11 +163,15 @@ describe("PDF document extractor", () => {
141163
142164 expect ( pdfDocument . extract ) . toHaveBeenNthCalledWith (
143165 1 ,
144- expect . objectContaining ( { pages : [ 2 , 1 ] } ) ,
166+ expect . objectContaining ( { mode : "text" , pages : [ 2 , 1 ] } ) ,
145167 ) ;
146168 expect ( pdfDocument . extract ) . toHaveBeenNthCalledWith (
147169 2 ,
148- expect . objectContaining ( { pages : [ 2 , 1 ] } ) ,
170+ expect . objectContaining ( { mode : "images" , pages : [ 2 ] } ) ,
171+ ) ;
172+ expect ( pdfDocument . extract ) . toHaveBeenNthCalledWith (
173+ 3 ,
174+ expect . objectContaining ( { mode : "images" , pages : [ 1 ] } ) ,
149175 ) ;
150176 } ) ;
151177
0 commit comments