Skip to content

Commit ac3ad5c

Browse files
committed
Fix tests
1 parent 7870b6a commit ac3ad5c

1 file changed

Lines changed: 51 additions & 46 deletions

File tree

tests/objects/storage-object.test.ts

Lines changed: 51 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,14 @@ import type { ObjectView, ObjectDownloadURLView } from '../../src/resources/obje
44
// Mock the Runloop client
55
jest.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
1117
jest.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

Comments
 (0)