mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-26 23:00:29 -04:00
Extensibility: Context menu support in Object Explorer (#1883)
- Fixes #1867 context menu should be extensible - Added context keys to support "when" conditions on the new extensions - Fixes issue where actions like New Query, scripting show up even if these are not valid for the provider type or object type - Fixed node expansion bug where rapid connect / expand / disconnect could break the app (fix in ObjectExplorerService.onNodeExpanded) - Major change to how internal actions work. These cannot assume the context has non-serializable objects. Opened up some APIs to make this easier to handle. - Fixed a number of existing bugs in internal actions. - Notably, DisconnectAction was adding a listener on each right-click on an active connection and never getting it disposed. This wasn't needed at all due to design changes. - Another bug fix is that the Manage action now correctly navigates to the DB dashboard for database-level connections. Before this it went to the server-level dashboard. * Define API for context info
This commit is contained in:
@@ -50,7 +50,7 @@ suite('SQL Connection Tree Action tests', () => {
|
||||
errorMessageService.setup(x => x.showDialog(Severity.Error, TypeMoq.It.isAnyString(), TypeMoq.It.isAnyString())).returns(() => nothing);
|
||||
});
|
||||
|
||||
function createConnectionManagementService(isConnectedReturnValue: boolean): TypeMoq.Mock<TestConnectionManagementService> {
|
||||
function createConnectionManagementService(isConnectedReturnValue: boolean, profileToReturn: ConnectionProfile): 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);
|
||||
@@ -65,13 +65,15 @@ suite('SQL Connection Tree Action tests', () => {
|
||||
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));
|
||||
connectionManagementService.setup(x => x.getConnectionProfile(TypeMoq.It.isAny())).returns(() => profileToReturn);
|
||||
|
||||
return connectionManagementService;
|
||||
}
|
||||
|
||||
function createObjectExplorerService(connectionManagementService: TestConnectionManagementService): TypeMoq.Mock<ObjectExplorerService> {
|
||||
function createObjectExplorerService(connectionManagementService: TestConnectionManagementService, getTreeNodeReturnVal: TreeNode): TypeMoq.Mock<ObjectExplorerService> {
|
||||
let objectExplorerService = TypeMoq.Mock.ofType(ObjectExplorerService, TypeMoq.MockBehavior.Strict, connectionManagementService);
|
||||
objectExplorerService.callBase = true;
|
||||
objectExplorerService.setup(x => x.getTreeNode(TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve(getTreeNodeReturnVal));
|
||||
objectExplorerService.setup(x => x.getObjectExplorerNode(TypeMoq.It.isAny())).returns(() => new TreeNode('', '', false, '', '', '', undefined, undefined, undefined));
|
||||
objectExplorerService.setup(x => x.getObjectExplorerNode(undefined)).returns(() => new TreeNode('', '', false, '', '', '', undefined, undefined, undefined));
|
||||
objectExplorerService.setup(x => x.onUpdateObjectExplorerNodes).returns(() => new Emitter<ObjectExplorerNodeEventArgs>().event);
|
||||
@@ -82,17 +84,6 @@ suite('SQL Connection Tree Action tests', () => {
|
||||
|
||||
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(capabilitiesService, {
|
||||
savePassword: false,
|
||||
groupFullName: 'testGroup',
|
||||
@@ -109,17 +100,8 @@ suite('SQL Connection Tree Action tests', () => {
|
||||
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 connectionManagementService = createConnectionManagementService(isConnectedReturnValue, connection);
|
||||
let objectExplorerService = createObjectExplorerService(connectionManagementService.object, undefined);
|
||||
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) => {
|
||||
@@ -127,7 +109,18 @@ suite('SQL Connection Tree Action tests', () => {
|
||||
});
|
||||
|
||||
let manageConnectionAction: ManageConnectionAction = new ManageConnectionAction(ManageConnectionAction.ID,
|
||||
ManageConnectionAction.LABEL, connectionManagementService.object, instantiationService.object, objectExplorerService.object);
|
||||
ManageConnectionAction.LABEL, undefined, connectionManagementService.object, capabilitiesService, instantiationService.object, objectExplorerService.object);
|
||||
|
||||
var actionContext = new ObjectExplorerActionsContext();
|
||||
actionContext.connectionProfile = connection.toIConnectionProfile();
|
||||
actionContext.isConnectionNode = true;
|
||||
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 connection: ConnectionProfile = new ConnectionProfile(capabilitiesService, {
|
||||
savePassword: false,
|
||||
groupFullName: 'testGroup',
|
||||
@@ -146,8 +139,20 @@ suite('SQL Connection Tree Action tests', () => {
|
||||
});
|
||||
let treeNode = new TreeNode(NodeType.Database, 'db node', false, '', '', '', undefined, undefined, undefined);
|
||||
treeNode.connection = connection;
|
||||
let connectionManagementService = createConnectionManagementService(isConnectedReturnValue, connection);
|
||||
let objectExplorerService = createObjectExplorerService(connectionManagementService.object, treeNode);
|
||||
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, undefined, connectionManagementService.object, capabilitiesService, instantiationService.object, objectExplorerService.object);
|
||||
|
||||
var actionContext = new ObjectExplorerActionsContext();
|
||||
actionContext.treeNode = treeNode;
|
||||
actionContext.connectionProfile = connection.toIConnectionProfile();
|
||||
actionContext.nodeInfo = treeNode.toNodeInfo();
|
||||
manageConnectionAction.run(actionContext).then((value) => {
|
||||
connectionManagementService.verify(x => x.showDashboard(TypeMoq.It.isAny()), TypeMoq.Times.once());
|
||||
}).then(() => done(), (err) => done(err));
|
||||
@@ -156,10 +161,6 @@ suite('SQL Connection Tree Action tests', () => {
|
||||
|
||||
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(capabilitiesService, {
|
||||
savePassword: false,
|
||||
groupFullName: 'testGroup',
|
||||
@@ -176,8 +177,13 @@ suite('SQL Connection Tree Action tests', () => {
|
||||
saveProfile: true,
|
||||
id: 'testId'
|
||||
});
|
||||
let connectionManagementService = createConnectionManagementService(isConnectedReturnValue, connection);
|
||||
let objectExplorerService = createObjectExplorerService(connectionManagementService.object, undefined);
|
||||
|
||||
let changeConnectionAction: DisconnectConnectionAction = new DisconnectConnectionAction(DisconnectConnectionAction.ID, DisconnectConnectionAction.LABEL, connection, connectionManagementService.object, objectExplorerService.object, errorMessageService.object);
|
||||
|
||||
var actionContext = new ObjectExplorerActionsContext();
|
||||
actionContext.connectionProfile = connection;
|
||||
actionContext.connectionProfile = connection.toIConnectionProfile();
|
||||
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());
|
||||
@@ -185,7 +191,7 @@ suite('SQL Connection Tree Action tests', () => {
|
||||
});
|
||||
|
||||
test('AddServerAction - test if show connection dialog is called', (done) => {
|
||||
let connectionManagementService = createConnectionManagementService(true);
|
||||
let connectionManagementService = createConnectionManagementService(true, undefined);
|
||||
|
||||
let connectionTreeAction: AddServerAction = new AddServerAction(AddServerAction.ID, AddServerAction.LABEL, connectionManagementService.object);
|
||||
let conProfGroup = new ConnectionProfileGroup('testGroup', undefined, 'testGroup', undefined, undefined);
|
||||
@@ -195,7 +201,7 @@ suite('SQL Connection Tree Action tests', () => {
|
||||
});
|
||||
|
||||
test('ActiveConnectionsFilterAction - test if view is called to display filtered results', (done) => {
|
||||
let connectionManagementService = createConnectionManagementService(true);
|
||||
let connectionManagementService = createConnectionManagementService(true, undefined);
|
||||
|
||||
let instantiationService = TypeMoq.Mock.ofType(InstantiationService, TypeMoq.MockBehavior.Loose);
|
||||
instantiationService.setup(x => x.createInstance(TypeMoq.It.isAny())).returns((input) => {
|
||||
@@ -212,7 +218,7 @@ suite('SQL Connection Tree Action tests', () => {
|
||||
});
|
||||
|
||||
test('ActiveConnectionsFilterAction - test if view is called refresh results if action is toggled', (done) => {
|
||||
let connectionManagementService = createConnectionManagementService(true);
|
||||
let connectionManagementService = createConnectionManagementService(true, undefined);
|
||||
|
||||
let instantiationService = TypeMoq.Mock.ofType(InstantiationService, TypeMoq.MockBehavior.Loose);
|
||||
instantiationService.setup(x => x.createInstance(TypeMoq.It.isAny())).returns((input) => {
|
||||
@@ -230,7 +236,7 @@ suite('SQL Connection Tree Action tests', () => {
|
||||
});
|
||||
|
||||
test('RecentConnectionsFilterAction - test if view is called to display filtered results', (done) => {
|
||||
let connectionManagementService = createConnectionManagementService(true);
|
||||
let connectionManagementService = createConnectionManagementService(true, undefined);
|
||||
|
||||
let instantiationService = TypeMoq.Mock.ofType(InstantiationService, TypeMoq.MockBehavior.Loose);
|
||||
instantiationService.setup(x => x.createInstance(TypeMoq.It.isAny())).returns((input) => {
|
||||
@@ -247,7 +253,7 @@ suite('SQL Connection Tree Action tests', () => {
|
||||
});
|
||||
|
||||
test('RecentConnectionsFilterAction - test if view is called refresh results if action is toggled', (done) => {
|
||||
let connectionManagementService = createConnectionManagementService(true);
|
||||
let connectionManagementService = createConnectionManagementService(true, undefined);
|
||||
|
||||
let instantiationService = TypeMoq.Mock.ofType(InstantiationService, TypeMoq.MockBehavior.Loose);
|
||||
instantiationService.setup(x => x.createInstance(TypeMoq.It.isAny())).returns((input) => {
|
||||
@@ -265,7 +271,7 @@ suite('SQL Connection Tree Action tests', () => {
|
||||
});
|
||||
|
||||
test('DeleteConnectionAction - test delete connection', (done) => {
|
||||
let connectionManagementService = createConnectionManagementService(true);
|
||||
let connectionManagementService = createConnectionManagementService(true, undefined);
|
||||
|
||||
let connection: ConnectionProfile = new ConnectionProfile(capabilitiesService, {
|
||||
savePassword: false,
|
||||
@@ -296,7 +302,7 @@ suite('SQL Connection Tree Action tests', () => {
|
||||
|
||||
test('DeleteConnectionAction - test delete connection group', (done) => {
|
||||
let isConnectedReturnValue: boolean = false;
|
||||
let connectionManagementService = createConnectionManagementService(isConnectedReturnValue);
|
||||
let connectionManagementService = createConnectionManagementService(isConnectedReturnValue, undefined);
|
||||
let conProfGroup = new ConnectionProfileGroup('testGroup', undefined, 'testGroup', undefined, undefined);
|
||||
let connectionAction: DeleteConnectionAction = new DeleteConnectionAction(DeleteConnectionAction.ID,
|
||||
DeleteConnectionAction.DELETE_CONNECTION_LABEL,
|
||||
@@ -311,7 +317,7 @@ suite('SQL Connection Tree Action tests', () => {
|
||||
|
||||
test('DeleteConnectionAction - delete should not be called if connect is an unsaved connection', (done) => {
|
||||
let isConnectedReturnValue: boolean = false;
|
||||
let connectionManagementService = createConnectionManagementService(isConnectedReturnValue);
|
||||
let connectionManagementService = createConnectionManagementService(isConnectedReturnValue, undefined);
|
||||
|
||||
let connection: ConnectionProfile = new ConnectionProfile(capabilitiesService, {
|
||||
savePassword: false,
|
||||
|
||||
Reference in New Issue
Block a user