Add Azure Function Service Error/Cancel tests (#19758)

* cleanup tests

* exit/error scenario tests

* remove + from manuallyEnterObjectName

* address comments

* add resolve for writeFile
This commit is contained in:
Vasu Bhog
2022-06-20 15:48:38 -07:00
committed by GitHub
parent 0aadd317fa
commit c5093dbb5a
8 changed files with 151 additions and 39 deletions

View File

@@ -680,7 +680,7 @@ export async function promptSelectTable(connectionURI: string, bindingType: Bind
// Get schema and table names from query result rows
const tableNames = queryResult!.rows.map(r => r[0].displayValue);
// add manual entry option to table names list for user to choose from as well (with pencil icon)
let manuallyEnterObjectName = '$(pencil) ' + userObjectName;
let manuallyEnterObjectName = constants.manuallyEnterObjectName(userObjectName);
tableNames.unshift(manuallyEnterObjectName);
// prompt user to select table from list of tables options
while (true) {

View File

@@ -84,3 +84,4 @@ export function settingAlreadyExists(settingName: string): string { return local
export function failedToParse(filename: string, error: any): string { return localize('failedToParse', 'Failed to parse "{0}": {1}.', filename, utils.getErrorMessage(error)); }
export function addSqlBinding(functionName: string): string { return localize('addSqlBinding', 'Adding SQL Binding to function "{0}"...'), functionName; }
export function errorNewAzureFunction(error: any): string { return localize('errorNewAzureFunction', 'Error creating new Azure Function: {0}', utils.getErrorMessage(error)); }
export function manuallyEnterObjectName(userObjectName: string): string { return `$(pencil) ${userObjectName}`; }

View File

@@ -113,13 +113,13 @@ export async function createAzureFunction(node?: ITreeNodeInfo): Promise<void> {
// Get connection string parameters and construct object name from prompt or connectionInfo given
let objectName: string | undefined;
const vscodeMssqlApi = await utils.getVscodeMssqlApi();
if (!node) {
// if user selects command in command palette we prompt user for information
telemetryStep = CreateAzureFunctionStep.launchFromCommandPalette;
// prompt user for connection profile to get connection info
while (true) {
try {
const vscodeMssqlApi = await utils.getVscodeMssqlApi();
connectionInfo = await vscodeMssqlApi.promptForConnection(true);
} catch (e) {
// user cancelled while creating connection profile

View File

@@ -41,7 +41,7 @@ describe('Add Connection String Execute Step', () => {
// Include Password Prompt - Yes to include password
let quickPickStub = sinon.stub(vscode.window, 'showQuickPick').onFirstCall().resolves((constants.yesString) as any);
// setup stub for setting local app setting with connection string
sinon.stub(fs.promises, 'writeFile');
sinon.stub(fs.promises, 'writeFile').resolves();
sinon.stub(azureFunctionUtils, 'setLocalAppSetting').withArgs(sinon.match.any, sinon.match.any, sinon.match.any).resolves(true);
// call execute step on the AzureWizardExecuteStep

View File

@@ -44,7 +44,7 @@ describe('AzureFunctionUtils', function (): void {
"Values": {"test1": "test1", "test2": "test2", "test3":"test3"}}`
);
let writeFileStub = sinon.stub(fs.promises, 'writeFile');
let writeFileStub = sinon.stub(fs.promises, 'writeFile').resolves();
await azureFunctionsUtils.setLocalAppSetting(path.dirname(localSettingsPath), 'test4', 'test4');
should(writeFileStub.calledWithExactly(localSettingsPath, `{\n "IsEncrypted": false,\n "Values": {\n "test1": "test1",\n "test2": "test2",\n "test3": "test3",\n "test4": "test4"\n }\n}`)).equals(true, 'writeFile should be called with the correct arguments');
});
@@ -77,7 +77,7 @@ describe('AzureFunctionUtils', function (): void {
);
const connectionString = 'testConnectionString';
let writeFileStub = sinon.stub(fs.promises, 'writeFile');
let writeFileStub = sinon.stub(fs.promises, 'writeFile').resolves();
await azureFunctionsUtils.addConnectionStringToConfig(connectionString, rootFolderPath);
should(writeFileStub.calledWithExactly(localSettingsPath, `{\n "IsEncrypted": false,\n "Values": {\n "test1": "test1",\n "test2": "test2",\n "test3": "test3",\n "SqlConnectionString": "testConnectionString"\n }\n}`)).equals(true, 'writeFile should be called with the correct arguments');
});

View File

@@ -71,7 +71,7 @@ describe('Add SQL Binding quick pick', () => {
quickpickStub.onCall(3).resolves((constants.connectionProfile) as any);
quickpickStub.onCall(4).resolves((constants.yesString) as any);
// setLocalAppSetting fails if we dont set writeFile stub
sinon.stub(fs.promises, 'writeFile');
sinon.stub(fs.promises, 'writeFile').resolves();
sinon.stub(azureFunctionUtils, 'setLocalAppSetting').withArgs(sinon.match.any, 'sqlConnectionString', 'testConnectionString1').resolves((true));
sinon.stub(utils, 'executeCommand').resolves('downloaded nuget package');
quickpickStub.onCall(5).resolves(('testDb') as any);
@@ -124,7 +124,7 @@ describe('Add SQL Binding quick pick', () => {
quickpickStub.onCall(3).resolves((constants.connectionProfile) as any);
quickpickStub.onCall(4).resolves((constants.yesString) as any);
// setLocalAppSetting fails if we dont set writeFile stub
sinon.stub(fs.promises, 'writeFile');
sinon.stub(fs.promises, 'writeFile').resolves();
sinon.stub(azureFunctionUtils, 'setLocalAppSetting').withArgs(sinon.match.any, 'sqlConnectionString', 'testConnectionString2').resolves((true));
sinon.stub(utils, 'executeCommand').resolves('downloaded nuget package');
quickpickStub.onCall(5).resolves(('testDb') as any);

View File

@@ -23,15 +23,10 @@ const rootFolderPath = 'test';
const projectFilePath: string = path.join(rootFolderPath, 'test.csproj');
let testUtils: TestUtils;
describe('AzureFunctionsService', () => {
beforeEach(function (): void {
testUtils = createTestUtils();
});
describe('Create Azure Function with SQL Binding', () => {
beforeEach(function (): void {
testUtils = createTestUtils();
});
afterEach(function (): void {
sinon.restore();
});
it('Should show info message to install azure functions extension if not installed', async function (): Promise<void> {
const infoStub = sinon.stub(vscode.window, 'showInformationMessage').resolves(undefined);
await azureFunctionService.createAzureFunction();
@@ -46,8 +41,7 @@ describe('AzureFunctionsService', () => {
sinon.stub(azureFunctionUtils, 'getAzureFunctionProject').resolves(projectFilePath); //set azure function project to have one project
sinon.stub(utils, 'getVscodeMssqlApi').resolves(testUtils.vscodeMssqlIExtension.object);
let connectionInfo: IConnectionInfo = createTestCredentials();// Mocks promptForConnection
connectionInfo.database = 'testDb';
let connectionInfo: IConnectionInfo = createTestCredentials();// create test connectionInfo
let connectionDetails = { options: connectionInfo };
testUtils.vscodeMssqlIExtension.setup(x => x.getConnectionString(connectionDetails, true, false)).returns(() => Promise.resolve('testConnectionString'));
@@ -55,43 +49,45 @@ describe('AzureFunctionsService', () => {
const showErrorMessageSpy = sinon.spy(vscode.window, 'showErrorMessage');
// select input or output binding
let quickpickStub = sinon.stub(vscode.window, 'showQuickPick').resolves(<any>{ label: constants.input, type: BindingType.input });
let quickPickStub = sinon.stub(vscode.window, 'showQuickPick').resolves(<any>{ label: constants.input, type: BindingType.input });
// no table used for connection info so prompt user to get connection info
testUtils.vscodeMssqlIExtension.setup(x => x.promptForConnection(true)).returns(() => Promise.resolve(connectionInfo));
testUtils.vscodeMssqlIExtension.setup(x => x.connect(connectionInfo)).returns(() => Promise.resolve('testConnectionURI'));
testUtils.vscodeMssqlIExtension.setup(x => x.listDatabases('testConnectionURI')).returns(() => Promise.resolve(['testDb']));
// select the testDB from list of databases based on connection info
quickpickStub.onSecondCall().resolves(('testDb') as any);
quickPickStub.onSecondCall().resolves(('testDb') as any);
// get tables from selected database
const params = { ownerUri: 'testConnectionURI', queryString: azureFunctionUtils.tablesQuery('testDb') };
testUtils.vscodeMssqlIExtension.setup(x => x.sendRequest(azureFunctionsContracts.SimpleExecuteRequest.type, params))
.returns(() => Promise.resolve({ rowCount: 1, columnInfo: [], rows: [['[schema].[testTable]']] }));
.returns(() => Promise.resolve({ rowCount: 1, columnInfo: [], rows: [[{ displayValue: '[schema].[testTable]' }]] }));
// select the schema.testTable from list of tables based on connection info and database
quickpickStub.onThirdCall().resolves(('[schema].[testTable]') as any);
quickPickStub.onThirdCall().resolves(('[schema].[testTable]') as any);
// set azure function name
let inputStub = sinon.stub(vscode.window, 'showInputBox').resolves('testFunctionName');
// promptAndUpdateConnectionStringSetting
quickpickStub.onCall(3).resolves(<any>{ label: constants.createNewLocalAppSettingWithIcon });
quickPickStub.onCall(3).resolves(<any>{ label: constants.createNewLocalAppSettingWithIcon });
inputStub.onSecondCall().resolves('SqlConnectionString');
// promptConnectionStringPasswordAndUpdateConnectionString - tested in AzureFunctionUtils.test.ts
quickpickStub.onCall(4).resolves((constants.yesString) as any);
quickPickStub.onCall(4).resolves((constants.yesString) as any);
testUtils.vscodeMssqlIExtension.setup(x => x.getConnectionString(connectionDetails, true, false)).returns(() => Promise.resolve('testConnectionString'));
// setLocalAppSetting with connection string setting name and connection string
// fails if we dont set writeFile stub
sinon.stub(fs.promises, 'writeFile');
sinon.stub(fs.promises, 'writeFile').resolves();
sinon.stub(azureFunctionUtils, 'setLocalAppSetting').withArgs(sinon.match.any, 'SqlConnectionString', 'testConnectionString').resolves((true));
sinon.stub(utils, 'executeCommand').resolves('downloaded nuget package');
const testWatcher = TypeMoq.Mock.ofType<vscode.FileSystemWatcher>().object;
sinon.stub(azureFunctionUtils, 'waitForNewFunctionFile').withArgs(sinon.match.any).returns({ filePromise: Promise.resolve('TestFileCreated'), watcherDisposable: testWatcher });
should(connectionInfo.database).equal('my_db', 'ConnectionInfo database should not be changed');
await azureFunctionService.createAzureFunction();
should(showErrorMessageSpy.notCalled).be.true('showErrorMessage should not have been called');
// set the connection info to be the one the user selects from list of databases quickpick
should(connectionInfo.database).equal('testDb', 'connectionInfo.database should be testDb after user selects testDb');
should(connectionInfo.database).equal('testDb', 'connectionInfo.database should be testDb after user selects testDb');
});
it('Should create azure function project using command via the sql server table OE', async function (): Promise<void> {
@@ -100,14 +96,14 @@ describe('AzureFunctionsService', () => {
sinon.stub(azureFunctionUtils, 'getAzureFunctionProject').resolves(projectFilePath); //set azure function project to have one project
sinon.stub(utils, 'getVscodeMssqlApi').resolves(testUtils.vscodeMssqlIExtension.object);
let connectionInfo: IConnectionInfo = createTestCredentials();// Mocks promptForConnection
let connectionInfo: IConnectionInfo = createTestCredentials();// create test connectionInfo
let connectionDetails = { options: connectionInfo };
testUtils.vscodeMssqlIExtension.setup(x => x.getConnectionString(connectionDetails, true, false)).returns(() => Promise.resolve('testConnectionString'));
const showErrorMessageSpy = sinon.spy(vscode.window, 'showErrorMessage');
// select input or output binding
let quickpickStub = sinon.stub(vscode.window, 'showQuickPick').resolves(<any>{ label: constants.input, type: BindingType.input });
let quickPickStub = sinon.stub(vscode.window, 'showQuickPick').resolves(<any>{ label: constants.input, type: BindingType.input });
// table node used when creating azure function project
let tableTestNode = createTestTableNode(connectionInfo);
@@ -115,25 +111,26 @@ describe('AzureFunctionsService', () => {
let inputStub = sinon.stub(vscode.window, 'showInputBox').resolves('testFunctionName');
// promptAndUpdateConnectionStringSetting
quickpickStub.onSecondCall().resolves(<any>{ label: constants.createNewLocalAppSettingWithIcon });
quickPickStub.onSecondCall().resolves(<any>{ label: constants.createNewLocalAppSettingWithIcon });
inputStub.onSecondCall().resolves('SqlConnectionString');
// promptConnectionStringPasswordAndUpdateConnectionString - tested in AzureFunctionUtils.test.ts
quickpickStub.onThirdCall().resolves((constants.yesString) as any);
quickPickStub.onThirdCall().resolves((constants.yesString) as any);
testUtils.vscodeMssqlIExtension.setup(x => x.getConnectionString(connectionDetails, true, false)).returns(() => Promise.resolve('testConnectionString'));
// setLocalAppSetting with connection string setting name and connection string
// fails if we dont set writeFile stub
sinon.stub(fs.promises, 'writeFile');
sinon.stub(fs.promises, 'writeFile').resolves();
sinon.stub(azureFunctionUtils, 'setLocalAppSetting').withArgs(sinon.match.any, 'SqlConnectionString', 'testConnectionString').resolves((true));
sinon.stub(utils, 'executeCommand').resolves('downloaded nuget package');
const testWatcher = TypeMoq.Mock.ofType<vscode.FileSystemWatcher>().object;
sinon.stub(azureFunctionUtils, 'waitForNewFunctionFile').withArgs(sinon.match.any).returns({ filePromise: Promise.resolve('TestFileCreated'), watcherDisposable: testWatcher });
should(connectionInfo.database).equal('my_db', 'ConnectionInfo database should not be changed');
await azureFunctionService.createAzureFunction(tableTestNode);
should(showErrorMessageSpy.notCalled).be.true('showErrorMessage should not have been called');
// set the connection info to be the one used from the test table node from OE
should(connectionInfo.database).equal('testDb','connectionInfo.database should be testDb after user selects testDb');
should(connectionInfo.database).equal('testDb', 'connectionInfo.database should be testDb after user selects testDb');
});
it('Should open link to learn more about SQL bindings when no azure function project found in folder or workspace', async function (): Promise<void> {
@@ -141,7 +138,7 @@ describe('AzureFunctionsService', () => {
sinon.stub(azureFunctionUtils, 'getAzureFunctionsExtensionApi').resolves(testUtils.azureFunctionsExtensionApi.object); // set azure functions extension api
sinon.stub(utils, 'getVscodeMssqlApi').resolves(testUtils.vscodeMssqlIExtension.object);
let connectionInfo: IConnectionInfo = createTestCredentials();// Mocks promptForConnection
let connectionInfo: IConnectionInfo = createTestCredentials();// create test connectionInfo
let connectionDetails = { options: connectionInfo };
testUtils.vscodeMssqlIExtension.setup(x => x.getConnectionString(connectionDetails, true, false)).returns(() => Promise.resolve('testConnectionString'));
@@ -158,7 +155,7 @@ describe('AzureFunctionsService', () => {
sinon.stub(azureFunctionUtils, 'getAzureFunctionsExtensionApi').resolves(testUtils.azureFunctionsExtensionApi.object); // set azure functions extension api
sinon.stub(utils, 'getVscodeMssqlApi').resolves(testUtils.vscodeMssqlIExtension.object);
let connectionInfo: IConnectionInfo = createTestCredentials();// Mocks promptForConnection
let connectionInfo: IConnectionInfo = createTestCredentials();// create test connectionInfo
let connectionDetails = { options: connectionInfo };
testUtils.vscodeMssqlIExtension.setup(x => x.getConnectionString(connectionDetails, true, false)).returns(() => Promise.resolve('testConnectionString'));
@@ -166,12 +163,12 @@ describe('AzureFunctionsService', () => {
const showErrorStub = sinon.stub(vscode.window, 'showErrorMessage').resolves((constants.createProject) as any);
// user chooses to browse for folder
let quickpickStub = sinon.stub(vscode.window, 'showQuickPick').resolves((constants.browseEllipsisWithIcon) as any);
let quickPickStub = sinon.stub(vscode.window, 'showQuickPick').resolves((constants.browseEllipsisWithIcon) as any);
// stub out folder to be chosen (showOpenDialog)
sinon.stub(vscode.window, 'showOpenDialog').withArgs(sinon.match.any).resolves([vscode.Uri.file(projectFilePath)]);
// select input or output binding
quickpickStub.onSecondCall().resolves(<any>{ label: constants.input, type: BindingType.input });
quickPickStub.onSecondCall().resolves(<any>{ label: constants.input, type: BindingType.input });
// table node used when creating azure function project
let tableTestNode = createTestTableNode(connectionInfo);
@@ -179,23 +176,137 @@ describe('AzureFunctionsService', () => {
let inputStub = sinon.stub(vscode.window, 'showInputBox').resolves('testFunctionName');
// promptAndUpdateConnectionStringSetting
quickpickStub.onThirdCall().resolves(<any>{ label: constants.createNewLocalAppSettingWithIcon });
quickPickStub.onThirdCall().resolves(<any>{ label: constants.createNewLocalAppSettingWithIcon });
inputStub.onSecondCall().resolves('SqlConnectionString');
// promptConnectionStringPasswordAndUpdateConnectionString - tested in AzureFunctionUtils.test.ts
quickpickStub.onCall(3).resolves((constants.yesString) as any);
quickPickStub.onCall(3).resolves((constants.yesString) as any);
testUtils.vscodeMssqlIExtension.setup(x => x.getConnectionString(connectionDetails, true, false)).returns(() => Promise.resolve('testConnectionString'));
// setLocalAppSetting with connection string setting name and connection string
// fails if we dont set writeFile stub
sinon.stub(fs.promises, 'writeFile');
sinon.stub(fs.promises, 'writeFile').resolves();
sinon.stub(azureFunctionUtils, 'setLocalAppSetting').withArgs(sinon.match.any, 'SqlConnectionString', 'testConnectionString').resolves((true));
sinon.stub(utils, 'executeCommand').resolves('downloaded nuget package');
const testWatcher = TypeMoq.Mock.ofType<vscode.FileSystemWatcher>().object;
sinon.stub(azureFunctionUtils, 'waitForNewFunctionFile').withArgs(sinon.match.any).returns({ filePromise: Promise.resolve('TestFileCreated'), watcherDisposable: testWatcher });
should(connectionInfo.database).equal('my_db', 'ConnectionInfo database should not be changed');
await azureFunctionService.createAzureFunction(tableTestNode);
should(showErrorStub.calledOnce).be.true('showErrorMessage should have been called');
});
});
describe('Cancel/Error scenarios for Azure Function with SQL Binding ', function (): void {
let quickPickStub: sinon.SinonStub;
beforeEach(function (): void {
sinon.stub(azureFunctionUtils, 'getAzureFunctionsExtensionApi').resolves(testUtils.azureFunctionsExtensionApi.object); // set azure functions extension api
sinon.stub(azureFunctionUtils, 'getAzureFunctionProject').resolves(projectFilePath); //set azure function project to have one project
sinon.stub(utils, 'getVscodeMssqlApi').resolves(testUtils.vscodeMssqlIExtension.object);
// select input or output binding
quickPickStub = sinon.stub(vscode.window, 'showQuickPick').resolves(<any>{ label: constants.input, type: BindingType.input });
});
it('Should prompt connection profile when user cancels selecting database', async function (): Promise<void> {
// This test will have an azure function project already in the project and the azure functions extension installed (stubbed)
let connectionInfo: IConnectionInfo = createTestCredentials();// create test connectionInfo
// promptForConnection is selected first time for user and then set undefined in order to exit out of the createFunction
let promptForConnectionStub = sinon.stub(testUtils.vscodeMssqlIExtension.object, 'promptForConnection').withArgs(true).onFirstCall().resolves(connectionInfo);
promptForConnectionStub.onSecondCall().resolves(undefined);
// required calls to get databases list for setting up promptForDatabase
testUtils.vscodeMssqlIExtension.setup(x => x.connect(connectionInfo)).returns(() => Promise.resolve('testConnectionURI'));
testUtils.vscodeMssqlIExtension.setup(x => x.listDatabases('testConnectionURI')).returns(() => Promise.resolve(['testDb']));
// cancel out of promptForDatabase - select database to use
quickPickStub.onSecondCall().resolves(undefined);
await azureFunctionService.createAzureFunction();
// promptForConnection should be prompted twice since the user cancels the quickpick to select database
should(promptForConnectionStub.callCount).equal(2, 'promptForConnection should have been called 2 times only');
});
it('Should prompt connection profile when user cancels selecting table', async function (): Promise<void> {
// This test will re-prompt the user to choose connection profile
let connectionInfo: IConnectionInfo = createTestCredentials();// create test connectionInfo
// promptForConnection is selected first time for user
let promptForConnectionStub = sinon.stub(testUtils.vscodeMssqlIExtension.object, 'promptForConnection').withArgs(true).onFirstCall().resolves(connectionInfo);
// required calls to get databases list for setting up promptForDatabase
testUtils.vscodeMssqlIExtension.setup(x => x.connect(connectionInfo)).returns(() => Promise.resolve('testConnectionURI'));
testUtils.vscodeMssqlIExtension.setup(x => x.listDatabases('testConnectionURI')).returns(() => Promise.resolve(['testDb']));
// select the testDB for promptForDatabase
quickPickStub.onSecondCall().resolves(('testDb') as any);
// get tables from selected database
const params = { ownerUri: 'testConnectionURI', queryString: azureFunctionUtils.tablesQuery('testDb') };
testUtils.vscodeMssqlIExtension.setup(x => x.sendRequest(azureFunctionsContracts.SimpleExecuteRequest.type, params))
.returns(() => Promise.resolve({ rowCount: 1, columnInfo: [], rows: [[{ displayValue: '[schema].[testTable]' }]] }));
// cancel out of promptForTables - select table to use
quickPickStub.onThirdCall().resolves(undefined);
// resolve promises to undefined to exit out of createFunction
promptForConnectionStub.onSecondCall().resolves(undefined);
await azureFunctionService.createAzureFunction();
// promptForConnection should be prompted twice since the user cancels the quickpick to select table
should(promptForConnectionStub.callCount).equal(2, 'promptForConnection should have been called 2 times only');
});
it('Should prompt select table when user cancels out of manually entering table', async function (): Promise<void> {
// This test will have an azure function project already in the project and the azure functions extension installed (stubbed)
let connectionInfo: IConnectionInfo = createTestCredentials();// create test connectionInfo
// no table used for connection info so prompt user to get connection info
// promptForConnection is set first time for user
let promptForConnectionStub = sinon.stub(testUtils.vscodeMssqlIExtension.object, 'promptForConnection').withArgs(true).onFirstCall().resolves(connectionInfo);
// setup listDatabases request with connectionURI
testUtils.vscodeMssqlIExtension.setup(x => x.connect(connectionInfo)).returns(() => Promise.resolve('testConnectionURI'));
testUtils.vscodeMssqlIExtension.setup(x => x.listDatabases('testConnectionURI')).returns(() => Promise.resolve(['testDb']));
// select the testDB from list of databases based on connection info
quickPickStub.onSecondCall().resolves(('testDb') as any);
// get tables from selected database
const params = { ownerUri: 'testConnectionURI', queryString: azureFunctionUtils.tablesQuery('testDb') };
testUtils.vscodeMssqlIExtension.setup(x => x.sendRequest(azureFunctionsContracts.SimpleExecuteRequest.type, params))
.returns(() => Promise.resolve({ rowCount: 1, columnInfo: [], rows: [[{ displayValue: '[schema].[testTable]' }]] }));
// select the option to manually enter table name
let manuallyEnterObjectName = constants.manuallyEnterObjectName(constants.enterObjectName);
quickPickStub.onThirdCall().resolves(manuallyEnterObjectName as any);
// cancel out of manually enter inputBox
sinon.stub(vscode.window, 'showInputBox').resolves(undefined);
// resolve promises to undefined to exit out of createFunction
quickPickStub.onCall(4).resolves(undefined);
promptForConnectionStub.onSecondCall().resolves(undefined);
should(connectionInfo.database).equal('my_db', 'ConnectionInfo database should not be changed');
await azureFunctionService.createAzureFunction();
should(connectionInfo.database).equal('testDb', 'ConnectionInfo database should be user selected database');
should(quickPickStub.getCall(3).args).containDeepOrdered([
[manuallyEnterObjectName, '[schema].[testTable]'],
{
canPickMany: false,
title: constants.selectTable,
ignoreFocusOut: true
}]
);
});
it('Should prompt for connection profile if connection throws connection error', async function (): Promise<void> {
// no table used for connection info so prompt user to get connection info
// promptForConnection is selected first time for user and then set undefined in order to exit out of the createFunction
let promptForConnectionStub = sinon.stub(testUtils.vscodeMssqlIExtension.object, 'promptForConnection').withArgs(true).throws('Error connecting to connection profile');
promptForConnectionStub.onSecondCall().resolves(undefined);
await azureFunctionService.createAzureFunction();
// re prompt the promptForConnection if the first connection throws an error
should(promptForConnectionStub.callCount).equal(2, 'promptForConnection should have been called 2 times only');
});
});
afterEach(function (): void {
sinon.restore();
});
});

View File

@@ -14,7 +14,7 @@ export interface TestUtils {
context: vscode.ExtensionContext;
dacFxService: TypeMoq.IMock<mssql.IDacFxService>;
outputChannel: vscode.OutputChannel;
vscodeMssqlIExtension: TypeMoq.IMock<vscodeMssql.IExtension>
vscodeMssqlIExtension: TypeMoq.IMock<vscodeMssql.IExtension>;
dacFxMssqlService: TypeMoq.IMock<vscodeMssql.IDacFxService>;
schemaCompareService: TypeMoq.IMock<vscodeMssql.ISchemaCompareService>;
azureFunctionsExtensionApi: TypeMoq.IMock<AzureFunctionsExtensionApi>;