@@ -4,8 +4,14 @@ import type { ObjectView, ObjectDownloadURLView } from '../../src/resources/obje
44// Mock the Runloop client
55jest . mock ( '../../src/index' ) ;
66
7- // Mock fetch globally
8- ( global as any ) . fetch = jest . fn ( ) ;
7+ // Mock fetch globally and in the shims module
8+ const mockFetch = jest . fn ( ) ;
9+ ( global as any ) . fetch = mockFetch ;
10+
11+ // Mock the shims module to use our mock fetch
12+ jest . mock ( '../../src/_shims/index' , ( ) => ( {
13+ fetch : mockFetch ,
14+ } ) ) ;
915
1016// Mock fs and path modules
1117jest . mock ( 'node:fs/promises' , ( ) => ( {
@@ -110,7 +116,7 @@ describe('StorageObject (New API)', () => {
110116 } ;
111117
112118 // Reset fetch mock
113- ( ( global as any ) . fetch as jest . Mock ) . mockReset ( ) ;
119+ mockFetch . mockReset ( ) ;
114120 } ) ;
115121
116122 describe ( 'create' , ( ) => {
@@ -251,7 +257,7 @@ describe('StorageObject (New API)', () => {
251257 statusText : 'OK' ,
252258 } ;
253259
254- ( ( global as any ) . fetch as jest . Mock ) . mockResolvedValue ( mockFetchResponse ) ;
260+ mockFetch . mockResolvedValue ( mockFetchResponse ) ;
255261
256262 await storageObject . uploadContent ( 'Hello, World!' ) ;
257263
@@ -271,7 +277,7 @@ describe('StorageObject (New API)', () => {
271277 statusText : 'OK' ,
272278 } ;
273279
274- ( ( global as any ) . fetch as jest . Mock ) . mockResolvedValue ( mockFetchResponse ) ;
280+ mockFetch . mockResolvedValue ( mockFetchResponse ) ;
275281
276282 const buffer = Buffer . from ( [ 0x89 , 0x50 , 0x4e , 0x47 ] ) ;
277283 await storageObject . uploadContent ( buffer ) ;
@@ -301,7 +307,7 @@ describe('StorageObject (New API)', () => {
301307 text : jest . fn ( ) . mockResolvedValue ( 'Forbidden' ) ,
302308 } ;
303309
304- ( ( global as any ) . fetch as jest . Mock ) . mockResolvedValue ( mockFetchResponse ) ;
310+ mockFetch . mockResolvedValue ( mockFetchResponse ) ;
305311
306312 await expect ( storageObject . uploadContent ( 'test' ) ) . rejects . toThrow ( 'Upload failed: 403' ) ;
307313 } ) ;
@@ -372,7 +378,7 @@ describe('StorageObject (New API)', () => {
372378 text : jest . fn ( ) . mockResolvedValue ( 'File contents' ) ,
373379 } ;
374380
375- ( ( global as any ) . fetch as jest . Mock ) . mockResolvedValue ( mockFetchResponse ) ;
381+ mockFetch . mockResolvedValue ( mockFetchResponse ) ;
376382
377383 const content = await storageObject . downloadAsText ( ) ;
378384
@@ -393,7 +399,7 @@ describe('StorageObject (New API)', () => {
393399 statusText : 'Not Found' ,
394400 } ;
395401
396- ( ( global as any ) . fetch as jest . Mock ) . mockResolvedValue ( mockFetchResponse ) ;
402+ mockFetch . mockResolvedValue ( mockFetchResponse ) ;
397403
398404 await expect ( storageObject . downloadAsText ( ) ) . rejects . toThrow ( 'Download failed: 404 Not Found' ) ;
399405 } ) ;
@@ -413,7 +419,7 @@ describe('StorageObject (New API)', () => {
413419 arrayBuffer : jest . fn ( ) . mockResolvedValue ( mockArrayBuffer ) ,
414420 } ;
415421
416- ( ( global as any ) . fetch as jest . Mock ) . mockResolvedValue ( mockFetchResponse ) ;
422+ mockFetch . mockResolvedValue ( mockFetchResponse ) ;
417423
418424 const buffer = await storageObject . downloadAsBuffer ( ) ;
419425
@@ -452,7 +458,7 @@ describe('StorageObject (New API)', () => {
452458
453459 // Upload - mock getInfo for uploadContent
454460 mockClient . objects . retrieve . mockResolvedValue ( mockObjectData ) ;
455- ( ( global as any ) . fetch as jest . Mock ) . mockResolvedValue ( { ok : true } ) ;
461+ mockFetch . mockResolvedValue ( { ok : true } ) ;
456462 await obj . uploadContent ( 'Test content' ) ;
457463
458464 // Complete
@@ -465,7 +471,7 @@ describe('StorageObject (New API)', () => {
465471 download_url : 'https://s3.example.com/download/workflow-test.txt' ,
466472 } ;
467473 mockClient . objects . download . mockResolvedValue ( mockDownloadUrl ) ;
468- ( ( global as any ) . fetch as jest . Mock ) . mockResolvedValue ( {
474+ mockFetch . mockResolvedValue ( {
469475 ok : true ,
470476 text : jest . fn ( ) . mockResolvedValue ( 'Test content' ) ,
471477 } ) ;
@@ -480,7 +486,7 @@ describe('StorageObject (New API)', () => {
480486 // Clear all mocks
481487 jest . clearAllMocks ( ) ;
482488 // Reset global fetch mock
483- ( ( global as any ) . fetch as jest . Mock ) . mockClear ( ) ;
489+ mockFetch . mockClear ( ) ;
484490 } ) ;
485491
486492 it ( 'should upload a text file with auto-detected content-type' , async ( ) => {
@@ -496,7 +502,7 @@ describe('StorageObject (New API)', () => {
496502 mockClient . objects . retrieve . mockResolvedValue ( mockObjectInfo ) ;
497503 mockClient . objects . complete . mockResolvedValue ( mockCompletedData ) ;
498504
499- ( ( global as any ) . fetch as jest . Mock ) . mockResolvedValue ( {
505+ mockFetch . mockResolvedValue ( {
500506 ok : true ,
501507 status : 200 ,
502508 statusText : 'OK' ,
@@ -526,7 +532,7 @@ describe('StorageObject (New API)', () => {
526532 mockClient . objects . retrieve . mockResolvedValue ( mockObjectInfo ) ;
527533 mockClient . objects . complete . mockResolvedValue ( mockCompletedData ) ;
528534
529- ( ( global as any ) . fetch as jest . Mock ) . mockResolvedValue ( {
535+ mockFetch . mockResolvedValue ( {
530536 ok : true ,
531537 status : 200 ,
532538 statusText : 'OK' ,
@@ -576,7 +582,7 @@ describe('StorageObject (New API)', () => {
576582 mockClient . objects . create . mockResolvedValue ( mockObjectData ) ;
577583 mockClient . objects . retrieve . mockResolvedValue ( mockObjectInfo ) ;
578584
579- ( ( global as any ) . fetch as jest . Mock ) . mockResolvedValue ( {
585+ mockFetch . mockResolvedValue ( {
580586 ok : false ,
581587 status : 500 ,
582588 statusText : 'Internal Server Error' ,
@@ -600,7 +606,7 @@ describe('StorageObject (New API)', () => {
600606 mockClient . objects . retrieve . mockResolvedValue ( mockObjectInfo ) ;
601607 mockClient . objects . complete . mockResolvedValue ( mockCompletedData ) ;
602608
603- ( ( global as any ) . fetch as jest . Mock ) . mockResolvedValue ( {
609+ mockFetch . mockResolvedValue ( {
604610 ok : true ,
605611 status : 200 ,
606612 statusText : 'OK' ,
@@ -627,7 +633,7 @@ describe('StorageObject (New API)', () => {
627633 // Clear all mocks
628634 jest . clearAllMocks ( ) ;
629635 // Reset global fetch mock
630- ( ( global as any ) . fetch as jest . Mock ) . mockClear ( ) ;
636+ mockFetch . mockClear ( ) ;
631637 } ) ;
632638
633639 it ( 'should upload text content with text content-type' , async ( ) => {
@@ -640,7 +646,7 @@ describe('StorageObject (New API)', () => {
640646 mockClient . objects . retrieve . mockResolvedValue ( mockObjectInfo ) ;
641647 mockClient . objects . complete . mockResolvedValue ( mockCompletedData ) ;
642648
643- ( ( global as any ) . fetch as jest . Mock ) . mockResolvedValue ( {
649+ mockFetch . mockResolvedValue ( {
644650 ok : true ,
645651 status : 200 ,
646652 statusText : 'OK' ,
@@ -652,11 +658,11 @@ describe('StorageObject (New API)', () => {
652658 { name : 'hello.txt' , content_type : 'text' , metadata : null } ,
653659 undefined ,
654660 ) ;
655- // uploadFromText uses Blob for fetch body
656- const fetchCalls = ( ( global as any ) . fetch as jest . Mock ) . mock . calls ;
661+ // uploadFromText uses Buffer for fetch body
662+ const fetchCalls = mockFetch . mock . calls ;
657663 expect ( fetchCalls [ 0 ] [ 0 ] ) . toBe ( 'https://upload.example.com/text' ) ;
658664 expect ( fetchCalls [ 0 ] [ 1 ] . method ) . toBe ( 'PUT' ) ;
659- expect ( fetchCalls [ 0 ] [ 1 ] . body ) . toBeInstanceOf ( Blob ) ;
665+ expect ( Buffer . isBuffer ( fetchCalls [ 0 ] [ 1 ] . body ) ) . toBe ( true ) ;
660666 expect ( result ) . toBeInstanceOf ( StorageObject ) ;
661667 expect ( result . id ) . toBe ( 'text-123' ) ;
662668 } ) ;
@@ -671,7 +677,7 @@ describe('StorageObject (New API)', () => {
671677 mockClient . objects . retrieve . mockResolvedValue ( mockObjectInfo ) ;
672678 mockClient . objects . complete . mockResolvedValue ( mockCompletedData ) ;
673679
674- ( ( global as any ) . fetch as jest . Mock ) . mockResolvedValue ( {
680+ mockFetch . mockResolvedValue ( {
675681 ok : true ,
676682 status : 200 ,
677683 statusText : 'OK' ,
@@ -696,7 +702,7 @@ describe('StorageObject (New API)', () => {
696702 mockClient . objects . create . mockResolvedValue ( mockObjectData ) ;
697703 mockClient . objects . retrieve . mockResolvedValue ( mockObjectInfo ) ;
698704
699- ( ( global as any ) . fetch as jest . Mock ) . mockResolvedValue ( {
705+ mockFetch . mockResolvedValue ( {
700706 ok : false ,
701707 status : 403 ,
702708 statusText : 'Forbidden' ,
@@ -717,7 +723,7 @@ describe('StorageObject (New API)', () => {
717723 mockClient . objects . retrieve . mockResolvedValue ( mockObjectInfo ) ;
718724 mockClient . objects . complete . mockResolvedValue ( mockCompletedData ) ;
719725
720- ( ( global as any ) . fetch as jest . Mock ) . mockResolvedValue ( {
726+ mockFetch . mockResolvedValue ( {
721727 ok : true ,
722728 status : 200 ,
723729 statusText : 'OK' ,
@@ -738,7 +744,7 @@ describe('StorageObject (New API)', () => {
738744 // Clear all mocks
739745 jest . clearAllMocks ( ) ;
740746 // Reset global fetch mock
741- ( ( global as any ) . fetch as jest . Mock ) . mockClear ( ) ;
747+ mockFetch . mockClear ( ) ;
742748 } ) ;
743749
744750 it ( 'should upload buffer with specified content-type and name' , async ( ) => {
@@ -751,7 +757,7 @@ describe('StorageObject (New API)', () => {
751757 mockClient . objects . retrieve . mockResolvedValue ( mockObjectInfo ) ;
752758 mockClient . objects . complete . mockResolvedValue ( mockCompletedData ) ;
753759
754- ( ( global as any ) . fetch as jest . Mock ) . mockResolvedValue ( {
760+ mockFetch . mockResolvedValue ( {
755761 ok : true ,
756762 status : 200 ,
757763 statusText : 'OK' ,
@@ -765,11 +771,11 @@ describe('StorageObject (New API)', () => {
765771 { name : 'buffer.txt' , content_type : 'text' , metadata : { source : 'buffer' } } ,
766772 { metadata : { source : 'buffer' } } ,
767773 ) ;
768- // uploadFromBuffer uses Blob for fetch body
769- const fetchCalls = ( ( global as any ) . fetch as jest . Mock ) . mock . calls ;
774+ // uploadFromBuffer uses Buffer for fetch body
775+ const fetchCalls = mockFetch . mock . calls ;
770776 expect ( fetchCalls [ 0 ] [ 0 ] ) . toBe ( 'https://upload.example.com/buffer' ) ;
771777 expect ( fetchCalls [ 0 ] [ 1 ] . method ) . toBe ( 'PUT' ) ;
772- expect ( fetchCalls [ 0 ] [ 1 ] . body ) . toBeInstanceOf ( Blob ) ;
778+ expect ( Buffer . isBuffer ( fetchCalls [ 0 ] [ 1 ] . body ) ) . toBe ( true ) ;
773779 expect ( result ) . toBeInstanceOf ( StorageObject ) ;
774780 expect ( result . id ) . toBe ( 'buffer-123' ) ;
775781 } ) ;
@@ -796,7 +802,7 @@ describe('StorageObject (New API)', () => {
796802 mockClient . objects . create . mockResolvedValue ( mockObjectData ) ;
797803 mockClient . objects . retrieve . mockResolvedValue ( mockObjectInfo ) ;
798804
799- ( ( global as any ) . fetch as jest . Mock ) . mockResolvedValue ( {
805+ mockFetch . mockResolvedValue ( {
800806 ok : false ,
801807 status : 403 ,
802808 statusText : 'Forbidden' ,
@@ -817,7 +823,7 @@ describe('StorageObject (New API)', () => {
817823 mockClient . objects . retrieve . mockResolvedValue ( mockObjectInfo ) ;
818824 mockClient . objects . complete . mockResolvedValue ( mockCompletedData ) ;
819825
820- ( ( global as any ) . fetch as jest . Mock ) . mockResolvedValue ( {
826+ mockFetch . mockResolvedValue ( {
821827 ok : true ,
822828 status : 200 ,
823829 statusText : 'OK' ,
@@ -840,7 +846,7 @@ describe('StorageObject (New API)', () => {
840846 // Clear all mocks
841847 jest . clearAllMocks ( ) ;
842848 // Reset global fetch mock
843- ( ( global as any ) . fetch as jest . Mock ) . mockClear ( ) ;
849+ mockFetch . mockClear ( ) ;
844850 // Get tar mock
845851 mockTar = require ( 'tar' ) ;
846852 // Reset ignore matcher mock
@@ -852,19 +858,15 @@ describe('StorageObject (New API)', () => {
852858 // Mock directory exists
853859 mockFs . stat . mockResolvedValue ( { isDirectory : ( ) => true , size : 100 } ) ;
854860 mockFs . mkdtemp . mockResolvedValue ( '/tmp/runloop-upload-123' ) ;
861+ // Mock reading the tarball file
862+ mockFs . readFile . mockResolvedValue ( Buffer . from ( 'mock tarball content' ) ) ;
855863
856864 // Mock write stream
857865 const mockWriteStream = {
858866 on : jest . fn ( ) . mockReturnThis ( ) ,
859867 } ;
860868 mockFsSync . createWriteStream . mockReturnValue ( mockWriteStream ) ;
861869
862- // Mock read stream
863- const mockReadStream = {
864- pipe : jest . fn ( ) ,
865- } ;
866- mockFsSync . createReadStream . mockReturnValue ( mockReadStream ) ;
867-
868870 // Mock tar stream
869871 const mockTarStream = {
870872 pipe : jest . fn ( ( dest ) => {
@@ -885,7 +887,7 @@ describe('StorageObject (New API)', () => {
885887 mockClient . objects . retrieve . mockResolvedValue ( mockObjectInfo ) ;
886888 mockClient . objects . complete . mockResolvedValue ( mockCompletedData ) ;
887889
888- ( ( global as any ) . fetch as jest . Mock ) . mockResolvedValue ( {
890+ mockFetch . mockResolvedValue ( {
889891 ok : true ,
890892 status : 200 ,
891893 statusText : 'OK' ,
@@ -902,7 +904,7 @@ describe('StorageObject (New API)', () => {
902904 expect ( mockTar . create ) . toHaveBeenCalled ( ) ;
903905 expect ( mockFs . mkdtemp ) . toHaveBeenCalled ( ) ;
904906 expect ( mockFsSync . createWriteStream ) . toHaveBeenCalled ( ) ;
905- expect ( mockFsSync . createReadStream ) . toHaveBeenCalled ( ) ;
907+ expect ( mockFs . readFile ) . toHaveBeenCalled ( ) ;
906908 expect ( mockFs . rm ) . toHaveBeenCalledWith ( '/tmp/runloop-upload-123' , { recursive : true , force : true } ) ;
907909 expect ( result ) . toBeInstanceOf ( StorageObject ) ;
908910 expect ( result . id ) . toBe ( 'dir-123' ) ;
@@ -912,13 +914,14 @@ describe('StorageObject (New API)', () => {
912914 // Mock directory exists
913915 mockFs . stat . mockResolvedValue ( { isDirectory : ( ) => true , size : 100 } ) ;
914916 mockFs . mkdtemp . mockResolvedValue ( '/tmp/runloop-upload-123' ) ;
917+ // Mock reading the tarball file
918+ mockFs . readFile . mockResolvedValue ( Buffer . from ( 'mock tarball content' ) ) ;
915919
916920 // Mocks for streams
917921 const mockWriteStream = {
918922 on : jest . fn ( ) . mockReturnThis ( ) ,
919923 } ;
920924 mockFsSync . createWriteStream . mockReturnValue ( mockWriteStream ) ;
921- mockFsSync . createReadStream . mockReturnValue ( { } ) ;
922925
923926 // Provide a fake matcher
924927 const matcher = { matches : jest . fn ( ) } ;
@@ -939,7 +942,7 @@ describe('StorageObject (New API)', () => {
939942 const mockObjectData = { id : 'dir-ignore' , upload_url : 'https://upload.example.com/dir' } ;
940943 mockClient . objects . create . mockResolvedValue ( mockObjectData ) ;
941944 mockClient . objects . complete . mockResolvedValue ( { ...mockObjectData , state : 'READ_ONLY' } ) ;
942- ( ( global as any ) . fetch as jest . Mock ) . mockResolvedValue ( { ok : true } ) ;
945+ mockFetch . mockResolvedValue ( { ok : true } ) ;
943946
944947 await StorageObject . uploadFromDir ( mockClient , './my-project' , {
945948 name : 'project.tar.gz' ,
@@ -966,13 +969,14 @@ describe('StorageObject (New API)', () => {
966969 // Mock directory exists
967970 mockFs . stat . mockResolvedValue ( { isDirectory : ( ) => true , size : 100 } ) ;
968971 mockFs . mkdtemp . mockResolvedValue ( '/tmp/runloop-upload-123' ) ;
972+ // Mock reading the tarball file
973+ mockFs . readFile . mockResolvedValue ( Buffer . from ( 'mock tarball content' ) ) ;
969974
970975 // Mocks for streams
971976 const mockWriteStream = {
972977 on : jest . fn ( ) . mockReturnThis ( ) ,
973978 } ;
974979 mockFsSync . createWriteStream . mockReturnValue ( mockWriteStream ) ;
975- mockFsSync . createReadStream . mockReturnValue ( { } ) ;
976980
977981 // Mock tar stream
978982 const mockTarStream = {
@@ -991,7 +995,7 @@ describe('StorageObject (New API)', () => {
991995 mockClient . objects . create . mockResolvedValue ( mockObjectData ) ;
992996 mockClient . objects . complete . mockResolvedValue ( mockCompletedData ) ;
993997
994- ( ( global as any ) . fetch as jest . Mock ) . mockResolvedValue ( {
998+ mockFetch . mockResolvedValue ( {
995999 ok : true ,
9961000 status : 200 ,
9971001 statusText : 'OK' ,
@@ -1040,12 +1044,13 @@ describe('StorageObject (New API)', () => {
10401044 it ( 'should handle upload failures gracefully' , async ( ) => {
10411045 mockFs . stat . mockResolvedValue ( { isDirectory : ( ) => true , size : 100 } ) ;
10421046 mockFs . mkdtemp . mockResolvedValue ( '/tmp/runloop-upload-123' ) ;
1047+ // Mock reading the tarball file
1048+ mockFs . readFile . mockResolvedValue ( Buffer . from ( 'mock tarball content' ) ) ;
10431049
10441050 const mockWriteStream = {
10451051 on : jest . fn ( ) . mockReturnThis ( ) ,
10461052 } ;
10471053 mockFsSync . createWriteStream . mockReturnValue ( mockWriteStream ) ;
1048- mockFsSync . createReadStream . mockReturnValue ( { } ) ;
10491054
10501055 const mockTarStream = {
10511056 pipe : jest . fn ( ( dest ) => {
@@ -1060,7 +1065,7 @@ describe('StorageObject (New API)', () => {
10601065 const mockObjectData = { id : 'dir-999' , upload_url : 'https://upload.example.com/dir' } ;
10611066 mockClient . objects . create . mockResolvedValue ( mockObjectData ) ;
10621067
1063- ( ( global as any ) . fetch as jest . Mock ) . mockResolvedValue ( {
1068+ mockFetch . mockResolvedValue ( {
10641069 ok : false ,
10651070 status : 500 ,
10661071 statusText : 'Internal Server Error' ,
0 commit comments