diff --git a/extensions/schema-compare/media/connect.svg b/extensions/schema-compare/media/connect.svg
new file mode 100644
index 0000000000..29e7182774
--- /dev/null
+++ b/extensions/schema-compare/media/connect.svg
@@ -0,0 +1,3 @@
+
diff --git a/extensions/schema-compare/media/selectConnection.svg b/extensions/schema-compare/media/selectConnection.svg
new file mode 100644
index 0000000000..44d7aa82f9
--- /dev/null
+++ b/extensions/schema-compare/media/selectConnection.svg
@@ -0,0 +1,10 @@
+
diff --git a/extensions/schema-compare/src/dialogs/schemaCompareDialog.ts b/extensions/schema-compare/src/dialogs/schemaCompareDialog.ts
index 43756fcc13..97a92f901e 100644
--- a/extensions/schema-compare/src/dialogs/schemaCompareDialog.ts
+++ b/extensions/schema-compare/src/dialogs/schemaCompareDialog.ts
@@ -6,6 +6,7 @@
import * as azdata from 'azdata';
import * as vscode from 'vscode';
import * as loc from '../localizedConstants';
+import * as path from 'path';
import { SchemaCompareMainWindow } from '../schemaCompareMainWindow';
import { TelemetryReporter, TelemetryViews } from '../telemetry';
import { getEndpointName, getRootPath, exists } from '../utils';
@@ -27,18 +28,18 @@ export class SchemaCompareDialog {
private sourceTextBox: azdata.InputBoxComponent;
private sourceFileButton: azdata.ButtonComponent;
private sourceServerComponent: azdata.FormComponent;
- private sourceServerDropdown: azdata.DropDownComponent;
+ protected sourceServerDropdown: azdata.DropDownComponent;
+ private sourceConnectionButton: azdata.ButtonComponent;
private sourceDatabaseComponent: azdata.FormComponent;
private sourceDatabaseDropdown: azdata.DropDownComponent;
- private sourceNoActiveConnectionsText: azdata.FormComponent;
private targetDacpacComponent: azdata.FormComponent;
private targetTextBox: azdata.InputBoxComponent;
private targetFileButton: azdata.ButtonComponent;
private targetServerComponent: azdata.FormComponent;
- private targetServerDropdown: azdata.DropDownComponent;
+ protected targetServerDropdown: azdata.DropDownComponent;
+ private targetConnectionButton: azdata.ButtonComponent;
private targetDatabaseComponent: azdata.FormComponent;
private targetDatabaseDropdown: azdata.DropDownComponent;
- private targetNoActiveConnectionsText: azdata.FormComponent;
private formBuilder: azdata.FormBuilder;
private sourceIsDacpac: boolean;
private targetIsDacpac: boolean;
@@ -50,7 +51,12 @@ export class SchemaCompareDialog {
private initDialogComplete: Deferred;
private initDialogPromise: Promise = new Promise((resolve, reject) => this.initDialogComplete = { resolve, reject });
- constructor(private schemaCompareMainWindow: SchemaCompareMainWindow, private view?: azdata.ModelView) {
+ private textBoxWidth: number = 280;
+
+ public promise;
+ public promise2;
+
+ constructor(private schemaCompareMainWindow: SchemaCompareMainWindow, private view?: azdata.ModelView, private extensionContext?: vscode.ExtensionContext) {
this.previousSource = schemaCompareMainWindow.sourceEndpointInfo;
this.previousTarget = schemaCompareMainWindow.targetEndpointInfo;
}
@@ -182,7 +188,7 @@ export class SchemaCompareDialog {
this.sourceTextBox = this.view.modelBuilder.inputBox().withProperties({
value: this.schemaCompareMainWindow.sourceEndpointInfo ? this.schemaCompareMainWindow.sourceEndpointInfo.packageFilePath : '',
- width: 275,
+ width: this.textBoxWidth,
ariaLabel: loc.sourceFile
}).component();
@@ -192,7 +198,7 @@ export class SchemaCompareDialog {
this.targetTextBox = this.view.modelBuilder.inputBox().withProperties({
value: this.schemaCompareMainWindow.targetEndpointInfo ? this.schemaCompareMainWindow.targetEndpointInfo.packageFilePath : '',
- width: 275,
+ width: this.textBoxWidth,
ariaLabel: loc.targetFile
}).component();
@@ -214,9 +220,6 @@ export class SchemaCompareDialog {
let sourceRadioButtons = this.createSourceRadiobuttons();
let targetRadioButtons = this.createTargetRadiobuttons();
- this.sourceNoActiveConnectionsText = this.createNoActiveConnectionsText();
- this.targetNoActiveConnectionsText = this.createNoActiveConnectionsText();
-
let sourceComponents = [];
let targetComponents = [];
@@ -345,23 +348,20 @@ export class SchemaCompareDialog {
// show dacpac file browser
this.sourceDacpacRadioButton.onDidClick(async () => {
this.sourceIsDacpac = true;
- this.formBuilder.removeFormItem(this.sourceNoActiveConnectionsText);
this.formBuilder.removeFormItem(this.sourceServerComponent);
this.formBuilder.removeFormItem(this.sourceDatabaseComponent);
this.formBuilder.insertFormItem(this.sourceDacpacComponent, 2, { horizontal: true, titleFontSize: titleFontSize });
this.dialog.okButton.enabled = await this.shouldEnableOkayButton();
});
- // show server and db dropdowns or 'No active connections' text
+ // show server and db dropdowns
this.sourceDatabaseRadioButton.onDidClick(async () => {
this.sourceIsDacpac = false;
- if ((this.sourceServerDropdown.value as ConnectionDropdownValue)) {
- this.formBuilder.insertFormItem(this.sourceServerComponent, 2, { horizontal: true, titleFontSize: titleFontSize });
- this.formBuilder.insertFormItem(this.sourceDatabaseComponent, 3, { horizontal: true, titleFontSize: titleFontSize });
- } else {
- this.formBuilder.insertFormItem(this.sourceNoActiveConnectionsText, 2, { horizontal: true, titleFontSize: titleFontSize });
- }
+ this.formBuilder.insertFormItem(this.sourceServerComponent, 2, { horizontal: true, titleFontSize: titleFontSize });
+ this.formBuilder.insertFormItem(this.sourceDatabaseComponent, 3, { horizontal: true, titleFontSize: titleFontSize });
this.formBuilder.removeFormItem(this.sourceDacpacComponent);
+
+ this.populateServerDropdown(false);
this.dialog.okButton.enabled = await this.shouldEnableOkayButton();
});
@@ -401,23 +401,20 @@ export class SchemaCompareDialog {
// show dacpac file browser
dacpacRadioButton.onDidClick(async () => {
this.targetIsDacpac = true;
- this.formBuilder.removeFormItem(this.targetNoActiveConnectionsText);
this.formBuilder.removeFormItem(this.targetServerComponent);
this.formBuilder.removeFormItem(this.targetDatabaseComponent);
this.formBuilder.addFormItem(this.targetDacpacComponent, { horizontal: true, titleFontSize: titleFontSize });
this.dialog.okButton.enabled = await this.shouldEnableOkayButton();
});
- // show server and db dropdowns or 'No active connections' text
+ // show server and db dropdowns
databaseRadioButton.onDidClick(async () => {
this.targetIsDacpac = false;
this.formBuilder.removeFormItem(this.targetDacpacComponent);
- if ((this.targetServerDropdown.value as ConnectionDropdownValue)) {
- this.formBuilder.addFormItem(this.targetServerComponent, { horizontal: true, titleFontSize: titleFontSize });
- this.formBuilder.addFormItem(this.targetDatabaseComponent, { horizontal: true, titleFontSize: titleFontSize });
- } else {
- this.formBuilder.addFormItem(this.targetNoActiveConnectionsText, { horizontal: true, titleFontSize: titleFontSize });
- }
+ this.formBuilder.addFormItem(this.targetServerComponent, { horizontal: true, titleFontSize: titleFontSize });
+ this.formBuilder.addFormItem(this.targetDatabaseComponent, { horizontal: true, titleFontSize: titleFontSize });
+
+ this.populateServerDropdown(true);
this.dialog.okButton.enabled = await this.shouldEnableOkayButton();
});
@@ -462,17 +459,22 @@ export class SchemaCompareDialog {
{
editable: true,
fireOnTextChange: true,
- ariaLabel: loc.sourceServer
+ ariaLabel: loc.sourceServer,
+ width: this.textBoxWidth
}
).component();
+
+ this.sourceConnectionButton = this.createConnectionButton(false);
+
this.sourceServerDropdown.onValueChanged(async (value) => {
- if (this.sourceServerDropdown.values.findIndex(x => this.matchesValue(x, value as string)) === -1) {
+ if (value.selected && this.sourceServerDropdown.values.findIndex(x => this.matchesValue(x, value.selected)) === -1) {
await this.sourceDatabaseDropdown.updateProperties({
values: [],
value: ' '
});
}
else {
+ this.sourceConnectionButton.iconPath = path.join(this.extensionContext.extensionPath, 'media', 'connect.svg');
await this.populateDatabaseDropdown((this.sourceServerDropdown.value as ConnectionDropdownValue).connection, false);
}
});
@@ -482,26 +484,57 @@ export class SchemaCompareDialog {
return {
component: this.sourceServerDropdown,
- title: loc.ServerDropdownLabel
+ title: loc.ServerDropdownLabel,
+ actions: [this.sourceConnectionButton]
};
}
+ private createConnectionButton(isTarget: boolean): azdata.ButtonComponent {
+ const selectConnectionButton = this.view.modelBuilder.button().withProperties({
+ ariaLabel: loc.selectConnection,
+ iconPath: path.join(this.extensionContext.extensionPath, 'media', 'selectConnection.svg'),
+ height: '20px',
+ width: '20px'
+ }).component();
+
+ selectConnectionButton.onDidClick(async () => {
+ await this.connectionButtonClick(isTarget);
+ selectConnectionButton.iconPath = path.join(this.extensionContext.extensionPath, 'media', 'connect.svg');
+ });
+
+ return selectConnectionButton;
+ }
+
+ public async connectionButtonClick(isTarget: boolean): Promise {
+ let connection = await azdata.connection.openConnectionDialog();
+ if (connection) {
+ this.connectionId = connection.connectionId;
+ this.promise = this.populateServerDropdown(isTarget);
+ this.promise2 = this.populateServerDropdown(!isTarget, true); // passively populate the other server dropdown as well to add the new connections
+ }
+ }
+
protected createTargetServerDropdown(): azdata.FormComponent {
this.targetServerDropdown = this.view.modelBuilder.dropDown().withProperties(
{
editable: true,
fireOnTextChange: true,
- ariaLabel: loc.targetServer
+ ariaLabel: loc.targetServer,
+ width: this.textBoxWidth
}
).component();
+
+ this.targetConnectionButton = this.createConnectionButton(true);
+
this.targetServerDropdown.onValueChanged(async (value) => {
- if (this.targetServerDropdown.values.findIndex(x => this.matchesValue(x, value as string)) === -1) {
+ if (value.selected && this.targetServerDropdown.values.findIndex(x => this.matchesValue(x, value.selected)) === -1) {
await this.targetDatabaseDropdown.updateProperties({
values: [],
value: ' '
});
}
else {
+ this.targetConnectionButton.iconPath = path.join(this.extensionContext.extensionPath, 'media', 'connect.svg');
await this.populateDatabaseDropdown((this.targetServerDropdown.value as ConnectionDropdownValue).connection, true);
}
});
@@ -511,25 +544,39 @@ export class SchemaCompareDialog {
return {
component: this.targetServerDropdown,
- title: loc.ServerDropdownLabel
+ title: loc.ServerDropdownLabel,
+ actions: [this.targetConnectionButton]
};
}
- protected async populateServerDropdown(isTarget: boolean): Promise {
+ protected async populateServerDropdown(isTarget: boolean, passivelyPopulate: boolean = false): Promise {
const currentDropdown = isTarget ? this.targetServerDropdown : this.sourceServerDropdown;
+
+ if (passivelyPopulate && isNullOrUndefined(currentDropdown.value)) {
+ passivelyPopulate = false; // Populate the dropdown if it is empty
+ }
+
currentDropdown.loading = true;
const values = await this.getServerValues(isTarget);
if (values && values.length > 0) {
- await currentDropdown.updateProperties({
- values: values,
- value: values[0]
- });
+ if (passivelyPopulate) { // only update the dropdown values, not the selected value
+ await currentDropdown.updateProperties({
+ values: values
+ });
+ } else {
+ await currentDropdown.updateProperties({
+ values: values,
+ value: values[0]
+ });
+ }
}
currentDropdown.loading = false;
- await this.populateDatabaseDropdown((currentDropdown.value as ConnectionDropdownValue).connection, isTarget);
+ if (!passivelyPopulate && currentDropdown.value) {
+ await this.populateDatabaseDropdown((currentDropdown.value as ConnectionDropdownValue).connection, isTarget);
+ }
}
protected async getServerValues(isTarget: boolean): Promise<{ connection: azdata.connection.ConnectionProfile, displayName: string, name: string }[]> {
@@ -539,6 +586,10 @@ export class SchemaCompareDialog {
return undefined;
}
+ // Update connection icon to "connected" state
+ let connectionButton = isTarget ? this.targetConnectionButton : this.sourceConnectionButton;
+ connectionButton.iconPath = path.join(this.extensionContext.extensionPath, 'media', 'connect.svg');
+
let endpointInfo = isTarget ? this.schemaCompareMainWindow.targetEndpointInfo : this.schemaCompareMainWindow.sourceEndpointInfo;
// reverse list so that most recent connections are first
cons.reverse();
@@ -603,7 +654,8 @@ export class SchemaCompareDialog {
{
editable: true,
fireOnTextChange: true,
- ariaLabel: loc.sourceDatabase
+ ariaLabel: loc.sourceDatabase,
+ width: this.textBoxWidth
}
).component();
this.sourceDatabaseDropdown.onValueChanged(async (value) => {
@@ -622,7 +674,8 @@ export class SchemaCompareDialog {
{
editable: true,
fireOnTextChange: true,
- ariaLabel: loc.targetDatabase
+ ariaLabel: loc.targetDatabase,
+ width: this.textBoxWidth
}
).component();
this.targetDatabaseDropdown.onValueChanged(async (value) => {
@@ -643,7 +696,10 @@ export class SchemaCompareDialog {
protected async populateDatabaseDropdown(connectionProfile: azdata.connection.ConnectionProfile, isTarget: boolean): Promise {
const currentDropdown = isTarget ? this.targetDatabaseDropdown : this.sourceDatabaseDropdown;
currentDropdown.loading = true;
- await currentDropdown.updateProperties({ values: [], value: null });
+ await currentDropdown.updateProperties({
+ values: [],
+ value: undefined
+ });
let values = [];
try {
@@ -687,21 +743,13 @@ export class SchemaCompareDialog {
}
return values;
}
-
- protected createNoActiveConnectionsText(): azdata.FormComponent {
- let noActiveConnectionsText = this.view.modelBuilder.text().withProperties({ value: loc.NoActiveConnectionsLabel }).component();
-
- return {
- component: noActiveConnectionsText,
- title: ''
- };
- }
}
-interface ConnectionDropdownValue extends azdata.CategoryValue {
+export interface ConnectionDropdownValue extends azdata.CategoryValue {
connection: azdata.connection.ConnectionProfile;
}
function isNullOrUndefined(val: any): boolean {
return val === null || val === undefined;
}
+
diff --git a/extensions/schema-compare/src/localizedConstants.ts b/extensions/schema-compare/src/localizedConstants.ts
index 9a2d1a1eb3..a00c8ce4fe 100644
--- a/extensions/schema-compare/src/localizedConstants.ts
+++ b/extensions/schema-compare/src/localizedConstants.ts
@@ -17,7 +17,6 @@ export const DatabaseRadioButtonLabel: string = localize('schemaCompare.database
export const RadioButtonsLabel: string = localize('schemaCompare.radioButtonsLabel', "Type");
export const ServerDropdownLabel: string = localize('schemaCompareDialog.serverDropdownTitle', "Server");
export const DatabaseDropdownLabel: string = localize('schemaCompareDialog.databaseDropdownTitle', "Database");
-export const NoActiveConnectionsLabel: string = localize('schemaCompare.noActiveConnectionsText', "No active connections");
export const SchemaCompareLabel: string = localize('schemaCompare.dialogTitle', "Schema Compare");
export const differentSourceMessage: string = localize('schemaCompareDialog.differentSourceMessage', "A different source schema has been selected. Compare to see the comparison?");
export const differentTargetMessage: string = localize('schemaCompareDialog.differentTargetMessage', "A different target schema has been selected. Compare to see the comparison?");
@@ -82,6 +81,7 @@ export const saveScmp: string = localize('schemaCompare.saveScmpButton', "Save .
export const saveScmpDescription: string = localize('schemaCompare.saveScmpButtonTitle', "Save source and target, options, and excluded elements");
export const save: string = localize('schemaCompare.saveFile', "Save");
export function getConnectionString(caller: string): string { return localize('schemaCompare.GetConnectionString', "Do you want to connect to {0}?", caller); }
+export const selectConnection: string = localize('schemaCompare.selectConnection', "Select connection");
// options
export const IgnoreTableOptions: string = localize('SchemaCompare.IgnoreTableOptions', "Ignore Table Options");
diff --git a/extensions/schema-compare/src/schemaCompareMainWindow.ts b/extensions/schema-compare/src/schemaCompareMainWindow.ts
index fd99603fbe..d8da54f506 100644
--- a/extensions/schema-compare/src/schemaCompareMainWindow.ts
+++ b/extensions/schema-compare/src/schemaCompareMainWindow.ts
@@ -899,7 +899,7 @@ export class SchemaCompareMainWindow {
this.selectSourceButton.onDidClick(async () => {
TelemetryReporter.sendActionEvent(TelemetryViews.SchemaCompareMainWindow, 'SchemaCompareSelectSource');
- this.schemaCompareDialog = new SchemaCompareDialog(this);
+ this.schemaCompareDialog = new SchemaCompareDialog(this, undefined, this.extensionContext);
this.promise = this.schemaCompareDialog.openDialog();
await this.promise;
});
@@ -913,7 +913,7 @@ export class SchemaCompareMainWindow {
this.selectTargetButton.onDidClick(async () => {
TelemetryReporter.sendActionEvent(TelemetryViews.SchemaCompareMainWindow, 'SchemaCompareSelectTarget');
- this.schemaCompareDialog = new SchemaCompareDialog(this);
+ this.schemaCompareDialog = new SchemaCompareDialog(this, undefined, this.extensionContext);
this.promise = await this.schemaCompareDialog.openDialog();
await this.promise;
});
diff --git a/extensions/schema-compare/src/test/schemaCompare.test.ts b/extensions/schema-compare/src/test/schemaCompare.test.ts
index 6dc9c0d2ba..4828d91bd1 100644
--- a/extensions/schema-compare/src/test/schemaCompare.test.ts
+++ b/extensions/schema-compare/src/test/schemaCompare.test.ts
@@ -93,7 +93,7 @@ let showErrorMessageSpy: any;
let showWarningMessageStub: any;
let showOpenDialogStub: any;
-describe('SchemaCompareMainWindow.results', function (): void {
+describe('SchemaCompareMainWindow.results @DacFx@', function (): void {
before(() => {
mockExtensionContext = TypeMoq.Mock.ofType();
mockExtensionContext.setup(x => x.extensionPath).returns(() => '');
@@ -370,7 +370,7 @@ describe('SchemaCompareMainWindow.results', function (): void {
});
let showErrorMessageStub: any;
-describe('SchemaCompareMainWindow.execute', function (): void {
+describe('SchemaCompareMainWindow.execute @DacFx@', function (): void {
before(() => {
mockExtensionContext = TypeMoq.Mock.ofType();
mockExtensionContext.setup(x => x.extensionPath).returns(() => '');
@@ -507,7 +507,7 @@ describe('SchemaCompareMainWindow.execute', function (): void {
});
-describe('SchemaCompareMainWindow.updateSourceAndTarget', function (): void {
+describe('SchemaCompareMainWindow.updateSourceAndTarget @DacFx@', function (): void {
before(() => {
mockExtensionContext = TypeMoq.Mock.ofType();
mockExtensionContext.setup(x => x.extensionPath).returns(() => '');
@@ -602,7 +602,7 @@ describe('SchemaCompareMainWindow.updateSourceAndTarget', function (): void {
});
-describe('SchemaCompareMainWindow: Button clicks', function (): void {
+describe('SchemaCompareMainWindow: Button clicks @DacFx@', function (): void {
before(() => {
mockExtensionContext = TypeMoq.Mock.ofType();
mockExtensionContext.setup(x => x.extensionPath).returns(() => '');
diff --git a/extensions/schema-compare/src/test/schemaCompareDialog.test.ts b/extensions/schema-compare/src/test/schemaCompareDialog.test.ts
index 10ec1b54c9..697510428c 100644
--- a/extensions/schema-compare/src/test/schemaCompareDialog.test.ts
+++ b/extensions/schema-compare/src/test/schemaCompareDialog.test.ts
@@ -7,12 +7,15 @@ import * as should from 'should';
import * as vscode from 'vscode';
import * as TypeMoq from 'typemoq';
import * as loc from '../localizedConstants';
+import * as sinon from 'sinon';
+import * as azdata from 'azdata';
import 'mocha';
-import { SchemaCompareDialog } from './../dialogs/schemaCompareDialog';
+import { ConnectionDropdownValue, SchemaCompareDialog } from './../dialogs/schemaCompareDialog';
import { SchemaCompareMainWindow } from '../schemaCompareMainWindow';
import { createContext, TestContext } from './testContext';
-import { setDacpacEndpointInfo } from './testUtils';
+import { mockConnectionProfile, mockConnectionProfile2, setDacpacEndpointInfo } from './testUtils';
import { SchemaCompareMainWindowTest } from './testSchemaCompareMainWindow';
+import { SchemaCompareDialogTest } from './testSchemaCompareDialog';
// Mock test data
const mocksource: string = 'source.dacpac';
@@ -25,6 +28,10 @@ before(function (): void {
testContext = createContext();
});
+afterEach(() => {
+ sinon.restore();
+});
+
describe('SchemaCompareDialog.openDialog @DacFx@', function (): void {
before(() => {
mockExtensionContext = TypeMoq.Mock.ofType();
@@ -33,7 +40,7 @@ describe('SchemaCompareDialog.openDialog @DacFx@', function (): void {
it('Should be correct when created.', async function (): Promise {
let schemaCompareResult = new SchemaCompareMainWindow(undefined, mockExtensionContext.object);
- let dialog = new SchemaCompareDialog(schemaCompareResult);
+ let dialog = new SchemaCompareDialog(schemaCompareResult, undefined, mockExtensionContext.object);
await dialog.openDialog();
should(dialog.dialog.title).equal(loc.SchemaCompareLabel);
@@ -47,7 +54,7 @@ describe('SchemaCompareDialog.openDialog @DacFx@', function (): void {
schemaCompareResult.sourceEndpointInfo = setDacpacEndpointInfo(mocksource);
schemaCompareResult.targetEndpointInfo = setDacpacEndpointInfo(mocktarget);
- let dialog = new SchemaCompareDialog(schemaCompareResult);
+ let dialog = new SchemaCompareDialog(schemaCompareResult, undefined, mockExtensionContext.object);
await dialog.openDialog();
await dialog.execute();
@@ -66,4 +73,59 @@ describe('SchemaCompareDialog.openDialog @DacFx@', function (): void {
applyButtonState: false
});
});
+
+ it('Verify server dropdown gets populated appropriately', async function (): Promise {
+ const getConnectionsResults: azdata.connection.ConnectionProfile[] = [{ ...mockConnectionProfile }];
+ sinon.stub(azdata.connection, 'getCurrentConnection').resolves(undefined);
+ sinon.stub(azdata.connection, 'openConnectionDialog').resolves(Promise.resolve(mockConnectionProfile));
+ sinon.stub(azdata.connection, 'getConnections').resolves(Promise.resolve(getConnectionsResults));
+ sinon.stub(azdata.connection, 'listDatabases').resolves(['My Database']);
+
+ let schemaCompareResult = new SchemaCompareMainWindow(undefined, mockExtensionContext.object);
+ let dialog = new SchemaCompareDialogTest(schemaCompareResult, undefined, mockExtensionContext.object);
+
+ should.equal(dialog.getSourceServerDropdownValue(), undefined);
+ should.equal(dialog.getTargetServerDropdownValue(), undefined);
+
+ await dialog.openDialog();
+ await dialog.connectionButtonClick(false);
+
+ await dialog.promise;
+ await dialog.promise2;
+
+ // Confirm source server dropdown has the new connection as its value
+ should.notEqual(dialog.getSourceServerDropdownValue(), undefined);
+ should((dialog.getSourceServerDropdownValue() as ConnectionDropdownValue).connection).deepEqual(mockConnectionProfile, `SourceDropdownValue: (Actual) ${(dialog.getSourceServerDropdownValue() as ConnectionDropdownValue).connection} (Expected) ${mockConnectionProfile}`);
+
+ // Target server dropdown passively populated with the new connection, since it wasn't pre-populated
+ should.notEqual(dialog.getTargetServerDropdownValue(), undefined);
+ should((dialog.getTargetServerDropdownValue() as ConnectionDropdownValue).connection).deepEqual(mockConnectionProfile, `TargetDropdownValue: (Actual) ${(dialog.getTargetServerDropdownValue() as ConnectionDropdownValue).connection} (Expected) ${mockConnectionProfile}`);
+ });
+
+ it('Verify source server dropdown does not get updated when target server is updated', async function (): Promise {
+ sinon.stub(azdata.connection, 'getCurrentConnection').resolves({ ...mockConnectionProfile });
+ sinon.stub(azdata.connection, 'openConnectionDialog').resolves(Promise.resolve(mockConnectionProfile2));
+ sinon.stub(azdata.connection, 'getConnections').resolves(Promise.resolve([{ ...mockConnectionProfile }, { ...mockConnectionProfile2 }]));
+ sinon.stub(azdata.connection, 'listDatabases').resolves(['My Database']);
+
+ let schemaCompareResult = new SchemaCompareMainWindow(undefined, mockExtensionContext.object);
+ let dialog = new SchemaCompareDialogTest(schemaCompareResult, undefined, mockExtensionContext.object);
+
+ should.equal(dialog.getSourceServerDropdownValue(), undefined);
+ should.equal(dialog.getTargetServerDropdownValue(), undefined);
+
+ await dialog.openDialog();
+ await dialog.connectionButtonClick(true); // openConnectionDialog for target server
+
+ await dialog.promise;
+ await dialog.promise2;
+
+ // Confirm source server dropdown has the current connection (from getCurrentConnection) as its value (and doesn't get updated to what target server is)
+ should.notEqual(dialog.getSourceServerDropdownValue(), undefined);
+ should((dialog.getSourceServerDropdownValue() as ConnectionDropdownValue).connection).deepEqual(mockConnectionProfile, `SourceDropdownValue: (Actual) ${(dialog.getSourceServerDropdownValue() as ConnectionDropdownValue).connection} (Expected) ${mockConnectionProfile}`);
+
+ // Confirm target server dropdown has the new connection (from openConnectionDialog) as its value
+ should.notEqual(dialog.getTargetServerDropdownValue(), undefined);
+ should((dialog.getTargetServerDropdownValue() as ConnectionDropdownValue).connection).deepEqual(mockConnectionProfile2, `TargetDropdownValue: (Actual) ${(dialog.getTargetServerDropdownValue() as ConnectionDropdownValue).connection} (Expected) ${mockConnectionProfile2}`);
+ });
});
diff --git a/extensions/schema-compare/src/test/testSchemaCompareDialog.ts b/extensions/schema-compare/src/test/testSchemaCompareDialog.ts
new file mode 100644
index 0000000000..646e66bd04
--- /dev/null
+++ b/extensions/schema-compare/src/test/testSchemaCompareDialog.ts
@@ -0,0 +1,34 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the Source EULA. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import * as azdata from 'azdata';
+import * as vscode from 'vscode';
+import { SchemaCompareDialog } from '../dialogs/schemaCompareDialog';
+import { SchemaCompareMainWindow } from '../schemaCompareMainWindow';
+
+export class SchemaCompareDialogTest extends SchemaCompareDialog {
+
+ constructor(
+ schemaCompareMainWindow: SchemaCompareMainWindow,
+ view: azdata.ModelView,
+ extensionContext: vscode.ExtensionContext) {
+ super(schemaCompareMainWindow, view, extensionContext);
+ }
+
+ // only for test
+ public getSourceServerDropdownValue(): string | azdata.CategoryValue {
+ if (this.sourceServerDropdown) {
+ return this.sourceServerDropdown.value;
+ }
+ return undefined;
+ }
+
+ public getTargetServerDropdownValue(): string | azdata.CategoryValue {
+ if (this.targetServerDropdown) {
+ return this.targetServerDropdown.value;
+ }
+ return undefined;
+ }
+}
diff --git a/extensions/schema-compare/src/test/testUtils.ts b/extensions/schema-compare/src/test/testUtils.ts
index 7940a1aef8..dfc9af8188 100644
--- a/extensions/schema-compare/src/test/testUtils.ts
+++ b/extensions/schema-compare/src/test/testUtils.ts
@@ -47,6 +47,28 @@ export const mockConnectionProfile: azdata.connection.ConnectionProfile = {
}
};
+export const mockConnectionProfile2: azdata.connection.ConnectionProfile = {
+ providerId: 'My Provider2',
+ connectionId: 'My Id2',
+ connectionName: 'My Connection2',
+ serverName: 'My Server2',
+ databaseName: 'My Database2',
+ userName: 'My User2',
+ password: 'My Pwd2',
+ authenticationType: 'SqlLogin',
+ savePassword: false,
+ groupFullName: 'My groupName2',
+ groupId: 'My GroupId2',
+ saveProfile: true,
+ options: {
+ server: 'My Server2',
+ database: 'My Database2',
+ user: 'My User2',
+ password: 'My Pwd2',
+ authenticationType: 'SqlLogin'
+ }
+};
+
export const mockConnectionResult: azdata.ConnectionResult = {
connected: false,
connectionId: undefined,