mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 18:46:40 -05:00
Update Schema Compare dialog to start a new connection (#15193)
* Update SC dialog to start a new connection * Functionally complete * Fix target db to pick correct database * Address comments * Added test+fixed one missing scenario * Address comments + add one more test
This commit is contained in:
@@ -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<void>;
|
||||
private initDialogPromise: Promise<void> = new Promise<void>((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<void> {
|
||||
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<void> {
|
||||
protected async populateServerDropdown(isTarget: boolean, passivelyPopulate: boolean = false): Promise<void> {
|
||||
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<void> {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
|
||||
@@ -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<vscode.ExtensionContext>();
|
||||
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<vscode.ExtensionContext>();
|
||||
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<vscode.ExtensionContext>();
|
||||
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<vscode.ExtensionContext>();
|
||||
mockExtensionContext.setup(x => x.extensionPath).returns(() => '');
|
||||
|
||||
@@ -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<vscode.ExtensionContext>();
|
||||
@@ -33,7 +40,7 @@ describe('SchemaCompareDialog.openDialog @DacFx@', function (): void {
|
||||
|
||||
it('Should be correct when created.', async function (): Promise<void> {
|
||||
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<void> {
|
||||
const getConnectionsResults: azdata.connection.ConnectionProfile[] = [{ ...mockConnectionProfile }];
|
||||
sinon.stub(azdata.connection, 'getCurrentConnection').resolves(undefined);
|
||||
sinon.stub(azdata.connection, 'openConnectionDialog').resolves(<any>Promise.resolve(mockConnectionProfile));
|
||||
sinon.stub(azdata.connection, 'getConnections').resolves(<any>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<void> {
|
||||
sinon.stub(azdata.connection, 'getCurrentConnection').resolves({ ...mockConnectionProfile });
|
||||
sinon.stub(azdata.connection, 'openConnectionDialog').resolves(<any>Promise.resolve(mockConnectionProfile2));
|
||||
sinon.stub(azdata.connection, 'getConnections').resolves(<any>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}`);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user