Add tests to NotebookUriHandler (#11959)

* NotebookUriHandler Test

* set test to previous, return promise for handleUri

* Added tests for file uri scheme https/http

* Updated NotebookUri to await handleUri calls and add more tests
This commit is contained in:
Vasu Bhog
2020-08-28 10:51:12 -05:00
committed by GitHub
parent 795300347b
commit d59063ebab
5 changed files with 145 additions and 7 deletions

View File

@@ -593,6 +593,7 @@
"mocha": "^5.2.0",
"mocha-junit-reporter": "^1.17.0",
"mocha-multi-reporters": "^1.1.7",
"nock": "^13.0.2",
"should": "^13.2.3",
"sinon": "^9.0.2",
"typemoq": "^2.1.0",

View File

@@ -10,6 +10,8 @@ const localize = nls.loadMessageBundle();
// CONFIG VALUES ///////////////////////////////////////////////////////////
export const extensionOutputChannelName = 'Notebooks';
export const notebookCommandNew = 'notebook.command.new';
// JUPYTER CONFIG //////////////////////////////////////////////////////////
export const pythonBundleVersion = '0.0.1';
export const pythonVersion = '3.6.6';

View File

@@ -14,6 +14,8 @@ const localize = nls.loadMessageBundle();
import { IQuestion, confirm } from '../prompts/question';
import CodeAdapter from '../prompts/adapter';
import { getErrorMessage, isEditorTitleFree } from '../common/utils';
import * as constants from '../common/constants';
export class NotebookUriHandler implements vscode.UriHandler {
private prompter = new CodeAdapter();
@@ -24,24 +26,22 @@ export class NotebookUriHandler implements vscode.UriHandler {
handleUri(uri: vscode.Uri): vscode.ProviderResult<void> {
switch (uri.path) {
case '/new':
vscode.commands.executeCommand('notebook.command.new');
break;
return vscode.commands.executeCommand(constants.notebookCommandNew);
case '/open':
this.open(uri);
break;
return this.open(uri);
default:
vscode.window.showErrorMessage(localize('notebook.unsupportedAction', "Action {0} is not supported for this handler", uri.path));
}
}
private open(uri: vscode.Uri): void {
private open(uri: vscode.Uri): Promise<void> {
const data = querystring.parse(uri.query);
if (!data.url) {
console.warn('Failed to open URI:', uri);
}
this.openNotebook(data.url);
return this.openNotebook(data.url);
}
private async openNotebook(url: string | string[]): Promise<void> {

View File

@@ -0,0 +1,115 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'mocha';
import * as vscode from 'vscode';
import * as sinon from 'sinon';
import * as azdata from 'azdata';
import * as nock from 'nock';
import * as loc from '../../common/localizedConstants';
import * as constants from '../../common/constants';
import { NotebookUriHandler } from '../../protocol/notebookUriHandler';
describe('Notebook URI Handler', function (): void {
let notebookUriHandler: NotebookUriHandler;
let showErrorMessageSpy: sinon.SinonSpy;
let executeCommandSpy: sinon.SinonSpy;
let showNotebookDocumentStub: sinon.SinonStub;
const notebookUri = vscode.Uri.parse('azuredatastudio://microsoft.notebook/open?url=https%3A%2F%2F127.0.0.1/Hello.ipynb');
const notebookContent = 'test content';
beforeEach(() => {
showErrorMessageSpy = sinon.spy(vscode.window, 'showErrorMessage');
executeCommandSpy = sinon.spy(vscode.commands, 'executeCommand');
notebookUriHandler = new NotebookUriHandler();
showNotebookDocumentStub = sinon.stub(azdata.nb, 'showNotebookDocument');
});
afterEach(function (): void {
sinon.restore();
nock.cleanAll();
nock.enableNetConnect();
});
it('should handle empty string gracefully', async function (): Promise<void> {
await notebookUriHandler.handleUri(vscode.Uri.parse(''));
sinon.assert.calledOnce(showErrorMessageSpy);
sinon.assert.neverCalledWith(executeCommandSpy, constants.notebookCommandNew);
sinon.assert.notCalled(showNotebookDocumentStub);
});
it('should create new notebook when new passed in', async function (): Promise<void> {
await notebookUriHandler.handleUri(vscode.Uri.parse('azuredatastudio://microsoft.notebook/new'));
sinon.assert.calledWith(executeCommandSpy, constants.notebookCommandNew);
});
it('should show error message when no query passed into open', async function (): Promise<void> {
await notebookUriHandler.handleUri(vscode.Uri.parse('azuredatastudio://microsoft.notebook/open'));
sinon.assert.calledOnce(showErrorMessageSpy);
});
it('should show error message when file uri scheme is not https or http', async function (): Promise<void> {
await notebookUriHandler.handleUri(vscode.Uri.parse('azuredatastudio://microsoft.notebook/open?file://hello.ipynb'));
sinon.assert.calledOnce(showErrorMessageSpy);
});
it('should show error when file is not found given file uri scheme https', async function (): Promise<void> {
let showQuickPickStub = sinon.stub(vscode.window, 'showQuickPick').resolves(Promise.resolve(loc.msgYes) as any);
await notebookUriHandler.handleUri(notebookUri);
sinon.assert.calledOnce(showQuickPickStub);
sinon.assert.callCount(showErrorMessageSpy, 1);
});
it('should show error when file is not found given file uri scheme http', async function (): Promise<void> {
let notebookUriHttp = vscode.Uri.parse('azuredatastudio://microsoft.notebook/open?url=http%3A%2F%2F127.0.0.1/Hello.ipynb');
let showQuickPickStub = sinon.stub(vscode.window, 'showQuickPick').resolves(Promise.resolve(loc.msgYes) as any);
await notebookUriHandler.handleUri(notebookUriHttp);
sinon.assert.calledOnce(showQuickPickStub);
sinon.assert.callCount(showErrorMessageSpy, 1);
});
it('should open the notebook when file uri is valid', async function (): Promise<void> {
let showQuickPickStub = sinon.stub(vscode.window, 'showQuickPick').resolves(Promise.resolve(loc.msgYes) as any);
nock('https://127.0.0.1')
.get(`/Hello.ipynb`)
.reply(200, notebookContent);
await notebookUriHandler.handleUri(notebookUri);
sinon.assert.calledOnce(showQuickPickStub);
sinon.assert.neverCalledWith(showErrorMessageSpy);
sinon.assert.calledWith(showNotebookDocumentStub, sinon.match.any, sinon.match({ initialContent: notebookContent }));
});
it('should not download notebook when user declines prompt', async function (): Promise<void> {
let showQuickPickStub = sinon.stub(vscode.window, 'showQuickPick').resolves(Promise.resolve(loc.msgNo) as any);
await notebookUriHandler.handleUri(notebookUri);
sinon.assert.calledOnce(showQuickPickStub);
sinon.assert.notCalled(showNotebookDocumentStub);
sinon.assert.callCount(showErrorMessageSpy, 0);
});
[403, 404, 500].forEach(httpErrorCode => {
it(`should reject when HTTP error ${httpErrorCode} occurs`, async function (): Promise<void> {
sinon.stub(vscode.window, 'showQuickPick').returns(Promise.resolve(loc.msgYes) as any);
nock('https://127.0.0.1')
.get(`/Hello.ipynb`)
.reply(httpErrorCode);
await notebookUriHandler.handleUri(notebookUri);
sinon.assert.callCount(showErrorMessageSpy, 1);
sinon.assert.notCalled(showNotebookDocumentStub);
});
});
});

View File

@@ -1113,7 +1113,7 @@ json-stable-stringify@^1.0.1:
dependencies:
jsonify "~0.0.0"
json-stringify-safe@~5.0.1:
json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
@@ -1157,6 +1157,11 @@ lodash.get@^4.4.2:
resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=
lodash.set@^4.3.2:
version "4.3.2"
resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23"
integrity sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=
lodash@^4.16.4, lodash@^4.17.13, lodash@^4.17.4:
version "4.17.19"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b"
@@ -1329,6 +1334,16 @@ nise@^4.0.1:
just-extend "^4.0.2"
path-to-regexp "^1.7.0"
nock@^13.0.2:
version "13.0.4"
resolved "https://registry.yarnpkg.com/nock/-/nock-13.0.4.tgz#9fb74db35d0aa056322e3c45be14b99105cd7510"
integrity sha512-alqTV8Qt7TUbc74x1pKRLSENzfjp4nywovcJgi/1aXDiUxXdt7TkruSTF5MDWPP7UoPVgea4F9ghVdmX0xxnSA==
dependencies:
debug "^4.1.0"
json-stringify-safe "^5.0.1"
lodash.set "^4.3.2"
propagate "^2.0.0"
node-fetch@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.3.0.tgz#1a1d940bbfb916a1d3e0219f037e89e71f8c5fa5"
@@ -1398,6 +1413,11 @@ postinstall-build@^5.0.1:
resolved "https://registry.yarnpkg.com/postinstall-build/-/postinstall-build-5.0.3.tgz#238692f712a481d8f5bc8960e94786036241efc7"
integrity sha512-vPvPe8TKgp4FLgY3+DfxCE5PIfoXBK2lyLfNCxsRbDsV6vS4oU5RG/IWxrblMn6heagbnMED3MemUQllQ2bQUg==
propagate@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/propagate/-/propagate-2.0.1.tgz#40cdedab18085c792334e64f0ac17256d38f9a45"
integrity sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==
psl@^1.1.24:
version "1.1.31"
resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.31.tgz#e9aa86d0101b5b105cbe93ac6b784cd547276184"