SQL Operations Studio Public Preview 1 (0.23) release source code

This commit is contained in:
Karl Burtram
2017-11-09 14:30:27 -08:00
parent b88ecb8d93
commit 3cdac41339
8829 changed files with 759707 additions and 286 deletions

View File

@@ -0,0 +1,106 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { OptionsDialog } from 'sql/base/browser/ui/modal/optionsDialog';
import { AdvancedPropertiesController } from 'sql/parts/connection/connectionDialog/advancedPropertiesController';
import { Builder, $ } from 'vs/base/browser/builder';
import { ContextKeyServiceStub } from 'sqltest/stubs/contextKeyServiceStub';
import * as data from 'data';
import * as TypeMoq from 'typemoq';
import * as assert from 'assert';
suite('Advanced properties dialog tests', () => {
var advancedController: AdvancedPropertiesController;
var providerOptions: data.ConnectionOption[];
setup(() => {
advancedController = new AdvancedPropertiesController(() => { }, null);
providerOptions = [
{
name: 'a1',
displayName: undefined,
description: undefined,
groupName: 'a',
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: null,
valueType: 0
},
{
name: 'b1',
displayName: undefined,
description: undefined,
groupName: 'b',
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: null,
valueType: 0
},
{
name: 'noType',
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: null,
valueType: 0
},
{
name: 'a2',
displayName: undefined,
description: undefined,
groupName: 'a',
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: null,
valueType: 0
},
{
name: 'b2',
displayName: undefined,
description: undefined,
groupName: 'b',
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: null,
valueType: 0
}
];
});
test('advanced dialog should open when showDialog in advancedController get called', () => {
var isAdvancedDialogCalled = false;
let options: { [name: string]: any } = {};
let builder: Builder = $().div();
let advanceDialog = TypeMoq.Mock.ofType(OptionsDialog, TypeMoq.MockBehavior.Strict,
'', // title
'', // name
{}, // options
undefined, // partsService
undefined, // themeService
undefined, // Context view service
undefined, // telemetry service
new ContextKeyServiceStub() // contextkeyservice
);
advanceDialog.setup(x => x.open(TypeMoq.It.isAny(), TypeMoq.It.isAny())).callback(() => {
isAdvancedDialogCalled = true;
});
advancedController.advancedDialog = advanceDialog.object;
advancedController.showDialog(providerOptions, builder.getHTMLElement(), options);
assert.equal(isAdvancedDialogCalled, true);
});
});

View File

