Skip to content

Commit bed67a2

Browse files
authored
fix: Intall latest version 3.3.1 and fix braking changes (#391)
1 parent c4820cb commit bed67a2

10 files changed

Lines changed: 232 additions & 229 deletions

package-lock.json

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@
220220
},
221221
"dependencies": {
222222
"@internxt/drive-desktop-core": "0.1.7",
223-
"@internxt/inxt-js": "^3.2.2",
223+
"@internxt/inxt-js": "^3.3.1",
224224
"@internxt/scan": "^1.0.7",
225225
"@internxt/sdk": "1.17.4",
226226
"async": "^3.2.4",
Lines changed: 66 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { Environment } from '@internxt/inxt-js';
2-
import { UploadOptions } from '@internxt/inxt-js/build/lib/core';
32
import { Readable } from 'stream';
43
import { deepMocked } from '../../../../../tests/vitest/utils.helper';
54
import { uploadContentToEnvironment } from './upload-content-to-environment';
@@ -13,38 +12,39 @@ vi.mock('../../../../infra/local-file-system/safe-access', () => ({
1312
}));
1413

1514
describe('upload-content-to-environment', () => {
15+
type UploadOptions = {
16+
source: NodeJS.ReadableStream;
17+
fileSize: number;
18+
progressCallback: (progress: number) => void;
19+
abortSignal?: AbortSignal;
20+
};
21+
1622
const createReadStreamMock = deepMocked(fs.createReadStream);
1723
const safeAccessMock = vi.mocked(safeAccessModule.safeAccess);
1824

1925
const SMALL_SIZE = 1024;
20-
const LARGE_SIZE = 200 * 1024 * 1024; // > 100MB threshold
2126

2227
let environment: Environment;
2328
let abortController: AbortController;
2429
let fakeStream: Readable;
25-
let capturedOpts: UploadOptions;
26-
27-
function makeActionState() {
28-
return { stop: vi.fn() };
29-
}
30-
31-
function makeUploadFn(actionState = makeActionState()) {
32-
return vi.fn((_bucket: string, opts: UploadOptions) => {
33-
capturedOpts = opts;
34-
return actionState;
35-
});
36-
}
30+
let capturedOpts: UploadOptions | null;
31+
let uploadMock: ReturnType<typeof vi.fn<(bucket: string, opts: UploadOptions) => Promise<string>>>;
3732

3833
beforeEach(() => {
3934
abortController = new AbortController();
40-
capturedOpts = undefined as unknown as UploadOptions;
35+
capturedOpts = null;
4136
fakeStream = Object.assign(new Readable({ read() {} }), { close: vi.fn(), destroy: vi.fn() });
4237
createReadStreamMock.mockReturnValue(fakeStream as ReturnType<typeof fs.createReadStream>);
4338
safeAccessMock.mockResolvedValue({ data: undefined });
4439

40+
uploadMock = vi.fn(async (_bucket: string, opts: UploadOptions) => {
41+
capturedOpts = opts;
42+
return 'default-contents-id';
43+
});
44+
4545
environment = {
46-
upload: makeUploadFn(),
47-
uploadMultipartFile: makeUploadFn(),
46+
upload: uploadMock,
47+
uploadMultipartFile: vi.fn(),
4848
} as unknown as Environment;
4949
});
5050

@@ -61,102 +61,81 @@ describe('upload-content-to-environment', () => {
6161
async function startUpload(size = SMALL_SIZE) {
6262
const promise = callUpload(size);
6363
await Promise.resolve();
64-
await Promise.resolve();
65-
await Promise.resolve();
6664
return { promise };
6765
}
6866

69-
function triggerFinished(err: Error | null, contentsId: string | null) {
70-
capturedOpts.finishedCallback(err, contentsId);
71-
}
72-
7367
it('should resolve with contentsId on successful upload', async () => {
7468
const contentsId = 'abc123';
75-
const { promise } = await startUpload();
76-
expect(capturedOpts).toBeDefined();
77-
triggerFinished(null, contentsId);
69+
uploadMock.mockResolvedValue(contentsId);
7870

79-
const result = await promise;
71+
const result = await callUpload();
8072

8173
expect(result.data).toBe(contentsId);
8274
expect(result.error).toBeUndefined();
8375
});
8476

85-
it('should use upload for files below multipart threshold', async () => {
86-
const { promise } = await startUpload(SMALL_SIZE);
87-
triggerFinished(null, 'id');
88-
89-
await promise;
90-
91-
expect(environment.upload).toHaveBeenCalled();
92-
expect(environment.uploadMultipartFile).not.toHaveBeenCalled();
93-
});
94-
95-
it('should use uploadMultipartFile for files above multipart threshold', async () => {
96-
const { promise } = await startUpload(LARGE_SIZE);
97-
triggerFinished(null, 'id');
77+
it('should call upload with file size and abortSignal', async () => {
78+
uploadMock.mockImplementation(async (_bucket: string, opts: UploadOptions) => {
79+
capturedOpts = opts;
80+
return 'id';
81+
});
9882

99-
await promise;
83+
await callUpload(SMALL_SIZE);
10084

101-
expect(environment.uploadMultipartFile).toHaveBeenCalled();
102-
expect(environment.upload).not.toHaveBeenCalled();
85+
expect(capturedOpts?.fileSize).toBe(SMALL_SIZE);
86+
expect(capturedOpts?.abortSignal).toBe(abortController.signal);
87+
expect(uploadMock).toHaveBeenCalled();
10388
});
10489

10590
it('should return NOT_ENOUGH_SPACE error when upload fails with "Max space used"', async () => {
106-
const { promise } = await startUpload();
107-
triggerFinished(new Error('Max space used'), null);
91+
uploadMock.mockRejectedValue(new Error('Max space used'));
10892

109-
const result = await promise;
93+
const result = await callUpload();
11094

11195
expect(result.error?.cause).toBe('NOT_ENOUGH_SPACE');
11296
});
11397

11498
it('should return RATE_LIMITED error on 429 with retry_after from message', async () => {
115-
const { promise } = await startUpload();
11699
const err = Object.assign(new Error(JSON.stringify({ retry_after: 10 })), { status: 429 });
117-
triggerFinished(err, null);
100+
uploadMock.mockRejectedValue(err);
118101

119-
const result = await promise;
102+
const result = await callUpload();
120103

121104
expect(result.error?.cause).toBe('RATE_LIMITED');
122105
expect(result.error?.message).toBe('10000');
123106
});
124107

125108
it('should return RATE_LIMITED with default delay when retry_after is missing', async () => {
126-
const { promise } = await startUpload();
127109
const err = Object.assign(new Error('{}'), { status: 429 });
128-
triggerFinished(err, null);
110+
uploadMock.mockRejectedValue(err);
129111

130-
const result = await promise;
112+
const result = await callUpload();
131113

132114
expect(result.error?.cause).toBe('RATE_LIMITED');
133115
expect(result.error?.message).toBe('30000');
134116
});
135117

136118
it('should return INTERNAL_SERVER_ERROR on 500+ errors', async () => {
137-
const { promise } = await startUpload();
138119
const err = Object.assign(new Error('Server error'), { status: 500 });
139-
triggerFinished(err, null);
120+
uploadMock.mockRejectedValue(err);
140121

141-
const result = await promise;
122+
const result = await callUpload();
142123

143124
expect(result.error?.cause).toBe('INTERNAL_SERVER_ERROR');
144125
});
145126

146127
it('should return UNKNOWN error for generic errors', async () => {
147-
const { promise } = await startUpload();
148-
triggerFinished(new Error('Something went wrong'), null);
128+
uploadMock.mockRejectedValue(new Error('Something went wrong'));
149129

150-
const result = await promise;
130+
const result = await callUpload();
151131

152132
expect(result.error?.cause).toBe('UNKNOWN');
153133
});
154134

155-
it('should return UNKNOWN error when contentsId is null on success', async () => {
156-
const { promise } = await startUpload();
157-
triggerFinished(null, null);
135+
it('should return UNKNOWN error when contentsId is empty on success', async () => {
136+
uploadMock.mockResolvedValue('');
158137

159-
const result = await promise;
138+
const result = await callUpload();
160139

161140
expect(result.error?.cause).toBe('UNKNOWN');
162141
});
@@ -179,8 +158,7 @@ describe('upload-content-to-environment', () => {
179158

180159
expect(result.error).toBe(accessError);
181160
expect(createReadStreamMock).not.toHaveBeenCalled();
182-
expect(environment.upload).not.toHaveBeenCalled();
183-
expect(environment.uploadMultipartFile).not.toHaveBeenCalled();
161+
expect(uploadMock).not.toHaveBeenCalled();
184162
});
185163

186164
it('should return ACTION_NOT_PERMITTED when createReadStream throws EACCES', async () => {
@@ -193,35 +171,49 @@ describe('upload-content-to-environment', () => {
193171
expect(result.error?.cause).toBe('ACTION_NOT_PERMITTED');
194172
expect(safeAccessMock).toHaveBeenCalledWith({ absolutePath: '/some/file.txt' });
195173
expect(createReadStreamMock).toHaveBeenCalledWith('/some/file.txt');
196-
expect(environment.upload).not.toHaveBeenCalled();
197-
expect(environment.uploadMultipartFile).not.toHaveBeenCalled();
174+
expect(uploadMock).not.toHaveBeenCalled();
198175
expect(result.data).toBeUndefined();
199176
});
200177

201178
it('should return ACTION_NOT_PERMITTED when the read stream emits EACCES', async () => {
179+
uploadMock.mockImplementation(
180+
async (_bucket: string, opts: UploadOptions) =>
181+
await new Promise<string>((_resolve, reject) => {
182+
opts.source.once('error', reject);
183+
}),
184+
);
185+
202186
const { promise } = await startUpload();
203187

204188
fakeStream.emit('error', Object.assign(new Error('permission denied'), { code: 'EACCES' }));
205-
triggerFinished(null, 'contents-id-after-stream-error');
206189

207190
const result = await promise;
208191

209192
expect(result.error?.cause).toBe('ACTION_NOT_PERMITTED');
210193
expect(safeAccessMock).toHaveBeenCalledWith({ absolutePath: '/some/file.txt' });
211194
expect(createReadStreamMock).toHaveBeenCalledWith('/some/file.txt');
212-
expect(environment.upload).toHaveBeenCalledTimes(1);
213-
expect(environment.uploadMultipartFile).not.toHaveBeenCalled();
195+
expect(uploadMock).toHaveBeenCalledTimes(1);
214196
expect(result.data).toBeUndefined();
215197
});
216198

217-
it('should stop the upload and destroy the stream when signal is aborted', async () => {
218-
const actionState = makeActionState();
219-
(environment.upload as unknown as ReturnType<typeof makeUploadFn>) = makeUploadFn(actionState);
199+
it('should abort the upload and destroy the stream when signal is aborted', async () => {
200+
uploadMock.mockImplementation(
201+
async (_bucket: string, opts: UploadOptions) =>
202+
await new Promise<string>((_resolve, reject) => {
203+
opts.abortSignal?.addEventListener(
204+
'abort',
205+
() => {
206+
reject(new Error('aborted'));
207+
},
208+
{ once: true },
209+
);
210+
}),
211+
);
220212

221-
await startUpload();
213+
const { promise } = await startUpload();
222214
abortController.abort();
215+
await promise;
223216

224-
expect(actionState.stop).toHaveBeenCalled();
225217
expect(fakeStream.destroy).toHaveBeenCalled();
226218
});
227219
});

0 commit comments

Comments
 (0)