mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 02:51:36 -05:00
Add Connection String Enhancement for SQL Bindings (#18011)
* sql database work to prompt users to choose connections * add test
This commit is contained in:
@@ -559,3 +559,9 @@ export function jsonParseError(error: string, line: number, column: number) { re
|
|||||||
export const moreInformation = localize('moreInformation', "More Information");
|
export const moreInformation = localize('moreInformation', "More Information");
|
||||||
export const addPackageReferenceMessage = localize('addPackageReferenceMessage', 'To use SQL bindings, ensure your Azure Functions project has a reference to {0}', sqlExtensionPackageName);
|
export const addPackageReferenceMessage = localize('addPackageReferenceMessage', 'To use SQL bindings, ensure your Azure Functions project has a reference to {0}', sqlExtensionPackageName);
|
||||||
export const addSqlBindingPackageError = localize('addSqlBindingPackageError', 'Error adding Sql Binding extension package to project');
|
export const addSqlBindingPackageError = localize('addSqlBindingPackageError', 'Error adding Sql Binding extension package to project');
|
||||||
|
export const failedToGetConnectionString = localize('failedToGetConnectionString', 'An error occurred generating the connection string for the selected connection');
|
||||||
|
export const connectionProfile = localize('connectionProfile', 'Select a connection profile');
|
||||||
|
export const userConnectionString = localize('userConnectionString', 'Enter connection string');
|
||||||
|
export const selectConnectionString = localize('selectConnectionString', 'Select SQL connection string method');
|
||||||
|
export const selectConnectionError = (err?: any) => err ? localize('selectConnectionError', "Failed to set connection string app setting: {0}", utils.getErrorMessage(err)) : localize('unableToSetConnectionString', "Failed to set connection string app setting");
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ import { TelemetryActions, TelemetryReporter, TelemetryViews } from '../common/t
|
|||||||
export async function launchAddSqlBindingQuickpick(uri: vscode.Uri | undefined, packageHelper: PackageHelper): Promise<void> {
|
export async function launchAddSqlBindingQuickpick(uri: vscode.Uri | undefined, packageHelper: PackageHelper): Promise<void> {
|
||||||
TelemetryReporter.sendActionEvent(TelemetryViews.SqlBindingsQuickPick, TelemetryActions.startAddSqlBinding);
|
TelemetryReporter.sendActionEvent(TelemetryViews.SqlBindingsQuickPick, TelemetryActions.startAddSqlBinding);
|
||||||
|
|
||||||
|
const vscodeMssqlApi = await utils.getVscodeMssqlApi();
|
||||||
|
|
||||||
if (!uri) {
|
if (!uri) {
|
||||||
// this command only shows in the command palette when the active editor is a .cs file, so we can safely assume that's the scenario
|
// this command only shows in the command palette when the active editor is a .cs file, so we can safely assume that's the scenario
|
||||||
// when this is called without a uri
|
// when this is called without a uri
|
||||||
@@ -113,16 +115,16 @@ export async function launchAddSqlBindingQuickpick(uri: vscode.Uri | undefined,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let existingSettings: (vscode.QuickPickItem & { isCreateNew?: boolean })[] = [];
|
let existingSettings: (vscode.QuickPickItem)[] = [];
|
||||||
if (settings?.Values) {
|
if (settings?.Values) {
|
||||||
existingSettings = Object.keys(settings.Values).map(setting => {
|
existingSettings = Object.keys(settings.Values).map(setting => {
|
||||||
return {
|
return {
|
||||||
label: setting
|
label: setting
|
||||||
} as vscode.QuickPickItem & { isCreateNew?: boolean };
|
} as vscode.QuickPickItem;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
existingSettings.unshift({ label: constants.createNewLocalAppSettingWithIcon, isCreateNew: true });
|
existingSettings.unshift({ label: constants.createNewLocalAppSettingWithIcon });
|
||||||
let sqlConnectionStringSettingExists = existingSettings.find(s => s.label === constants.sqlConnectionStringSetting);
|
let sqlConnectionStringSettingExists = existingSettings.find(s => s.label === constants.sqlConnectionStringSetting);
|
||||||
|
|
||||||
while (!connectionStringSettingName) {
|
while (!connectionStringSettingName) {
|
||||||
@@ -136,7 +138,7 @@ export async function launchAddSqlBindingQuickpick(uri: vscode.Uri | undefined,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectedSetting.isCreateNew) {
|
if (selectedSetting.label === constants.createNewLocalAppSettingWithIcon) {
|
||||||
const newConnectionStringSettingName = await vscode.window.showInputBox(
|
const newConnectionStringSettingName = await vscode.window.showInputBox(
|
||||||
{
|
{
|
||||||
title: constants.enterConnectionStringSettingName,
|
title: constants.enterConnectionStringSettingName,
|
||||||
@@ -151,7 +153,23 @@ export async function launchAddSqlBindingQuickpick(uri: vscode.Uri | undefined,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const newConnectionStringValue = await vscode.window.showInputBox(
|
// show the connection string methods (user input and connection profile options)
|
||||||
|
const listOfConnectionStringMethods = [constants.connectionProfile, constants.userConnectionString];
|
||||||
|
while (true) {
|
||||||
|
const selectedConnectionStringMethod = await vscode.window.showQuickPick(listOfConnectionStringMethods, {
|
||||||
|
canPickMany: false,
|
||||||
|
title: constants.selectConnectionString,
|
||||||
|
ignoreFocusOut: true
|
||||||
|
});
|
||||||
|
if (!selectedConnectionStringMethod) {
|
||||||
|
// User cancelled
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let connectionString: string = '';
|
||||||
|
if (selectedConnectionStringMethod === constants.userConnectionString) {
|
||||||
|
// User chooses to enter connection string manually
|
||||||
|
connectionString = await vscode.window.showInputBox(
|
||||||
{
|
{
|
||||||
title: constants.enterConnectionString,
|
title: constants.enterConnectionString,
|
||||||
ignoreFocusOut: true,
|
ignoreFocusOut: true,
|
||||||
@@ -159,28 +177,54 @@ export async function launchAddSqlBindingQuickpick(uri: vscode.Uri | undefined,
|
|||||||
validateInput: input => input ? undefined : constants.valueMustNotBeEmpty
|
validateInput: input => input ? undefined : constants.valueMustNotBeEmpty
|
||||||
}
|
}
|
||||||
) ?? '';
|
) ?? '';
|
||||||
|
} else {
|
||||||
if (!newConnectionStringValue) {
|
// Let user choose from existing connections to create connection string from
|
||||||
// go back to select setting quickpick if user escapes from inputting the value in case they changed their mind
|
let connectionUri: string = '';
|
||||||
|
const connectionInfo = await vscodeMssqlApi.promptForConnection(true);
|
||||||
|
if (!connectionInfo) {
|
||||||
|
// User cancelled return to selectedConnectionStringMethod prompt
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const success = await azureFunctionsUtils.setLocalAppSetting(path.dirname(projectUri.fsPath), newConnectionStringSettingName, newConnectionStringValue);
|
// TO DO: https://github.com/microsoft/azuredatastudio/issues/18012
|
||||||
|
connectionUri = await vscodeMssqlApi.connect(connectionInfo);
|
||||||
|
} catch (e) {
|
||||||
|
// display an mssql error due to connection request failing and go back to prompt for connection string methods
|
||||||
|
console.warn(e);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
connectionString = await vscodeMssqlApi.getConnectionString(connectionUri, false);
|
||||||
|
} catch (e) {
|
||||||
|
// failed to get connection string for selected connection and will go back to prompt for connection string methods
|
||||||
|
console.warn(e);
|
||||||
|
void vscode.window.showErrorMessage(constants.failedToGetConnectionString);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (connectionString) {
|
||||||
|
try {
|
||||||
|
const success = await azureFunctionsUtils.setLocalAppSetting(path.dirname(projectUri.fsPath), newConnectionStringSettingName, connectionString);
|
||||||
if (success) {
|
if (success) {
|
||||||
|
// exit both loops and insert binding
|
||||||
connectionStringSettingName = newConnectionStringSettingName;
|
connectionStringSettingName = newConnectionStringSettingName;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
void vscode.window.showErrorMessage(constants.selectConnectionError());
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// display error message and show select setting quickpick again
|
// display error message and show select setting quickpick again
|
||||||
void vscode.window.showErrorMessage(utils.getErrorMessage(e));
|
void vscode.window.showErrorMessage(constants.selectConnectionError(e));
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
// If user cancels out of this or doesn't want to overwrite an existing setting
|
// If user cancels out of this or doesn't want to overwrite an existing setting
|
||||||
// just return them to the select setting quickpick in case they changed their mind
|
// just return them to the select setting quickpick in case they changed their mind
|
||||||
} else {
|
|
||||||
connectionStringSettingName = selectedSetting.label;
|
connectionStringSettingName = selectedSetting.label;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// if no AF project was found or there's more than one AF functions project in the workspace,
|
// if no AF project was found or there's more than one AF functions project in the workspace,
|
||||||
// ask for the user to input the setting name
|
// ask for the user to input the setting name
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import * as utils from '../../common/utils';
|
|||||||
import * as constants from '../../common/constants';
|
import * as constants from '../../common/constants';
|
||||||
import * as azureFunctionUtils from '../../common/azureFunctionsUtils';
|
import * as azureFunctionUtils from '../../common/azureFunctionsUtils';
|
||||||
|
|
||||||
import { createContext, TestContext } from '../testContext';
|
import { createContext, TestContext, createTestCredentials } from '../testContext';
|
||||||
import { launchAddSqlBindingQuickpick } from '../../dialogs/addSqlBindingQuickpick';
|
import { launchAddSqlBindingQuickpick } from '../../dialogs/addSqlBindingQuickpick';
|
||||||
import { PackageHelper } from '../../tools/packageHelper';
|
import { PackageHelper } from '../../tools/packageHelper';
|
||||||
|
|
||||||
@@ -29,6 +29,7 @@ describe('Add SQL Binding quick pick', () => {
|
|||||||
|
|
||||||
it('Should show error if the file contains no Azure Functions', async function (): Promise<void> {
|
it('Should show error if the file contains no Azure Functions', async function (): Promise<void> {
|
||||||
sinon.stub(utils, 'getAzureFunctionService').resolves(testContext.azureFunctionService.object);
|
sinon.stub(utils, 'getAzureFunctionService').resolves(testContext.azureFunctionService.object);
|
||||||
|
sinon.stub(utils, 'getVscodeMssqlApi').resolves(testContext.vscodeMssqlIExtension.object);
|
||||||
const spy = sinon.spy(vscode.window, 'showErrorMessage');
|
const spy = sinon.spy(vscode.window, 'showErrorMessage');
|
||||||
testContext.azureFunctionService.setup(x => x.getAzureFunctions(TypeMoq.It.isAny())).returns(async () => {
|
testContext.azureFunctionService.setup(x => x.getAzureFunctions(TypeMoq.It.isAny())).returns(async () => {
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
@@ -46,6 +47,7 @@ describe('Add SQL Binding quick pick', () => {
|
|||||||
|
|
||||||
it('Should show error if adding SQL binding was not successful', async function (): Promise<void> {
|
it('Should show error if adding SQL binding was not successful', async function (): Promise<void> {
|
||||||
sinon.stub(utils, 'getAzureFunctionService').resolves(testContext.azureFunctionService.object);
|
sinon.stub(utils, 'getAzureFunctionService').resolves(testContext.azureFunctionService.object);
|
||||||
|
sinon.stub(utils, 'getVscodeMssqlApi').resolves(testContext.vscodeMssqlIExtension.object);
|
||||||
const spy = sinon.spy(vscode.window, 'showErrorMessage');
|
const spy = sinon.spy(vscode.window, 'showErrorMessage');
|
||||||
testContext.azureFunctionService.setup(x => x.getAzureFunctions(TypeMoq.It.isAny())).returns(async () => {
|
testContext.azureFunctionService.setup(x => x.getAzureFunctions(TypeMoq.It.isAny())).returns(async () => {
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
@@ -54,6 +56,7 @@ describe('Add SQL Binding quick pick', () => {
|
|||||||
azureFunctions: ['af1', 'af2']
|
azureFunctions: ['af1', 'af2']
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
//failure since no AFs are found in the project
|
||||||
sinon.stub(azureFunctionUtils, 'getAFProjectContainingFile').resolves(undefined);
|
sinon.stub(azureFunctionUtils, 'getAFProjectContainingFile').resolves(undefined);
|
||||||
const errormsg = 'Error inserting binding';
|
const errormsg = 'Error inserting binding';
|
||||||
testContext.azureFunctionService.setup(x => x.addSqlBinding(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(async () => {
|
testContext.azureFunctionService.setup(x => x.addSqlBinding(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(async () => {
|
||||||
@@ -77,5 +80,55 @@ describe('Add SQL Binding quick pick', () => {
|
|||||||
should(spy.calledOnce).be.true('showErrorMessage should have been called exactly once');
|
should(spy.calledOnce).be.true('showErrorMessage should have been called exactly once');
|
||||||
should(spy.calledWith(errormsg)).be.true(`showErrorMessage not called with expected message '${errormsg}' Actual '${spy.getCall(0).args[0]}'`);
|
should(spy.calledWith(errormsg)).be.true(`showErrorMessage not called with expected message '${errormsg}' Actual '${spy.getCall(0).args[0]}'`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Should show error connection profile does not connect', async function (): Promise<void> {
|
||||||
|
sinon.stub(utils, 'getAzureFunctionService').resolves(testContext.azureFunctionService.object);
|
||||||
|
sinon.stub(utils, 'getVscodeMssqlApi').resolves(testContext.vscodeMssqlIExtension.object);
|
||||||
|
let connectionCreds = createTestCredentials();
|
||||||
|
|
||||||
|
sinon.stub(azureFunctionUtils, 'getAFProjectContainingFile').resolves(vscode.Uri.file('testUri'));
|
||||||
|
testContext.azureFunctionService.setup(x => x.getAzureFunctions(TypeMoq.It.isAny())).returns(async () => {
|
||||||
|
return Promise.resolve({
|
||||||
|
success: true,
|
||||||
|
errorMessage: '',
|
||||||
|
azureFunctions: ['af1']
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Mocks connect call to mssql
|
||||||
|
let error = new Error('Connection Request Failed');
|
||||||
|
testContext.vscodeMssqlIExtension.setup(x => x.connect(TypeMoq.It.isAny(), undefined)).throws(error);
|
||||||
|
|
||||||
|
// Mocks promptForConnection
|
||||||
|
testContext.vscodeMssqlIExtension.setup(x => x.promptForConnection(true)).returns(() => Promise.resolve(connectionCreds));
|
||||||
|
let quickpickStub = sinon.stub(vscode.window, 'showQuickPick');
|
||||||
|
// select Azure function
|
||||||
|
quickpickStub.onFirstCall().resolves({ label: 'af1' });
|
||||||
|
// select input or output binding
|
||||||
|
quickpickStub.onSecondCall().resolves({ label: constants.input });
|
||||||
|
|
||||||
|
// give object name
|
||||||
|
let inputBoxStub = sinon.stub(vscode.window, 'showInputBox').onFirstCall().resolves('dbo.table1');
|
||||||
|
|
||||||
|
// select connection profile
|
||||||
|
quickpickStub.onThirdCall().resolves({ label: constants.createNewLocalAppSettingWithIcon });
|
||||||
|
|
||||||
|
// give connection string setting name
|
||||||
|
inputBoxStub.onSecondCall().resolves('SqlConnectionString');
|
||||||
|
|
||||||
|
// select connection profile method
|
||||||
|
quickpickStub.onCall(3).resolves({ label: constants.connectionProfile });
|
||||||
|
|
||||||
|
await launchAddSqlBindingQuickpick(vscode.Uri.file('testUri'), packageHelper);
|
||||||
|
|
||||||
|
// should go back to the select connection string methods
|
||||||
|
should(quickpickStub.callCount === 5);
|
||||||
|
should(quickpickStub.getCall(4).args).deepEqual([
|
||||||
|
[constants.connectionProfile, constants.userConnectionString],
|
||||||
|
{
|
||||||
|
canPickMany: false,
|
||||||
|
ignoreFocusOut: true,
|
||||||
|
title: constants.selectConnectionString
|
||||||
|
}]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ export interface TestContext {
|
|||||||
dacFxService: TypeMoq.IMock<mssql.IDacFxService>;
|
dacFxService: TypeMoq.IMock<mssql.IDacFxService>;
|
||||||
azureFunctionService: TypeMoq.IMock<vscodeMssql.IAzureFunctionsService>;
|
azureFunctionService: TypeMoq.IMock<vscodeMssql.IAzureFunctionsService>;
|
||||||
outputChannel: vscode.OutputChannel;
|
outputChannel: vscode.OutputChannel;
|
||||||
|
vscodeMssqlIExtension: TypeMoq.IMock<vscodeMssql.IExtension>
|
||||||
|
dacFxMssqlService: TypeMoq.IMock<vscodeMssql.IDacFxService>;
|
||||||
|
schemaCompareService: TypeMoq.IMock<vscodeMssql.ISchemaCompareService>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const mockDacFxResult = {
|
export const mockDacFxResult = {
|
||||||
@@ -137,6 +140,137 @@ export class MockAzureFunctionService implements vscodeMssql.IAzureFunctionsServ
|
|||||||
getAzureFunctions(_: string): Thenable<vscodeMssql.GetAzureFunctionsResult> { return Promise.resolve(mockGetAzureFunctionsResult); }
|
getAzureFunctions(_: string): Thenable<vscodeMssql.GetAzureFunctionsResult> { return Promise.resolve(mockGetAzureFunctionsResult); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const mockDacFxMssqlOptionResult: vscodeMssql.DacFxOptionsResult = {
|
||||||
|
success: true,
|
||||||
|
errorMessage: '',
|
||||||
|
deploymentOptions: {
|
||||||
|
ignoreTableOptions: false,
|
||||||
|
ignoreSemicolonBetweenStatements: false,
|
||||||
|
ignoreRouteLifetime: false,
|
||||||
|
ignoreRoleMembership: false,
|
||||||
|
ignoreQuotedIdentifiers: false,
|
||||||
|
ignorePermissions: false,
|
||||||
|
ignorePartitionSchemes: false,
|
||||||
|
ignoreObjectPlacementOnPartitionScheme: false,
|
||||||
|
ignoreNotForReplication: false,
|
||||||
|
ignoreLoginSids: false,
|
||||||
|
ignoreLockHintsOnIndexes: false,
|
||||||
|
ignoreKeywordCasing: false,
|
||||||
|
ignoreIndexPadding: false,
|
||||||
|
ignoreIndexOptions: false,
|
||||||
|
ignoreIncrement: false,
|
||||||
|
ignoreIdentitySeed: false,
|
||||||
|
ignoreUserSettingsObjects: false,
|
||||||
|
ignoreFullTextCatalogFilePath: false,
|
||||||
|
ignoreWhitespace: false,
|
||||||
|
ignoreWithNocheckOnForeignKeys: false,
|
||||||
|
verifyCollationCompatibility: false,
|
||||||
|
unmodifiableObjectWarnings: false,
|
||||||
|
treatVerificationErrorsAsWarnings: false,
|
||||||
|
scriptRefreshModule: false,
|
||||||
|
scriptNewConstraintValidation: false,
|
||||||
|
scriptFileSize: false,
|
||||||
|
scriptDeployStateChecks: false,
|
||||||
|
scriptDatabaseOptions: false,
|
||||||
|
scriptDatabaseCompatibility: false,
|
||||||
|
scriptDatabaseCollation: false,
|
||||||
|
runDeploymentPlanExecutors: false,
|
||||||
|
registerDataTierApplication: false,
|
||||||
|
populateFilesOnFileGroups: false,
|
||||||
|
noAlterStatementsToChangeClrTypes: false,
|
||||||
|
includeTransactionalScripts: false,
|
||||||
|
includeCompositeObjects: false,
|
||||||
|
allowUnsafeRowLevelSecurityDataMovement: false,
|
||||||
|
ignoreWithNocheckOnCheckConstraints: false,
|
||||||
|
ignoreFillFactor: false,
|
||||||
|
ignoreFileSize: false,
|
||||||
|
ignoreFilegroupPlacement: false,
|
||||||
|
doNotAlterReplicatedObjects: false,
|
||||||
|
doNotAlterChangeDataCaptureObjects: false,
|
||||||
|
disableAndReenableDdlTriggers: false,
|
||||||
|
deployDatabaseInSingleUserMode: false,
|
||||||
|
createNewDatabase: false,
|
||||||
|
compareUsingTargetCollation: false,
|
||||||
|
commentOutSetVarDeclarations: false,
|
||||||
|
blockWhenDriftDetected: false,
|
||||||
|
blockOnPossibleDataLoss: false,
|
||||||
|
backupDatabaseBeforeChanges: false,
|
||||||
|
allowIncompatiblePlatform: false,
|
||||||
|
allowDropBlockingAssemblies: false,
|
||||||
|
dropConstraintsNotInSource: false,
|
||||||
|
dropDmlTriggersNotInSource: false,
|
||||||
|
dropExtendedPropertiesNotInSource: false,
|
||||||
|
dropIndexesNotInSource: false,
|
||||||
|
ignoreFileAndLogFilePath: false,
|
||||||
|
ignoreExtendedProperties: false,
|
||||||
|
ignoreDmlTriggerState: false,
|
||||||
|
ignoreDmlTriggerOrder: false,
|
||||||
|
ignoreDefaultSchema: false,
|
||||||
|
ignoreDdlTriggerState: false,
|
||||||
|
ignoreDdlTriggerOrder: false,
|
||||||
|
ignoreCryptographicProviderFilePath: false,
|
||||||
|
verifyDeployment: false,
|
||||||
|
ignoreComments: false,
|
||||||
|
ignoreColumnCollation: false,
|
||||||
|
ignoreAuthorizer: false,
|
||||||
|
ignoreAnsiNulls: false,
|
||||||
|
generateSmartDefaults: false,
|
||||||
|
dropStatisticsNotInSource: false,
|
||||||
|
dropRoleMembersNotInSource: false,
|
||||||
|
dropPermissionsNotInSource: false,
|
||||||
|
dropObjectsNotInSource: false,
|
||||||
|
ignoreColumnOrder: false,
|
||||||
|
doNotDropObjectTypes: [],
|
||||||
|
excludeObjectTypes: []
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export class MockDacFxMssqlService implements vscodeMssql.IDacFxService {
|
||||||
|
public exportBacpac(_: string, __: string, ___: string, ____: vscodeMssql.TaskExecutionMode): Thenable<vscodeMssql.DacFxResult> { return Promise.resolve(mockDacFxResult); }
|
||||||
|
public importBacpac(_: string, __: string, ___: string, ____: vscodeMssql.TaskExecutionMode): Thenable<mssql.DacFxResult> { return Promise.resolve(mockDacFxResult); }
|
||||||
|
public extractDacpac(_: string, __: string, ___: string, ____: string, _____: string, ______: vscodeMssql.TaskExecutionMode): Thenable<mssql.DacFxResult> { return Promise.resolve(mockDacFxResult); }
|
||||||
|
public createProjectFromDatabase(_: string, __: string, ___: string, ____: string, _____: string, ______: vscodeMssql.ExtractTarget, _______: vscodeMssql.TaskExecutionMode): Thenable<vscodeMssql.DacFxResult> { return Promise.resolve(mockDacFxResult); }
|
||||||
|
public deployDacpac(_: string, __: string, ___: boolean, ____: string, _____: vscodeMssql.TaskExecutionMode, ______?: Record<string, string>): Thenable<mssql.DacFxResult> { return Promise.resolve(mockDacFxResult); }
|
||||||
|
public generateDeployScript(_: string, __: string, ___: string, ____: vscodeMssql.TaskExecutionMode, ______?: Record<string, string>): Thenable<mssql.DacFxResult> { return Promise.resolve(mockDacFxResult); }
|
||||||
|
public generateDeployPlan(_: string, __: string, ___: string, ____: vscodeMssql.TaskExecutionMode): Thenable<vscodeMssql.GenerateDeployPlanResult> { return Promise.resolve(mockDacFxResult); }
|
||||||
|
public getOptionsFromProfile(_: string): Thenable<vscodeMssql.DacFxOptionsResult> { return Promise.resolve(mockDacFxMssqlOptionResult); }
|
||||||
|
public validateStreamingJob(_: string, __: string): Thenable<mssql.ValidateStreamingJobResult> { return Promise.resolve(mockDacFxResult); }
|
||||||
|
}
|
||||||
|
|
||||||
|
export class MockSchemaCompareService implements vscodeMssql.ISchemaCompareService {
|
||||||
|
schemaCompareGetDefaultOptions(): Thenable<vscodeMssql.SchemaCompareOptionsResult> {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class MockVscodeMssqlIExtension implements vscodeMssql.IExtension {
|
||||||
|
sqlToolsServicePath: string = '';
|
||||||
|
dacFx: vscodeMssql.IDacFxService;
|
||||||
|
schemaCompare: vscodeMssql.ISchemaCompareService;
|
||||||
|
azureFunctions: vscodeMssql.IAzureFunctionsService;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.dacFx = new MockDacFxMssqlService;
|
||||||
|
this.schemaCompare = new MockSchemaCompareService;
|
||||||
|
this.azureFunctions = new MockAzureFunctionService;
|
||||||
|
}
|
||||||
|
promptForConnection(_?: boolean): Promise<vscodeMssql.IConnectionInfo | undefined> {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
connect(_: vscodeMssql.IConnectionInfo, __?: boolean): Promise<string> {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
listDatabases(_: string): Promise<string[]> {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
getDatabaseNameFromTreeNode(_: vscodeMssql.ITreeNodeInfo): string {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
getConnectionString(__: string, ___?: boolean): Promise<string> {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function createContext(): TestContext {
|
export function createContext(): TestContext {
|
||||||
let extensionPath = path.join(__dirname, '..', '..');
|
let extensionPath = path.join(__dirname, '..', '..');
|
||||||
|
|
||||||
@@ -170,6 +304,9 @@ export function createContext(): TestContext {
|
|||||||
},
|
},
|
||||||
dacFxService: TypeMoq.Mock.ofType(MockDacFxService),
|
dacFxService: TypeMoq.Mock.ofType(MockDacFxService),
|
||||||
azureFunctionService: TypeMoq.Mock.ofType(MockAzureFunctionService),
|
azureFunctionService: TypeMoq.Mock.ofType(MockAzureFunctionService),
|
||||||
|
vscodeMssqlIExtension: TypeMoq.Mock.ofType(MockVscodeMssqlIExtension),
|
||||||
|
dacFxMssqlService: TypeMoq.Mock.ofType(MockDacFxMssqlService),
|
||||||
|
schemaCompareService: TypeMoq.Mock.ofType(MockSchemaCompareService),
|
||||||
outputChannel: {
|
outputChannel: {
|
||||||
name: '',
|
name: '',
|
||||||
append: () => { },
|
append: () => { },
|
||||||
@@ -205,3 +342,41 @@ export const mockConnectionProfile: azdata.IConnectionProfile = {
|
|||||||
connectionName: 'My Connection Name'
|
connectionName: 'My Connection Name'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function createTestCredentials(): vscodeMssql.IConnectionInfo {
|
||||||
|
const creds: vscodeMssql.IConnectionInfo = {
|
||||||
|
server: 'my-server',
|
||||||
|
database: 'my_db',
|
||||||
|
user: 'sa',
|
||||||
|
password: '12345678',
|
||||||
|
email: 'test-email',
|
||||||
|
accountId: 'test-account-id',
|
||||||
|
port: 1234,
|
||||||
|
authenticationType: 'test',
|
||||||
|
azureAccountToken: '',
|
||||||
|
expiresOn: 0,
|
||||||
|
encrypt: false,
|
||||||
|
trustServerCertificate: false,
|
||||||
|
persistSecurityInfo: false,
|
||||||
|
connectTimeout: 15,
|
||||||
|
connectRetryCount: 0,
|
||||||
|
connectRetryInterval: 0,
|
||||||
|
applicationName: 'vscode-mssql',
|
||||||
|
workstationId: 'test',
|
||||||
|
applicationIntent: '',
|
||||||
|
currentLanguage: '',
|
||||||
|
pooling: true,
|
||||||
|
maxPoolSize: 15,
|
||||||
|
minPoolSize: 0,
|
||||||
|
loadBalanceTimeout: 0,
|
||||||
|
replication: false,
|
||||||
|
attachDbFilename: '',
|
||||||
|
failoverPartner: '',
|
||||||
|
multiSubnetFailover: false,
|
||||||
|
multipleActiveResultSets: false,
|
||||||
|
packetSize: 8192,
|
||||||
|
typeSystemVersion: 'Latest',
|
||||||
|
connectionString: ''
|
||||||
|
};
|
||||||
|
return creds;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user