@@ -0,0 +1,931 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as TypeMoq from 'typemoq';
import { ConnectionConfig, ISaveGroupResult } from 'sql/parts/connection/common/connectionConfig';
import { IConnectionProfile, IConnectionProfileStore } from 'sql/parts/connection/common/interfaces';
import { ConnectionProfile } from 'sql/parts/connection/common/connectionProfile';
import { ConfigurationTarget, IConfigurationValue } from 'vs/workbench/services/configuration/common/configurationEditing';
import { IConfigurationValue as TConfigurationValue } from 'vs/platform/configuration/common/configuration';
import { WorkspaceConfigurationTestService } from 'sqltest/stubs/workspaceConfigurationTestService';
import { ConfigurationEditingService } from 'vs/workbench/services/configuration/node/configurationEditingService';
import * as Constants from 'sql/parts/connection/common/constants';
import { IConnectionProfileGroup, ConnectionProfileGroup } from 'sql/parts/connection/common/connectionProfileGroup';
import { TPromise } from 'vs/base/common/winjs.base';
import * as assert from 'assert';
import { CapabilitiesService } from 'sql/services/capabilities/capabilitiesService';
import data = require('data');
import { Emitter } from 'vs/base/common/event';
suite('SQL ConnectionConfig tests', () => {
let capabilitiesService: TypeMoq.Mock<CapabilitiesService>;
let workspaceConfigurationServiceMock: TypeMoq.Mock<WorkspaceConfigurationTestService>;
let configEditingServiceMock: TypeMoq.Mock<ConfigurationEditingService>;
let msSQLCapabilities: data.DataProtocolServerCapabilities;
let capabilities: data.DataProtocolServerCapabilities[];
let onProviderRegistered = new Emitter<data.DataProtocolServerCapabilities>();
let configValueToConcat: TConfigurationValue<IConnectionProfileGroup[]> = {
workspace: [{
name: 'g1',
id: 'g1',
parentId: 'ROOT',
color: 'pink',
description: 'g1'
},
{
name: 'g1-1',
id: 'g1-1',
parentId: 'g1',
color: 'blue',
description: 'g1-1'
}
],
user: [{
name: 'ROOT',
id: 'ROOT',
parentId: '',
color: 'white',
description: 'ROOT'
}, {
name: 'g2',
id: 'g2',
parentId: 'ROOT',
color: 'green',
description: 'g2'
},
{
name: 'g2-1',
id: 'g2-1',
parentId: 'g2',
color: 'yellow',
description: 'g2'
},
{
name: 'g3',
id: 'g3',
parentId: '',
color: 'orange',
description: 'g3'
},
{
name: 'g3-1',
id: 'g3-1',
parentId: 'g3',
color: 'purple',
description: 'g3-1'
}
],
value: [],
default: [],
folder: []
};
let configValueToMerge: TConfigurationValue<IConnectionProfileGroup[]> = {
workspace: [
{
name: 'g1',
id: 'g1',
parentId: '',
color: 'pink',
description: 'g1'
},
{
name: 'g1-1',
id: 'g1-1',
parentId: 'g1',
color: 'blue',
description: 'g1-1'
}
],
user: [
{
name: 'g2',
id: 'g2',
parentId: '',
color: 'green',
description: 'g2'
},
{
name: 'g2-1',
id: 'g2-1',
parentId: 'g2',
color: 'yellow',
description: 'g2'
},
{
name: 'g1',
id: 'g1',
parentId: '',
color: 'pink',
description: 'g1'
},
{
name: 'g1-2',
id: 'g1-2',
parentId: 'g1',
color: 'silver',
description: 'g1-2'
}],
value: [],
default: [],
folder: []
};
let connections: TConfigurationValue<IConnectionProfileStore[]> = {
workspace: [{
options: {
serverName: 'server1',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: ''
},
providerName: 'MSSQL',
groupId: 'test',
savePassword: true,
id: 'server1'
}
],
user: [{
options: {
serverName: 'server2',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: ''
},
providerName: 'MSSQL',
groupId: 'test',
savePassword: true,
id: 'server2'
}, {
options: {
serverName: 'server3',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: ''
},
providerName: 'MSSQL',
groupId: 'g3',
savePassword: true,
id: 'server3'
}
],
value: [],
default: [],
folder: []
};
setup(() => {
capabilitiesService = TypeMoq.Mock.ofType(CapabilitiesService);
capabilities = [];
let connectionProvider: data.ConnectionProviderOptions = {
options: [
{
name: 'serverName',
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: 0,
valueType: 0
},
{
name: 'databaseName',
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: 1,
valueType: 0
},
{
name: 'userName',
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: 3,
valueType: 0
},
{
name: 'authenticationType',
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: 2,
valueType: 0
},
{
name: 'password',
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: 4,
valueType: 0
}
]
};
msSQLCapabilities = {
protocolVersion: '1',
providerName: 'MSSQL',
providerDisplayName: 'MSSQL',
connectionProvider: connectionProvider,
adminServicesProvider: undefined,
features: undefined
};
capabilities.push(msSQLCapabilities);
capabilitiesService.setup(x => x.getCapabilities()).returns(() => capabilities);
capabilitiesService.setup(x => x.onProviderRegisteredEvent).returns(() => onProviderRegistered.event);
workspaceConfigurationServiceMock = TypeMoq.Mock.ofType(WorkspaceConfigurationTestService);
workspaceConfigurationServiceMock.setup(x => x.reloadConfiguration())
.returns(() => TPromise.as<{}>({}));
configEditingServiceMock = TypeMoq.Mock.ofType(ConfigurationEditingService);
let nothing: void;
configEditingServiceMock.setup(x => x.writeConfiguration(ConfigurationTarget.USER, TypeMoq.It.isAny())).returns(() => TPromise.as<void>(nothing));
configEditingServiceMock.setup(x => x.writeConfiguration(ConfigurationTarget.WORKSPACE, TypeMoq.It.isAny())).returns(() => TPromise.as<void>(nothing));
});
function groupsAreEqual(groups1: IConnectionProfileGroup[], groups2: IConnectionProfileGroup[]): Boolean {
if (!groups1 && !groups2) {
return true;
} else if ((!groups1 && groups2 && groups2.length === 0) || (!groups2 && groups1 && groups1.length === 0)) {
return true;
}
if (groups1.length !== groups2.length) {
return false;
}
let areEqual = true;
groups1.map(g1 => {
if (areEqual) {
let g2 = groups2.find(g => g.name === g1.name);
if (!g2) {
areEqual = false;
} else {
let result = groupsAreEqual(groups1.filter(a => a.parentId === g1.id), groups2.filter(b => b.parentId === g2.id));
if (result === false) {
areEqual = false;
}
}
}
});
return areEqual;
}
test('allGroups should return groups from user and workspace settings', () => {
workspaceConfigurationServiceMock.setup(x => x.lookup<IConnectionProfile[] | IConnectionProfileGroup[] | data.DataProtocolServerCapabilities[]>(
Constants.connectionGroupsArrayName))
.returns(() => configValueToConcat);
let config = new ConnectionConfig(configEditingServiceMock.object, workspaceConfigurationServiceMock.object, capabilitiesService.object);
let allGroups = config.getAllGroups();
assert.notEqual(allGroups, undefined);
assert.equal(allGroups.length, configValueToConcat.workspace.length + configValueToConcat.user.length);
});
test('allGroups should merge groups from user and workspace settings', () => {
let expectedAllGroups: IConnectionProfileGroup[] = [
{
name: 'g1',
id: 'g1',
parentId: '',
color: 'pink',
description: 'g1'
},
{
name: 'g1-1',
id: 'g1-1',
parentId: 'g1',
color: 'blue',
description: 'g1-1'
},
{
name: 'g2',
id: 'g2',
parentId: '',
color: 'yellow',
description: 'g2'
},
{
name: 'g2-1',
id: 'g2-1',
parentId: 'g2',
color: 'red',
description: 'g2'
},
{
name: 'g1-2',
id: 'g1-2',
parentId: 'g1',
color: 'green',
description: 'g1-2'
}];
workspaceConfigurationServiceMock.setup(x => x.lookup<IConnectionProfileStore[] | IConnectionProfileGroup[] | data.DataProtocolServerCapabilities[]>(
Constants.connectionGroupsArrayName))
.returns(() => configValueToMerge);
let config = new ConnectionConfig(configEditingServiceMock.object, workspaceConfigurationServiceMock.object, capabilitiesService.object);
let allGroups = config.getAllGroups();
assert.notEqual(allGroups, undefined);
assert.equal(groupsAreEqual(allGroups, expectedAllGroups), true);
});
test('addConnection should add the new profile to user settings if does not exist', done => {
let newProfile: IConnectionProfile = {
serverName: 'new server',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: '',
savePassword: true,
groupFullName: undefined,
groupId: undefined,
getOptionsKey: undefined,
matches: undefined,
providerName: 'MSSQL',
options: {},
saveProfile: true,
id: undefined
};
let expectedNumberOfConnections = connections.user.length + 1;
workspaceConfigurationServiceMock.setup(x => x.lookup<IConnectionProfileStore[] | IConnectionProfileGroup[] | data.DataProtocolServerCapabilities[]>(
Constants.connectionsArrayName))
.returns(() => connections);
workspaceConfigurationServiceMock.setup(x => x.lookup<IConnectionProfileStore[] | IConnectionProfileGroup[] | data.DataProtocolServerCapabilities[]>(
Constants.connectionGroupsArrayName))
.returns(() => configValueToConcat);
let connectionProfile = new ConnectionProfile(msSQLCapabilities, newProfile);
connectionProfile.options['databaseDisplayName'] = 'database';
let config = new ConnectionConfig(configEditingServiceMock.object, workspaceConfigurationServiceMock.object, capabilitiesService.object);
config.addConnection(connectionProfile).then(savedConnectionProfile => {
configEditingServiceMock.verify(y => y.writeConfiguration(ConfigurationTarget.USER,
TypeMoq.It.is<IConfigurationValue>(c => (c.value as IConnectionProfileStore[]).length === expectedNumberOfConnections)), TypeMoq.Times.once());
assert.notEqual(savedConnectionProfile.id, undefined);
done();
}).catch(error => {
assert.fail();
done();
});
});
test('addConnection should not add the new profile to user settings if already exists', done => {
let profileFromConfig = connections.user[0];
let newProfile: IConnectionProfile = {
serverName: profileFromConfig.options['serverName'],
databaseName: profileFromConfig.options['databaseName'],
userName: profileFromConfig.options['userName'],
password: profileFromConfig.options['password'],
authenticationType: profileFromConfig.options['authenticationType'],
groupId: profileFromConfig.groupId,
savePassword: true,
groupFullName: undefined,
getOptionsKey: undefined,
matches: undefined,
providerName: 'MSSQL',
options: {},
saveProfile: true,
id: undefined
};
let expectedNumberOfConnections = connections.user.length;
workspaceConfigurationServiceMock.setup(x => x.lookup<IConnectionProfileStore[] | IConnectionProfileGroup[] | data.DataProtocolServerCapabilities[]>(
Constants.connectionsArrayName))
.returns(() => connections);
workspaceConfigurationServiceMock.setup(x => x.lookup<IConnectionProfileStore[] | IConnectionProfileGroup[] | data.DataProtocolServerCapabilities[]>(
Constants.connectionGroupsArrayName))
.returns(() => configValueToConcat);
let connectionProfile = new ConnectionProfile(msSQLCapabilities, newProfile);
connectionProfile.options['databaseDisplayName'] = profileFromConfig.options['databaseName'];
let config = new ConnectionConfig(configEditingServiceMock.object, workspaceConfigurationServiceMock.object, capabilitiesService.object);
config.addConnection(connectionProfile).then(savedConnectionProfile => {
configEditingServiceMock.verify(y => y.writeConfiguration(ConfigurationTarget.USER,
TypeMoq.It.is<IConfigurationValue>(c => (c.value as IConnectionProfileStore[]).length === expectedNumberOfConnections)), TypeMoq.Times.once());
assert.equal(savedConnectionProfile.id, profileFromConfig.id);
done();
}).catch(error => {
assert.fail();
done();
});
});
test('addConnection should add the new group to user settings if does not exist', done => {
let newProfile: IConnectionProfile = {
serverName: 'new server',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: '',
savePassword: true,
groupFullName: 'g2/g2-2',
groupId: undefined,
getOptionsKey: undefined,
matches: undefined,
providerName: 'MSSQL',
options: {},
saveProfile: true,
id: undefined
};
let expectedNumberOfConnections = connections.user.length + 1;
let expectedNumberOfGroups = configValueToConcat.user.length + 1;
workspaceConfigurationServiceMock.setup(x => x.lookup<IConnectionProfileStore[] | IConnectionProfileGroup[] | data.DataProtocolServerCapabilities[]>(
Constants.connectionsArrayName))
.returns(() => connections);
workspaceConfigurationServiceMock.setup(x => x.lookup<IConnectionProfileStore[] | IConnectionProfileGroup[] | data.DataProtocolServerCapabilities[]>(
Constants.connectionGroupsArrayName))
.returns(() => configValueToConcat);
let connectionProfile = new ConnectionProfile(msSQLCapabilities, newProfile);
let config = new ConnectionConfig(configEditingServiceMock.object, workspaceConfigurationServiceMock.object, capabilitiesService.object);
config.addConnection(connectionProfile).then(success => {
configEditingServiceMock.verify(y => y.writeConfiguration(ConfigurationTarget.USER,
TypeMoq.It.is<IConfigurationValue>(c => (c.value as IConnectionProfileStore[]).length === expectedNumberOfConnections)), TypeMoq.Times.once());
configEditingServiceMock.verify(y => y.writeConfiguration(ConfigurationTarget.USER,
TypeMoq.It.is<IConfigurationValue>(c => (c.value as IConnectionProfileGroup[]).length === expectedNumberOfGroups)), TypeMoq.Times.once());
done();
}).catch(error => {
assert.fail();
done();
});
});
test('getConnections should return connections from user and workspace settings given getWorkspaceConnections set to true', () => {
let getWorkspaceConnections: boolean = true;
workspaceConfigurationServiceMock.setup(x => x.lookup<IConnectionProfileStore[] | IConnectionProfileGroup[] | data.DataProtocolServerCapabilities[]>(
Constants.connectionsArrayName))
.returns(() => connections);
let config = new ConnectionConfig(configEditingServiceMock.object, workspaceConfigurationServiceMock.object, capabilitiesService.object);
let allConnections = config.getConnections(getWorkspaceConnections);
assert.equal(allConnections.length, connections.user.length + connections.workspace.length);
});
test('getConnections should return connections from user settings given getWorkspaceConnections set to false', () => {
let getWorkspaceConnections: boolean = false;
workspaceConfigurationServiceMock.setup(x => x.lookup<IConnectionProfileStore[] | IConnectionProfileGroup[] | data.DataProtocolServerCapabilities[]>(
Constants.connectionsArrayName))
.returns(() => connections);
let config = new ConnectionConfig(configEditingServiceMock.object, workspaceConfigurationServiceMock.object, capabilitiesService.object);
let allConnections = config.getConnections(getWorkspaceConnections);
assert.equal(allConnections.length, connections.user.length);
});
test('getConnections should return connections with a valid id', () => {
let getWorkspaceConnections: boolean = false;
let connectionsWithNoId: TConfigurationValue<IConnectionProfileStore[]> = {
user: connections.user.map(c => {
c.id = undefined;
return c;
}),
default: connections.default,
workspace: connections.workspace.map(c => {
c.id = c.options['serverName'];
return c;
}),
value: connections.value,
folder: []
};
workspaceConfigurationServiceMock.setup(x => x.lookup<IConnectionProfileStore[] | IConnectionProfileGroup[] | data.DataProtocolServerCapabilities[]>(
Constants.connectionsArrayName))
.returns(() => connectionsWithNoId);
let config = new ConnectionConfig(configEditingServiceMock.object, workspaceConfigurationServiceMock.object, capabilitiesService.object);
let allConnections = config.getConnections(getWorkspaceConnections);
assert.equal(allConnections.length, connections.user.length);
allConnections.forEach(connection => {
let userConnection = connectionsWithNoId.user.find(u => u.options['serverName'] === connection.serverName);
if (userConnection !== undefined) {
assert.notEqual(connection.id, connection.getOptionsKey());
assert.notEqual(connection.id, undefined);
} else {
let workspaceConnection = connectionsWithNoId.workspace.find(u => u.options['serverName'] === connection.serverName);
assert.notEqual(connection.id, connection.getOptionsKey());
assert.equal(workspaceConnection.id, connection.id);
}
});
});
test('getConnections update the capabilities in each profile when the provider capabilities is registered', () => {
let oldOptionName: string = 'oldOptionName';
let optionsMetadataFromConfig = capabilities[0].connectionProvider.options.concat({
name: oldOptionName,
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: 0,
valueType: 0
});
let capabilitiesFromConfig: data.DataProtocolServerCapabilities[] = [];
let connectionProvider: data.ConnectionProviderOptions = {
options: optionsMetadataFromConfig
};
let msSQLCapabilities2 = {
protocolVersion: '1',
providerName: 'MSSQL',
providerDisplayName: 'MSSQL',
connectionProvider: connectionProvider,
adminServicesProvider: undefined,
features: undefined
};
capabilitiesFromConfig.push(msSQLCapabilities2);
let connectionUsingOldMetadata = connections.user.map(c => {
c.options[oldOptionName] = 'oldOptionValue';
return c;
});
let configValue = Object.assign({}, connections, { user: connectionUsingOldMetadata });
let capabilitiesService2: TypeMoq.Mock<CapabilitiesService> = TypeMoq.Mock.ofType(CapabilitiesService);
capabilitiesService2.setup(x => x.getCapabilities()).returns(() => []);
capabilitiesService2.setup(x => x.onProviderRegisteredEvent).returns(() => onProviderRegistered.event);
workspaceConfigurationServiceMock.setup(x => x.lookup<IConnectionProfileStore[] | IConnectionProfileGroup[] | data.DataProtocolServerCapabilities[]>(
Constants.connectionsArrayName))
.returns(() => configValue);
let config = new ConnectionConfig(configEditingServiceMock.object, workspaceConfigurationServiceMock.object, capabilitiesService2.object, capabilitiesFromConfig);
let allConnections = config.getConnections(false);
allConnections.forEach(element => {
assert.notEqual(element.serverName, undefined);
assert.notEqual(element.getOptionsKey().indexOf('oldOptionValue|'), -1);
});
onProviderRegistered.fire(msSQLCapabilities);
allConnections.forEach(element => {
assert.notEqual(element.serverName, undefined);
assert.equal(element.getOptionsKey().indexOf('oldOptionValue|'), -1);
});
});
test('saveGroup should save the new groups to tree and return the id of the last group name', () => {
let config = new ConnectionConfig(undefined, undefined, undefined, undefined);
let groups: IConnectionProfileGroup[] = configValueToConcat.user;
let expectedLength = configValueToConcat.user.length + 2;
let newGroups: string = 'ROOT/g1/g1-1';
let color: string = 'red';
let result: ISaveGroupResult = config.saveGroup(groups, newGroups, color, newGroups);
assert.notEqual(result, undefined);
assert.equal(result.groups.length, expectedLength, 'The result groups length is invalid');
let newGroup = result.groups.find(g => g.name === 'g1-1');
assert.equal(result.newGroupId, newGroup.id, 'The groups id is invalid');
});
test('saveGroup should only add the groups that are not in the tree', () => {
let config = new ConnectionConfig(undefined, undefined, undefined, undefined);
let groups: IConnectionProfileGroup[] = configValueToConcat.user;
let expectedLength = configValueToConcat.user.length + 1;
let newGroups: string = 'ROOT/g2/g2-5';
let color: string = 'red';
let result: ISaveGroupResult = config.saveGroup(groups, newGroups, color, newGroups);
assert.notEqual(result, undefined);
assert.equal(result.groups.length, expectedLength, 'The result groups length is invalid');
let newGroup = result.groups.find(g => g.name === 'g2-5');
assert.equal(result.newGroupId, newGroup.id, 'The groups id is invalid');
});
test('saveGroup should not add any new group if tree already has all the groups in the full path', () => {
let config = new ConnectionConfig(undefined, undefined, undefined, undefined);
let groups: IConnectionProfileGroup[] = configValueToConcat.user;
let expectedLength = configValueToConcat.user.length;
let newGroups: string = 'ROOT/g2/g2-1';
let color: string = 'red';
let result: ISaveGroupResult = config.saveGroup(groups, newGroups, color, newGroups);
assert.notEqual(result, undefined);
assert.equal(result.groups.length, expectedLength, 'The result groups length is invalid');
let newGroup = result.groups.find(g => g.name === 'g2-1');
assert.equal(result.newGroupId, newGroup.id, 'The groups id is invalid');
});
test('deleteConnection should remove the connection from config', done => {
let newProfile: IConnectionProfile = {
serverName: 'server3',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: '',
savePassword: true,
groupFullName: 'g3',
groupId: 'g3',
getOptionsKey: undefined,
matches: undefined,
providerName: 'MSSQL',
options: {},
saveProfile: true,
id: undefined
};
let expectedNumberOfConnections = connections.user.length - 1;
workspaceConfigurationServiceMock.setup(x => x.lookup<IConnectionProfileStore[] | IConnectionProfileGroup[] | data.DataProtocolServerCapabilities[]>(
Constants.connectionsArrayName))
.returns(() => connections);
let connectionProfile = new ConnectionProfile(msSQLCapabilities, newProfile);
connectionProfile.options['databaseDisplayName'] = 'database';
let config = new ConnectionConfig(configEditingServiceMock.object, workspaceConfigurationServiceMock.object, capabilitiesService.object);
config.deleteConnection(connectionProfile).then(() => {
configEditingServiceMock.verify(y => y.writeConfiguration(ConfigurationTarget.USER,
TypeMoq.It.is<IConfigurationValue>(c => (c.value as IConnectionProfileStore[]).length === expectedNumberOfConnections)), TypeMoq.Times.once());
done();
}).catch(error => {
assert.fail();
done();
});
});
test('deleteConnectionGroup should remove the children connections and subgroups from config', done => {
let newProfile: IConnectionProfile = {
serverName: 'server3',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: '',
savePassword: true,
groupFullName: 'g3',
groupId: 'g3',
getOptionsKey: undefined,
matches: undefined,
providerName: 'MSSQL',
options: {},
saveProfile: true,
id: undefined
};
let connectionProfile = new ConnectionProfile(msSQLCapabilities, newProfile);
connectionProfile.options['databaseDisplayName'] = 'database';
let connectionProfileGroup = new ConnectionProfileGroup('g3', undefined, 'g3', undefined, undefined);
let childGroup = new ConnectionProfileGroup('g3-1', connectionProfileGroup, 'g3-1', undefined, undefined);
connectionProfileGroup.addGroups([childGroup]);
connectionProfileGroup.addConnections([connectionProfile]);
let expectedNumberOfConnections = connections.user.length - 1;
let expectedNumberOfGroups = configValueToConcat.user.length - 2;
workspaceConfigurationServiceMock.setup(x => x.lookup<IConnectionProfileStore[] | IConnectionProfileGroup[] | data.DataProtocolServerCapabilities[]>(
Constants.connectionsArrayName))
.returns(() => connections);
workspaceConfigurationServiceMock.setup(x => x.lookup<IConnectionProfileStore[] | IConnectionProfileGroup[] | data.DataProtocolServerCapabilities[]>(
Constants.connectionGroupsArrayName))
.returns(() => configValueToConcat);
let config = new ConnectionConfig(configEditingServiceMock.object, workspaceConfigurationServiceMock.object, capabilitiesService.object);
config.deleteGroup(connectionProfileGroup).then(() => {
configEditingServiceMock.verify(y => y.writeConfiguration(ConfigurationTarget.USER,
TypeMoq.It.is<IConfigurationValue>(c => (c.value as IConnectionProfileStore[]).length === expectedNumberOfConnections)), TypeMoq.Times.once());
configEditingServiceMock.verify(y => y.writeConfiguration(ConfigurationTarget.USER,
TypeMoq.It.is<IConfigurationValue>(c => (c.value as IConnectionProfileGroup[]).length === expectedNumberOfGroups)), TypeMoq.Times.once());
done();
}).catch(error => {
assert.fail();
done();
});
});
test('deleteConnection should not throw error for connection not in config', done => {
let newProfile: IConnectionProfile = {
serverName: 'server3',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: '',
savePassword: true,
groupFullName: 'g3',
groupId: 'newid',
getOptionsKey: undefined,
matches: undefined,
providerName: 'MSSQL',
options: {},
saveProfile: true,
id: undefined
};
let expectedNumberOfConnections = connections.user.length;
workspaceConfigurationServiceMock.setup(x => x.lookup<IConnectionProfileStore[] | IConnectionProfileGroup[] | data.DataProtocolServerCapabilities[]>(
Constants.connectionsArrayName))
.returns(() => connections);
let connectionProfile = new ConnectionProfile(msSQLCapabilities, newProfile);
let config = new ConnectionConfig(configEditingServiceMock.object, workspaceConfigurationServiceMock.object, capabilitiesService.object);
config.deleteConnection(connectionProfile).then(() => {
configEditingServiceMock.verify(y => y.writeConfiguration(ConfigurationTarget.USER,
TypeMoq.It.is<IConfigurationValue>(c => (c.value as IConnectionProfileStore[]).length === expectedNumberOfConnections)), TypeMoq.Times.once());
done();
}).catch(error => {
assert.fail();
done();
});
});
test('renameGroup should change group name', done => {
let expectedNumberOfConnections = configValueToConcat.user.length;
let calledValue: any;
let called: boolean = false;
let nothing: void;
let configEditingServiceMock: TypeMoq.Mock<ConfigurationEditingService> = TypeMoq.Mock.ofType(ConfigurationEditingService);
configEditingServiceMock.setup(x => x.writeConfiguration(ConfigurationTarget.USER, TypeMoq.It.isAny())).callback((x: any, val: any) => {
calledValue = val.value as IConnectionProfileStore[];
}).returns(() => TPromise.as<void>(nothing));
workspaceConfigurationServiceMock.setup(x => x.lookup<IConnectionProfileStore[] | IConnectionProfileGroup[] | data.DataProtocolServerCapabilities[]>(
Constants.connectionGroupsArrayName))
.returns(() => configValueToConcat);
let connectionProfileGroup = new ConnectionProfileGroup('g-renamed', undefined, 'g2', undefined, undefined);
let config = new ConnectionConfig(configEditingServiceMock.object, workspaceConfigurationServiceMock.object, capabilitiesService.object);
config.editGroup(connectionProfileGroup).then(() => {
configEditingServiceMock.verify(y => y.writeConfiguration(ConfigurationTarget.USER,
TypeMoq.It.is<IConfigurationValue>(c => (c.value as IConnectionProfileStore[]).length === expectedNumberOfConnections)), TypeMoq.Times.once());
calledValue.forEach(con => {
if (con.id === 'g2') {
assert.equal(con.name, 'g-renamed', 'Group was not renamed');
called = true;
}
});
assert.equal(called, true, 'group was not renamed');
}).then(() => done(), (err) => done(err));
});
test('change group(parent) for connection group', done => {
let expectedNumberOfConnections = configValueToConcat.user.length;
let calledValue: any;
let nothing: void;
let configEditingServiceMock: TypeMoq.Mock<ConfigurationEditingService> = TypeMoq.Mock.ofType(ConfigurationEditingService);
configEditingServiceMock.setup(x => x.writeConfiguration(ConfigurationTarget.USER, TypeMoq.It.isAny())).callback((x: any, val: any) => {
calledValue = val.value as IConnectionProfileStore[];
}).returns(() => TPromise.as<void>(nothing));
workspaceConfigurationServiceMock.setup(x => x.lookup<IConnectionProfileStore[] | IConnectionProfileGroup[] | data.DataProtocolServerCapabilities[]>(
Constants.connectionGroupsArrayName))
.returns(() => configValueToConcat);
let sourceProfileGroup = new ConnectionProfileGroup('g2', undefined, 'g2', undefined, undefined);
let targetProfileGroup = new ConnectionProfileGroup('g3', undefined, 'g3', undefined, undefined);
let config = new ConnectionConfig(configEditingServiceMock.object, workspaceConfigurationServiceMock.object, capabilitiesService.object);
config.changeGroupIdForConnectionGroup(sourceProfileGroup, targetProfileGroup).then(() => {
configEditingServiceMock.verify(y => y.writeConfiguration(ConfigurationTarget.USER,
TypeMoq.It.is<IConfigurationValue>(c => (c.value as IConnectionProfileStore[]).length === expectedNumberOfConnections)), TypeMoq.Times.once());
calledValue.forEach(con => {
if (con.id === 'g2') {
assert.equal(con.parentId, 'g3', 'Group parent was not changed');
}
});
}).then(() => done(), (err) => done(err));
});
test('change group(parent) for connection', done => {
let newProfile: IConnectionProfile = {
serverName: 'server3',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: '',
savePassword: true,
groupFullName: 'g3',
groupId: 'g3',
getOptionsKey: () => { return 'connectionId'; },
matches: undefined,
providerName: 'MSSQL',
options: {},
saveProfile: true,
id: 'test'
};
let expectedNumberOfConnections = connections.user.length;
workspaceConfigurationServiceMock.setup(x => x.lookup<IConnectionProfileStore[] | IConnectionProfileGroup[] | data.DataProtocolServerCapabilities[]>(
Constants.connectionsArrayName))
.returns(() => connections);
let connectionProfile = new ConnectionProfile(msSQLCapabilities, newProfile);
let newId = 'newid';
let calledValue: any;
let nothing: void;
let configEditingServiceMock: TypeMoq.Mock<ConfigurationEditingService> = TypeMoq.Mock.ofType(ConfigurationEditingService);
configEditingServiceMock.setup(x => x.writeConfiguration(ConfigurationTarget.USER, TypeMoq.It.isAny())).callback((x: any, val: any) => {
calledValue = val.value as IConnectionProfileStore[];
}).returns(() => TPromise.as<void>(nothing));
configEditingServiceMock.setup(x => x.writeConfiguration(ConfigurationTarget.WORKSPACE, TypeMoq.It.isAny())).callback((x: any, val: any) => {
}).returns(() => TPromise.as<void>(nothing));
let config = new ConnectionConfig(configEditingServiceMock.object, workspaceConfigurationServiceMock.object, capabilitiesService.object);
config.changeGroupIdForConnection(connectionProfile, newId).then(() => {
configEditingServiceMock.verify(y => y.writeConfiguration(ConfigurationTarget.USER,
TypeMoq.It.is<IConfigurationValue>(c => (c.value as IConnectionProfileStore[]).length === expectedNumberOfConnections)), TypeMoq.Times.atLeastOnce());
calledValue.forEach(con => {
});
}).then(() => done(), (err) => done(err));
});
test('fixConnectionIds should replace duplicate ids with new ones', (done) => {
let profiles: IConnectionProfileStore[] = [
{
options: {},
groupId: '1',
id: '1',
providerName: undefined,
savePassword: true,
}, {
options: {},
groupId: '1',
id: '2',
providerName: undefined,
savePassword: true,
}, {
options: {},
groupId: '1',
id: '3',
providerName: undefined,
savePassword: true,
}, {
options: {},
groupId: '1',
id: '2',
providerName: undefined,
savePassword: true,
}, {
options: {},
groupId: '1',
id: '4',
providerName: undefined,
savePassword: true,
}, {
options: {},
groupId: '1',
id: '3',
providerName: undefined,
savePassword: true,
}, {
options: {},
groupId: '1',
id: '2',
providerName: undefined,
savePassword: true,
}
];
let config = new ConnectionConfig(configEditingServiceMock.object, workspaceConfigurationServiceMock.object, capabilitiesService.object);
config.fixConnectionIds(profiles);
let ids = profiles.map(x => x.id);
for (var index = 0; index < ids.length; index++) {
var id = ids[index];
assert.equal(ids.lastIndexOf(id), index);
}
done();
});
});

View File

