Skip to content

Commit 4214d58

Browse files
committed
chore: fix tests
1 parent 87c5210 commit 4214d58

File tree

1 file changed

+97
-55
lines changed

1 file changed

+97
-55
lines changed

src/notebooks/deepnote/openInDeepnoteHandler.node.unit.test.ts

Lines changed: 97 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,27 @@ suite('OpenInDeepnoteHandler', () => {
3131

3232
suite('activate', () => {
3333
test('should register command when activated', () => {
34-
const registerCommandStub = sandbox.stub(mockedVSCodeNamespaces.commands, 'registerCommand');
34+
let registeredCommandId: string | undefined;
35+
let registeredCallback: Function | undefined;
36+
37+
when(mockedVSCodeNamespaces.commands.registerCommand(anything(), anything())).thenCall((id, callback) => {
38+
registeredCommandId = id;
39+
registeredCallback = callback;
40+
return {
41+
dispose: () => {
42+
/* no-op */
43+
}
44+
};
45+
});
3546

3647
handler.activate();
3748

38-
assert.isTrue(registerCommandStub.calledOnce, 'registerCommand should be called once');
3949
assert.strictEqual(
40-
registerCommandStub.firstCall.args[0],
50+
registeredCommandId,
4151
'deepnote.openInDeepnote',
4252
'Command should be registered with correct ID'
4353
);
44-
assert.isFunction(registerCommandStub.firstCall.args[1], 'Second argument should be a function');
54+
assert.isFunction(registeredCallback, 'Second argument should be a function');
4555
});
4656
});
4757

@@ -74,55 +84,61 @@ suite('OpenInDeepnoteHandler', () => {
7484
}
7585

7686
test('should handle no active editor or notebook', async () => {
87+
let errorMessage: string | undefined;
88+
7789
when(mockedVSCodeNamespaces.window.activeNotebookEditor).thenReturn(undefined);
7890
when(mockedVSCodeNamespaces.window.activeTextEditor).thenReturn(undefined);
79-
const showErrorStub = sandbox.stub(mockedVSCodeNamespaces.window, 'showErrorMessage');
91+
when(mockedVSCodeNamespaces.window.showErrorMessage(anything())).thenCall((message) => {
92+
errorMessage = message;
93+
return Promise.resolve(undefined);
94+
});
8095

8196
await (handler as any).handleOpenInDeepnote();
8297

83-
assert.isTrue(showErrorStub.calledOnce, 'Should show error message');
98+
assert.isDefined(errorMessage, 'Should show error message');
8499
assert.isTrue(
85-
showErrorStub.firstCall.args[0].includes('Please open a .deepnote file first'),
100+
errorMessage!.includes('Please open a .deepnote file first'),
86101
'Error message should mention opening a .deepnote file'
87102
);
88103
});
89104

90105
test('should handle Deepnote notebook editor', async () => {
91106
const notebookUri = testFileUri.with({ query: 'notebook=123' });
92107
const mockNotebookEditor = createMockNotebookEditor(notebookUri, 'deepnote');
108+
let withProgressCalled = false;
93109

94110
when(mockedVSCodeNamespaces.window.activeNotebookEditor).thenReturn(mockNotebookEditor);
95111
when(mockedVSCodeNamespaces.commands.executeCommand(anything())).thenReturn(Promise.resolve(undefined));
96112

97113
const statStub = sandbox.stub(fs.promises, 'stat').resolves({ size: 1000 } as fs.Stats);
98114
const readFileStub = sandbox.stub(fs.promises, 'readFile').resolves(testFileBuffer);
99-
const withProgressStub = sandbox
100-
.stub(mockedVSCodeNamespaces.window, 'withProgress')
101-
.callsFake((_options, callback) => {
102-
return callback(
103-
{
104-
report: sinon.stub()
105-
} as any,
106-
{} as any
107-
);
108-
});
115+
when(mockedVSCodeNamespaces.window.withProgress(anything(), anything())).thenCall((_options, callback) => {
116+
withProgressCalled = true;
117+
return callback(
118+
{
119+
report: () => {
120+
/* no-op */
121+
}
122+
} as any,
123+
{} as any
124+
);
125+
});
109126
const initImportStub = sandbox.stub(importClient, 'initImport').resolves({
110127
importId: 'test-import-id',
111128
uploadUrl: 'https://test.com/upload',
112129
expiresAt: '2025-12-31T23:59:59Z'
113130
});
114131
const uploadFileStub = sandbox.stub(importClient, 'uploadFile').resolves();
115132
sandbox.stub(importClient, 'getDeepnoteDomain').returns('app.deepnote.com');
116-
const openExternalStub = sandbox.stub(mockedVSCodeNamespaces.env, 'openExternal').resolves();
133+
when(mockedVSCodeNamespaces.env.openExternal(anything())).thenReturn(Promise.resolve(true));
117134

118135
await (handler as any).handleOpenInDeepnote();
119136

120137
assert.isTrue(statStub.calledOnce, 'Should stat the file');
121138
assert.isTrue(readFileStub.calledOnce, 'Should read the file');
122-
assert.isTrue(withProgressStub.calledOnce, 'Should show progress');
139+
assert.isTrue(withProgressCalled, 'Should show progress');
123140
assert.isTrue(initImportStub.calledOnce, 'Should initialize import');
124141
assert.isTrue(uploadFileStub.calledOnce, 'Should upload file');
125-
assert.isTrue(openExternalStub.calledOnce, 'Should open external URL');
126142
});
127143

128144
test('should fall back to text editor when notebook is not Deepnote type', async () => {
@@ -135,10 +151,12 @@ suite('OpenInDeepnoteHandler', () => {
135151

136152
const statStub = sandbox.stub(fs.promises, 'stat').resolves({ size: 1000 } as fs.Stats);
137153
const readFileStub = sandbox.stub(fs.promises, 'readFile').resolves(testFileBuffer);
138-
sandbox.stub(mockedVSCodeNamespaces.window, 'withProgress').callsFake((_options, callback) => {
154+
when(mockedVSCodeNamespaces.window.withProgress(anything(), anything())).thenCall((_options, callback) => {
139155
return callback(
140156
{
141-
report: sinon.stub()
157+
report: () => {
158+
/* no-op */
159+
}
142160
} as any,
143161
{} as any
144162
);
@@ -150,7 +168,7 @@ suite('OpenInDeepnoteHandler', () => {
150168
});
151169
sandbox.stub(importClient, 'uploadFile').resolves();
152170
sandbox.stub(importClient, 'getDeepnoteDomain').returns('app.deepnote.com');
153-
sandbox.stub(mockedVSCodeNamespaces.env, 'openExternal').resolves();
171+
when(mockedVSCodeNamespaces.env.openExternal(anything())).thenReturn(Promise.resolve(true));
154172

155173
await (handler as any).handleOpenInDeepnote();
156174

@@ -166,10 +184,12 @@ suite('OpenInDeepnoteHandler', () => {
166184

167185
const statStub = sandbox.stub(fs.promises, 'stat').resolves({ size: 1000 } as fs.Stats);
168186
const readFileStub = sandbox.stub(fs.promises, 'readFile').resolves(testFileBuffer);
169-
sandbox.stub(mockedVSCodeNamespaces.window, 'withProgress').callsFake((_options, callback) => {
187+
when(mockedVSCodeNamespaces.window.withProgress(anything(), anything())).thenCall((_options, callback) => {
170188
return callback(
171189
{
172-
report: sinon.stub()
190+
report: () => {
191+
/* no-op */
192+
}
173193
} as any,
174194
{} as any
175195
);
@@ -181,7 +201,7 @@ suite('OpenInDeepnoteHandler', () => {
181201
});
182202
sandbox.stub(importClient, 'uploadFile').resolves();
183203
sandbox.stub(importClient, 'getDeepnoteDomain').returns('app.deepnote.com');
184-
sandbox.stub(mockedVSCodeNamespaces.env, 'openExternal').resolves();
204+
when(mockedVSCodeNamespaces.env.openExternal(anything())).thenReturn(Promise.resolve(true));
185205

186206
await (handler as any).handleOpenInDeepnote();
187207

@@ -192,16 +212,20 @@ suite('OpenInDeepnoteHandler', () => {
192212
test('should reject non-.deepnote files', async () => {
193213
const otherFileUri = Uri.file('/test/notebook.ipynb');
194214
const mockTextEditor = createMockTextEditor(otherFileUri);
215+
let errorMessage: string | undefined;
195216

196217
when(mockedVSCodeNamespaces.window.activeNotebookEditor).thenReturn(undefined);
197218
when(mockedVSCodeNamespaces.window.activeTextEditor).thenReturn(mockTextEditor);
198-
const showErrorStub = sandbox.stub(mockedVSCodeNamespaces.window, 'showErrorMessage');
219+
when(mockedVSCodeNamespaces.window.showErrorMessage(anything())).thenCall((message) => {
220+
errorMessage = message;
221+
return Promise.resolve(undefined);
222+
});
199223

200224
await (handler as any).handleOpenInDeepnote();
201225

202-
assert.isTrue(showErrorStub.calledOnce, 'Should show error message');
226+
assert.isDefined(errorMessage, 'Should show error message');
203227
assert.isTrue(
204-
showErrorStub.firstCall.args[0].includes('only works with .deepnote files'),
228+
errorMessage!.includes('only works with .deepnote files'),
205229
'Error message should mention .deepnote files'
206230
);
207231
});
@@ -216,10 +240,12 @@ suite('OpenInDeepnoteHandler', () => {
216240
const saveStub = sandbox.stub(mockDocument, 'save').resolves(true);
217241
sandbox.stub(fs.promises, 'stat').resolves({ size: 1000 } as fs.Stats);
218242
sandbox.stub(fs.promises, 'readFile').resolves(testFileBuffer);
219-
sandbox.stub(mockedVSCodeNamespaces.window, 'withProgress').callsFake((_options, callback) => {
243+
when(mockedVSCodeNamespaces.window.withProgress(anything(), anything())).thenCall((_options, callback) => {
220244
return callback(
221245
{
222-
report: sinon.stub()
246+
report: () => {
247+
/* no-op */
248+
}
223249
} as any,
224250
{} as any
225251
);
@@ -231,7 +257,7 @@ suite('OpenInDeepnoteHandler', () => {
231257
});
232258
sandbox.stub(importClient, 'uploadFile').resolves();
233259
sandbox.stub(importClient, 'getDeepnoteDomain').returns('app.deepnote.com');
234-
sandbox.stub(mockedVSCodeNamespaces.env, 'openExternal').resolves();
260+
when(mockedVSCodeNamespaces.env.openExternal(anything())).thenReturn(Promise.resolve(true));
235261

236262
await (handler as any).handleOpenInDeepnote();
237263

@@ -241,80 +267,91 @@ suite('OpenInDeepnoteHandler', () => {
241267
test('should handle file save failure', async () => {
242268
const mockTextEditor = createMockTextEditor(testFileUri, true);
243269
const mockDocument = mockTextEditor.document;
270+
let errorMessage: string | undefined;
244271

245272
when(mockedVSCodeNamespaces.window.activeNotebookEditor).thenReturn(undefined);
246273
when(mockedVSCodeNamespaces.window.activeTextEditor).thenReturn(mockTextEditor);
247274

248275
const saveStub = sandbox.stub(mockDocument, 'save').resolves(false);
249-
const showErrorStub = sandbox.stub(mockedVSCodeNamespaces.window, 'showErrorMessage');
276+
when(mockedVSCodeNamespaces.window.showErrorMessage(anything())).thenCall((message) => {
277+
errorMessage = message;
278+
return Promise.resolve(undefined);
279+
});
250280

251281
await (handler as any).handleOpenInDeepnote();
252282

253283
assert.isTrue(saveStub.calledOnce, 'Should attempt to save');
254-
assert.isTrue(showErrorStub.calledOnce, 'Should show error message');
255-
assert.isTrue(
256-
showErrorStub.firstCall.args[0].includes('save the file'),
257-
'Error message should mention saving'
258-
);
284+
assert.isDefined(errorMessage, 'Should show error message');
285+
assert.isTrue(errorMessage!.includes('save the file'), 'Error message should mention saving');
259286
});
260287

261288
test('should reject files exceeding size limit', async () => {
262289
const mockTextEditor = createMockTextEditor(testFileUri);
290+
let errorMessage: string | undefined;
263291

264292
when(mockedVSCodeNamespaces.window.activeNotebookEditor).thenReturn(undefined);
265293
when(mockedVSCodeNamespaces.window.activeTextEditor).thenReturn(mockTextEditor);
266294

267295
const largeSize = importClient.MAX_FILE_SIZE + 1;
268296
const statStub = sandbox.stub(fs.promises, 'stat').resolves({ size: largeSize } as fs.Stats);
269-
const showErrorStub = sandbox.stub(mockedVSCodeNamespaces.window, 'showErrorMessage');
297+
when(mockedVSCodeNamespaces.window.showErrorMessage(anything())).thenCall((message) => {
298+
errorMessage = message;
299+
return Promise.resolve(undefined);
300+
});
270301

271302
await (handler as any).handleOpenInDeepnote();
272303

273304
assert.isTrue(statStub.calledOnce, 'Should stat the file');
274-
assert.isTrue(showErrorStub.calledOnce, 'Should show error message');
275-
assert.isTrue(
276-
showErrorStub.firstCall.args[0].includes('exceeds'),
277-
'Error message should mention file size limit'
278-
);
305+
assert.isDefined(errorMessage, 'Should show error message');
306+
assert.isTrue(errorMessage!.includes('exceeds'), 'Error message should mention file size limit');
279307
});
280308

281309
test('should handle import initialization error', async () => {
282310
const mockTextEditor = createMockTextEditor(testFileUri);
311+
let errorMessage: string | undefined;
283312

284313
when(mockedVSCodeNamespaces.window.activeNotebookEditor).thenReturn(undefined);
285314
when(mockedVSCodeNamespaces.window.activeTextEditor).thenReturn(mockTextEditor);
286315

287316
sandbox.stub(fs.promises, 'stat').resolves({ size: 1000 } as fs.Stats);
288317
sandbox.stub(fs.promises, 'readFile').resolves(testFileBuffer);
289-
sandbox.stub(mockedVSCodeNamespaces.window, 'withProgress').callsFake((_options, callback) => {
318+
when(mockedVSCodeNamespaces.window.withProgress(anything(), anything())).thenCall((_options, callback) => {
290319
return callback(
291320
{
292-
report: sinon.stub()
321+
report: () => {
322+
/* no-op */
323+
}
293324
} as any,
294325
{} as any
295326
);
296327
});
297328
const initImportStub = sandbox.stub(importClient, 'initImport').rejects(new Error('Network error'));
298-
const showErrorStub = sandbox.stub(mockedVSCodeNamespaces.window, 'showErrorMessage');
329+
when(mockedVSCodeNamespaces.window.showErrorMessage(anything())).thenCall((message) => {
330+
errorMessage = message;
331+
return Promise.resolve(undefined);
332+
});
299333

300334
await (handler as any).handleOpenInDeepnote();
301335

302336
assert.isTrue(initImportStub.calledOnce, 'Should attempt to initialize import');
303-
assert.isTrue(showErrorStub.calledOnce, 'Should show error message');
337+
assert.isDefined(errorMessage, 'Should show error message');
304338
});
305339

306340
test('should handle upload error', async () => {
307341
const mockTextEditor = createMockTextEditor(testFileUri);
342+
let errorMessage: string | undefined;
308343

309344
when(mockedVSCodeNamespaces.window.activeNotebookEditor).thenReturn(undefined);
310345
when(mockedVSCodeNamespaces.window.activeTextEditor).thenReturn(mockTextEditor);
311346

312347
sandbox.stub(fs.promises, 'stat').resolves({ size: 1000 } as fs.Stats);
313348
sandbox.stub(fs.promises, 'readFile').resolves(testFileBuffer);
314-
sandbox.stub(mockedVSCodeNamespaces.window, 'withProgress').callsFake((_options, callback) => {
349+
when(mockedVSCodeNamespaces.window.withProgress(anything(), anything())).thenCall((_options, callback) => {
315350
return callback(
316351
{
317-
report: sinon.stub()
352+
report: () => {
353+
/* no-op */
354+
}
318355
} as any,
319356
{} as any
320357
);
@@ -325,12 +362,15 @@ suite('OpenInDeepnoteHandler', () => {
325362
expiresAt: '2025-12-31T23:59:59Z'
326363
});
327364
const uploadFileStub = sandbox.stub(importClient, 'uploadFile').rejects(new Error('Upload failed'));
328-
const showErrorStub = sandbox.stub(mockedVSCodeNamespaces.window, 'showErrorMessage');
365+
when(mockedVSCodeNamespaces.window.showErrorMessage(anything())).thenCall((message) => {
366+
errorMessage = message;
367+
return Promise.resolve(undefined);
368+
});
329369

330370
await (handler as any).handleOpenInDeepnote();
331371

332372
assert.isTrue(uploadFileStub.calledOnce, 'Should attempt to upload');
333-
assert.isTrue(showErrorStub.calledOnce, 'Should show error message');
373+
assert.isDefined(errorMessage, 'Should show error message');
334374
});
335375

336376
test('should remove query params from notebook URI', async () => {
@@ -342,10 +382,12 @@ suite('OpenInDeepnoteHandler', () => {
342382

343383
const statStub = sandbox.stub(fs.promises, 'stat').resolves({ size: 1000 } as fs.Stats);
344384
sandbox.stub(fs.promises, 'readFile').resolves(testFileBuffer);
345-
sandbox.stub(mockedVSCodeNamespaces.window, 'withProgress').callsFake((_options, callback) => {
385+
when(mockedVSCodeNamespaces.window.withProgress(anything(), anything())).thenCall((_options, callback) => {
346386
return callback(
347387
{
348-
report: sinon.stub()
388+
report: () => {
389+
/* no-op */
390+
}
349391
} as any,
350392
{} as any
351393
);
@@ -357,7 +399,7 @@ suite('OpenInDeepnoteHandler', () => {
357399
});
358400
sandbox.stub(importClient, 'uploadFile').resolves();
359401
sandbox.stub(importClient, 'getDeepnoteDomain').returns('app.deepnote.com');
360-
sandbox.stub(mockedVSCodeNamespaces.env, 'openExternal').resolves();
402+
when(mockedVSCodeNamespaces.env.openExternal(anything())).thenReturn(Promise.resolve(true));
361403

362404
await (handler as any).handleOpenInDeepnote();
363405

0 commit comments

Comments
 (0)