@@ -339,6 +339,61 @@ describe('Request', function () {
339339 assert . equal ( request . reqOptions . headers . foo , 'bar' ) ;
340340 } ) ;
341341
342+ it ( 'attach() sets body correctly with single file' , async function ( ) {
343+ const fn = ( ) => { } ;
344+ const jar = { } ;
345+ const opts = new RequestOptions ( ) ;
346+ const request = new Request ( fn , jar , opts ) ;
347+
348+ const path = require ( 'path' ) ;
349+ const filePath = path . join ( __dirname , 'fixtures/ghost-favicon.png' ) ;
350+
351+ request . attach ( 'image' , filePath ) ;
352+
353+ assert . equal ( request . _formData instanceof FormData , true ) ;
354+ assert . equal ( request . reqOptions . body , undefined ) ;
355+
356+ // Verify the FormData contains the file
357+ const buffer = request . _formData . getBuffer ( ) ;
358+ const content = buffer . toString ( ) ;
359+ assert . match ( content , / C o n t e n t - D i s p o s i t i o n : f o r m - d a t a ; n a m e = " i m a g e " / ) ;
360+ assert . match ( content , / f i l e n a m e = " g h o s t - f a v i c o n .p n g " / ) ;
361+ } ) ;
362+
363+ it ( 'attach() sets body correctly with multiple files' , async function ( ) {
364+ const fn = ( ) => { } ;
365+ const jar = { } ;
366+ const opts = new RequestOptions ( ) ;
367+ const request = new Request ( fn , jar , opts ) ;
368+
369+ const path = require ( 'path' ) ;
370+ const fs = require ( 'fs' ) ;
371+ const imagePath = path . join ( __dirname , 'fixtures/ghost-favicon.png' ) ;
372+ const textPath = path . join ( __dirname , 'fixtures/test-multi.txt' ) ;
373+
374+ // Create a test text file
375+ fs . writeFileSync ( textPath , 'test content' ) ;
376+
377+ try {
378+ request
379+ . attach ( 'image' , imagePath )
380+ . attach ( 'document' , textPath ) ;
381+
382+ assert . equal ( request . _formData instanceof FormData , true ) ;
383+
384+ // Verify the FormData contains both files
385+ const buffer = request . _formData . getBuffer ( ) ;
386+ const content = buffer . toString ( ) ;
387+ assert . match ( content , / C o n t e n t - D i s p o s i t i o n : f o r m - d a t a ; n a m e = " i m a g e " / ) ;
388+ assert . match ( content , / f i l e n a m e = " g h o s t - f a v i c o n .p n g " / ) ;
389+ assert . match ( content , / C o n t e n t - D i s p o s i t i o n : f o r m - d a t a ; n a m e = " d o c u m e n t " / ) ;
390+ assert . match ( content , / f i l e n a m e = " t e s t - m u l t i .t x t " / ) ;
391+ } finally {
392+ // Clean up
393+ fs . unlinkSync ( textPath ) ;
394+ }
395+ } ) ;
396+
342397 it ( 'class is thenable [public api]' , async function ( ) {
343398 const fn = ( req , res ) => {
344399 // This is how reqresnext works
0 commit comments