Remove/comment out connection title generation from all areas. (#23873)

This commit is contained in:
Alex Ma
2023-07-18 10:47:50 -07:00
committed by GitHub
parent 992b19fe93
commit a0a685bbcf
25 changed files with 30 additions and 1189 deletions

View File

@@ -508,15 +508,6 @@ declare module 'azdata' {
* @returns The new password that is returned from the operation or undefined if unsuccessful.
*/
export function openChangePasswordDialog(profile: IConnectionProfile): Thenable<string | undefined>;
/**
* Gets the formatted title of the connection profile for display
* @param profile The connection profile we want to get the full display info for.
* @param getOptionsOnly Provide if you only want to get the differing advanced options (for some titles).
* @param includeGroupName Provide if you want to include the groupName as well (in areas that do not display the groupName).
* @returns The title formatted with server info in front, with non default options at the end.
*/
export function getEditorConnectionProfileTitle(profile: IConnectionProfile, getOptionsOnly?: boolean, includeGroupName?: boolean): Thenable<string>;
}
/*

View File

@@ -381,15 +381,6 @@ export interface IConnectionManagementService {
* @returns the new valid password that is entered, or undefined if cancelled or errored.
*/
openChangePasswordDialog(profile: IConnectionProfile): Promise<string | undefined>;
/**
* Gets the formatted title of the connection profile for display.
* @param profile The connection profile we want to get the full display info for.
* @param getOptionsOnly Provide if you only want to get the differing advanced options (for some titles).
* @param includeGroupName Provide if you want to include the groupName as well (in areas that do not display the groupName).
* @returns The title formatted with server info in front, with non default options at the end.
*/
getEditorConnectionProfileTitle(profile: IConnectionProfile, getOptionsOnly?: boolean, includeGroupName?: boolean): string;
}
export enum RunQueryOnConnectionMode {

View File

@@ -326,12 +326,6 @@ export class ConnectionStore {
return this.convertToConnectionGroup(groups, profilesInConfiguration);
}
public getAllConnectionsFromConfig(): ConnectionProfile[] {
let profilesInConfiguration: ConnectionProfile[] | undefined;
profilesInConfiguration = this.connectionConfig.getConnections(true);
return profilesInConfiguration;
}
private convertToConnectionGroup(groups: IConnectionProfileGroup[], connections?: ConnectionProfile[], parent?: ConnectionProfileGroup): ConnectionProfileGroup[] {
const result: ConnectionProfileGroup[] = [];
const children = groups.filter(g => g.parentId === (parent ? parent.id : undefined));

View File

@@ -134,7 +134,7 @@ export class ProviderConnectionInfo implements azdata.ConnectionInfo {
this.options[name] = value;
}
public getServerInfo() {
private getServerInfo() {
let title = '';
if (this.serverCapabilities) {
title = this.serverName;
@@ -169,7 +169,7 @@ export class ProviderConnectionInfo implements azdata.ConnectionInfo {
return label;
}
public hasLoaded(): boolean {
private hasLoaded(): boolean {
return Object.keys(this.capabilitiesService.providers).length > 0;
}

View File

@@ -355,10 +355,6 @@ export class TestConnectionManagementService implements IConnectionManagementSer
return undefined;
}
getEditorConnectionProfileTitle(profile: IConnectionProfile, getOptionsOnly?: boolean, includeGroupName?: boolean): string {
return undefined!;
}
openCustomErrorDialog(options: azdata.window.IErrorDialogOptions): Promise<string | undefined> {
return undefined;
}

View File

@@ -185,10 +185,6 @@ export class MainThreadConnectionManagement extends Disposable implements MainTh
return this._connectionManagementService.openChangePasswordDialog(convertedProfile);
}
public $getEditorConnectionProfileTitle(profile: IConnectionProfile, getOptionsOnly?: boolean, includeGroupName?: boolean): Thenable<string | undefined> {
return Promise.resolve(this._connectionManagementService.getEditorConnectionProfileTitle(profile, getOptionsOnly, includeGroupName));
}
public async $listDatabases(connectionId: string): Promise<string[]> {
let connectionUri = await this.$getUriForConnection(connectionId);
let result = await this._connectionManagementService.listDatabases(connectionUri);

View File

@@ -78,10 +78,6 @@ export class ExtHostConnectionManagement extends ExtHostConnectionManagementShap
return this._proxy.$openChangePasswordDialog(profile);
}
public $getEditorConnectionProfileTitle(profile: azdata.IConnectionProfile, getOptionsOnly?: boolean, includeGroupName?: boolean): Thenable<string> {
return this._proxy.$getEditorConnectionProfileTitle(profile, getOptionsOnly, includeGroupName);
}
public $listDatabases(connectionId: string): Thenable<string[]> {
return this._proxy.$listDatabases(connectionId);
}

View File

@@ -141,9 +141,6 @@ export function createAdsApiFactory(accessor: ServicesAccessor): IAdsExtensionAp
openChangePasswordDialog(profile: azdata.IConnectionProfile): Thenable<string | undefined> {
return extHostConnectionManagement.$openChangePasswordDialog(profile);
},
getEditorConnectionProfileTitle(profile: azdata.IConnectionProfile, getOptionsOnly?: boolean, includeGroupName?: boolean): Thenable<string> {
return extHostConnectionManagement.$getEditorConnectionProfileTitle(profile, getOptionsOnly, includeGroupName);
},
listDatabases(connectionId: string): Thenable<string[]> {
return extHostConnectionManagement.$listDatabases(connectionId);
},

View File

@@ -729,7 +729,6 @@ export interface MainThreadConnectionManagementShape extends IDisposable {
$getServerInfo(connectedId: string): Thenable<azdata.ServerInfo>;
$openConnectionDialog(providers: string[], initialConnectionProfile?: azdata.IConnectionProfile, connectionCompletionOptions?: azdata.IConnectionCompletionOptions): Thenable<azdata.connection.Connection>;
$openChangePasswordDialog(profile: azdata.IConnectionProfile): Thenable<string | undefined>;
$getEditorConnectionProfileTitle(profile: azdata.IConnectionProfile, getOptionsOnly?: boolean, includeGroupName?: boolean): Thenable<string>;
$listDatabases(connectionId: string): Thenable<string[]>;
$getConnectionString(connectionId: string, includePassword: boolean): Thenable<string>;
$getUriForConnection(connectionId: string): Thenable<string>;

View File

@@ -85,14 +85,11 @@ export class DashboardInput extends EditorInput {
}
let name = this.connectionProfile.connectionName ? this.connectionProfile.connectionName : this.connectionProfile.serverName
if (!this.connectionProfile.connectionName && this.connectionProfile.databaseName
if (this.connectionProfile.databaseName
&& !this.isMasterMssql()) {
// Only add DB name if this is a non-default, non-master connection
name = name + ':' + this.connectionProfile.databaseName;
}
// Append any differing options if needed.
name += this._connectionService.getEditorConnectionProfileTitle(this.connectionProfile, true, true)
return name;
}

View File

@@ -243,17 +243,11 @@ export abstract class QueryEditorInput extends EditorInput implements IConnectab
title = this._description + ' ';
}
if (profile) {
let distinguishedTitle = this.connectionManagementService.getEditorConnectionProfileTitle(profile);
if (distinguishedTitle !== '') {
title += distinguishedTitle;
}
else {
title += `${profile.serverName}`;
if (profile.databaseName) {
title += `.${profile.databaseName}`;
}
title += ` (${profile.userName || profile.authenticationType})`;
title += `${profile.serverName}`;
if (profile.databaseName) {
title += `.${profile.databaseName}`;
}
title += ` (${profile.userName || profile.authenticationType})`;
} else {
title += localize('disconnected', "disconnected");
}

View File

@@ -68,30 +68,20 @@ export class ConnectionStatusbarItem extends Disposable implements IWorkbenchCon
// Set connection info to connection status bar
private _setConnectionText(connectionProfile: IConnectionProfile): void {
let distinguishedTitle = this.connectionManagementService.getEditorConnectionProfileTitle(connectionProfile);
let text: string = '';
let tooltip: string = '';
if (distinguishedTitle === '') {
text = connectionProfile.serverName;
if (text) {
if (connectionProfile.databaseName && connectionProfile.databaseName !== '') {
text = text + ' : ' + connectionProfile.databaseName;
} else {
text = text + ' : ' + '<default>';
}
}
tooltip = 'Server: ' + connectionProfile.serverName + '\r\n' +
'Database: ' + (connectionProfile.databaseName ? connectionProfile.databaseName : '<default>') + '\r\n';
if (connectionProfile.userName && connectionProfile.userName !== '') {
tooltip = tooltip + 'Login: ' + connectionProfile.userName + '\r\n';
let text: string = connectionProfile.serverName;
if (text) {
if (connectionProfile.databaseName && connectionProfile.databaseName !== '') {
text = text + ' : ' + connectionProfile.databaseName;
} else {
text = text + ' : ' + '<default>';
}
}
else {
text = distinguishedTitle;
tooltip = (connectionProfile as any).serverInfo;
let tooltip = 'Server: ' + connectionProfile.serverName + '\r\n' +
'Database: ' + (connectionProfile.databaseName ? connectionProfile.databaseName : '<default>') + '\r\n';
if (connectionProfile.userName && connectionProfile.userName !== '') {
tooltip = tooltip + 'Login: ' + connectionProfile.userName + '\r\n';
}
this.statusItem.update({

View File

@@ -57,9 +57,7 @@ export class BreadcrumbService implements IBreadcrumbService {
}
private getServerBreadcrumb(profile: ConnectionProfile): MenuItem {
let formattedProfileName = profile.connectionName ? profile.connectionName : profile.serverName;
formattedProfileName += this.commonService.connectionManagementService.getEditorConnectionProfileTitle(profile, true, true);
return { label: formattedProfileName, routerLink: ['server-dashboard'] };
return profile.connectionName ? { label: profile.connectionName, routerLink: ['server-dashboard'] } : { label: profile.serverName, routerLink: ['server-dashboard'] };
}
private getDbBreadcrumb(profile: ConnectionProfile): MenuItem {

View File

@@ -756,10 +756,7 @@ export class AttachToDropdown extends SelectBox {
} else {
let connections: string[] = [];
if (model.context && model.context.title && (connProviderIds.includes(this.model.context.providerName))) {
let textResult = model.context.title;
let fullTitleText = this._connectionManagementService.getEditorConnectionProfileTitle(model.context);
textResult = fullTitleText.length !== 0 ? fullTitleText : textResult;
connections.push(textResult);
connections.push(model.context.title);
} else if (this._configurationService.getValue(saveConnectionNameConfigName) && model.savedConnectionName) {
connections.push(model.savedConnectionName);
} else {

View File

@@ -126,7 +126,6 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
// get the full ConnectionProfiles with the server info updated properly
const treeInput = TreeUpdateUtils.getTreeInput(this._connectionManagementService)!;
await this._tree.setInput(treeInput);
await this.refreshConnectionTreeTitles();
this._treeSelectionHandler.onTreeActionStateChange(false);
} else {
if (this._connectionManagementService.hasRegisteredServers()) {
@@ -273,7 +272,6 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
if (connectionParentGroup) {
connectionParentGroup.addOrReplaceConnection(newConnection);
await this._tree.updateChildren(connectionParentGroup);
await this.refreshConnectionTreeTitles();
await this._tree.revealSelectFocusElement(newConnection);
await this._tree.expand(newConnection);
}
@@ -288,7 +286,6 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
await this._tree.rerender(connectionInTree);
await this._tree.revealSelectFocusElement(connectionInTree);
await this._tree.updateChildren(connectionInTree);
await this.refreshConnectionTreeTitles();
await this._tree.expand(connectionInTree);
}
}
@@ -301,7 +298,6 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
if (parentGroup) {
parentGroup.removeConnections([e]);
await this._tree.updateChildren(parentGroup);
await this.refreshConnectionTreeTitles();
await this._tree.revealSelectFocusElement(parentGroup);
}
}
@@ -319,14 +315,12 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
const newProfileParent = <ConnectionProfileGroup>this._tree.getElementById(e.profile.groupId);
newProfileParent.addOrReplaceConnection(e.profile);
await this._tree.updateChildren(newProfileParent);
await this.refreshConnectionTreeTitles();
await this._tree.revealSelectFocusElement(e.profile);
await this._tree.expand(e.profile);
} else {
// If the profile was not moved to a different group then just update the profile in the group.
oldProfileParent.replaceConnection(e.profile, e.oldProfileId);
await this._tree.updateChildren(oldProfileParent)
await this.refreshConnectionTreeTitles();
await this._tree.updateChildren(oldProfileParent);
await this._tree.revealSelectFocusElement(e.profile);
await this._tree.expand(e.profile);
}
@@ -351,7 +345,6 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
await this._tree.updateChildren(newParent);
await this._tree.expand(newParent);
}
await this.refreshConnectionTreeTitles();
const newConnection = this._tree.getElementById(movedConnection.id);
if (newConnection) {
await this._tree.revealSelectFocusElement(newConnection);
@@ -366,7 +359,6 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
const parent = <ConnectionProfileGroup>this._tree.getElementById(e.parentId);
parent.children = parent.children.filter(c => c.id !== e.id);
await this._tree.updateChildren(parent);
await this.refreshConnectionTreeTitles();
await this._tree.revealSelectFocusElement(parent);
}
}));
@@ -389,7 +381,6 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
e.parent = parent;
e.parentId = parent.id;
await this._tree.updateChildren(parent);
await this.refreshConnectionTreeTitles();
await this._tree.revealSelectFocusElement(e);
}
}));
@@ -400,7 +391,6 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
if (newParent) {
newParent.children[newParent.children.findIndex(c => c.id === e.id)] = e;
await this._tree.updateChildren(newParent);
await this.refreshConnectionTreeTitles();
await this._tree.revealSelectFocusElement(e);
}
}
@@ -419,7 +409,6 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
(<ConnectionProfileGroup>movedGroup).parent = newParent;
(<ConnectionProfileGroup>movedGroup).parentId = newParent.id;
await this._tree.updateChildren(newParent);
await this.refreshConnectionTreeTitles();
await this._tree.revealSelectFocusElement(movedGroup);
// Expanding the previously expanded children of the moved group after the move.
this._tree.expandElements(profileExpandedState);
@@ -709,7 +698,6 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
return;
}
await this._tree.setInput(treeInput!);
await this.refreshConnectionTreeTitles();
if (isHidden(this.messages!)) {
this._tree.getFocus();
if (this._tree instanceof AsyncServerTree) {
@@ -975,13 +963,6 @@ export class ServerTreeView extends Disposable implements IServerTreeView {
return actionContext;
}
private async refreshConnectionTreeTitles(): Promise<void> {
let treeInput = this._tree.getInput();
let treeArray = TreeUpdateUtils.alterTreeChildrenTitles([treeInput], this._connectionManagementService, false);
treeInput = treeArray[0];
await this._tree!.setInput(treeInput);
}
public collapseAllConnections(): void {
const root = TreeUpdateUtils.getTreeInput(this._connectionManagementService)!;
const connections = ConnectionProfileGroup.getConnectionsInGroup(root);

View File

@@ -61,10 +61,6 @@ export class SingleConnectionManagementService {
public get connectionInfo(): ConnectionManagementInfo {
return this._connectionService.getConnectionInfo(this._uri);
}
public getEditorConnectionProfileTitle(profile: IConnectionProfile, getOptionsOnly?: boolean, includeGroupName?: boolean): string {
return this._connectionService.getEditorConnectionProfileTitle(profile, getOptionsOnly, includeGroupName);
}
}
export class SingleAdminService {

View File

@@ -553,12 +553,7 @@ class SavedConnectionNode {
}
getChildren() {
let input = TreeUpdateUtils.getTreeInput(this.connectionManagementService);
let newInput = [input];
if (input instanceof ConnectionProfileGroup) {
newInput = TreeUpdateUtils.alterTreeChildrenTitles([input], this.connectionManagementService);
}
return this.dataSource.getChildren(newInput[0]);
return this.dataSource.getChildren(TreeUpdateUtils.getTreeInput(this.connectionManagementService));
}
}

View File

@@ -724,183 +724,6 @@ export class ConnectionManagementService extends Disposable implements IConnecti
return result;
}
public getEditorConnectionProfileTitle(profile: interfaces.IConnectionProfile, getOptionsOnly?: boolean, includeGroupName: boolean = true): string {
let result = '';
if (profile) {
let tempProfile = new ConnectionProfile(this._capabilitiesService, profile);
let trimTitle = tempProfile.getOriginalTitle();
let idToFind = tempProfile.id;
let isChild = false;
let totalConnections: ConnectionProfile[] = [];
let allConnections = this.getConnections();
totalConnections = totalConnections.concat(allConnections);
let initialSearch = totalConnections.filter(inputProfile => {
return inputProfile.id === tempProfile.id;
});
let secondarySearch = totalConnections.filter(inputProfile => {
return inputProfile.matches(tempProfile)
});
if (initialSearch.length === 0) {
if (secondarySearch.length === 1) {
// Sometimes the connection id will change for an object explorer connection, especially when connecting from dashboard,
// and it will identify as different from the stored one even without changes. Get the info for the stored version as it's the same profile.
idToFind = secondarySearch[0].id;
}
}
// Handle case where a profile may have been an edited existing connection (the one retrieved may not be up to date)
if (initialSearch.length === 1 && !initialSearch[0].matches(tempProfile)) {
// Remove the old profile with outdated information.
totalConnections = totalConnections.filter(inputProfile => {
return inputProfile.id !== tempProfile.id;
});
// Replace with up to date version of the profile.
totalConnections = totalConnections.concat(tempProfile);
}
let newConnectionTitles = [];
this.generateEditorConnectionTitles(totalConnections);
if (includeGroupName) {
this.appendGroupName(totalConnections);
}
newConnectionTitles = totalConnections;
let searchResult = newConnectionTitles.filter(inputProfile => inputProfile.id === idToFind);
let finalTitle = searchResult[0]?.title;
if (finalTitle) {
let optionsAppend = finalTitle.substring(trimTitle.length);
if (getOptionsOnly) {
finalTitle = optionsAppend;
}
else if (!getOptionsOnly && isChild) {
finalTitle = tempProfile.getOriginalTitle() + optionsAppend;
}
else {
finalTitle = searchResult[0].getOriginalTitle() + optionsAppend;
}
result = finalTitle;
}
}
return result;
}
/**
* Change the connection title to display only the unique properties among profiles provided. (used for editors)
*/
private generateEditorConnectionTitles(inputList: ConnectionProfile[]): void {
let profileListMap = new Map<string, number[]>();
// Need to reset title to when it was before (as it may have contained a previously generated title)
for (let i = 0; i < inputList.length; i++) {
inputList[i].title = inputList[i].getOriginalTitle();
}
// Map the indices of profiles that share the same server info
for (let i = 0; i < inputList.length; i++) {
// do not add if the profile is still loading as that will result in erroneous entries.
if (inputList[i].serverCapabilities && inputList[i].hasLoaded()) {
let titleKey = inputList[i].getOriginalTitle();
if (profileListMap.has(titleKey)) {
let profilesForKey = profileListMap.get(titleKey);
profilesForKey.push(i);
profileListMap.set(titleKey, profilesForKey);
}
else {
profileListMap.set(titleKey, [i]);
}
}
}
profileListMap.forEach(function (indexes, titleString) {
if (profileListMap.get(titleString)?.length > 1) {
let combinedOptions = [];
let needSpecial = false;
if (titleString === inputList[indexes[0]].connectionName) {
// check for potential connections with the same name but technically different connections.
let listOfDuplicates = indexes.filter(item => inputList[item].getOptionsKey() !== inputList[indexes[0]].getOptionsKey());
if (listOfDuplicates.length > 0) {
// if we do find duplicates, we will need to include the special properties.
needSpecial = true;
}
}
indexes.forEach((indexValue) => {
// Add all possible options across all profiles with the same title to an option list.
let valueOptions = inputList[indexValue].getConnectionOptionsList(needSpecial, false);
combinedOptions = combinedOptions.concat(valueOptions.filter(item => combinedOptions.indexOf(item) < 0));
});
// Generate list of non default option keys for each profile that shares the same server info.
let optionKeyMap = new Map<ConnectionProfile, string[]>();
let optionValueOccuranceMap = new Map<string, number>();
for (let p = 0; p < indexes.length; p++) {
optionKeyMap.set(inputList[indexes[p]], []);
for (let i = 0; i < combinedOptions.length; i++) {
// See if the option is not default for the inputList profile or is.
if (inputList[indexes[p]].getConnectionOptionsList(needSpecial, true).indexOf(combinedOptions[i]) > -1) {
let optionValue = inputList[indexes[p]].getOptionValue(combinedOptions[i].name);
let currentArray = optionKeyMap.get(inputList[indexes[p]]);
let valueString = combinedOptions[i].name + ConnectionProfile.displayNameValueSeparator + optionValue;
if (!optionValueOccuranceMap.get(valueString)) {
optionValueOccuranceMap.set(valueString, 0);
}
optionValueOccuranceMap.set(valueString, optionValueOccuranceMap.get(valueString) + 1);
currentArray.push(valueString);
optionKeyMap.set(inputList[indexes[p]], currentArray);
}
}
}
// Filter out options that are found in ALL the entries with the same server info.
optionValueOccuranceMap.forEach(function (count, optionValue) {
optionKeyMap.forEach(function (connOptionValues, profile) {
if (count === optionKeyMap.size) {
optionKeyMap.set(profile, connOptionValues.filter(value => value !== optionValue));
}
});
});
// Generate the final unique connection string for each profile in the list.
optionKeyMap.forEach(function (connOptionValues, profile) {
let uniqueOptionString = connOptionValues.join(ConnectionProfile.displayIdSeparator);
if (uniqueOptionString.length > 0) {
profile.title = profile.getOriginalTitle() + ' (' + uniqueOptionString + ')';
}
});
}
});
}
private appendGroupName(inputList: ConnectionProfile[]): void {
let profileListMap = new Map<string, number[]>();
// Map the indices of profiles that share the same server group
for (let i = 0; i < inputList.length; i++) {
let groupName = inputList[i].groupFullName;
if (profileListMap.has(groupName)) {
let profilesForKey = profileListMap.get(groupName);
profilesForKey.push(i);
profileListMap.set(groupName, profilesForKey);
}
else {
profileListMap.set(groupName, [i]);
}
}
if (profileListMap.size > 1) {
profileListMap.forEach(function (indexes, groupName) {
for (let t = 0; t < indexes.length; t++) {
if (groupName !== '') {
inputList[indexes[t]].title += nls.localize('connection.connTitleGroupSection', ' (Group: {0})', groupName);
}
}
});
}
}
private doActionsAfterConnectionComplete(uri: string, options: IConnectionCompletionOptions): void {
let connectionManagementInfo = this._connectionStatusManager.findConnection(uri);
if (!connectionManagementInfo) {

View File

@@ -16,7 +16,7 @@ import * as Constants from 'sql/platform/connection/common/constants';
import * as Utils from 'sql/platform/connection/common/utils';
import { IHandleFirewallRuleResult } from 'sql/workbench/services/resourceProvider/common/resourceProviderService';
import { IConnectionProfile, ServiceOptionType } from 'sql/platform/connection/common/interfaces';
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
import { TestCapabilitiesService } from 'sql/platform/capabilities/test/common/testCapabilitiesService';
import { TestConnectionProvider } from 'sql/platform/connection/test/common/testConnectionProvider';
import { TestResourceProvider } from 'sql/workbench/services/resourceProvider/test/common/testResourceProviderService';
@@ -2046,184 +2046,6 @@ suite('SQL ConnectionManagementService tests', () => {
});
});
// TODO - need to rework test to match new format.
test.skip('getEditorConnectionProfileTitle should return a correctly formatted title for a connection profile', () => {
let profile: IConnectionProfile = {
connectionName: 'new name',
serverName: 'new server',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: Constants.AuthenticationType.Integrated,
savePassword: true,
groupFullName: 'g2/g2-2',
groupId: 'group id',
serverCapabilities: undefined,
getOptionsKey: () => { return ''; },
getOptionKeyIdNames: undefined!,
matches: undefined,
providerName: 'MSSQL',
options: {},
saveProfile: true,
id: undefined
};
let capabilitiesService = new TestCapabilitiesService();
const testOption1 = {
name: 'testOption1',
displayName: 'testOption1',
description: 'test description',
groupName: 'test group name',
valueType: ServiceOptionType.string,
specialValueType: undefined,
defaultValue: '',
categoryValues: undefined,
isIdentity: false,
isRequired: false
};
const testOption2 = {
name: 'testOption2',
displayName: 'testOption2',
description: 'test description',
groupName: 'test group name',
valueType: ServiceOptionType.number,
specialValueType: undefined,
defaultValue: '10',
categoryValues: undefined,
isIdentity: false,
isRequired: false
};
const testOption3 = {
name: 'testOption3',
displayName: 'testOption3',
description: 'test description',
groupName: 'test group name',
valueType: ServiceOptionType.string,
specialValueType: undefined,
defaultValue: 'default',
categoryValues: undefined,
isIdentity: false,
isRequired: false
};
profile.options['testOption1'] = 'test value';
profile.options['testOption2'] = '50';
profile.options['testOption3'] = 'default';
let mainProvider = capabilitiesService.capabilities['MSSQL'];
let mainProperties = mainProvider.connection;
let mainOptions = mainProperties.connectionOptions;
mainOptions.push(testOption1);
mainOptions.push(testOption2);
mainOptions.push(testOption3);
mainProperties.connectionOptions = mainOptions;
mainProvider.connection = mainProperties;
capabilitiesService.capabilities['MSSQL'] = mainProvider;
const connectionStoreMock = TypeMoq.Mock.ofType(ConnectionStore, TypeMoq.MockBehavior.Loose, new TestStorageService());
const connectionStatusManagerMock = TypeMoq.Mock.ofType(ConnectionStatusManager, TypeMoq.MockBehavior.Loose);
connectionStatusManagerMock.setup(x => x.getActiveConnectionProfiles(undefined)).returns(() => {
return [];
});
const testInstantiationService = new TestInstantiationService();
testInstantiationService.stub(IStorageService, new TestStorageService());
sinon.stub(testInstantiationService, 'createInstance').withArgs(ConnectionStore).returns(connectionStoreMock.object).withArgs(ConnectionStatusManager).returns(connectionStatusManagerMock.object);
const connectionManagementService = new ConnectionManagementService(undefined, testInstantiationService, undefined, undefined, undefined, capabilitiesService, undefined, undefined, undefined, new TestErrorDiagnosticsService(), undefined, undefined, undefined, undefined, getBasicExtensionService(), undefined, undefined, undefined);
// We should expect that options by themselves are empty if no other profiles exist.
let result = connectionManagementService.getEditorConnectionProfileTitle(profile, true);
assert.strictEqual(result, '', `Options appeared when they should not have.`);
// We should expect that the string contains only the server info (basic) if there is no other connection with the same server info.
result = connectionManagementService.getEditorConnectionProfileTitle(profile);
let generatedProfile = ConnectionProfile.fromIConnectionProfile(capabilitiesService, profile);
let expectedNonDefaultOption = ' (testOption1=test value; testOption2=50)';
let profileServerInfo = generatedProfile.serverInfo.substring(0, generatedProfile.serverInfo.indexOf(expectedNonDefaultOption));
assert.strictEqual(result, `${profileServerInfo}`, `getEditorConnectionProfileTitle included a connection name when it shouldn't`);
connectionStoreMock.setup(x => x.getAllConnectionsFromConfig()).returns(() => {
return [generatedProfile];
});
// We should expect that the string only contains the server info (basic) if there is only default options, and another connection with similar title but non default options.
profile.options['testOption1'] = undefined;
profile.options['testOption2'] = undefined;
profile.options['testOption3'] = undefined;
result = connectionManagementService.getEditorConnectionProfileTitle(profile);
assert.strictEqual(result, `${profileServerInfo}`, `getEditorConnectionProfileTitle included differing connection options when it shouldn't`);
//Reset profiles for next test and add secondary profile .
profile.options['testOption1'] = 'test value';
profile.options['testOption2'] = '50';
profile.options['testOption3'] = 'default';
generatedProfile = ConnectionProfile.fromIConnectionProfile(capabilitiesService, profile);
profile.options['testOption1'] = undefined;
profile.options['testOption2'] = undefined;
profile.options['testOption3'] = undefined;
let emptyGeneratedProfile = ConnectionProfile.fromIConnectionProfile(capabilitiesService, profile);
connectionStoreMock.setup(x => x.getAllConnectionsFromConfig()).returns(() => {
return [generatedProfile, emptyGeneratedProfile];
});
// We should expect that the string contains the server info appended with differing options, if there's another connection with similar title that has only default options.
result = connectionManagementService.getEditorConnectionProfileTitle(generatedProfile);
assert.equal(result, `${generatedProfile.serverInfo}`, `getEditorConnectionProfileTitle did not include differing connection options when it should`);
connectionStoreMock.setup(x => x.getAllConnectionsFromConfig()).returns(() => {
return [generatedProfile, emptyGeneratedProfile];
});
// We should expect that the string contains only the differing options when we ask for options only
result = connectionManagementService.getEditorConnectionProfileTitle(generatedProfile, true);
assert.equal(result, expectedNonDefaultOption, `getEditorConnectionProfileTitle did not return differing options only`);
//Reset profiles for next test and add secondary profile .
profile.options['testOption1'] = 'test value';
profile.options['testOption2'] = '50';
profile.options['testOption3'] = 'default';
profile.connectionName = 'New Connection Name';
profile.options['connectionName'] = profile.connectionName;
generatedProfile = ConnectionProfile.fromIConnectionProfile(capabilitiesService, profile);
profile.options['testOption1'] = undefined;
profile.options['testOption2'] = undefined;
profile.options['testOption3'] = undefined;
profile.connectionName = 'new name';
profile.options['connectionName'] = profile.connectionName;
emptyGeneratedProfile = ConnectionProfile.fromIConnectionProfile(capabilitiesService, profile);
expectedNonDefaultOption = ' (connectionName=New Connection Name; testOption1=test value; testOption2=50)';
connectionStoreMock.setup(x => x.getAllConnectionsFromConfig()).returns(() => {
return [generatedProfile, emptyGeneratedProfile];
});
// We should expect that the string now contains connectionName, when it is different.
result = connectionManagementService.getEditorConnectionProfileTitle(generatedProfile, false);
assert.equal(result, `${profileServerInfo}${expectedNonDefaultOption}`, `getEditorConnectionProfileTitle did not include connectionName in options when it should`);
connectionStoreMock.setup(x => x.getAllConnectionsFromConfig()).returns(() => {
return [generatedProfile, emptyGeneratedProfile];
});
// We should expect that the string contains only the differing options (including Connection Name) against server info when we ask for options only.
result = connectionManagementService.getEditorConnectionProfileTitle(generatedProfile, true);
assert.equal(result, expectedNonDefaultOption, `getEditorConnectionProfileTitle did not include only options with connectionName`);
});
export function createConnectionProfile(id: string, password?: string): ConnectionProfile {
const capabilitiesService = new TestCapabilitiesService();
return new ConnectionProfile(capabilitiesService, {

View File

@@ -149,7 +149,7 @@ class ConnectionProfileTemplate extends Disposable {
this._label.element.setLabel(labelText, '', {
matches: createMatches(filterData)
});
this._root.title = labelText;
this._root.title = treeNode?.filters?.length > 0 ? getLabelWithFilteredSuffix(element.serverInfo) : element.serverInfo;
const actionProvider = this._objectExplorerService.getServerTreeView().treeActionProvider;
if (!this._isCompact) {
const tree = this._objectExplorerService.getServerTreeView().tree;

View File

@@ -235,7 +235,7 @@ export class ServerTreeRenderer implements IRenderer {
const treeNode = this._objectExplorerService.getObjectExplorerNode(connection);
let label = treeNode?.filters?.length > 0 ? getLabelWithFilteredSuffix(connection.title) : connection.title;
templateData.label.textContent = label;
templateData.root.title = treeNode?.filters?.length > 0 ? getLabelWithFilteredSuffix(connection.title) : connection.serverInfo;
templateData.root.title = treeNode?.filters?.length > 0 ? getLabelWithFilteredSuffix(connection.serverInfo) : connection.serverInfo;
templateData.connectionProfile = connection;
}
}

View File

@@ -47,21 +47,6 @@ export class TreeUpdateUtils {
public static isInDragAndDrop: boolean = false;
/**
* Functions to restore/remove the groupId for title generation as they are removed when added to treeInput
*/
private static restoreGroupId(treeInput: ConnectionProfileGroup, originalProfiles: ConnectionProfile[]) {
for (let i = 0; i < treeInput.connections.length; i++) {
treeInput.connections[i].groupId = originalProfiles[i].groupId
}
}
private static removeGroupId(treeInput: ConnectionProfileGroup) {
for (let i = 0; i < treeInput.connections.length; i++) {
treeInput.connections[i].groupId = undefined;
}
}
/**
* Set input for the tree.
*/
@@ -83,21 +68,11 @@ export class TreeUpdateUtils {
if (viewKey === 'recent') {
groups = connectionManagementService.getRecentConnections(providers);
treeInput.addConnections(groups);
this.restoreGroupId(treeInput, connectionManagementService.getRecentConnections(providers));
let treeArray = TreeUpdateUtils.alterTreeChildrenTitles([treeInput], connectionManagementService);
this.removeGroupId(treeInput);
treeInput = treeArray[0];
} else if (viewKey === 'active') {
groups = connectionManagementService.getActiveConnections(providers);
treeInput.addConnections(groups);
this.restoreGroupId(treeInput, connectionManagementService.getActiveConnections(providers));
let treeArray = TreeUpdateUtils.alterTreeChildrenTitles([treeInput], connectionManagementService);
this.removeGroupId(treeInput);
treeInput = treeArray[0];
} else if (viewKey === 'saved') {
treeInput = TreeUpdateUtils.getTreeInput(connectionManagementService, providers);
let treeArray = TreeUpdateUtils.alterTreeChildrenTitles([treeInput], connectionManagementService);
treeInput = treeArray[0];
}
const previousTreeInput = tree.getInput();
if (treeInput) {
@@ -118,29 +93,13 @@ export class TreeUpdateUtils {
}
}
/**
* Calls alterConnectionTitles on all levels of the Object Explorer Tree
* so that profiles in connection groups can have distinguishing titles too.
*/
public static alterTreeChildrenTitles(inputGroups: ConnectionProfileGroup[], connectionManagementService: IConnectionManagementService, includeGroupName?: boolean): ConnectionProfileGroup[] {
inputGroups.forEach(group => {
group.children = TreeUpdateUtils.alterTreeChildrenTitles(group.children, connectionManagementService, includeGroupName);
let connections = group.connections;
TreeUpdateUtils.alterConnectionTitles(connections, connectionManagementService, includeGroupName);
group.connections = connections;
});
return inputGroups;
}
/**
* Set input for the registered servers tree.
*/
public static async registeredServerUpdate(tree: ITree | AsyncServerTree, connectionManagementService: IConnectionManagementService, elementToSelect?: any): Promise<void> {
if (tree instanceof AsyncServerTree) {
let treeInput = TreeUpdateUtils.getTreeInput(connectionManagementService);
const treeInput = TreeUpdateUtils.getTreeInput(connectionManagementService);
if (treeInput) {
let treeArray = this.alterTreeChildrenTitles([treeInput], connectionManagementService, false);
treeInput = treeArray[0];
await tree.setInput(treeInput);
}
tree.rerender();
@@ -169,8 +128,6 @@ export class TreeUpdateUtils {
let treeInput = TreeUpdateUtils.getTreeInput(connectionManagementService);
if (treeInput) {
let treeArray = TreeUpdateUtils.alterTreeChildrenTitles([treeInput], connectionManagementService, false);
treeInput = treeArray[0];
const originalInput = tree.getInput();
if (treeInput !== originalInput) {
return tree.setInput(treeInput).then(async () => {
@@ -413,14 +370,4 @@ export class TreeUpdateUtils {
}
return connectionProfile;
}
private static alterConnectionTitles(inputList: ConnectionProfile[], connectionManagementService: IConnectionManagementService, includeGroupName?: boolean): void {
for (let i = 0; i < inputList.length; i++) {
let currentConnection = inputList[i];
let listOfDuplicates = inputList.filter(connection => connection.getOriginalTitle() === currentConnection.getOriginalTitle());
if (listOfDuplicates.length > 1) {
inputList[i].title = connectionManagementService.getEditorConnectionProfileTitle(inputList[i], false, includeGroupName);
}
}
}
}

View File

@@ -1,645 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
import { ConnectionProfileGroup } from 'sql/platform/connection/common/connectionProfileGroup';
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
import { TestCapabilitiesService } from 'sql/platform/capabilities/test/common/testCapabilitiesService';
import { mssqlProviderName } from 'sql/platform/connection/common/constants';
import { TreeUpdateUtils } from 'sql/workbench/services/objectExplorer/browser/treeUpdateUtils';
import * as assert from 'assert';
import * as azdata from 'azdata';
// TODO - Need to fix these tests to match the refactoring of the Connection Title Generation.
suite.skip('treeUpdateUtils alterConnection', () => {
let capabilitiesService: TestCapabilitiesService;
const testOption1 = {
name: 'testOption1',
displayName: 'testOption1',
description: 'test description',
groupName: 'test group name',
valueType: 'string',
specialValueType: undefined,
defaultValue: '',
categoryValues: undefined,
isIdentity: false,
isRequired: false
};
const testOption2 = {
name: 'testOption2',
displayName: 'testOption2',
description: 'test description',
groupName: 'test group name',
valueType: 'number',
specialValueType: undefined,
defaultValue: '10',
categoryValues: undefined,
isIdentity: false,
isRequired: false
};
const testOption3 = {
name: 'testOption3',
displayName: 'testOption3',
description: 'test description',
groupName: 'test group name',
valueType: 'string',
specialValueType: undefined,
defaultValue: 'default',
categoryValues: undefined,
isIdentity: false,
isRequired: false
};
setup(() => {
capabilitiesService = new TestCapabilitiesService();
let mainProvider = capabilitiesService.capabilities[mssqlProviderName];
let mainProperties = mainProvider.connection;
let mainOptions = mainProperties.connectionOptions;
mainOptions.push((testOption1 as azdata.ConnectionOption));
mainOptions.push((testOption2 as azdata.ConnectionOption));
mainOptions.push((testOption3 as azdata.ConnectionOption));
mainProperties.connectionOptions = mainOptions;
mainProvider.connection = mainProperties;
capabilitiesService.capabilities['MSSQL'] = mainProvider;
});
test('Default properties should not be added to the altered title', async () => {
let profile1: IConnectionProfile = {
serverName: 'server3',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: '',
savePassword: true,
groupFullName: 'g3',
groupId: 'g3',
serverCapabilities: undefined,
getOptionsKey: undefined!,
getOptionKeyIdNames: undefined!,
matches: undefined!,
providerName: 'MSSQL',
options: { testOption3: 'default', testOption2: '10' },
saveProfile: true,
id: undefined!,
connectionName: undefined!
};
let profile2: IConnectionProfile = {
serverName: 'server3',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: '',
savePassword: true,
groupFullName: 'g3',
groupId: 'g3',
serverCapabilities: undefined,
getOptionsKey: undefined!,
getOptionKeyIdNames: undefined!,
matches: undefined!,
providerName: 'MSSQL',
options: { testOption3: 'nonDefault' },
saveProfile: true,
id: undefined!,
connectionName: undefined!
};
let connectionProfile1 = new ConnectionProfile(capabilitiesService, profile1);
let connectionProfile2 = new ConnectionProfile(capabilitiesService, profile2);
let connectionProfileGroup = new ConnectionProfileGroup('g3', undefined, 'g3', undefined, undefined);
connectionProfileGroup.addConnections([connectionProfile1, connectionProfile2]);
let updatedProfileGroup = TreeUpdateUtils.alterTreeChildrenTitles([connectionProfileGroup], undefined);
let updatedTitleMap = updatedProfileGroup[0].connections.map(profile => profile.title);
assert.equal(connectionProfile1.title, updatedTitleMap[0]);
assert.equal(connectionProfile1.title + ' (testOption3=nonDefault)', updatedTitleMap[1]);
});
test('Similar connections should have different titles based on all differing properties', async () => {
let profile1: IConnectionProfile = {
serverName: 'server3',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: '',
savePassword: true,
groupFullName: 'g3',
groupId: 'g3',
serverCapabilities: undefined,
getOptionsKey: undefined!,
getOptionKeyIdNames: undefined!,
matches: undefined!,
providerName: 'MSSQL',
options: { testOption2: '15', testOption1: 'test string 1', testOption3: 'nonDefault' },
saveProfile: true,
id: undefined!,
connectionName: undefined!
};
let profile2: IConnectionProfile = {
serverName: 'server3',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: '',
savePassword: true,
groupFullName: 'g3',
groupId: 'g3',
serverCapabilities: undefined,
getOptionsKey: undefined!,
getOptionKeyIdNames: undefined!,
matches: undefined!,
providerName: 'MSSQL',
options: { testOption2: '50', testOption1: 'test string 1', testOption3: 'nonDefault' },
saveProfile: true,
id: undefined!,
connectionName: undefined!
};
let profile3: IConnectionProfile = {
serverName: 'server3',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: '',
savePassword: true,
groupFullName: 'g3',
groupId: 'g3',
serverCapabilities: undefined,
getOptionsKey: undefined!,
getOptionKeyIdNames: undefined!,
matches: undefined!,
providerName: 'MSSQL',
options: { testOption2: '15', testOption1: 'test string 2', testOption3: 'nonDefault' },
saveProfile: true,
id: undefined!,
connectionName: undefined!
};
let profile4: IConnectionProfile = {
serverName: 'server3',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: '',
savePassword: true,
groupFullName: 'g3',
groupId: 'g3',
serverCapabilities: undefined,
getOptionsKey: undefined!,
getOptionKeyIdNames: undefined!,
matches: undefined!,
providerName: 'MSSQL',
options: { testOption2: '50', testOption1: 'test string 2', testOption3: 'nonDefault' },
saveProfile: true,
id: undefined!,
connectionName: undefined!
};
let defaultProfile: IConnectionProfile = {
serverName: 'server3',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: '',
savePassword: true,
groupFullName: 'g3',
groupId: 'g3',
serverCapabilities: undefined,
getOptionsKey: undefined!,
getOptionKeyIdNames: undefined!,
matches: undefined!,
providerName: 'MSSQL',
options: { testOption3: 'nonDefault' },
saveProfile: true,
id: undefined!,
connectionName: undefined!
};
let defaultConnectionProfile = new ConnectionProfile(capabilitiesService, defaultProfile);
let connectionProfile1 = new ConnectionProfile(capabilitiesService, profile1);
let connectionProfile2 = new ConnectionProfile(capabilitiesService, profile2);
let connectionProfile3 = new ConnectionProfile(capabilitiesService, profile3);
let connectionProfile4 = new ConnectionProfile(capabilitiesService, profile4);
let connectionProfileGroup = new ConnectionProfileGroup('g3', undefined, 'g3', undefined, undefined);
let originalTitle = defaultConnectionProfile.title;
connectionProfileGroup.addConnections([defaultConnectionProfile, connectionProfile1, connectionProfile2, connectionProfile3, connectionProfile4]);
let updatedProfileGroup = TreeUpdateUtils.alterTreeChildrenTitles([connectionProfileGroup], undefined);
let updatedTitleMap = updatedProfileGroup[0].connections.map(profile => profile.title);
assert.equal(originalTitle, updatedTitleMap[0]);
assert.equal(originalTitle + ' (testOption1=test string 1; testOption2=15)', updatedTitleMap[1]);
assert.equal(originalTitle + ' (testOption1=test string 1; testOption2=50)', updatedTitleMap[2]);
assert.equal(originalTitle + ' (testOption1=test string 2; testOption2=15)', updatedTitleMap[3]);
assert.equal(originalTitle + ' (testOption1=test string 2; testOption2=50)', updatedTitleMap[4]);
});
test('identical connections should have same title if on different levels', async () => {
let profile1: IConnectionProfile = {
serverName: 'server3',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: '',
savePassword: true,
groupFullName: 'g3',
groupId: 'g3',
serverCapabilities: undefined,
getOptionsKey: undefined!,
getOptionKeyIdNames: undefined!,
matches: undefined!,
providerName: 'MSSQL',
options: {},
saveProfile: true,
id: undefined!,
connectionName: undefined!
};
let profile2: IConnectionProfile = {
serverName: 'server3',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: '',
savePassword: true,
groupFullName: 'g3-1',
groupId: 'g3-1',
serverCapabilities: undefined,
getOptionsKey: undefined!,
getOptionKeyIdNames: undefined!,
matches: undefined!,
providerName: 'MSSQL',
options: {},
saveProfile: true,
id: undefined!,
connectionName: undefined!
};
let profile3: IConnectionProfile = {
serverName: 'server3',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: '',
savePassword: true,
groupFullName: 'g3-2',
groupId: 'g3-2',
serverCapabilities: undefined,
getOptionsKey: undefined!,
getOptionKeyIdNames: undefined!,
matches: undefined!,
providerName: 'MSSQL',
options: {},
saveProfile: true,
id: undefined!,
connectionName: undefined!
};
let connectionProfile1 = new ConnectionProfile(capabilitiesService, profile1);
let connectionProfile2 = new ConnectionProfile(capabilitiesService, profile2);
let connectionProfile3 = new ConnectionProfile(capabilitiesService, profile3);
let connectionProfileGroup = new ConnectionProfileGroup('g3', undefined, 'g3', undefined, undefined);
let childConnectionProfileGroup = new ConnectionProfileGroup('g3-1', undefined, 'g3-1', undefined, undefined);
let grandChildConnectionProfileGroup = new ConnectionProfileGroup('g3-2', undefined, 'g3-2', undefined, undefined);
childConnectionProfileGroup.addConnections([connectionProfile2]);
connectionProfileGroup.addConnections([connectionProfile1]);
grandChildConnectionProfileGroup.addConnections([connectionProfile3]);
childConnectionProfileGroup.addGroups([grandChildConnectionProfileGroup]);
connectionProfileGroup.addGroups([childConnectionProfileGroup]);
let updatedProfileGroup = TreeUpdateUtils.alterTreeChildrenTitles([connectionProfileGroup], undefined);
let updatedTitleMap = updatedProfileGroup[0].connections.map(profile => profile.title);
let updatedChildTitleMap = updatedProfileGroup[0].children[0].connections.map(profile => profile.title);
let updatedGrandChildTitleMap = updatedProfileGroup[0].children[0].children[0].connections.map(profile => profile.title);
// Titles should be the same if they're in different levels.
assert.equal(updatedTitleMap[0], updatedChildTitleMap[0]);
assert.equal(updatedTitleMap[0], updatedGrandChildTitleMap[0]);
assert.equal(updatedChildTitleMap[0], updatedGrandChildTitleMap[0]);
});
test('connections should not affect connections on a different level', async () => {
let profile1: IConnectionProfile = {
serverName: 'server3',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: '',
savePassword: true,
groupFullName: 'g3',
groupId: 'g3',
serverCapabilities: undefined,
getOptionsKey: undefined!,
getOptionKeyIdNames: undefined!,
matches: undefined!,
providerName: 'MSSQL',
options: { testOption1: 'value1' },
saveProfile: true,
id: undefined!,
connectionName: undefined!
};
let profile1a: IConnectionProfile = {
serverName: 'server3',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: '',
savePassword: true,
groupFullName: 'g3',
groupId: 'g3',
serverCapabilities: undefined,
getOptionsKey: undefined!,
getOptionKeyIdNames: undefined!,
matches: undefined!,
providerName: 'MSSQL',
options: { testOption1: 'value2' },
saveProfile: true,
id: undefined!,
connectionName: undefined!
};
let profile2: IConnectionProfile = {
serverName: 'server3',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: '',
savePassword: true,
groupFullName: 'g3-1',
groupId: 'g3-1',
serverCapabilities: undefined,
getOptionsKey: undefined!,
getOptionKeyIdNames: undefined!,
matches: undefined!,
providerName: 'MSSQL',
options: {},
saveProfile: true,
id: undefined!,
connectionName: undefined!
};
let connectionProfile1 = new ConnectionProfile(capabilitiesService, profile1);
let connectionProfile1a = new ConnectionProfile(capabilitiesService, profile1a);
let connectionProfile2 = new ConnectionProfile(capabilitiesService, profile2);
let connectionProfileGroup = new ConnectionProfileGroup('g3', undefined, 'g3', undefined, undefined);
let childConnectionProfileGroup = new ConnectionProfileGroup('g3-1', undefined, 'g3-1', undefined, undefined);
childConnectionProfileGroup.addConnections([connectionProfile2]);
connectionProfileGroup.addConnections([connectionProfile1, connectionProfile1a]);
connectionProfileGroup.addGroups([childConnectionProfileGroup]);
let updatedProfileGroup = TreeUpdateUtils.alterTreeChildrenTitles([connectionProfileGroup], undefined);
let updatedTitleMap = updatedProfileGroup[0].connections.map(profile => profile.title);
let updatedChildTitleMap = updatedProfileGroup[0].children[0].connections.map(profile => profile.title);
// Titles should be altered for the first group only.
assert.equal(updatedChildTitleMap[0] + ' (testOption1=value1)', updatedTitleMap[0]);
assert.equal(updatedChildTitleMap[0] + ' (testOption1=value2)', updatedTitleMap[1]);
});
test('non default options should only be appended to the connection with non default options', async () => {
let profile1: IConnectionProfile = {
serverName: 'server3',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: '',
savePassword: true,
groupFullName: 'g3',
groupId: 'g3',
serverCapabilities: undefined,
getOptionsKey: undefined!,
getOptionKeyIdNames: undefined!,
matches: undefined!,
providerName: 'MSSQL',
options: {},
saveProfile: true,
id: undefined!,
connectionName: undefined!
};
let profile2: IConnectionProfile = {
serverName: 'server3',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: '',
savePassword: true,
groupFullName: 'g3',
groupId: 'g3',
serverCapabilities: undefined,
getOptionsKey: undefined!,
getOptionKeyIdNames: undefined!,
matches: undefined!,
providerName: 'MSSQL',
options: { testOption1: 'value1', testOption2: '15' },
saveProfile: true,
id: undefined!,
connectionName: undefined!
};
let connectionProfile1 = new ConnectionProfile(capabilitiesService, profile1);
let connectionProfile2 = new ConnectionProfile(capabilitiesService, profile2);
let connectionProfileGroup = new ConnectionProfileGroup('g3', undefined, 'g3', undefined, undefined);
connectionProfileGroup.addConnections([connectionProfile1, connectionProfile2]);
let updatedProfileGroup = TreeUpdateUtils.alterTreeChildrenTitles([connectionProfileGroup], undefined);
let updatedTitleMap = updatedProfileGroup[0].connections.map(profile => profile.title);
//Title for second profile should be the same as the first but with non default options appended.
assert.equal(updatedTitleMap[0] + ' (testOption1=value1; testOption2=15)', updatedTitleMap[1]);
});
test('identical profiles added into one group and separate groups should have the same options appended', async () => {
let profile1: IConnectionProfile = {
serverName: 'server3',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: '',
savePassword: true,
groupFullName: 'g3',
groupId: 'g3',
serverCapabilities: undefined,
getOptionsKey: undefined!,
getOptionKeyIdNames: undefined!,
matches: undefined!,
providerName: 'MSSQL',
options: { testOption1: 'value1', testOption2: '15' },
saveProfile: true,
id: undefined!,
connectionName: undefined!
};
let profile2: IConnectionProfile = {
serverName: 'server3',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: '',
savePassword: true,
groupFullName: 'g3',
groupId: 'g3',
serverCapabilities: undefined,
getOptionsKey: undefined!,
getOptionKeyIdNames: undefined!,
matches: undefined!,
providerName: 'MSSQL',
options: { testOption1: 'value2', testOption2: '30' },
saveProfile: true,
id: undefined!,
connectionName: undefined!
};
let connectionProfile1Base = new ConnectionProfile(capabilitiesService, profile1);
let connectionProfile2Base = new ConnectionProfile(capabilitiesService, profile2);
let connectionProfileGroup = new ConnectionProfileGroup('g3', undefined, 'g3', undefined, undefined);
connectionProfileGroup.addConnections([connectionProfile1Base, connectionProfile2Base]);
profile1.groupFullName = 'g3-1';
profile1.groupId = 'g3-1';
profile2.groupFullName = 'g3-1';
profile2.groupId = 'g3-1';
let connectionProfile1Child = new ConnectionProfile(capabilitiesService, profile1);
let connectionProfile2Child = new ConnectionProfile(capabilitiesService, profile2);
let childConnectionProfileGroup = new ConnectionProfileGroup('g3-1', undefined, 'g3-1', undefined, undefined);
childConnectionProfileGroup.addConnections([connectionProfile1Child, connectionProfile2Child]);
profile1.groupFullName = 'g3-2';
profile1.groupId = 'g3-2';
profile2.groupFullName = 'g3-2';
profile2.groupId = 'g3-2';
let connectionProfile1Grandchild = new ConnectionProfile(capabilitiesService, profile1);
let connectionProfile2Grandchild = new ConnectionProfile(capabilitiesService, profile2);
let grandchildConnectionProfileGroup = new ConnectionProfileGroup('g3-2', undefined, 'g3-2', undefined, undefined);
grandchildConnectionProfileGroup.addConnections([connectionProfile1Grandchild, connectionProfile2Grandchild]);
childConnectionProfileGroup.addGroups([grandchildConnectionProfileGroup]);
connectionProfileGroup.addGroups([childConnectionProfileGroup]);
let updatedProfileGroup = TreeUpdateUtils.alterTreeChildrenTitles([connectionProfileGroup], undefined);
let updatedTitleMap = updatedProfileGroup[0].connections.map(profile => profile.title);
let updatedChildTitleMap = updatedProfileGroup[0].children[0].connections.map(profile => profile.title);
let updatedGrandchildTitleMap = updatedProfileGroup[0].children[0].children[0].connections.map(profile => profile.title);
//Titles for the same profile in different groups should be identical
assert.equal(updatedTitleMap[0], updatedChildTitleMap[0]);
assert.equal(updatedTitleMap[0], updatedGrandchildTitleMap[0]);
assert.equal(updatedTitleMap[1], updatedChildTitleMap[1]);
assert.equal(updatedTitleMap[1], updatedGrandchildTitleMap[1]);
});
test('profiles in adjacent groups on the same layer should not affect titles on nearby groups', async () => {
let profile1: IConnectionProfile = {
serverName: 'server3',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: '',
savePassword: true,
groupFullName: 'g3a',
groupId: 'g3a',
serverCapabilities: undefined,
getOptionsKey: undefined!,
getOptionKeyIdNames: undefined!,
matches: undefined!,
providerName: 'MSSQL',
options: {},
saveProfile: true,
id: undefined!,
connectionName: undefined!
};
let profile2: IConnectionProfile = {
serverName: 'server3',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: '',
savePassword: true,
groupFullName: 'g3a',
groupId: 'g3a',
serverCapabilities: undefined,
getOptionsKey: undefined!,
getOptionKeyIdNames: undefined!,
matches: undefined!,
providerName: 'MSSQL',
options: { testOption1: 'value2', testOption2: '30' },
saveProfile: true,
id: undefined!,
connectionName: undefined!
};
let connectionProfile1a = new ConnectionProfile(capabilitiesService, profile1);
let connectionProfile2a = new ConnectionProfile(capabilitiesService, profile2);
let connectionProfileGroup = new ConnectionProfileGroup('g3', undefined, 'g3', undefined, undefined);
let childConnectionProfileGroup1 = new ConnectionProfileGroup('g3a', undefined, 'g3a', undefined, undefined);
childConnectionProfileGroup1.addConnections([connectionProfile1a, connectionProfile2a]);
profile1.groupFullName = 'g3b';
profile1.groupId = 'g3b';
profile2.groupFullName = 'g3b';
profile2.groupId = 'g3b';
let connectionProfile1b = new ConnectionProfile(capabilitiesService, profile1);
let connectionProfile2b = new ConnectionProfile(capabilitiesService, profile2);
let childConnectionProfileGroup2 = new ConnectionProfileGroup('g3b', undefined, 'g3b', undefined, undefined);
childConnectionProfileGroup2.addConnections([connectionProfile1b, connectionProfile2b]);
connectionProfileGroup.addGroups([childConnectionProfileGroup1]);
connectionProfileGroup.addGroups([childConnectionProfileGroup2]);
let updatedProfileGroup = TreeUpdateUtils.alterTreeChildrenTitles([connectionProfileGroup], undefined);
let updatedChildATitleMap = updatedProfileGroup[0].children[0].connections.map(profile => profile.title);
let updatedChildBTitleMap = updatedProfileGroup[0].children[1].connections.map(profile => profile.title);
//Check that titles are generated properly for the first group.
assert.equal(updatedChildATitleMap[0] + ' (testOption1=value2; testOption2=30)', updatedChildATitleMap[1]);
//Titles for the same profile in adjacent groups should be identical
assert.equal(updatedChildATitleMap[0], updatedChildBTitleMap[0]);
assert.equal(updatedChildATitleMap[1], updatedChildBTitleMap[1]);
});
});