diff --git a/src/sql/workbench/contrib/objectExplorer/test/browser/connectionTreeActions.test.ts b/src/sql/workbench/contrib/objectExplorer/test/browser/connectionTreeActions.test.ts index a6d649d7bf..4dae196c63 100644 --- a/src/sql/workbench/contrib/objectExplorer/test/browser/connectionTreeActions.test.ts +++ b/src/sql/workbench/contrib/objectExplorer/test/browser/connectionTreeActions.test.ts @@ -41,6 +41,8 @@ import { ConsoleLogger, LogService } from 'vs/platform/log/common/log'; import { TestAccessibilityService } from 'vs/platform/accessibility/test/common/testAccessibilityService'; import { TestEditorService } from 'vs/workbench/test/browser/workbenchTestServices'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { TestDialogService } from 'vs/platform/dialogs/test/common/testDialogService'; +import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; suite('SQL Connection Tree Action tests', () => { let errorMessageService: TypeMoq.Mock; @@ -79,6 +81,22 @@ suite('SQL Connection Tree Action tests', () => { return connectionManagementService; } + /** + * Creates a mock dialog service that and select the choice at the given index when show is called. + * @param choiceIndex index of the button in the dialog to be selected starting from 0. + * @returns + */ + function createDialogService(choiceIndex: number): TypeMoq.Mock { + let dialogService = TypeMoq.Mock.ofType(TestDialogService, TypeMoq.MockBehavior.Loose); + dialogService.callBase = true; + dialogService.setup(x => x.show(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => { + return Promise.resolve({ + choice: choiceIndex + }) + }); + return dialogService; + } + function createEditorService(): TypeMoq.Mock { let editorService = TypeMoq.Mock.ofType(TestEditorService, TypeMoq.MockBehavior.Strict); @@ -329,7 +347,8 @@ suite('SQL Connection Tree Action tests', () => { let connectionAction: DeleteConnectionAction = new DeleteConnectionAction(DeleteConnectionAction.ID, DeleteConnectionAction.DELETE_CONNECTION_LABEL, connection, - connectionManagementService.object); + connectionManagementService.object, + createDialogService(0).object); // Select 'Yes' on the modal dialog return connectionAction.run().then((value) => { connectionManagementService.verify(x => x.deleteConnection(TypeMoq.It.isAny()), TypeMoq.Times.atLeastOnce()); @@ -337,6 +356,34 @@ suite('SQL Connection Tree Action tests', () => { }); + test('DeleteConnectionAction - connection not deleted when user selects no on the prompt', async () => { + let connectionManagementService = createConnectionManagementService(true, undefined); + + let connection: ConnectionProfile = new ConnectionProfile(capabilitiesService, { + connectionName: 'Test', + savePassword: false, + groupFullName: 'testGroup', + serverName: 'testServerName', + databaseName: 'testDatabaseName', + authenticationType: AuthenticationType.Integrated, + password: 'test', + userName: 'testUsername', + groupId: undefined, + providerName: mssqlProviderName, + options: {}, + saveProfile: true, + id: 'testId' + }); + let connectionAction: DeleteConnectionAction = new DeleteConnectionAction(DeleteConnectionAction.ID, + DeleteConnectionAction.DELETE_CONNECTION_LABEL, + connection, + connectionManagementService.object, + createDialogService(1).object); // Selecting 'No' on the modal dialog + + await connectionAction.run(); + connectionManagementService.verify(x => x.deleteConnection(TypeMoq.It.isAny()), TypeMoq.Times.never()); + }); + test('DeleteConnectionAction - test delete connection group', () => { let isConnectedReturnValue: boolean = false; let connectionManagementService = createConnectionManagementService(isConnectedReturnValue, undefined); @@ -344,7 +391,8 @@ suite('SQL Connection Tree Action tests', () => { let connectionAction: DeleteConnectionAction = new DeleteConnectionAction(DeleteConnectionAction.ID, DeleteConnectionAction.DELETE_CONNECTION_LABEL, conProfGroup, - connectionManagementService.object); + connectionManagementService.object, + createDialogService(0).object); // Select 'Yes' on the modal dialog return connectionAction.run().then((value) => { connectionManagementService.verify(x => x.deleteConnectionGroup(TypeMoq.It.isAny()), TypeMoq.Times.atLeastOnce()); @@ -375,7 +423,8 @@ suite('SQL Connection Tree Action tests', () => { let connectionAction: DeleteConnectionAction = new DeleteConnectionAction(DeleteConnectionAction.ID, DeleteConnectionAction.DELETE_CONNECTION_LABEL, connection, - connectionManagementService.object); + connectionManagementService.object, + createDialogService(0).object); assert.strictEqual(connectionAction.enabled, false, 'delete action should be disabled.'); }); diff --git a/src/sql/workbench/services/objectExplorer/browser/connectionTreeAction.ts b/src/sql/workbench/services/objectExplorer/browser/connectionTreeAction.ts index 80ebd4cdcd..ffea7b6c75 100644 --- a/src/sql/workbench/services/objectExplorer/browser/connectionTreeAction.ts +++ b/src/sql/workbench/services/objectExplorer/browser/connectionTreeAction.ts @@ -20,6 +20,7 @@ import { IServerGroupController } from 'sql/platform/serverGroup/common/serverGr import { ILogService } from 'vs/platform/log/common/log'; import { AsyncServerTree, ServerTreeElement } from 'sql/workbench/services/objectExplorer/browser/asyncServerTree'; import { SqlIconId } from 'sql/base/common/codicons'; +import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; export interface IServerView { showFilteredTree(filter: string): void; @@ -266,7 +267,8 @@ export class DeleteConnectionAction extends Action { id: string, label: string, private element: IConnectionProfile | ConnectionProfileGroup, - @IConnectionManagementService private _connectionManagementService: IConnectionManagementService + @IConnectionManagementService private _connectionManagementService: IConnectionManagementService, + @IDialogService private _dialogService: IDialogService ) { super(id, label); this.class = 'delete-connection-action'; @@ -283,10 +285,22 @@ export class DeleteConnectionAction extends Action { } public override async run(): Promise { + + const deleteConnectionConfirmationYes = localize('deleteConnectionConfirmationYes', "Yes"); + const deleteConnectionConfirmationNo = localize('deleteConnectionConfirmationNo', "No"); + if (this.element instanceof ConnectionProfile) { - await this._connectionManagementService.deleteConnection(this.element); + const modalResult = await this._dialogService.show(Severity.Warning, localize('deleteConnectionConfirmation', "Are you sure you want to delete connection '{0}'?", this.element.connectionName), + [deleteConnectionConfirmationYes, deleteConnectionConfirmationNo]); + if (modalResult.choice === 0) { + await this._connectionManagementService.deleteConnection(this.element); + } } else if (this.element instanceof ConnectionProfileGroup) { - await this._connectionManagementService.deleteConnectionGroup(this.element); + const modalResult = await this._dialogService.show(Severity.Warning, localize('deleteConnectionGroupConfirmation', "Are you sure you want to delete connection group '{0}'?", this.element.name), + [deleteConnectionConfirmationYes, deleteConnectionConfirmationNo]); + if (modalResult.choice === 0) { + await this._connectionManagementService.deleteConnectionGroup(this.element); + } } } }