@@ -0,0 +1,87 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { ConnectionDialogService } from 'sql/parts/connection/connectionDialog/connectionDialogService';
import { ConnectionDialogWidget } from 'sql/parts/connection/connectionDialog/connectionDialogWidget';
import { ConnectionManagementService } from 'sql/parts/connection/common/connectionManagementService';
import { ConnectionType, IConnectableInput, IConnectionResult, INewConnectionParams } from 'sql/parts/connection/common/connectionManagement';
import { ContextKeyServiceStub } from 'sqltest/stubs/contextKeyServiceStub';
import { ErrorMessageServiceStub } from 'sqltest/stubs/errorMessageServiceStub';
import * as TypeMoq from 'typemoq';
suite('ConnectionDialogService tests', () => {
let connectionDialogService: ConnectionDialogService;
let mockConnectionManagementService: TypeMoq.Mock<ConnectionManagementService>;
let mockConnectionDialog: TypeMoq.Mock<ConnectionDialogWidget>;
setup(() => {
let errorMessageService = getMockErrorMessageService();
connectionDialogService = new ConnectionDialogService(undefined, undefined, undefined, errorMessageService.object, undefined);
mockConnectionManagementService = TypeMoq.Mock.ofType(ConnectionManagementService, TypeMoq.MockBehavior.Strict, {}, {});
(connectionDialogService as any)._connectionManagementService = mockConnectionManagementService.object;
mockConnectionDialog = TypeMoq.Mock.ofType(ConnectionDialogWidget, TypeMoq.MockBehavior.Strict,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
new ContextKeyServiceStub()
);
mockConnectionDialog.setup(c => c.resetConnection());
(connectionDialogService as any)._connectionDialog = mockConnectionDialog.object;
});
function getMockErrorMessageService(): TypeMoq.Mock<ErrorMessageServiceStub> {
let mockMessageService = TypeMoq.Mock.ofType(ErrorMessageServiceStub);
mockMessageService.setup(x => x.showDialog(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()));
return mockMessageService;
}
function testHandleDefaultOnConnectUri(isEditor: boolean): Thenable<void> {
let testUri = 'test_uri';
let connectionParams = <INewConnectionParams>{
connectionType: isEditor ? ConnectionType.editor : ConnectionType.default,
input: <IConnectableInput>{
uri: testUri,
onConnectStart: undefined,
onConnectSuccess: undefined,
onConnectReject: undefined,
onDisconnect: undefined
},
runQueryOnCompletion: undefined,
querySelection: undefined
};
mockConnectionManagementService.setup(x => x.connectAndSaveProfile(undefined, TypeMoq.It.is(_ => true), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(
() => Promise.resolve(<IConnectionResult>{ connected: true, errorMessage: undefined, errorCode: undefined }));
// If I call handleDefaultOnConnect with the given parameters
let thenable: Thenable<void> = (connectionDialogService as any).handleDefaultOnConnect(connectionParams, undefined);
return thenable.then(() => {
// Then the Connection Management Service's connect method was called with the expected URI
let expectedUri = isEditor ? testUri : undefined;
mockConnectionManagementService.verify(
x => x.connectAndSaveProfile(undefined, TypeMoq.It.is(uri => uri === expectedUri), TypeMoq.It.isAny(), TypeMoq.It.isAny()),
TypeMoq.Times.once());
});
}
test('handleDefaultOnConnect uses params URI for editor connections', done => {
testHandleDefaultOnConnectUri(true).then(() => done(), err => {
done(err);
});
});
test('handleDefaultOnConnect uses undefined URI for non-editor connections', done => {
testHandleDefaultOnConnectUri(false).then(() => done(), err => {
done(err);
});
});
});

View File

@@ -0,0 +1,563 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { ConnectionDialogTestService } from 'sqltest/stubs/connectionDialogTestService';
import { ConnectionManagementService } from 'sql/parts/connection/common/connectionManagementService';
import { ConnectionStatusManager } from 'sql/parts/connection/common/connectionStatusManager';
import { ConnectionStore } from 'sql/parts/connection/common/connectionStore';
import {
INewConnectionParams, ConnectionType,
IConnectionCompletionOptions, IConnectionResult,
RunQueryOnConnectionMode
} from 'sql/parts/connection/common/connectionManagement';
import * as Constants from 'sql/parts/connection/common/constants';
import * as Utils from 'sql/parts/connection/common/utils';
import { WorkbenchEditorTestService } from 'sqltest/stubs/workbenchEditorTestService';
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
import { EditorGroupTestService } from 'sqltest/stubs/editorGroupService';
import { CapabilitiesTestService } from 'sqltest/stubs/capabilitiesTestService';
import { ConnectionProviderStub } from 'sqltest/stubs/connectionProviderStub';
import * as data from 'data';
import { TPromise } from 'vs/base/common/winjs.base';
import { WorkspaceConfigurationTestService } from 'sqltest/stubs/workspaceConfigurationTestService';
import * as assert from 'assert';
import * as TypeMoq from 'typemoq';
suite('SQL ConnectionManagementService tests', () => {
let capabilitiesService: CapabilitiesTestService;
let connectionDialogService: TypeMoq.Mock<ConnectionDialogTestService>;
let connectionStore: TypeMoq.Mock<ConnectionStore>;
let workbenchEditorService: TypeMoq.Mock<WorkbenchEditorTestService>;
let editorGroupService: TypeMoq.Mock<EditorGroupTestService>;
let connectionStatusManager: ConnectionStatusManager;
let mssqlConnectionProvider: TypeMoq.Mock<ConnectionProviderStub>;
let otherConnectionProvider: TypeMoq.Mock<ConnectionProviderStub>;
let workspaceConfigurationServiceMock: TypeMoq.Mock<WorkspaceConfigurationTestService>;
let none: void;
let connectionProfile: IConnectionProfile = {
serverName: 'new server',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: 'integrated',
savePassword: true,
groupFullName: 'g2/g2-2',
groupId: 'group id',
getOptionsKey: () => { return 'connectionId'; },
matches: undefined,
providerName: 'MSSQL',
options: {},
saveProfile: true,
id: undefined
};
let connectionProfileWithEmptySavedPassword: IConnectionProfile =
Object.assign({}, connectionProfile, { password: '', serverName: connectionProfile.serverName + 1 });
let connectionProfileWithEmptyUnsavedPassword: IConnectionProfile =
Object.assign({}, connectionProfile, { password: '', serverName: connectionProfile.serverName + 2, savePassword: false });
let connectionManagementService: ConnectionManagementService;
let configResult: { [key: string]: any } = {};
setup(() => {
capabilitiesService = new CapabilitiesTestService();
connectionDialogService = TypeMoq.Mock.ofType(ConnectionDialogTestService);
connectionStore = TypeMoq.Mock.ofType(ConnectionStore);
workbenchEditorService = TypeMoq.Mock.ofType(WorkbenchEditorTestService);
editorGroupService = TypeMoq.Mock.ofType(EditorGroupTestService);
connectionStatusManager = new ConnectionStatusManager(capabilitiesService);
mssqlConnectionProvider = TypeMoq.Mock.ofType(ConnectionProviderStub);
otherConnectionProvider = TypeMoq.Mock.ofType(ConnectionProviderStub);
connectionDialogService.setup(x => x.showDialog(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), undefined)).returns(() => TPromise.as(none));
connectionDialogService.setup(x => x.showDialog(TypeMoq.It.isAny(), TypeMoq.It.isAny(), undefined, undefined)).returns(() => TPromise.as(none));
connectionDialogService.setup(x => x.showDialog(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => TPromise.as(none));
connectionDialogService.setup(x => x.showDialog(TypeMoq.It.isAny(), TypeMoq.It.isAny(), undefined, TypeMoq.It.isAny())).returns(() => TPromise.as(none));
connectionStore.setup(x => x.addActiveConnection(TypeMoq.It.isAny())).returns(() => Promise.resolve());
connectionStore.setup(x => x.saveProfile(TypeMoq.It.isAny())).returns(() => Promise.resolve(connectionProfile));
workbenchEditorService.setup(x => x.openEditor(undefined, TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => TPromise.as(undefined));
editorGroupService.setup(x => x.getStacksModel()).returns(() => undefined);
connectionStore.setup(x => x.addSavedPassword(TypeMoq.It.is<IConnectionProfile>(
c => c.serverName === connectionProfile.serverName))).returns(() => Promise.resolve({ profile: connectionProfile, savedCred: true }));
connectionStore.setup(x => x.addSavedPassword(TypeMoq.It.is<IConnectionProfile>(
c => c.serverName === connectionProfileWithEmptySavedPassword.serverName))).returns(
() => Promise.resolve({ profile: connectionProfileWithEmptySavedPassword, savedCred: true }));
connectionStore.setup(x => x.addSavedPassword(TypeMoq.It.is<IConnectionProfile>(
c => c.serverName === connectionProfileWithEmptyUnsavedPassword.serverName))).returns(
() => Promise.resolve({ profile: connectionProfileWithEmptyUnsavedPassword, savedCred: false }));
connectionStore.setup(x => x.isPasswordRequired(TypeMoq.It.isAny())).returns(() => true);
mssqlConnectionProvider.setup(x => x.connect(TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => undefined);
otherConnectionProvider.setup(x => x.connect(TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => undefined);
// setup configuration to return a config that can be modified later.
workspaceConfigurationServiceMock = TypeMoq.Mock.ofType(WorkspaceConfigurationTestService);
workspaceConfigurationServiceMock.setup(x => x.getConfiguration(Constants.sqlConfigSectionName))
.returns(() => configResult);
connectionManagementService = createConnectionManagementService();
connectionManagementService.registerProvider('MSSQL', mssqlConnectionProvider.object);
});
function createConnectionManagementService(): ConnectionManagementService {
let connectionManagementService = new ConnectionManagementService(
undefined,
connectionStore.object,
connectionDialogService.object,
undefined,
undefined,
undefined,
workbenchEditorService.object,
undefined,
undefined,
undefined,
undefined,
workspaceConfigurationServiceMock.object,
undefined,
capabilitiesService,
undefined,
editorGroupService.object,
undefined,
undefined,
undefined,
undefined
);
return connectionManagementService;
}
function verifyShowDialog(connectionProfile: IConnectionProfile, connectionType: ConnectionType, uri: string, error?: string, didShow: boolean = true): void {
if (connectionProfile) {
connectionDialogService.verify(x => x.showDialog(
TypeMoq.It.isAny(),
TypeMoq.It.is<INewConnectionParams>(p => p.connectionType === connectionType && (uri === undefined || p.input.uri === uri)),
TypeMoq.It.is<IConnectionProfile>(c => c.serverName === connectionProfile.serverName), error),
didShow ? TypeMoq.Times.once() : TypeMoq.Times.never());
} else {
connectionDialogService.verify(x => x.showDialog(
TypeMoq.It.isAny(),
TypeMoq.It.is<INewConnectionParams>(p => p.connectionType === connectionType && ((uri === undefined && p.input === undefined) || p.input.uri === uri)),
undefined, error), didShow ? TypeMoq.Times.once() : TypeMoq.Times.never());
}
}
function verifyOptions(options?: IConnectionCompletionOptions, fromDialog?: boolean): void {
if (options) {
if (options.saveTheConnection) {
connectionStore.verify(x => x.saveProfile(TypeMoq.It.isAny()), TypeMoq.Times.once());
}
if (options.showDashboard) {
workbenchEditorService.verify(x => x.openEditor(undefined, TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once());
}
}
if (fromDialog !== undefined && !fromDialog) {
connectionStore.verify(x => x.addSavedPassword(TypeMoq.It.isAny()), TypeMoq.Times.once());
}
}
function connect(uri: string, options?: IConnectionCompletionOptions, fromDialog?: boolean, connection?: IConnectionProfile, error?: string): Promise<IConnectionResult> {
let connectionToUse = connection ? connection : connectionProfile;
return new Promise<IConnectionResult>((resolve, reject) => {
let id = connectionToUse.getOptionsKey();
let defaultUri = 'connection://' + (id ? id : connection.serverName + ':' + connection.databaseName);
connectionManagementService.onConnectionRequestSent(() => {
let info: data.ConnectionInfoSummary = {
connectionId: error ? undefined : 'id',
connectionSummary: {
databaseName: connectionToUse.databaseName,
serverName: connectionToUse.serverName,
userName: connectionToUse.userName
},
errorMessage: error,
errorNumber: undefined,
messages: error,
ownerUri: uri ? uri : defaultUri,
serverInfo: undefined
};
connectionManagementService.onConnectionComplete(0, info);
});
connectionManagementService.cancelConnectionForUri(uri).then(() => {
if (fromDialog) {
resolve(connectionManagementService.connectAndSaveProfile(connectionToUse, uri, options));
} else {
resolve(connectionManagementService.connect(connectionToUse, uri, options));
}
});
});
}
test('showConnectionDialog should open the dialog with default type given no parameters', done => {
connectionManagementService.showConnectionDialog().then(() => {
verifyShowDialog(undefined, ConnectionType.default, undefined);
done();
}).catch(err => {
done(err);
});
});
test('showConnectionDialog should open the dialog with given type given valid input', done => {
let params: INewConnectionParams = {
connectionType: ConnectionType.editor,
input: {
onConnectReject: undefined,
onConnectStart: undefined,
onDisconnect: undefined,
onConnectSuccess: undefined,
uri: 'Editor Uri'
},
runQueryOnCompletion: RunQueryOnConnectionMode.executeQuery
};
connectionManagementService.showConnectionDialog(params).then(() => {
verifyShowDialog(undefined, params.connectionType, params.input.uri);
done();
}).catch(err => {
done(err);
});
});
test('showConnectionDialog should pass the model to the dialog if there is a model assigned to the uri', done => {
let params: INewConnectionParams = {
connectionType: ConnectionType.editor,
input: {
onConnectReject: undefined,
onConnectStart: undefined,
onDisconnect: undefined,
onConnectSuccess: undefined,
uri: 'Editor Uri'
},
runQueryOnCompletion: RunQueryOnConnectionMode.executeQuery
};
connect(params.input.uri).then(() => {
let saveConnection = connectionManagementService.getConnectionProfile(params.input.uri);
assert.notEqual(saveConnection, undefined, `profile was not added to the connections`);
assert.equal(saveConnection.serverName, connectionProfile.serverName, `Server names are different`);
connectionManagementService.showConnectionDialog(params).then(() => {
verifyShowDialog(connectionProfile, params.connectionType, params.input.uri);
done();
}).catch(err => {
done(err);
});
});
});
test('connect should save profile given options with saveProfile set to true', done => {
let uri: string = 'Editor Uri';
let options: IConnectionCompletionOptions = {
params: undefined,
saveTheConnection: true,
showDashboard: false,
showConnectionDialogOnError: false,
showFirewallRuleOnError: false
};
connect(uri, options).then(() => {
verifyOptions(options);
done();
}).catch(err => {
done(err);
});
});
/* Andresse 10/5/17 commented this test out since it was only working before my changes by the chance of how Promises work
If we want to continue to test this, the connection logic needs to be rewritten to actually wait for everything to be done before it resolves */
// test('connect should show dashboard given options with showDashboard set to true', done => {
// let uri: string = 'Editor Uri';
// let options: IConnectionCompletionOptions = {
// params: undefined,
// saveTheConnection: false,
// showDashboard: true,
// showConnectionDialogOnError: false
// };
// connect(uri, options).then(() => {
// verifyOptions(options);
// done();
// }).catch(err => {
// done(err);
// });
// });
test('connect should pass the params in options to onConnectSuccess callback', done => {
let uri: string = 'Editor Uri';
let paramsInOnConnectSuccess: INewConnectionParams;
let options: IConnectionCompletionOptions = {
params: {
connectionType: ConnectionType.editor,
input: {
onConnectSuccess: (params?: INewConnectionParams) => {
paramsInOnConnectSuccess = params;
},
onConnectReject: undefined,
onConnectStart: undefined,
onDisconnect: undefined,
uri: uri
},
querySelection: undefined,
runQueryOnCompletion: RunQueryOnConnectionMode.none
},
saveTheConnection: true,
showDashboard: false,
showConnectionDialogOnError: true,
showFirewallRuleOnError: false
};
connect(uri, options).then(() => {
verifyOptions(options);
assert.notEqual(paramsInOnConnectSuccess, undefined);
assert.equal(paramsInOnConnectSuccess.connectionType, options.params.connectionType);
done();
}).catch(err => {
done(err);
});
});
test('connectAndSaveProfile should show not load the password', done => {
let uri: string = 'Editor Uri';
let options: IConnectionCompletionOptions = undefined;
connect(uri, options, true).then(() => {
verifyOptions(options, true);
done();
}).catch(err => {
done(err);
});
});
test('connect with undefined uri and options should connect using the default uri', done => {
let uri = undefined;
let options: IConnectionCompletionOptions = undefined;
connect(uri, options).then(() => {
assert.equal(connectionManagementService.isProfileConnected(connectionProfile), true);
done();
}).catch(err => {
done(err);
});
});
test('failed connection should open the dialog if connection fails', done => {
let uri = undefined;
let error: string = 'error';
let expectedConnection: boolean = false;
let expectedError: string = error;
let options: IConnectionCompletionOptions = {
params: undefined,
saveTheConnection: false,
showDashboard: false,
showConnectionDialogOnError: true,
showFirewallRuleOnError: false
};
connect(uri, options, false, connectionProfile, error).then(result => {
assert.equal(result.connected, expectedConnection);
assert.equal(result.errorMessage, expectedError);
verifyShowDialog(connectionProfile, ConnectionType.default, uri, error);
done();
}).catch(err => {
done(err);
});
});
test('failed connection should not open the dialog if the option is set to false even if connection fails', done => {
let uri = undefined;
let error: string = 'error when options set to false';
let expectedConnection: boolean = false;
let expectedError: string = error;
let options: IConnectionCompletionOptions = {
params: undefined,
saveTheConnection: false,
showDashboard: false,
showConnectionDialogOnError: false,
showFirewallRuleOnError: false
};
connect(uri, options, false, connectionProfile, error).then(result => {
assert.equal(result.connected, expectedConnection);
assert.equal(result.errorMessage, expectedError);
// TODO: not sure how to verify not called
done();
}).catch(err => {
done(err);
});
});
test('connect when password is empty and unsaved should open the dialog', done => {
let uri = undefined;
let expectedConnection: boolean = false;
let expectedError: string = undefined;
let options: IConnectionCompletionOptions = {
params: undefined,
saveTheConnection: false,
showDashboard: false,
showConnectionDialogOnError: true,
showFirewallRuleOnError: false
};
connect(uri, options, false, connectionProfileWithEmptyUnsavedPassword).then(result => {
assert.equal(result.connected, expectedConnection);
assert.equal(result.errorMessage, expectedError);
verifyShowDialog(connectionProfileWithEmptyUnsavedPassword, ConnectionType.default, uri, expectedError);
done();
}).catch(err => {
done(err);
});
});
test('connect when password is empty and saved should not open the dialog', done => {
let uri = undefined;
let expectedConnection: boolean = true;
let expectedError: string = undefined;
let options: IConnectionCompletionOptions = {
params: undefined,
saveTheConnection: false,
showDashboard: false,
showConnectionDialogOnError: true,
showFirewallRuleOnError: false
};
connect(uri, options, false, connectionProfileWithEmptySavedPassword).then(result => {
assert.equal(result.connected, expectedConnection);
assert.equal(result.errorMessage, expectedError);
verifyShowDialog(connectionProfileWithEmptySavedPassword, ConnectionType.default, uri, expectedError, false);
done();
}).catch(err => {
done(err);
});
});
test('connect from editor when empty password when it is required and saved should not open the dialog', done => {
let uri = 'editor 3';
let expectedConnection: boolean = true;
let expectedError: string = undefined;
let options: IConnectionCompletionOptions = {
params: {
connectionType: ConnectionType.editor,
input: {
onConnectSuccess: undefined,
onConnectReject: undefined,
onConnectStart: undefined,
onDisconnect: undefined,
uri: uri
},
querySelection: undefined,
runQueryOnCompletion: RunQueryOnConnectionMode.none
},
saveTheConnection: true,
showDashboard: false,
showConnectionDialogOnError: true,
showFirewallRuleOnError: false
};
connect(uri, options, false, connectionProfileWithEmptySavedPassword).then(result => {
assert.equal(result.connected, expectedConnection);
assert.equal(result.errorMessage, expectedError);
verifyShowDialog(connectionProfileWithEmptySavedPassword, ConnectionType.editor, uri, expectedError, false);
done();
}).catch(err => {
done(err);
});
});
test('doChangeLanguageFlavor should throw on unknown provider', done => {
// given a provider that will never exist
let invalidProvider = 'notaprovider';
// when I call doChangeLanguageFlavor
// Then I expect it to throw
assert.throws(() => connectionManagementService.doChangeLanguageFlavor('file://my.sql', 'sql', invalidProvider));
done();
});
test('doChangeLanguageFlavor should send event for known provider', done => {
// given a provider that is registered
let uri = 'file://my.sql';
let language = 'sql';
let flavor = 'MSSQL';
// when I call doChangeLanguageFlavor
try {
let called = false;
connectionManagementService.onLanguageFlavorChanged((changeParams: data.DidChangeLanguageFlavorParams) => {
called = true;
assert.equal(changeParams.uri, uri);
assert.equal(changeParams.language, language);
assert.equal(changeParams.flavor, flavor);
});
connectionManagementService.doChangeLanguageFlavor(uri, language, flavor);
assert.ok(called, 'expected onLanguageFlavorChanged event to be sent');
done();
} catch (error) {
done(error);
}
});
test('ensureDefaultLanguageFlavor should not send event if uri is connected', done => {
let uri: string = 'Editor Uri';
let options: IConnectionCompletionOptions = {
params: undefined,
saveTheConnection: false,
showDashboard: false,
showConnectionDialogOnError: false,
showFirewallRuleOnError: false
};
let connectionManagementService = createConnectionManagementService();
let called = false;
connectionManagementService.onLanguageFlavorChanged((changeParams: data.DidChangeLanguageFlavorParams) => {
called = true;
});
connect(uri, options).then(() => {
connectionManagementService.ensureDefaultLanguageFlavor(uri);
assert.equal(called, false, 'do not expect flavor change to be called');
done();
}).catch(err => {
done(err);
});
});
test('getConnectionId returns the URI associated with a connection that has had its database filled in', done => {
// Set up the connection management service with a connection corresponding to a default database
let dbName = 'master';
let serverName = 'test_server';
let userName = 'test_user';
let connectionProfileWithoutDb: IConnectionProfile = Object.assign(connectionProfile,
{ serverName: serverName, databaseName: '', userName: userName, getOptionsKey: () => undefined });
let connectionProfileWithDb: IConnectionProfile = Object.assign(connectionProfileWithoutDb, { databaseName: dbName });
// Save the database with a URI that has the database name filled in, to mirror Carbon's behavior
let ownerUri = Utils.generateUri(connectionProfileWithDb);
connect(ownerUri, undefined, false, connectionProfileWithoutDb).then(() => {
try {
// If I get the URI for the connection with or without a database from the connection management service
let actualUriWithDb = connectionManagementService.getConnectionId(connectionProfileWithDb);
let actualUriWithoutDb = connectionManagementService.getConnectionId(connectionProfileWithoutDb);
// Then the retrieved URIs should match the one on the connection
let expectedUri = Utils.generateUri(connectionProfileWithoutDb);
assert.equal(actualUriWithDb, expectedUri);
assert.equal(actualUriWithoutDb, expectedUri);
done();
} catch (err) {
done(err);
}
}, err => done(err));
});
});

View File

@@ -0,0 +1,206 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { ConnectionProfile } from 'sql/parts/connection/common/connectionProfile';
import { IConnectionProfile, IConnectionProfileStore } from 'sql/parts/connection/common/interfaces';
import data = require('data');
import * as assert from 'assert';
suite('SQL ConnectionProfileInfo tests', () => {
let msSQLCapabilities: data.DataProtocolServerCapabilities;
let connectionProfile: IConnectionProfile = {
serverName: 'new server',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: '',
savePassword: true,
groupFullName: 'g2/g2-2',
groupId: 'group id',
getOptionsKey: undefined,
matches: undefined,
providerName: 'MSSQL',
options: {},
saveProfile: true,
id: undefined
};
let storedProfile: IConnectionProfileStore = {
groupId: 'groupId',
id: 'id',
options: {
serverName: 'new server',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: ''
},
providerName: 'MSSQL',
savePassword: true
};
setup(() => {
let capabilities: data.DataProtocolServerCapabilities[] = [];
let connectionProvider: data.ConnectionProviderOptions = {
options: [
{
name: 'serverName',
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: 0,
valueType: 0
},
{
name: 'databaseName',
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: 1,
valueType: 0
},
{
name: 'userName',
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: 3,
valueType: 0
},
{
name: 'authenticationType',
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: 2,
valueType: 0
},
{
name: 'password',
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: 4,
valueType: 0
}
]
};
msSQLCapabilities = {
protocolVersion: '1',
providerName: 'MSSQL',
providerDisplayName: 'MSSQL',
connectionProvider: connectionProvider,
adminServicesProvider: undefined,
features: undefined
};
capabilities.push(msSQLCapabilities);
});
test('set properties should set the values correctly', () => {
let conn = new ConnectionProfile(msSQLCapabilities, undefined);
assert.equal(conn.serverName, undefined);
conn.serverName = connectionProfile.serverName;
conn.databaseName = connectionProfile.databaseName;
conn.authenticationType = connectionProfile.authenticationType;
conn.password = connectionProfile.password;
conn.userName = connectionProfile.userName;
conn.groupId = connectionProfile.groupId;
conn.groupFullName = connectionProfile.groupFullName;
conn.savePassword = connectionProfile.savePassword;
assert.equal(conn.serverName, connectionProfile.serverName);
assert.equal(conn.databaseName, connectionProfile.databaseName);
assert.equal(conn.authenticationType, connectionProfile.authenticationType);
assert.equal(conn.password, connectionProfile.password);
assert.equal(conn.userName, connectionProfile.userName);
assert.equal(conn.groupId, connectionProfile.groupId);
assert.equal(conn.groupFullName, connectionProfile.groupFullName);
assert.equal(conn.savePassword, connectionProfile.savePassword);
});
test('constructor should initialize the options given a valid model', () => {
let conn = new ConnectionProfile(msSQLCapabilities, connectionProfile);
assert.equal(conn.serverName, connectionProfile.serverName);
assert.equal(conn.databaseName, connectionProfile.databaseName);
assert.equal(conn.authenticationType, connectionProfile.authenticationType);
assert.equal(conn.password, connectionProfile.password);
assert.equal(conn.userName, connectionProfile.userName);
assert.equal(conn.groupId, connectionProfile.groupId);
assert.equal(conn.groupFullName, connectionProfile.groupFullName);
assert.equal(conn.savePassword, connectionProfile.savePassword);
});
test('getOptionsKey should create a valid unique id', () => {
let conn = new ConnectionProfile(msSQLCapabilities, connectionProfile);
let expectedId = 'providerName:MSSQL|authenticationType:|databaseName:database|serverName:new server|userName:user|databaseDisplayName:database|group:group id';
let id = conn.getOptionsKey();
assert.equal(id, expectedId);
});
test('createFromStoredProfile should create connection profile from stored profile', () => {
let savedProfile = storedProfile;
let connectionProfile = ConnectionProfile.createFromStoredProfile(savedProfile, msSQLCapabilities);
assert.equal(savedProfile.groupId, connectionProfile.groupId);
assert.deepEqual(savedProfile.options, connectionProfile.options);
assert.deepEqual(savedProfile.providerName, connectionProfile.providerName);
assert.deepEqual(savedProfile.savePassword, connectionProfile.savePassword);
assert.deepEqual(savedProfile.id, connectionProfile.id);
});
test('createFromStoredProfile should set the id to new guid if not set in stored profile', () => {
let savedProfile = Object.assign({}, storedProfile, { id: undefined });
let connectionProfile = ConnectionProfile.createFromStoredProfile(savedProfile, msSQLCapabilities);
assert.equal(savedProfile.groupId, connectionProfile.groupId);
assert.deepEqual(savedProfile.options, connectionProfile.options);
assert.deepEqual(savedProfile.providerName, connectionProfile.providerName);
assert.equal(savedProfile.savePassword, connectionProfile.savePassword);
assert.notEqual(connectionProfile.id, undefined);
assert.equal(savedProfile.id, undefined);
});
test('withoutPassword should create a new instance without password', () => {
let conn = new ConnectionProfile(msSQLCapabilities, connectionProfile);
assert.notEqual(conn.password, '');
let withoutPassword = conn.withoutPassword();
assert.equal(withoutPassword.password, '');
});
test('unique id should not include password', () => {
let conn = new ConnectionProfile(msSQLCapabilities, connectionProfile);
let withoutPassword = conn.withoutPassword();
assert.equal(withoutPassword.getOptionsKey(), conn.getOptionsKey());
});
test('cloneWithDatabase should create new profile with new id', () => {
let conn = new ConnectionProfile(msSQLCapabilities, connectionProfile);
let newProfile = conn.cloneWithDatabase('new db');
assert.notEqual(newProfile.id, conn.id);
assert.equal(newProfile.databaseName, 'new db');
});
});

View File

@@ -0,0 +1,148 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { ConnectionProfileGroup } from 'sql/parts/connection/common/connectionProfileGroup';
import * as assert from 'assert';
suite('SQL ConnectionProfileGroup tests', () => {
let root: ConnectionProfileGroup;
let Groups1 = 'G1';
let Groups11 = 'G11';
let Groups2 = 'G2';
let group1Node: ConnectionProfileGroup;
let group11Node: ConnectionProfileGroup;
let group2Node: ConnectionProfileGroup;
setup(() => {
root = new ConnectionProfileGroup(ConnectionProfileGroup.RootGroupName, undefined, ConnectionProfileGroup.RootGroupName, undefined, undefined);
group1Node = new ConnectionProfileGroup(Groups1, root, Groups1, undefined, undefined);
group2Node = new ConnectionProfileGroup(Groups2, root, Groups2, undefined, undefined);
group11Node = new ConnectionProfileGroup(Groups11, root, Groups11, undefined, undefined);
root.addGroups([group1Node]);
group1Node.addGroups([group11Node]);
root.addGroups([group2Node]);
});
test('Root name should be returned as empty string', () => {
assert.equal(root.name, '');
});
test('Fullname should return the group full name correctly', () => {
assert.equal(group1Node.fullName, 'G1');
assert.equal(group2Node.fullName, 'G2');
assert.equal(group11Node.fullName, 'G1/G11');
});
test('getGroupFullNameParts should return a list With ROOT in it given an empty string', () => {
let groupFullName: string = '';
let expected: string[] = [ConnectionProfileGroup.RootGroupName];
let actual = ConnectionProfileGroup.getGroupFullNameParts(groupFullName);
assert.deepEqual(actual, expected);
});
test('getGroupFullNameParts should return a list With ROOT in it given null', () => {
let groupFullName: string = undefined;
let expected: string[] = [ConnectionProfileGroup.RootGroupName];
let actual = ConnectionProfileGroup.getGroupFullNameParts(groupFullName);
assert.deepEqual(actual, expected);
});
test('getGroupFullNameParts should return a list With ROOT in it given /', () => {
let groupFullName: string = '/';
let expected: string[] = [ConnectionProfileGroup.RootGroupName];
let actual = ConnectionProfileGroup.getGroupFullNameParts(groupFullName);
assert.deepEqual(actual, expected);
});
test('getGroupFullNameParts should add ROOT as first item if not added already and string starts with /', () => {
let groupFullName: string = '/Groups/Group1';
let expected: string[] = [ConnectionProfileGroup.RootGroupName, 'Groups', 'Group1'];
let actual = ConnectionProfileGroup.getGroupFullNameParts(groupFullName);
assert.deepEqual(actual, expected);
});
test('getGroupFullNameParts should add ROOT as first item if not added already', () => {
let groupFullName: string = 'Groups/Group1';
let expected: string[] = [ConnectionProfileGroup.RootGroupName, 'Groups', 'Group1'];
let actual = ConnectionProfileGroup.getGroupFullNameParts(groupFullName);
assert.deepEqual(actual, expected);
});
test('getGroupFullNameParts should not add ROOT if already added and string starts with /', () => {
let groupFullName: string = '/ROOT/Groups/Group1';
let expected: string[] = [ConnectionProfileGroup.RootGroupName, 'Groups', 'Group1'];
let actual = ConnectionProfileGroup.getGroupFullNameParts(groupFullName);
assert.deepEqual(actual, expected);
});
test('getGroupFullNameParts should not add ROOT if already added', () => {
let groupFullName: string = 'ROOT/Groups/Group1';
let expected: string[] = [ConnectionProfileGroup.RootGroupName, 'Groups', 'Group1'];
let actual = ConnectionProfileGroup.getGroupFullNameParts(groupFullName);
assert.deepEqual(actual, expected);
});
test('getGroupFullNameParts should not add ROOT if already added and it is not uppercase', () => {
let groupFullName: string = 'rOOT/Groups/Group1';
let expected: string[] = [ConnectionProfileGroup.RootGroupName, 'Groups', 'Group1'];
let actual = ConnectionProfileGroup.getGroupFullNameParts(groupFullName);
assert.deepEqual(actual, expected);
});
test('isRoot should return true given empty string', () => {
let name: string = '';
let expected: boolean = true;
let actual = ConnectionProfileGroup.isRoot(name);
assert.deepEqual(actual, expected);
});
test('isRoot should return true given null', () => {
let name: string = undefined;
let expected: boolean = true;
let actual = ConnectionProfileGroup.isRoot(name);
assert.deepEqual(actual, expected);
});
test('isRoot should return true given /', () => {
let name: string = '/';
let expected: boolean = true;
let actual = ConnectionProfileGroup.isRoot(name);
assert.deepEqual(actual, expected);
});
test('isRoot should return true given root', () => {
let name: string = 'root';
let expected: boolean = true;
let actual = ConnectionProfileGroup.isRoot(name);
assert.deepEqual(actual, expected);
});
test('sameGroupName should return true given root', () => {
let name1: string = '/';
let name2: string = '';
let expected: boolean = true;
let actual = ConnectionProfileGroup.sameGroupName(name1, name2);
assert.deepEqual(actual, expected);
});
test('sameGroupName should return true given same group names', () => {
let name1: string = '/group1';
let name2: string = '/Group1';
let expected: boolean = true;
let actual = ConnectionProfileGroup.sameGroupName(name1, name2);
assert.deepEqual(actual, expected);
});
test('sameGroupName should return false given two different groups', () => {
let name1: string = '/';
let name2: string = '/Group1';
let expected: boolean = false;
let actual = ConnectionProfileGroup.sameGroupName(name1, name2);
assert.deepEqual(actual, expected);
});
});

View File

@@ -0,0 +1,239 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import data = require('data');
import { ConnectionStatusManager } from 'sql/parts/connection/common/connectionStatusManager';
import * as Utils from 'sql/parts/connection/common/utils';
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
import { CapabilitiesTestService } from 'sqltest/stubs/capabilitiesTestService';
import { ConnectionProfile } from 'sql/parts/connection/common/connectionProfile';
let connections: ConnectionStatusManager;
let capabilitiesService: CapabilitiesTestService;
let connectionProfileObject: ConnectionProfile;
let connectionProfile: IConnectionProfile = {
serverName: 'new server',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: '',
savePassword: true,
groupFullName: 'g2/g2-2',
groupId: 'group id',
getOptionsKey: () => 'connection1',
matches: undefined,
providerName: 'MSSQL',
options: {},
saveProfile: true,
id: undefined
};
let editorConnectionProfile: IConnectionProfile = {
serverName: 'new server',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: '',
savePassword: true,
groupFullName: 'g2/g2-2',
groupId: 'group id',
getOptionsKey: () => 'connection2',
matches: undefined,
providerName: 'MSSQL',
options: {},
saveProfile: true,
id: undefined
};
let connectionProfileWithoutDbName: IConnectionProfile = {
serverName: 'new server',
databaseName: '',
userName: 'user',
password: 'password',
authenticationType: '',
savePassword: true,
groupFullName: 'g2/g2-2',
groupId: 'group id',
getOptionsKey: () => 'connection1',
matches: undefined,
providerName: 'MSSQL',
options: {},
saveProfile: true,
id: undefined
};
let connection1Id: string;
let connection2Id: string;
let connection3Id: string;
suite('SQL ConnectionStatusManager tests', () => {
setup(() => {
capabilitiesService = new CapabilitiesTestService();
connectionProfileObject = new ConnectionProfile(capabilitiesService.getCapabilities().find(x => x.providerName === 'MSSQL')
, connectionProfile);
connections = new ConnectionStatusManager(capabilitiesService);
connection1Id = Utils.generateUri(connectionProfile);
connection2Id = 'connection2Id';
connection3Id = 'connection3Id';
connections.addConnection(connectionProfile, connection1Id);
connections.addConnection(editorConnectionProfile, connection2Id);
connections.addConnection(connectionProfileWithoutDbName, connection3Id);
});
test('findConnection should return undefined given invalid id', () => {
let id: string = 'invalid id';
let expected = undefined;
let actual = connections.findConnection(id);
assert.equal(actual, expected);
});
test('findConnection should return connection given valid id', () => {
let id: string = connection1Id;
let expected = connectionProfileObject;
let actual = connections.findConnection(id);
assert.deepEqual(actual.connectionProfile, expected);
});
test('getConnectionProfile should return undefined given invalid id', () => {
let id: string = 'invalid id';
let expected = undefined;
let actual = connections.getConnectionProfile(id);
assert.equal(actual, expected);
});
test('getConnectionProfile should return connection given valid id', () => {
let id: string = connection1Id;
let expected = connectionProfileObject;
let actual = connections.getConnectionProfile(id);
assert.deepEqual(actual, expected);
});
test('hasConnection should return false given invalid id', () => {
let id: string = 'invalid id';
let expected = false;
let actual = connections.hasConnection(id);
assert.equal(actual, expected);
});
test('hasConnection should return true given valid id', () => {
let id: string = connection1Id;
let expected = true;
let actual = connections.hasConnection(id);
assert.equal(actual, expected);
});
test('addConnection should set connecting to true', () => {
let expected = true;
let summary: data.ConnectionInfoSummary = {
ownerUri: connection1Id,
connectionId: connection1Id,
messages: undefined,
errorMessage: undefined,
errorNumber: undefined,
serverInfo: undefined,
connectionSummary: undefined
};
connections.onConnectionComplete(summary);
let actual = connections.addConnection(connectionProfile, connection1Id).connecting;
assert.equal(actual, expected);
});
test('onConnectionComplete should set connecting to false', () => {
let expected = false;
let summary: data.ConnectionInfoSummary = {
ownerUri: connection1Id,
connectionId: connection1Id,
messages: undefined,
errorMessage: undefined,
errorNumber: undefined,
serverInfo: undefined,
connectionSummary: undefined
};
connections.onConnectionComplete(summary);
let actual = connections.findConnection(connection1Id).connecting;
assert.equal(actual, expected);
actual = connections.isConnecting(connection1Id);
assert.equal(actual, expected);
});
test('updateConnection should update the connection info', () => {
let expected = connectionProfile.groupId + '1';
let expectedConnectionId = 'new id';
connections.addConnection(connectionProfile, connection1Id);
let updatedConnection = Object.assign({}, connectionProfile, { groupId: expected, getOptionsKey: () => connectionProfile.getOptionsKey() + expected, id: expectedConnectionId });
let actualId = connections.updateConnectionProfile(updatedConnection, connection1Id);
let newId = Utils.generateUri(updatedConnection);
let actual = connections.getConnectionProfile(newId).groupId;
let actualConnectionId = connections.getConnectionProfile(newId).id;
assert.equal(actual, expected);
assert.equal(actualId, newId);
assert.equal(actualConnectionId, expectedConnectionId);
});
test('updateDatabaseName should update the database name in connection', () => {
let dbName: string = 'db name';
let summary: data.ConnectionInfoSummary = {
connectionSummary: {
databaseName: dbName,
serverName: undefined,
userName: undefined
}
, ownerUri: connection3Id,
connectionId: 'connection id',
errorMessage: undefined,
errorNumber: undefined,
messages: undefined,
serverInfo: undefined
};
//The original connection didn't have database name
let connectionStatus = connections.findConnection(connection3Id);
connectionStatus.connectionProfile.databaseName = '';
//Verify database name changed after connection is complete
connections.updateDatabaseName(summary);
connectionStatus = connections.findConnection(connection3Id);
assert.equal(connectionStatus.connectionProfile.databaseName, dbName);
});
test('getOriginalOwnerUri should return the original uri given uri with db name', () => {
let dbName: string = 'db name';
let summary: data.ConnectionInfoSummary = {
connectionSummary: {
databaseName: dbName,
serverName: undefined,
userName: undefined
}
, ownerUri: connection3Id,
connectionId: 'connection id',
errorMessage: undefined,
errorNumber: undefined,
messages: undefined,
serverInfo: undefined
};
//The original connection didn't have database name
let connectionStatus = connections.findConnection(connection3Id);
connectionStatus.connectionProfile.databaseName = '';
//Verify database name changed after connection is complete
connections.updateDatabaseName(summary);
connectionStatus = connections.findConnection(connection3Id);
let ownerUriWithDbName = Utils.generateUriWithPrefix(connectionStatus.connectionProfile, 'connection://');
//The uri assigned to connection without db name should be the original one
let connectionWitDbStatus = connections.getOriginalOwnerUri(ownerUriWithDbName);
assert.equal(connectionWitDbStatus, connection3Id);
});
test('getOriginalOwnerUri should return given uri if the original uri is the same as the given uri', () => {
let connectionStatus = connections.getOriginalOwnerUri(connection2Id);
assert.equal(connectionStatus, connection2Id);
});
});

View File

@@ -0,0 +1,459 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as TypeMoq from 'typemoq';
import { ConnectionConfig } from 'sql/parts/connection/common/connectionConfig';
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
import { WorkspaceConfigurationTestService } from 'sqltest/stubs/workspaceConfigurationTestService';
import * as Constants from 'sql/parts/connection/common/constants';
import { StorageTestService } from 'sqltest/stubs/storageTestService';
import { ConnectionStore } from 'sql/parts/connection/common/connectionStore';
import { CredentialsService } from 'sql/services/credentials/credentialsService';
import * as assert from 'assert';
import { Memento } from 'vs/workbench/common/memento';
import { CapabilitiesService } from 'sql/services/capabilities/capabilitiesService';
import * as data from 'data';
import { ConnectionProfile } from 'sql/parts/connection/common/connectionProfile';
import { Emitter } from 'vs/base/common/event';
import { IConnectionProfileGroup } from 'sql/parts/connection/common/connectionProfileGroup';
suite('SQL ConnectionStore tests', () => {
let defaultNamedProfile: IConnectionProfile;
let defaultUnnamedProfile: IConnectionProfile;
let context: TypeMoq.Mock<Memento>;
let credentialStore: TypeMoq.Mock<CredentialsService>;
let connectionConfig: TypeMoq.Mock<ConnectionConfig>;
let workspaceConfigurationServiceMock: TypeMoq.Mock<WorkspaceConfigurationTestService>;
let storageServiceMock: TypeMoq.Mock<StorageTestService>;
let capabilitiesService: TypeMoq.Mock<CapabilitiesService>;
let mementoArray: any = [];
let maxRecent = 5;
let msSQLCapabilities: data.DataProtocolServerCapabilities;
let defaultNamedConnectionProfile: ConnectionProfile;
let onProviderRegistered = new Emitter<data.DataProtocolServerCapabilities>();
setup(() => {
defaultNamedProfile = Object.assign({}, {
serverName: 'namedServer',
databaseName: 'bcd',
authenticationType: 'SqlLogin',
userName: 'cde',
password: 'asdf!@#$',
savePassword: true,
groupId: '',
groupFullName: '',
getOptionsKey: undefined,
matches: undefined,
providerName: 'MSSQL',
options: {},
saveProfile: true,
id: undefined
});
defaultUnnamedProfile = Object.assign({}, {
serverName: 'unnamedServer',
databaseName: undefined,
authenticationType: 'SqlLogin',
userName: 'aUser',
password: 'asdf!@#$',
savePassword: true,
groupId: '',
groupFullName: '',
getOptionsKey: undefined,
matches: undefined,
providerName: 'MSSQL',
options: {},
saveProfile: true,
id: undefined
});
let momento = new Memento('ConnectionManagement');
context = TypeMoq.Mock.ofInstance(momento);
context.setup(x => x.getMemento(TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => mementoArray);
credentialStore = TypeMoq.Mock.ofType(CredentialsService);
connectionConfig = TypeMoq.Mock.ofType(ConnectionConfig);
// setup configuration to return maxRecent for the #MRU items
let configResult: { [key: string]: any } = {};
configResult[Constants.configMaxRecentConnections] = maxRecent;
workspaceConfigurationServiceMock = TypeMoq.Mock.ofType(WorkspaceConfigurationTestService);
workspaceConfigurationServiceMock.setup(x => x.getConfiguration(Constants.sqlConfigSectionName))
.returns(() => configResult);
storageServiceMock = TypeMoq.Mock.ofType(StorageTestService);
capabilitiesService = TypeMoq.Mock.ofType(CapabilitiesService);
let capabilities: data.DataProtocolServerCapabilities[] = [];
let connectionProvider: data.ConnectionProviderOptions = {
options: [
{
name: 'serverName',
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: 0,
valueType: 0
},
{
name: 'databaseName',
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: 1,
valueType: 0
},
{
name: 'userName',
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: 3,
valueType: 0
},
{
name: 'authenticationType',
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: 2,
valueType: 0
},
{
name: 'password',
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: 4,
valueType: 0
}
]
};
msSQLCapabilities = {
protocolVersion: '1',
providerName: 'MSSQL',
providerDisplayName: 'MSSQL',
connectionProvider: connectionProvider,
adminServicesProvider: undefined,
features: undefined
};
capabilities.push(msSQLCapabilities);
capabilitiesService.setup(x => x.getCapabilities()).returns(() => capabilities);
capabilitiesService.setup(x => x.onProviderRegisteredEvent).returns(() => onProviderRegistered.event);
connectionConfig.setup(x => x.getCapabilities('MSSQL')).returns(() => msSQLCapabilities);
let groups: IConnectionProfileGroup[] = [
{
id: 'root',
name: 'root',
parentId: '',
color: '',
description: ''
},
{
id: 'g1',
name: 'g1',
parentId: 'root',
color: 'blue',
description: 'g1'
}
];
connectionConfig.setup(x => x.getAllGroups()).returns(() => groups);
defaultNamedConnectionProfile = new ConnectionProfile(msSQLCapabilities, defaultNamedProfile);
});
test('addActiveConnection should limit recent connection saves to the MaxRecentConnections amount', (done) => {
// Given 5 is the max # creds
let numCreds = 6;
// setup memento for MRU to return a list we have access to
credentialStore.setup(x => x.saveCredential(TypeMoq.It.isAny(), TypeMoq.It.isAny()))
.returns(() => Promise.resolve(true));
// When saving 4 connections
// Expect all of them to be saved even if size is limited to 3
let connectionStore = new ConnectionStore(storageServiceMock.object, context.object, undefined, workspaceConfigurationServiceMock.object,
credentialStore.object, capabilitiesService.object, connectionConfig.object);
let promise = Promise.resolve();
for (let i = 0; i < numCreds; i++) {
let cred = Object.assign({}, defaultNamedProfile, { serverName: defaultNamedProfile.serverName + i });
let connectionProfile = new ConnectionProfile(msSQLCapabilities, cred);
promise = promise.then(() => {
return connectionStore.addActiveConnection(connectionProfile);
}).then(() => {
let current = connectionStore.getRecentlyUsedConnections();
if (i >= maxRecent) {
assert.equal(current.length, maxRecent, `expect only top ${maxRecent} creds to be saved`);
} else {
assert.equal(current.length, i + 1, `expect all credentials to be saved ${current.length}|${i + 1} `);
}
assert.equal(current[0].serverName, cred.serverName, 'Expect most recently saved item to be first in list');
assert.ok(!current[0].password);
});
}
promise.then(() => {
credentialStore.verify(x => x.saveCredential(TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.exactly(numCreds));
let recentConnections = connectionStore.getActiveConnections();
assert.equal(numCreds, recentConnections.length, `expect number of active connection ${numCreds}|${recentConnections.length} `);
done();
}, err => {
// Must call done here so test indicates it's finished if errors occur
done(err);
});
});
test('addActiveConnection should add same connection exactly once', (done) => {
// setup memento for MRU to return a list we have access to
credentialStore.setup(x => x.saveCredential(TypeMoq.It.isAny(), TypeMoq.It.isAny()))
.returns(() => Promise.resolve(true));
// Given we save the same connection twice
// Then expect the only 1 instance of that connection to be listed in the MRU
let connectionStore = new ConnectionStore(storageServiceMock.object, context.object, undefined, workspaceConfigurationServiceMock.object,
credentialStore.object, capabilitiesService.object, connectionConfig.object);
connectionStore.clearActiveConnections();
connectionStore.clearRecentlyUsed();
let promise = Promise.resolve();
let cred = Object.assign({}, defaultNamedProfile, { serverName: defaultNamedProfile.serverName + 1 });
let connectionProfile = new ConnectionProfile(msSQLCapabilities, cred);
promise = promise.then(() => {
return connectionStore.addActiveConnection(defaultNamedConnectionProfile);
}).then(() => {
return connectionStore.addActiveConnection(connectionProfile);
}).then(() => {
return connectionStore.addActiveConnection(connectionProfile);
}).then(() => {
let current = connectionStore.getRecentlyUsedConnections();
assert.equal(current.length, 2, 'expect 2 unique credentials to have been added');
assert.equal(current[0].serverName, cred.serverName, 'Expect most recently saved item to be first in list');
assert.ok(!current[0].password);
}).then(() => done(), err => done(err));
});
test('addActiveConnection should save password to credential store', (done) => {
// Setup credential store to capture credentials sent to it
let capturedCreds: any;
credentialStore.setup(x => x.saveCredential(TypeMoq.It.isAny(), TypeMoq.It.isAny()))
.callback((cred: string, pass: any) => {
capturedCreds = {
'credentialId': cred,
'password': pass
};
})
.returns(() => Promise.resolve(true));
// Given we save 1 connection with password and multiple other connections without
let connectionStore = new ConnectionStore(storageServiceMock.object, context.object, undefined, workspaceConfigurationServiceMock.object,
credentialStore.object, capabilitiesService.object, connectionConfig.object);
connectionStore.clearActiveConnections();
connectionStore.clearRecentlyUsed();
let integratedCred = Object.assign({}, defaultNamedProfile, {
serverName: defaultNamedProfile.serverName + 'Integrated',
authenticationType: 'Integrated',
userName: '',
password: ''
});
let noPwdCred = Object.assign({}, defaultNamedProfile, {
serverName: defaultNamedProfile.serverName + 'NoPwd',
password: ''
});
let connectionProfile = new ConnectionProfile(msSQLCapabilities, defaultNamedProfile);
let expectedCredCount = 0;
let promise = Promise.resolve();
promise = promise.then(() => {
expectedCredCount++;
return connectionStore.addActiveConnection(connectionProfile);
}).then(() => {
let current = connectionStore.getRecentlyUsedConnections();
// Then verify that since its password based we save the password
credentialStore.verify(x => x.saveCredential(TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once());
assert.strictEqual(capturedCreds.password, defaultNamedProfile.password);
let credId: string = capturedCreds.credentialId;
assert.ok(credId.includes(ConnectionStore.CRED_PROFILE_USER), 'Expect credential to be marked as an Profile cred');
assert.ok(!current[0].password);
}).then(() => {
// When add integrated auth connection
expectedCredCount++;
let integratedCredConnectionProfile = new ConnectionProfile(msSQLCapabilities, integratedCred);
return connectionStore.addActiveConnection(integratedCredConnectionProfile);
}).then(() => {
let current = connectionStore.getRecentlyUsedConnections();
// then expect no to have credential store called, but MRU count upped to 2
credentialStore.verify(x => x.saveCredential(TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once());
assert.equal(current.length, expectedCredCount, `expect ${expectedCredCount} unique credentials to have been added`);
}).then(() => {
// When add connection without password
expectedCredCount++;
let noPwdCredConnectionProfile = new ConnectionProfile(msSQLCapabilities, noPwdCred);
return connectionStore.addActiveConnection(noPwdCredConnectionProfile);
}).then(() => {
let current = connectionStore.getRecentlyUsedConnections();
// then expect no to have credential store called, but MRU count upped to 3
credentialStore.verify(x => x.saveCredential(TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once());
assert.equal(current.length, expectedCredCount, `expect ${expectedCredCount} unique credentials to have been added`);
}).then(() => done(), err => done(err));
});
test('can clear connections list', (done) => {
connectionConfig.setup(x => x.getConnections(TypeMoq.It.isAny())).returns(() => []);
let connectionStore = new ConnectionStore(storageServiceMock.object, context.object, undefined, workspaceConfigurationServiceMock.object,
credentialStore.object, capabilitiesService.object, connectionConfig.object);
// When we clear the connections list and get the list of available connection items
connectionStore.clearActiveConnections();
connectionStore.clearRecentlyUsed();
// Expect no connection items
let result = connectionStore.getActiveConnections();
let expectedCount = 0; // 1 for create connection profile
assert.equal(result.length, expectedCount);
result = connectionStore.getRecentlyUsedConnections();
assert.equal(result.length, expectedCount);
// Then test is complete
done();
});
test('isPasswordRequired should return true for MSSQL SqlLogin', () => {
let connectionStore = new ConnectionStore(storageServiceMock.object, context.object, undefined, workspaceConfigurationServiceMock.object,
credentialStore.object, capabilitiesService.object, connectionConfig.object);
let expected: boolean = true;
let actual = connectionStore.isPasswordRequired(defaultNamedProfile);
assert.equal(expected, actual);
});
test('isPasswordRequired should return true for MSSQL SqlLogin for connection profile object', () => {
let connectionStore = new ConnectionStore(storageServiceMock.object, context.object, undefined, workspaceConfigurationServiceMock.object,
credentialStore.object, capabilitiesService.object, connectionConfig.object);
let connectionProfile = new ConnectionProfile(msSQLCapabilities, defaultNamedProfile);
let expected: boolean = true;
let actual = connectionStore.isPasswordRequired(connectionProfile);
assert.equal(expected, actual);
});
test('isPasswordRequired should return false if the password is not required in capabilities', () => {
let providerName: string = 'providername';
let connectionProvider: data.ConnectionProviderOptions = {
options: msSQLCapabilities.connectionProvider.options.map(o => {
if (o.name === 'password') {
o.isRequired = false;
}
return o;
})
};
let providerCapabilities = {
protocolVersion: '1',
providerName: providerName,
providerDisplayName: providerName,
connectionProvider: connectionProvider,
adminServicesProvider: undefined,
features: undefined
};
connectionConfig.setup(x => x.getCapabilities(providerName)).returns(() => providerCapabilities);
let connectionStore = new ConnectionStore(storageServiceMock.object, context.object, undefined, workspaceConfigurationServiceMock.object,
credentialStore.object, capabilitiesService.object, connectionConfig.object);
let connectionProfile: IConnectionProfile = Object.assign({}, defaultNamedProfile, { providerName: providerName });
let expected: boolean = false;
let actual = connectionStore.isPasswordRequired(connectionProfile);
assert.equal(expected, actual);
});
test('saveProfile should save the password after the profile is saved', done => {
let password: string = 'asdf!@#$';
let groupId: string = 'group id';
let connectionProfile: IConnectionProfile = Object.assign({}, defaultNamedProfile, { password: password });
let savedConnection: IConnectionProfile = Object.assign({}, connectionProfile, { groupId: groupId, password: '' });
connectionConfig.setup(x => x.addConnection(TypeMoq.It.isAny())).returns(() => Promise.resolve(savedConnection));
credentialStore.setup(x => x.saveCredential(TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve(true));
let connectionStore = new ConnectionStore(storageServiceMock.object, context.object, undefined, workspaceConfigurationServiceMock.object,
credentialStore.object, capabilitiesService.object, connectionConfig.object);
connectionStore.saveProfile(connectionProfile).then(profile => {
// add connection should be called with a profile without password
connectionConfig.verify(x => x.addConnection(TypeMoq.It.is<IConnectionProfile>(c => c.password === '')), TypeMoq.Times.once());
credentialStore.verify(x => x.saveCredential(TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once());
assert.equal(profile.password, password, 'The returned profile should still keep the password');
assert.equal(profile.groupId, groupId, 'Group id should be set in the profile');
done();
}).catch(err => {
assert.fail(err);
done(err);
});
});
test('addConnectionToMemento should not add duplicate items', () => {
let connectionStore = new ConnectionStore(storageServiceMock.object, context.object, undefined, workspaceConfigurationServiceMock.object,
credentialStore.object, capabilitiesService.object, connectionConfig.object);
let mementoKey = 'RECENT_CONNECTIONS2';
connectionStore.clearFromMemento(mementoKey);
let connectionProfile: IConnectionProfile = Object.assign({}, defaultNamedProfile);
connectionStore.addConnectionToMemento(connectionProfile, mementoKey);
connectionProfile = Object.assign({}, defaultNamedProfile, { authenticationType: 'Integrated', userName: '' });
connectionStore.addConnectionToMemento(connectionProfile, mementoKey);
let currentList = connectionStore.getConnectionsFromMemento(mementoKey);
assert.equal(currentList.length, 2, 'Adding same connection with different auth');
connectionProfile = Object.assign({}, defaultNamedProfile, { groupFullName: 'new group' });
connectionStore.addConnectionToMemento(connectionProfile, mementoKey);
currentList = connectionStore.getConnectionsFromMemento(mementoKey);
assert.equal(currentList.length, 3, 'Adding same connection with different group name');
connectionProfile = Object.assign({}, defaultNamedProfile,
{ groupFullName: defaultNamedProfile.groupFullName.toUpperCase() });
connectionStore.addConnectionToMemento(connectionProfile, mementoKey);
currentList = connectionStore.getConnectionsFromMemento(mementoKey);
assert.equal(currentList.length, 3, 'Adding same connection with same group name but uppercase');
connectionProfile = Object.assign({}, defaultNamedProfile,
{ groupFullName: '' });
connectionStore.addConnectionToMemento(connectionProfile, mementoKey);
currentList = connectionStore.getConnectionsFromMemento(mementoKey);
assert.equal(currentList.length, 3, 'Adding same connection with group empty string');
connectionProfile = Object.assign({}, defaultNamedProfile,
{ groupFullName: '/' });
connectionStore.addConnectionToMemento(connectionProfile, mementoKey);
currentList = connectionStore.getConnectionsFromMemento(mementoKey);
assert.equal(currentList.length, 3, 'Adding same connection with group /');
});
});

View File

@@ -0,0 +1,516 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { TPromise } from 'vs/base/common/winjs.base';
import * as TypeMoq from 'typemoq';
import * as assert from 'assert';
import { ConnectionProfileGroup } from 'sql/parts/connection/common/connectionProfileGroup';
import { ConnectionProfile } from 'sql/parts/connection/common/connectionProfile';
import {
RefreshAction, AddServerAction, DeleteConnectionAction, DisconnectConnectionAction,
ActiveConnectionsFilterAction, RecentConnectionsFilterAction
}
from 'sql/parts/registeredServer/viewlet/connectionTreeAction';
import { TestConnectionManagementService } from 'sqltest/stubs/connectionManagementService.test';
import { ErrorMessageServiceStub } from 'sqltest/stubs/errorMessageServiceStub';
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
import { ServerTreeView } from 'sql/parts/registeredServer/viewlet/serverTreeView';
import * as Constants from 'sql/parts/connection/common/constants';
import * as LocalizedConstants from 'sql/parts/connection/common/localizedConstants';
import { ObjectExplorerService, ObjectExplorerNodeEventArgs } from 'sql/parts/registeredServer/common/objectExplorerService';
import { TreeNode } from 'sql/parts/registeredServer/common/treeNode';
import { NodeType } from 'sql/parts/registeredServer/common/nodeType';
import { Tree } from 'vs/base/parts/tree/browser/treeImpl';
import { ServerTreeDataSource } from 'sql/parts/registeredServer/viewlet/serverTreeDataSource';
import { Builder, $ } from 'vs/base/browser/builder';
import WinJS = require('vs/base/common/winjs.base');
import { Emitter } from 'vs/base/common/event';
import Severity from 'vs/base/common/severity';
import { ObjectExplorerActionsContext, ManageConnectionAction } from 'sql/parts/registeredServer/viewlet/objectExplorerActions';
import { IConnectionResult, IConnectionParams } from 'sql/parts/connection/common/connectionManagement';
import { TreeSelectionHandler } from 'sql/parts/registeredServer/viewlet/treeSelectionHandler';
suite('SQL Connection Tree Action tests', () => {
let errorMessageService: TypeMoq.Mock<ErrorMessageServiceStub>;
let connectionResult: IConnectionResult = {
connected: true,
errorMessage: undefined,
errorCode: undefined
};
setup(() => {
errorMessageService = TypeMoq.Mock.ofType(ErrorMessageServiceStub, TypeMoq.MockBehavior.Loose);
let nothing: void;
errorMessageService.setup(x => x.showDialog(Severity.Error, TypeMoq.It.isAnyString(), TypeMoq.It.isAnyString())).returns(() => nothing);
});
function createConnectionManagementService(isConnectedReturnValue: boolean): TypeMoq.Mock<TestConnectionManagementService> {
let connectionManagementService = TypeMoq.Mock.ofType(TestConnectionManagementService, TypeMoq.MockBehavior.Strict);
connectionManagementService.callBase = true;
connectionManagementService.setup(x => x.isConnected(undefined, TypeMoq.It.isAny())).returns(() => isConnectedReturnValue);
connectionManagementService.setup(x => x.connect(TypeMoq.It.isAny(), undefined, TypeMoq.It.isAny(), undefined)).returns(() => Promise.resolve(connectionResult));
connectionManagementService.setup(x => x.disconnect(TypeMoq.It.isAny())).returns(() => Promise.resolve(true));
connectionManagementService.setup(x => x.findExistingConnection(TypeMoq.It.isAny())).returns(() => undefined);
connectionManagementService.setup(x => x.showDashboard(TypeMoq.It.isAny())).returns(() => Promise.resolve(true));
connectionManagementService.setup(x => x.isProfileConnected(TypeMoq.It.isAny())).returns(() => isConnectedReturnValue);
connectionManagementService.setup(x => x.isProfileConnecting(TypeMoq.It.isAny())).returns(() => false);
connectionManagementService.setup(x => x.showConnectionDialog(undefined, TypeMoq.It.isAny())).returns(() => new Promise<void>((resolve, reject) => resolve()));
connectionManagementService.setup(x => x.onConnect).returns(() => new Emitter<IConnectionParams>().event);
connectionManagementService.setup(x => x.onDisconnect).returns(() => new Emitter<any>().event);
connectionManagementService.setup(x => x.deleteConnectionGroup(TypeMoq.It.isAny())).returns(() => Promise.resolve(true));
connectionManagementService.setup(x => x.deleteConnection(TypeMoq.It.isAny())).returns(() => Promise.resolve(true));
return connectionManagementService;
}
function createObjectExplorerService(connectionManagementService: TestConnectionManagementService): TypeMoq.Mock<ObjectExplorerService> {
let objectExplorerService = TypeMoq.Mock.ofType(ObjectExplorerService, TypeMoq.MockBehavior.Strict, connectionManagementService);
objectExplorerService.callBase = true;
objectExplorerService.setup(x => x.getObjectExplorerNode(TypeMoq.It.isAny())).returns(() => new TreeNode('', '', false, '', '', '', undefined, undefined));
objectExplorerService.setup(x => x.getObjectExplorerNode(undefined)).returns(() => new TreeNode('', '', false, '', '', '', undefined, undefined));
objectExplorerService.setup(x => x.onUpdateObjectExplorerNodes).returns(() => new Emitter<ObjectExplorerNodeEventArgs>().event);
objectExplorerService.setup(x => x.onUpdateObjectExplorerNodes).returns(() => new Emitter<ObjectExplorerNodeEventArgs>().event);
return objectExplorerService;
}
test('ManageConnectionAction - test if connect is called for manage action if not already connected', (done) => {
let isConnectedReturnValue: boolean = false;
let connectionManagementService = createConnectionManagementService(isConnectedReturnValue);
let objectExplorerService = createObjectExplorerService(connectionManagementService.object);
let treeSelectionMock = TypeMoq.Mock.ofType(TreeSelectionHandler);
let instantiationService = TypeMoq.Mock.ofType(InstantiationService, TypeMoq.MockBehavior.Loose);
instantiationService.setup(x => x.createInstance(TypeMoq.It.isAny())).returns((input) => {
return treeSelectionMock.object;
});
let manageConnectionAction: ManageConnectionAction = new ManageConnectionAction(ManageConnectionAction.ID,
ManageConnectionAction.LABEL, connectionManagementService.object, instantiationService.object, objectExplorerService.object);
let connection: ConnectionProfile = new ConnectionProfile(undefined, {
savePassword: false,
groupFullName: 'testGroup',
serverName: 'testServerName',
databaseName: 'testDatabaseName',
authenticationType: 'integrated',
password: 'test',
userName: 'testUsername',
groupId: undefined,
getOptionsKey: undefined,
matches: undefined,
providerName: 'MSSQL',
options: {},
saveProfile: true,
id: 'testId'
});
var actionContext = new ObjectExplorerActionsContext();
actionContext.connectionProfile = connection;
manageConnectionAction.run(actionContext).then((value) => {
connectionManagementService.verify(x => x.connect(TypeMoq.It.isAny(), undefined, TypeMoq.It.isAny(), undefined), TypeMoq.Times.once());
}).then(() => done(), (err) => done(err));
});
test('ManageConnectionAction - test if connect is called for manage action on database node if not already connected', (done) => {
let isConnectedReturnValue: boolean = false;
let connectionManagementService = createConnectionManagementService(isConnectedReturnValue);
let objectExplorerService = createObjectExplorerService(connectionManagementService.object);
let treeSelectionMock = TypeMoq.Mock.ofType(TreeSelectionHandler);
let instantiationService = TypeMoq.Mock.ofType(InstantiationService, TypeMoq.MockBehavior.Loose);
instantiationService.setup(x => x.createInstance(TypeMoq.It.isAny())).returns((input) => {
return treeSelectionMock.object;
});
let manageConnectionAction: ManageConnectionAction = new ManageConnectionAction(ManageConnectionAction.ID,
ManageConnectionAction.LABEL, connectionManagementService.object, instantiationService.object, objectExplorerService.object);
let connection: ConnectionProfile = new ConnectionProfile(undefined, {
savePassword: false,
groupFullName: 'testGroup',
serverName: 'testServerName',
databaseName: 'testDatabaseName',
authenticationType: 'integrated',
password: 'test',
userName: 'testUsername',
groupId: undefined,
getOptionsKey: undefined,
matches: undefined,
providerName: 'MSSQL',
options: {},
saveProfile: true,
id: 'testId'
});
let treeNode = new TreeNode(NodeType.Database, 'db node', false, '', '', '', undefined, undefined);
treeNode.connection = connection;
var actionContext = new ObjectExplorerActionsContext();
actionContext.treeNode = treeNode;
manageConnectionAction.run(actionContext).then((value) => {
connectionManagementService.verify(x => x.showDashboard(TypeMoq.It.isAny()), TypeMoq.Times.once());
}).then(() => done(), (err) => done(err));
});
test('DisconnectConnectionAction - test if disconnect is called when profile is connected', (done) => {
let isConnectedReturnValue: boolean = true;
let connectionManagementService = createConnectionManagementService(isConnectedReturnValue);
let objectExplorerService = createObjectExplorerService(connectionManagementService.object);
let changeConnectionAction: DisconnectConnectionAction = new DisconnectConnectionAction(DisconnectConnectionAction.ID, DisconnectConnectionAction.LABEL, connectionManagementService.object, objectExplorerService.object, errorMessageService.object);
let connection: ConnectionProfile = new ConnectionProfile(undefined, {
savePassword: false,
groupFullName: 'testGroup',
serverName: 'testServerName',
databaseName: 'testDatabaseName',
authenticationType: 'integrated',
password: 'test',
userName: 'testUsername',
groupId: undefined,
getOptionsKey: undefined,
matches: undefined,
providerName: 'MSSQL',
options: {},
saveProfile: true,
id: 'testId'
});
var actionContext = new ObjectExplorerActionsContext();
actionContext.connectionProfile = connection;
changeConnectionAction.run(actionContext).then((value) => {
connectionManagementService.verify(x => x.isProfileConnected(TypeMoq.It.isAny()), TypeMoq.Times.atLeastOnce());
connectionManagementService.verify(x => x.disconnect(TypeMoq.It.isAny()), TypeMoq.Times.once());
}).then(() => done(), (err) => done(err));
});
test('AddServerAction - test if show connection dialog is called', (done) => {
let connectionManagementService = createConnectionManagementService(true);
let connectionTreeAction: AddServerAction = new AddServerAction(AddServerAction.ID, AddServerAction.LABEL, connectionManagementService.object);
let conProfGroup = new ConnectionProfileGroup('testGroup', undefined, 'testGroup', undefined, undefined);
connectionTreeAction.run(conProfGroup).then((value) => {
connectionManagementService.verify(x => x.showConnectionDialog(undefined, TypeMoq.It.isAny()), TypeMoq.Times.once());
}).then(() => done(), (err) => done(err));
});
test('ActiveConnectionsFilterAction - test if view is called to display filtered results', (done) => {
let connectionManagementService = createConnectionManagementService(true);
let instantiationService = TypeMoq.Mock.ofType(InstantiationService, TypeMoq.MockBehavior.Loose);
instantiationService.setup(x => x.createInstance(TypeMoq.It.isAny())).returns((input) => {
return new TPromise((resolve) => resolve({}));
});
let serverTreeView = TypeMoq.Mock.ofType(ServerTreeView, TypeMoq.MockBehavior.Strict, undefined, instantiationService.object, undefined, undefined, undefined);
serverTreeView.setup(x => x.showFilteredTree(TypeMoq.It.isAnyString()));
serverTreeView.setup(x => x.refreshTree());
let connectionTreeAction: ActiveConnectionsFilterAction = new ActiveConnectionsFilterAction(ActiveConnectionsFilterAction.ID, ActiveConnectionsFilterAction.LABEL, serverTreeView.object, connectionManagementService.object);
connectionTreeAction.run().then((value) => {
serverTreeView.verify(x => x.showFilteredTree('active'), TypeMoq.Times.once());
}).then(() => done(), (err) => done(err));
});
test('ActiveConnectionsFilterAction - test if view is called refresh results if action is toggled', (done) => {
let connectionManagementService = createConnectionManagementService(true);
let instantiationService = TypeMoq.Mock.ofType(InstantiationService, TypeMoq.MockBehavior.Loose);
instantiationService.setup(x => x.createInstance(TypeMoq.It.isAny())).returns((input) => {
return new TPromise((resolve) => resolve({}));
});
let serverTreeView = TypeMoq.Mock.ofType(ServerTreeView, TypeMoq.MockBehavior.Strict, undefined, instantiationService.object, undefined, undefined, undefined);
serverTreeView.setup(x => x.showFilteredTree(TypeMoq.It.isAnyString()));
serverTreeView.setup(x => x.refreshTree());
let connectionTreeAction: ActiveConnectionsFilterAction = new ActiveConnectionsFilterAction(ActiveConnectionsFilterAction.ID, ActiveConnectionsFilterAction.LABEL, serverTreeView.object, connectionManagementService.object);
connectionTreeAction.isSet = true;
connectionTreeAction.run().then((value) => {
serverTreeView.verify(x => x.refreshTree(), TypeMoq.Times.once());
}).then(() => done(), (err) => done(err));
});
test('RecentConnectionsFilterAction - test if view is called to display filtered results', (done) => {
let connectionManagementService = createConnectionManagementService(true);
let instantiationService = TypeMoq.Mock.ofType(InstantiationService, TypeMoq.MockBehavior.Loose);
instantiationService.setup(x => x.createInstance(TypeMoq.It.isAny())).returns((input) => {
return new TPromise((resolve) => resolve({}));
});
let serverTreeView = TypeMoq.Mock.ofType(ServerTreeView, TypeMoq.MockBehavior.Strict, undefined, instantiationService.object, undefined, undefined, undefined);
serverTreeView.setup(x => x.showFilteredTree(TypeMoq.It.isAnyString()));
serverTreeView.setup(x => x.refreshTree());
let connectionTreeAction: RecentConnectionsFilterAction = new RecentConnectionsFilterAction(RecentConnectionsFilterAction.ID, RecentConnectionsFilterAction.LABEL, serverTreeView.object, connectionManagementService.object);
connectionTreeAction.run().then((value) => {
serverTreeView.verify(x => x.showFilteredTree('recent'), TypeMoq.Times.once());
}).then(() => done(), (err) => done(err));
});
test('RecentConnectionsFilterAction - test if view is called refresh results if action is toggled', (done) => {
let connectionManagementService = createConnectionManagementService(true);
let instantiationService = TypeMoq.Mock.ofType(InstantiationService, TypeMoq.MockBehavior.Loose);
instantiationService.setup(x => x.createInstance(TypeMoq.It.isAny())).returns((input) => {
return new TPromise((resolve) => resolve({}));
});
let serverTreeView = TypeMoq.Mock.ofType(ServerTreeView, TypeMoq.MockBehavior.Strict, undefined, instantiationService.object, undefined, undefined, undefined);
serverTreeView.setup(x => x.showFilteredTree(TypeMoq.It.isAnyString()));
serverTreeView.setup(x => x.refreshTree());
let connectionTreeAction: RecentConnectionsFilterAction = new RecentConnectionsFilterAction(RecentConnectionsFilterAction.ID, RecentConnectionsFilterAction.LABEL, serverTreeView.object, connectionManagementService.object);
connectionTreeAction.isSet = true;
connectionTreeAction.run().then((value) => {
serverTreeView.verify(x => x.refreshTree(), TypeMoq.Times.once());
}).then(() => done(), (err) => done(err));
});
test('DeleteConnectionAction - test delete connection', (done) => {
let connectionManagementService = createConnectionManagementService(true);
let connection: ConnectionProfile = new ConnectionProfile(undefined, {
savePassword: false,
groupFullName: 'testGroup',
serverName: 'testServerName',
databaseName: 'testDatabaseName',
authenticationType: 'integrated',
password: 'test',
userName: 'testUsername',
groupId: undefined,
getOptionsKey: undefined,
matches: undefined,
providerName: 'MSSQL',
options: {},
saveProfile: true,
id: 'testId'
});
let connectionAction: DeleteConnectionAction = new DeleteConnectionAction(DeleteConnectionAction.ID,
DeleteConnectionAction.DELETE_CONNECTION_LABEL,
connection,
connectionManagementService.object);
connectionAction.run().then((value) => {
connectionManagementService.verify(x => x.deleteConnection(TypeMoq.It.isAny()), TypeMoq.Times.atLeastOnce());
}).then(() => done(), (err) => done(err));
});
test('DeleteConnectionAction - test delete connection group', (done) => {
let isConnectedReturnValue: boolean = false;
let connectionManagementService = createConnectionManagementService(isConnectedReturnValue);
let conProfGroup = new ConnectionProfileGroup('testGroup', undefined, 'testGroup', undefined, undefined);
let connectionAction: DeleteConnectionAction = new DeleteConnectionAction(DeleteConnectionAction.ID,
DeleteConnectionAction.DELETE_CONNECTION_LABEL,
conProfGroup,
connectionManagementService.object);
connectionAction.run().then((value) => {
connectionManagementService.verify(x => x.deleteConnectionGroup(TypeMoq.It.isAny()), TypeMoq.Times.atLeastOnce());
}).then(() => done(), (err) => done(err));
});
test('DeleteConnectionAction - delete should not be called if connect is an unsaved connection', (done) => {
let isConnectedReturnValue: boolean = false;
let connectionManagementService = createConnectionManagementService(isConnectedReturnValue);
let connection: ConnectionProfile = new ConnectionProfile(undefined, {
savePassword: false,
groupFullName: 'testGroup',
serverName: 'testServerName',
databaseName: 'testDatabaseName',
authenticationType: 'integrated',
password: 'test',
userName: 'testUsername',
groupId: undefined,
getOptionsKey: undefined,
matches: undefined,
providerName: 'MSSQL',
options: {},
saveProfile: true,
id: 'testId'
});
connection.parent = new ConnectionProfileGroup(LocalizedConstants.unsavedGroupLabel, undefined, Constants.unsavedGroupId, undefined, undefined);
let connectionAction: DeleteConnectionAction = new DeleteConnectionAction(DeleteConnectionAction.ID,
DeleteConnectionAction.DELETE_CONNECTION_LABEL,
connection,
connectionManagementService.object);
assert.equal(connectionAction.enabled, false, 'delete action should be disabled.');
done();
});
test('RefreshConnectionAction - refresh should be called if connection status is connect', (done) => {
let isConnectedReturnValue: boolean = true;
let sqlProvider = {
protocolVersion: '1',
providerName: 'MSSQL',
providerDisplayName: 'MSSQL',
connectionProvider: { options: [] },
adminServicesProvider: { databaseInfoOptions: [], databaseFileInfoOptions: [], fileGroupInfoOptions: [] },
features: undefined
};
var connection = new ConnectionProfile(sqlProvider, {
savePassword: false,
groupFullName: 'testGroup',
serverName: 'testServerName',
databaseName: 'testDatabaseName',
authenticationType: 'inetgrated',
password: 'test',
userName: 'testUsername',
groupId: undefined,
getOptionsKey: undefined,
matches: undefined,
providerName: 'MSSQL',
options: {},
saveProfile: true,
id: 'testID'
});
var conProfGroup = new ConnectionProfileGroup('testGroup', undefined, 'testGroup', undefined, undefined);
conProfGroup.connections = [connection];
var connectionManagementService = TypeMoq.Mock.ofType(TestConnectionManagementService, TypeMoq.MockBehavior.Strict);
connectionManagementService.callBase = true;
connectionManagementService.setup(x => x.getConnectionGroups()).returns(() => [conProfGroup]);
connectionManagementService.setup(x => x.getActiveConnections()).returns(() => [connection]);
connectionManagementService.setup(x => x.addSavedPassword(TypeMoq.It.isAny())).returns(() => new Promise<ConnectionProfile>((resolve) => {
resolve(connection);
}));
connectionManagementService.setup(x => x.isConnected(undefined, TypeMoq.It.isAny())).returns(() => isConnectedReturnValue);
var objectExplorerSession = {
success: true,
sessionId: '1234',
rootNode: {
nodePath: 'testServerName\tables',
nodeType: NodeType.Folder,
label: 'Tables',
isLeaf: false,
metadata: null,
nodeSubType: '',
nodeStatus: '',
errorMessage: ''
},
errorMessage: ''
};
var tablesNode = new TreeNode(NodeType.Folder, 'Tables', false, 'testServerName\Db1\tables', '', '', null, null);
tablesNode.connection = connection;
tablesNode.session = objectExplorerSession;
var table1Node = new TreeNode(NodeType.Table, 'dbo.Table1', false, 'testServerName\tables\dbo.Table1', '', '', tablesNode, null);
var table2Node = new TreeNode(NodeType.Table, 'dbo.Table1', false, 'testServerName\tables\dbo.Table1', '', '', tablesNode, null);
tablesNode.children = [table1Node, table2Node];
let objectExplorerService = TypeMoq.Mock.ofType(ObjectExplorerService, TypeMoq.MockBehavior.Loose, connectionManagementService.object);
objectExplorerService.callBase = true;
objectExplorerService.setup(x => x.getObjectExplorerNode(TypeMoq.It.isAny())).returns(() => tablesNode);
objectExplorerService.setup(x => x.refreshTreeNode(TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => TPromise.as([table1Node, table2Node]));
let builder: Builder = $().div();
var dataSource = new ServerTreeDataSource(objectExplorerService.object, connectionManagementService.object, undefined);
let tree = TypeMoq.Mock.ofType(Tree, TypeMoq.MockBehavior.Loose, builder.getHTMLElement(), { dataSource });
tree.callBase = true;
tree.setup(x => x.refresh(TypeMoq.It.isAny())).returns(() => WinJS.TPromise.as(null));
tree.setup(x => x.expand(TypeMoq.It.isAny())).returns(() => WinJS.TPromise.as(null));
tree.setup(x => x.collapse(TypeMoq.It.isAny())).returns(() => WinJS.TPromise.as(null));
let connectionAction: RefreshAction = new RefreshAction(RefreshAction.ID,
RefreshAction.LABEL,
tree.object,
connection,
connectionManagementService.object,
objectExplorerService.object,
undefined);
connectionAction.run().then((value) => {
connectionManagementService.verify(x => x.isConnected(undefined, TypeMoq.It.isAny()), TypeMoq.Times.atLeastOnce());
objectExplorerService.verify(x => x.getObjectExplorerNode(TypeMoq.It.isAny()), TypeMoq.Times.atLeastOnce());
objectExplorerService.verify(x => x.refreshTreeNode(TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.atLeastOnce());
tree.verify(x => x.refresh(TypeMoq.It.isAny()), TypeMoq.Times.atLeastOnce());
tree.verify(x => x.expand(TypeMoq.It.isAny()), TypeMoq.Times.atLeastOnce());
}).then(() => done(), (err) => done(err));
});
test('RefreshConnectionAction - refresh should not be called if connection status is not connect', (done) => {
let isConnectedReturnValue: boolean = false;
let sqlProvider = {
protocolVersion: '1',
providerName: 'MSSQL',
providerDisplayName: 'MSSQL',
connectionProvider: { options: [] },
adminServicesProvider: { databaseInfoOptions: [], databaseFileInfoOptions: [], fileGroupInfoOptions: [] },
features: undefined
};
var connection = new ConnectionProfile(sqlProvider, {
savePassword: false,
groupFullName: 'testGroup',
serverName: 'testServerName',
databaseName: 'testDatabaseName',
authenticationType: 'inetgrated',
password: 'test',
userName: 'testUsername',
groupId: undefined,
getOptionsKey: undefined,
matches: undefined,
providerName: 'MSSQL',
options: {},
saveProfile: true,
id: 'testID'
});
var conProfGroup = new ConnectionProfileGroup('testGroup', undefined, 'testGroup', undefined, undefined);
conProfGroup.connections = [connection];
var connectionManagementService = TypeMoq.Mock.ofType(TestConnectionManagementService, TypeMoq.MockBehavior.Strict);
connectionManagementService.callBase = true;
connectionManagementService.setup(x => x.getConnectionGroups()).returns(() => [conProfGroup]);
connectionManagementService.setup(x => x.getActiveConnections()).returns(() => [connection]);
connectionManagementService.setup(x => x.addSavedPassword(TypeMoq.It.isAny())).returns(() => new Promise<ConnectionProfile>((resolve) => {
resolve(connection);
}));
connectionManagementService.setup(x => x.isConnected(undefined, TypeMoq.It.isAny())).returns(() => isConnectedReturnValue);
var objectExplorerSession = {
success: true,
sessionId: '1234',
rootNode: {
nodePath: 'testServerName\tables',
nodeType: NodeType.Folder,
label: 'Tables',
isLeaf: false,
metadata: null,
nodeSubType: '',
nodeStatus: '',
errorMessage: ''
},
errorMessage: ''
};
var tablesNode = new TreeNode(NodeType.Folder, 'Tables', false, 'testServerName\Db1\tables', '', '', null, null);
tablesNode.connection = connection;
tablesNode.session = objectExplorerSession;
var table1Node = new TreeNode(NodeType.Table, 'dbo.Table1', false, 'testServerName\tables\dbo.Table1', '', '', tablesNode, null);
var table2Node = new TreeNode(NodeType.Table, 'dbo.Table1', false, 'testServerName\tables\dbo.Table1', '', '', tablesNode, null);
tablesNode.children = [table1Node, table2Node];
let objectExplorerService = TypeMoq.Mock.ofType(ObjectExplorerService, TypeMoq.MockBehavior.Loose, connectionManagementService.object);
objectExplorerService.callBase = true;
objectExplorerService.setup(x => x.getObjectExplorerNode(TypeMoq.It.isAny())).returns(() => tablesNode);
objectExplorerService.setup(x => x.refreshTreeNode(TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => TPromise.as([table1Node, table2Node]));
let builder: Builder = $().div();
var dataSource = new ServerTreeDataSource(objectExplorerService.object, connectionManagementService.object, undefined);
let tree = TypeMoq.Mock.ofType(Tree, TypeMoq.MockBehavior.Loose, builder.getHTMLElement(), { dataSource });
tree.callBase = true;
tree.setup(x => x.refresh(TypeMoq.It.isAny())).returns(() => WinJS.TPromise.as(null));
tree.setup(x => x.expand(TypeMoq.It.isAny())).returns(() => WinJS.TPromise.as(null));
let connectionAction: RefreshAction = new RefreshAction(RefreshAction.ID,
RefreshAction.LABEL,
tree.object,
connection,
connectionManagementService.object,
objectExplorerService.object,
undefined);
connectionAction.run().then((value) => {
connectionManagementService.verify(x => x.isConnected(undefined, TypeMoq.It.isAny()), TypeMoq.Times.atLeastOnce());
objectExplorerService.verify(x => x.getObjectExplorerNode(TypeMoq.It.isAny()), TypeMoq.Times.exactly(0));
objectExplorerService.verify(x => x.refreshTreeNode(TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.exactly(0));
tree.verify(x => x.refresh(TypeMoq.It.isAny()), TypeMoq.Times.exactly(0));
tree.verify(x => x.expand(TypeMoq.It.isAny()), TypeMoq.Times.exactly(0));
}).then(() => done(), (err) => done(err));
});
});

View File

@@ -0,0 +1,450 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { ObjectExplorerProviderTestService } from 'sqltest/stubs/objectExplorerProviderTestService';
import { TestConnectionManagementService } from 'sqltest/stubs/connectionManagementService.test';
import { ConnectionProfile } from 'sql/parts/connection/common/connectionProfile';
import { ConnectionProfileGroup } from 'sql/parts/connection/common/connectionProfileGroup';
import { ObjectExplorerService } from 'sql/parts/registeredServer/common/objectExplorerService';
import { NodeType } from 'sql/parts/registeredServer/common/nodeType';
import { TreeNode } from 'sql/parts/registeredServer/common/treeNode';
import { TPromise } from 'vs/base/common/winjs.base';
import * as data from 'data';
import * as TypeMoq from 'typemoq';
import * as assert from 'assert';
suite('SQL Object Explorer Service tests', () => {
var sqlOEProvider: TypeMoq.Mock<ObjectExplorerProviderTestService>;
let connectionManagementService: TypeMoq.Mock<TestConnectionManagementService>;
let connection: ConnectionProfile;
let connectionToFail: ConnectionProfile;
let conProfGroup: ConnectionProfileGroup;
let objectExplorerService: ObjectExplorerService;
let objectExplorerSession: data.ObjectExplorerSession;
let objectExplorerFailedSession: data.ObjectExplorerSession;
let objectExplorerCloseSessionResponse: data.ObjectExplorerCloseSessionResponse;
let objectExplorerExpandInfo: data.ObjectExplorerExpandInfo;
let objectExplorerExpandInfoRefresh: data.ObjectExplorerExpandInfo;
let sessionId = '1234';
let failedSessionId = '12345';
let numberOfFailedSession: number = 0;
setup(() => {
let NodeInfoTable1 = {
nodePath: 'testServerName\tables\dbo.Table1',
nodeType: NodeType.Table,
label: 'dbo.Table1',
isLeaf: false,
metadata: null,
nodeSubType: '',
nodeStatus: '',
errorMessage: ''
};
let NodeInfoTable2 = {
nodePath: 'testServerName\tables\dbo.Table2',
nodeType: NodeType.Table,
label: 'dbo.Table2',
isLeaf: false,
metadata: null,
nodeSubType: '',
nodeStatus: '',
errorMessage: ''
};
let NodeInfoTable3 = {
nodePath: 'testServerName\tables\dbo.Table3',
nodeType: NodeType.Table,
label: 'dbo.Table3',
isLeaf: false,
metadata: null,
nodeSubType: '',
nodeStatus: '',
errorMessage: ''
};
objectExplorerSession = {
success: true,
sessionId: sessionId,
rootNode: {
nodePath: 'testServerName\tables',
nodeType: NodeType.Folder,
label: 'Tables',
isLeaf: false,
metadata: null,
nodeSubType: '',
nodeStatus: '',
errorMessage: ''
},
errorMessage: ''
};
objectExplorerFailedSession = {
success: false,
sessionId: failedSessionId,
rootNode: undefined,
errorMessage: 'Connection Failed'
};
objectExplorerCloseSessionResponse = {
success: true,
sessionId: sessionId,
};
objectExplorerExpandInfo = {
sessionId: sessionId,
nodes: [NodeInfoTable1, NodeInfoTable2],
errorMessage: '',
nodePath: objectExplorerSession.rootNode.nodePath
};
objectExplorerExpandInfoRefresh = {
sessionId: sessionId,
nodes: [NodeInfoTable1, NodeInfoTable3],
errorMessage: '',
nodePath: objectExplorerSession.rootNode.nodePath
};
let response: data.ObjectExplorerSessionResponse = {
sessionId: objectExplorerSession.sessionId
};
let failedResponse: data.ObjectExplorerSessionResponse = {
sessionId: failedSessionId
};
sqlOEProvider = TypeMoq.Mock.ofType(ObjectExplorerProviderTestService, TypeMoq.MockBehavior.Loose);
sqlOEProvider.callBase = true;
let sqlProvider = {
protocolVersion: '1',
providerName: 'MSSQL',
providerDisplayName: 'MSSQL',
connectionProvider: {
options: [
{
name: 'serverName',
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: 0,
valueType: 0
},
{
name: 'databaseName',
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: 1,
valueType: 0
},
{
name: 'userName',
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: 3,
valueType: 0
},
{
name: 'authenticationType',
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: 2,
valueType: 0
},
{
name: 'password',
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: 4,
valueType: 0
},
{
name: 'encrypt',
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: false,
isRequired: false,
specialValueType: undefined,
valueType: 0
}]
},
adminServicesProvider: { databaseInfoOptions: [], databaseFileInfoOptions: [], fileGroupInfoOptions: [] },
features: undefined
};
connection = new ConnectionProfile(sqlProvider, {
savePassword: false,
groupFullName: 'testGroup',
serverName: 'testServerName',
databaseName: 'testDatabaseName',
authenticationType: 'inetgrated',
password: 'test',
userName: 'testUsername',
groupId: undefined,
getOptionsKey: undefined,
matches: undefined,
providerName: 'MSSQL',
options: {},
saveProfile: true,
id: 'testID'
});
conProfGroup = new ConnectionProfileGroup('testGroup', undefined, 'testGroup', undefined, undefined);
connectionToFail = new ConnectionProfile(sqlProvider, {
savePassword: false,
groupFullName: 'testGroup',
serverName: 'testServerName2',
databaseName: 'testDatabaseName2',
authenticationType: 'inetgrated',
password: 'test',
userName: 'testUsername',
groupId: undefined,
getOptionsKey: undefined,
matches: undefined,
providerName: 'MSSQL',
options: {},
saveProfile: true,
id: 'testID2'
});
conProfGroup = new ConnectionProfileGroup('testGroup', undefined, 'testGroup', undefined, undefined);
conProfGroup.connections = [connection];
connectionManagementService = TypeMoq.Mock.ofType(TestConnectionManagementService, TypeMoq.MockBehavior.Strict);
connectionManagementService.setup(x => x.getConnectionGroups()).returns(() => [conProfGroup]);
connectionManagementService.setup(x => x.getActiveConnections()).returns(() => [connection]);
connectionManagementService.setup(x => x.addSavedPassword(TypeMoq.It.isAny())).returns(() => new Promise<ConnectionProfile>((resolve) => {
resolve(connection);
}));
connectionManagementService.setup(x => x.getCapabilities('MSSQL')).returns(() => undefined);
objectExplorerService = new ObjectExplorerService(connectionManagementService.object, undefined);
objectExplorerService.registerProvider('MSSQL', sqlOEProvider.object);
sqlOEProvider.setup(x => x.createNewSession(TypeMoq.It.is<data.ConnectionInfo>(x => x.options['serverName'] === connection.serverName))).returns(() => new Promise<any>((resolve) => {
resolve(response);
}));
sqlOEProvider.setup(x => x.createNewSession(TypeMoq.It.is<data.ConnectionInfo>(x => x.options['serverName'] === connectionToFail.serverName))).returns(() => new Promise<any>((resolve) => {
resolve(failedResponse);
}));
sqlOEProvider.setup(x => x.expandNode(TypeMoq.It.isAny())).callback(() => {
objectExplorerService.onNodeExpanded(1, objectExplorerExpandInfo);
}).returns(() => TPromise.as(true));
sqlOEProvider.setup(x => x.refreshNode(TypeMoq.It.isAny())).callback(() => {
objectExplorerService.onNodeExpanded(1, objectExplorerExpandInfoRefresh);
}).returns(() => TPromise.as(true));
sqlOEProvider.setup(x => x.closeSession(TypeMoq.It.isAny())).returns(() => TPromise.as(objectExplorerCloseSessionResponse));
objectExplorerService.onUpdateObjectExplorerNodes(args => {
if (args && args.errorMessage !== undefined) {
numberOfFailedSession++;
}
});
});
test('create new session should create session successfully', (done) => {
objectExplorerService.createNewSession('MSSQL', connection).then(session => {
assert.equal(session !== null || session !== undefined, true);
assert.equal(session.sessionId, '1234');
objectExplorerService.onSessionCreated(1, objectExplorerSession);
let node = objectExplorerService.getObjectExplorerNode(connection);
assert.notEqual(node, undefined);
assert.equal(node.session.success, true);
done();
}, err => {
// Must call done here so test indicates it's finished if errors occur
done(err);
});
});
test('create new session should raise failed event for failed session', (done) => {
objectExplorerService.createNewSession('MSSQL', connectionToFail).then(session => {
assert.equal(session !== null || session !== undefined, true);
assert.equal(session.sessionId, failedSessionId);
let currentNumberOfFailedSession = numberOfFailedSession;
objectExplorerService.onSessionCreated(1, objectExplorerFailedSession);
let node = objectExplorerService.getObjectExplorerNode(connection);
assert.equal(node, undefined);
assert.equal(currentNumberOfFailedSession + 1, numberOfFailedSession);
done();
}, err => {
// Must call done here so test indicates it's finished if errors occur
done(err);
});
});
test('close session should close session successfully', (done) => {
objectExplorerService.closeSession('MSSQL', objectExplorerSession).then(session => {
assert.equal(session !== null || session !== undefined, true);
assert.equal(session.success, true);
assert.equal(session.sessionId, '1234');
done();
}, err => {
// Must call done here so test indicates it's finished if errors occur
done(err);
});
});
test('expand node should expand node correctly', (done) => {
objectExplorerService.createNewSession('MSSQL', connection).then(result => {
objectExplorerService.onSessionCreated(1, objectExplorerSession);
objectExplorerService.expandNode('MSSQL', objectExplorerSession, 'testServerName\tables').then(expandInfo => {
assert.equal(expandInfo !== null || expandInfo !== undefined, true);
assert.equal(expandInfo.sessionId, '1234');
assert.equal(expandInfo.nodes.length, 2);
var children = expandInfo.nodes;
assert.equal(children[0].label, 'dbo.Table1');
assert.equal(children[1].label, 'dbo.Table2');
done();
}, err => {
// Must call done here so test indicates it's finished if errors occur
done(err);
});
});
});
test('refresh node should refresh node correctly', (done) => {
objectExplorerService.createNewSession('MSSQL', connection).then(result => {
objectExplorerService.onSessionCreated(1, objectExplorerSession);
objectExplorerService.refreshNode('MSSQL', objectExplorerSession, 'testServerName\tables').then(expandInfo => {
assert.equal(expandInfo !== null || expandInfo !== undefined, true);
assert.equal(expandInfo.sessionId, '1234');
assert.equal(expandInfo.nodes.length, 2);
var children = expandInfo.nodes;
assert.equal(children[0].label, 'dbo.Table1');
assert.equal(children[1].label, 'dbo.Table3');
done();
}, err => {
// Must call done here so test indicates it's finished if errors occur
done(err);
});
});
});
test('expand tree node should children correctly', (done) => {
var tablesNode = new TreeNode(NodeType.Folder, 'Tables', false, 'testServerName\tables', '', '', null, null);
tablesNode.connection = connection;
objectExplorerService.createNewSession('MSSQL', connection).then(result => {
objectExplorerService.onSessionCreated(1, objectExplorerSession);
objectExplorerService.expandTreeNode(objectExplorerSession, tablesNode).then(children => {
assert.equal(children !== null || children !== undefined, true);
assert.equal(children[0].label, 'dbo.Table1');
assert.equal(children[0].parent, tablesNode);
assert.equal(children[0].nodePath, 'testServerName\tables\dbo.Table1');
assert.equal(children[1].label, 'dbo.Table2');
assert.equal(children[1].parent, tablesNode);
assert.equal(children[1].nodePath, 'testServerName\tables\dbo.Table2');
done();
}, err => {
// Must call done here so test indicates it's finished if errors occur
done(err);
});
});
});
test('refresh tree node should children correctly', (done) => {
var tablesNode = new TreeNode(NodeType.Folder, 'Tables', false, 'testServerName\tables', '', '', null, null);
tablesNode.connection = connection;
objectExplorerService.createNewSession('MSSQL', connection).then(result => {
objectExplorerService.onSessionCreated(1, objectExplorerSession);
objectExplorerService.refreshTreeNode(objectExplorerSession, tablesNode).then(children => {
assert.equal(children !== null || children !== undefined, true);
assert.equal(children[0].label, 'dbo.Table1');
assert.equal(children[0].parent, tablesNode);
assert.equal(children[0].nodePath, 'testServerName\tables\dbo.Table1');
assert.equal(children[1].label, 'dbo.Table3');
assert.equal(children[1].parent, tablesNode);
assert.equal(children[1].nodePath, 'testServerName\tables\dbo.Table3');
done();
}, err => {
// Must call done here so test indicates it's finished if errors occur
done(err);
});
});
});
test('update object explorer nodes should get active connection, create session, add to the active OE nodes successfully', (done) => {
objectExplorerService.createNewSession('MSSQL', connection).then(result => {
objectExplorerService.onSessionCreated(1, objectExplorerSession);
objectExplorerService.updateObjectExplorerNodes(connection).then(() => {
var treeNode = objectExplorerService.getObjectExplorerNode(connection);
assert.equal(treeNode !== null || treeNode !== undefined, true);
assert.equal(treeNode.getSession(), objectExplorerSession);
assert.equal(treeNode.getConnectionProfile(), connection);
assert.equal(treeNode.label, 'Tables');
assert.equal(treeNode.nodePath, 'testServerName\tables');
done();
}, err => {
// Must call done here so test indicates it's finished if errors occur
done(err);
});
});
});
test('delete object explorerNode nodes should delete session, delete the root node to the active OE node', (done) => {
objectExplorerService.createNewSession('MSSQL', connection).then(result => {
objectExplorerService.onSessionCreated(1, objectExplorerSession);
objectExplorerService.updateObjectExplorerNodes(connection).then(() => {
var treeNode = objectExplorerService.getObjectExplorerNode(connection);
assert.equal(treeNode !== null && treeNode !== undefined, true);
objectExplorerService.deleteObjectExplorerNode(connection);
treeNode = objectExplorerService.getObjectExplorerNode(connection);
assert.equal(treeNode === null || treeNode === undefined, true);
done();
}, err => {
// Must call done here so test indicates it's finished if errors occur
done(err);
});
});
});
test('children tree nodes should return correct object explorer session, connection profile and database name', () => {
var databaseMetaData = {
metadataType: 0,
metadataTypeName: 'Database',
urn: '//server/db1/',
name: 'Db1',
schema: null
};
var databaseNode = new TreeNode(NodeType.Database, 'Db1', false, 'testServerName\Db1', '', '', null, databaseMetaData);
databaseNode.connection = connection;
databaseNode.session = objectExplorerSession;
var tablesNode = new TreeNode(NodeType.Folder, 'Tables', false, 'testServerName\Db1\tables', '', '', databaseNode, null);
databaseNode.children = [tablesNode];
var table1Node = new TreeNode(NodeType.Table, 'dbo.Table1', false, 'testServerName\Db1\tables\dbo.Table1', '', '', tablesNode, null);
var table2Node = new TreeNode(NodeType.Table, 'dbo.Table2', false, 'testServerName\Db1\tables\dbo.Table2', '', '', tablesNode, null);
tablesNode.children = [table1Node, table2Node];
assert.equal(table1Node.getSession(), objectExplorerSession);
assert.equal(table1Node.getConnectionProfile(), connection);
assert.equal(table1Node.getDatabaseName(), 'Db1');
});
});

View File

@@ -0,0 +1,248 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { ProviderConnectionInfo } from 'sql/parts/connection/common/providerConnectionInfo';
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
import data = require('data');
import * as assert from 'assert';
suite('SQL ProviderConnectionInfo tests', () => {
let msSQLCapabilities: data.DataProtocolServerCapabilities;
let connectionProfile: IConnectionProfile = {
serverName: 'new server',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: '',
savePassword: true,
groupFullName: 'g2/g2-2',
groupId: undefined,
getOptionsKey: undefined,
matches: undefined,
providerName: 'MSSQL',
options: undefined,
saveProfile: true,
id: undefined
};
setup(() => {
let capabilities: data.DataProtocolServerCapabilities[] = [];
let connectionProvider: data.ConnectionProviderOptions = {
options: [
{
name: 'serverName',
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: 0,
valueType: 0
},
{
name: 'databaseName',
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: 1,
valueType: 0
},
{
name: 'userName',
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: 3,
valueType: 0
},
{
name: 'authenticationType',
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: 2,
valueType: 0
},
{
name: 'password',
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: true,
isRequired: true,
specialValueType: 4,
valueType: 0
},
{
name: 'encrypt',
displayName: undefined,
description: undefined,
groupName: undefined,
categoryValues: undefined,
defaultValue: undefined,
isIdentity: false,
isRequired: false,
specialValueType: undefined,
valueType: 0
}
]
};
msSQLCapabilities = {
protocolVersion: '1',
providerName: 'MSSQL',
providerDisplayName: 'MSSQL',
connectionProvider: connectionProvider,
adminServicesProvider: undefined,
features: undefined
};
capabilities.push(msSQLCapabilities);
});
test('constructor should accept undefined parameters', () => {
let conn = new ProviderConnectionInfo(undefined, undefined);
assert.equal(conn.serverName, undefined);
});
test('set properties should set the values correctly', () => {
let conn = new ProviderConnectionInfo(msSQLCapabilities, undefined);
assert.equal(conn.serverName, undefined);
conn.serverName = connectionProfile.serverName;
conn.databaseName = connectionProfile.databaseName;
conn.authenticationType = connectionProfile.authenticationType;
conn.password = connectionProfile.password;
conn.userName = connectionProfile.userName;
assert.equal(conn.serverName, connectionProfile.serverName);
assert.equal(conn.databaseName, connectionProfile.databaseName);
assert.equal(conn.authenticationType, connectionProfile.authenticationType);
assert.equal(conn.password, connectionProfile.password);
assert.equal(conn.userName, connectionProfile.userName);
});
test('set properties should store the values in the options', () => {
let conn = new ProviderConnectionInfo(msSQLCapabilities, undefined);
assert.equal(conn.serverName, undefined);
conn.serverName = connectionProfile.serverName;
conn.databaseName = connectionProfile.databaseName;
conn.authenticationType = connectionProfile.authenticationType;
conn.password = connectionProfile.password;
conn.userName = connectionProfile.userName;
assert.equal(conn.getOptionValue('serverName'), connectionProfile.serverName);
assert.equal(conn.getOptionValue('databaseName'), connectionProfile.databaseName);
assert.equal(conn.getOptionValue('authenticationType'), connectionProfile.authenticationType);
assert.equal(conn.getOptionValue('password'), connectionProfile.password);
assert.equal(conn.getOptionValue('userName'), connectionProfile.userName);
});
test('constructor should initialize the options given a valid model', () => {
let conn = new ProviderConnectionInfo(msSQLCapabilities, connectionProfile);
assert.equal(conn.serverName, connectionProfile.serverName);
assert.equal(conn.databaseName, connectionProfile.databaseName);
assert.equal(conn.authenticationType, connectionProfile.authenticationType);
assert.equal(conn.password, connectionProfile.password);
assert.equal(conn.userName, connectionProfile.userName);
});
test('clone should create a new instance that equals the old one', () => {
let conn = new ProviderConnectionInfo(msSQLCapabilities, connectionProfile);
let conn2 = conn.clone();
assert.equal(conn.serverName, conn2.serverName);
assert.equal(conn.databaseName, conn2.databaseName);
assert.equal(conn.authenticationType, conn2.authenticationType);
assert.equal(conn.password, conn2.password);
assert.equal(conn.userName, conn2.userName);
});
test('Changing the cloned object should not change the original one', () => {
let conn = new ProviderConnectionInfo(msSQLCapabilities, connectionProfile);
let conn2 = conn.clone();
conn2.serverName = conn.serverName + '1';
assert.notEqual(conn.serverName, conn2.serverName);
});
test('constructor should initialize the options given a valid model with options', () => {
let options = {};
options['encrypt'] = 'test value';
let conn2 = Object.assign({}, connectionProfile, { options: options });
let conn = new ProviderConnectionInfo(msSQLCapabilities, conn2);
assert.equal(conn.serverName, conn2.serverName);
assert.equal(conn.databaseName, conn2.databaseName);
assert.equal(conn.authenticationType, conn2.authenticationType);
assert.equal(conn.password, conn2.password);
assert.equal(conn.userName, conn2.userName);
assert.equal(conn.options['encrypt'], 'test value');
});
test('getOptionsKey should create a valid unique id', () => {
let conn = new ProviderConnectionInfo(msSQLCapabilities, connectionProfile);
let expectedId = 'providerName:MSSQL|authenticationType:|databaseName:database|serverName:new server|userName:user';
let id = conn.getOptionsKey();
assert.equal(id, expectedId);
});
test('getOptionsKey should create different id for different server names', () => {
let conn = new ProviderConnectionInfo(msSQLCapabilities, connectionProfile);
let conn2 = new ProviderConnectionInfo(msSQLCapabilities, Object.assign({}, connectionProfile, { serverName: connectionProfile.serverName + '1' }));
assert.notEqual(conn.getOptionsKey(), conn2.getOptionsKey());
});
test('titleParts should return server, database and auth type as first items', () => {
let conn = new ProviderConnectionInfo(msSQLCapabilities, connectionProfile);
let titleParts = conn.titleParts;
assert.equal(titleParts.length, 4);
assert.equal(titleParts[0], connectionProfile.serverName);
assert.equal(titleParts[1], connectionProfile.databaseName);
assert.equal(titleParts[2], connectionProfile.authenticationType);
assert.equal(titleParts[3], connectionProfile.userName);
});
test('getProviderFromOptionsKey should return the provider name from the options key successfully', () => {
let optionsKey = 'providerName:MSSQL|authenticationType:|databaseName:database|serverName:new server|userName:user';
let expectedProviderId: string = 'MSSQL';
let actual = ProviderConnectionInfo.getProviderFromOptionsKey(optionsKey);
assert.equal(expectedProviderId, actual);
});
test('getProviderFromOptionsKey should return empty string give null', () => {
let optionsKey = undefined;
let expectedProviderId: string = '';
let actual = ProviderConnectionInfo.getProviderFromOptionsKey(optionsKey);
assert.equal(expectedProviderId, actual);
});
test('getProviderFromOptionsKey should return empty string give key without provider name', () => {
let optionsKey = 'providerName2:MSSQL|authenticationType:|databaseName:database|serverName:new server|userName:user';
let expectedProviderId: string = '';
let actual = ProviderConnectionInfo.getProviderFromOptionsKey(optionsKey);
assert.equal(expectedProviderId, actual);
});
});