Inital platform relayering (#6385)

* moving test files and inital refactoring

* relayer extension host code

* fix imports

* make insights work

* relayer dashboard

* relayer notebooks

* moveing more code around

* formatting

* accept angular as browser

* fix serializer

* add missing files

* remove declarations from extensions

* fix build errors

* more relayering

* change urls to relative to help code relayering

* remove layering to prep for merge

* fix hygiene errors

* fix hygiene errors

* fix tests
This commit is contained in:
Anthony Dresser
2019-07-18 17:29:17 -07:00
committed by GitHub
parent 45c13116de
commit c23738f935
576 changed files with 2090 additions and 2788 deletions

View File

@@ -32,7 +32,7 @@ import { AddAccountAction } from 'sql/platform/accounts/common/accountActions';
import { AccountListRenderer, AccountListDelegate } from 'sql/platform/accounts/browser/accountListRenderer';
import { AccountProviderAddedEventParams, UpdateAccountListEventParams } from 'sql/platform/accounts/common/eventTypes';
import { IClipboardService } from 'sql/platform/clipboard/common/clipboardService';
import * as TelemetryKeys from 'sql/platform/telemetry/telemetryKeys';
import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys';
import { ILogService } from 'vs/platform/log/common/log';
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';

View File

@@ -19,7 +19,7 @@ import { Modal } from 'sql/workbench/browser/modal/modal';
import { InputBox } from 'sql/base/browser/ui/inputBox/inputBox';
import { attachModalDialogStyler, attachButtonStyler } from 'sql/platform/theme/common/styler';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import * as TelemetryKeys from 'sql/platform/telemetry/telemetryKeys';
import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { ILogService } from 'vs/platform/log/common/log';
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';

View File

@@ -26,7 +26,7 @@ import { FirewallRuleViewModel } from 'sql/platform/accounts/common/firewallRule
import { attachModalDialogStyler, attachButtonStyler } from 'sql/platform/theme/common/styler';
import { InputBox } from 'sql/base/browser/ui/inputBox/inputBox';
import { IAccountPickerService } from 'sql/platform/accounts/common/accountPicker';
import * as TelemetryKeys from 'sql/platform/telemetry/telemetryKeys';
import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys';
import { ILogService } from 'vs/platform/log/common/log';
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';

View File

@@ -0,0 +1,103 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import * as TypeMoq from 'typemoq';
import { Emitter } from 'vs/base/common/event';
import { AccountDialog } from 'sql/platform/accounts/browser/accountDialog';
import { AccountDialogController } from 'sql/platform/accounts/browser/accountDialogController';
import { AccountViewModel } from 'sql/platform/accounts/common/accountViewModel';
import { TestAccountManagementService } from 'sql/platform/accounts/test/common/testAccountManagementService';
import { TestErrorMessageService } from 'sql/platform/errorMessage/test/common/testErrorMessageService';
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
import { AccountListRenderer } from 'sql/platform/accounts/browser/accountListRenderer';
import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService';
// TESTS ///////////////////////////////////////////////////////////////////
suite('Account Management Dialog Controller Tests', () => {
test('Open Account Dialog - Dialog Doesn\'t Exist', () => {
// Setup: Create instance of the controller
let instantiationService = createInstantiationService();
let controller = new AccountDialogController(instantiationService, undefined);
assert.strictEqual(controller.accountDialog, undefined);
// If: I open the account dialog when one hasn't been opened
controller.openAccountDialog();
// Then:
// ... The account dialog should be defined
assert.notStrictEqual(controller.accountDialog, undefined);
});
test('Open Account Dialog - Dialog Exists', () => {
// Setup: Create instance of the controller with an account dialog already loaded
let instantiationService = createInstantiationService();
let controller = new AccountDialogController(instantiationService, undefined);
controller.openAccountDialog();
let accountDialog = controller.accountDialog;
// If: I open the account dialog when one has already been opened
controller.openAccountDialog();
// Then: It should be the same dialog that already existed
assert.equal(controller.accountDialog, accountDialog);
});
test('Add Account Failure - Error Message Shown', () => {
// Setup:
// ... Create instantiation service that returns mock emitter for account dialog
let mockEventEmitter = new Emitter<string>();
let instantiationService = createInstantiationService(mockEventEmitter);
// ... Create a mock instance of the error message service
let errorMessageServiceStub = new TestErrorMessageService();
let mockErrorMessageService = TypeMoq.Mock.ofInstance(errorMessageServiceStub);
mockErrorMessageService.setup(x => x.showDialog(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()));
// ... Create instance of the controller with an opened dialog
let controller = new AccountDialogController(instantiationService, mockErrorMessageService.object);
controller.openAccountDialog();
// If: The account dialog reports a failure adding an account
mockEventEmitter.fire('Error message');
// Then: An error dialog should have been opened
mockErrorMessageService.verify(x => x.showDialog(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once());
});
});
function createInstantiationService(addAccountFailureEmitter?: Emitter<string>): InstantiationService {
// Create a mock account dialog view model
let accountViewModel = new AccountViewModel(new TestAccountManagementService());
let mockAccountViewModel = TypeMoq.Mock.ofInstance(accountViewModel);
let mockEvent = new Emitter<any>();
mockAccountViewModel.setup(x => x.addProviderEvent).returns(() => mockEvent.event);
mockAccountViewModel.setup(x => x.removeProviderEvent).returns(() => mockEvent.event);
mockAccountViewModel.setup(x => x.updateAccountListEvent).returns(() => mockEvent.event);
mockAccountViewModel.setup(x => x.initialize()).returns(() => Promise.resolve([]));
// Create a mocked out instantiation service
let instantiationService = TypeMoq.Mock.ofType(InstantiationService, TypeMoq.MockBehavior.Strict);
instantiationService.setup(x => x.createInstance(TypeMoq.It.isValue(AccountViewModel)))
.returns(() => mockAccountViewModel.object);
instantiationService.setup(x => x.createInstance(TypeMoq.It.isValue(AccountListRenderer)))
.returns(() => undefined);
// Create a mock account dialog
let accountDialog = new AccountDialog(null, null, instantiationService.object, null, null, null, null, new MockContextKeyService(), null, undefined);
let mockAccountDialog = TypeMoq.Mock.ofInstance(accountDialog);
mockAccountDialog.setup(x => x.onAddAccountErrorEvent)
.returns(() => { return addAccountFailureEmitter ? addAccountFailureEmitter.event : mockEvent.event; });
mockAccountDialog.setup(x => x.onCloseEvent)
.returns(() => mockEvent.event);
mockAccountDialog.setup(x => x.render())
.returns(() => undefined);
mockAccountDialog.setup(x => x.open())
.returns(() => undefined);
instantiationService.setup(x => x.createInstance(TypeMoq.It.isValue(AccountDialog)))
.returns(() => mockAccountDialog.object);
return instantiationService.object;
}

View File

@@ -0,0 +1,120 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as azdata from 'azdata';
import * as assert from 'assert';
import * as TypeMoq from 'typemoq';
import { EventVerifierSingle } from 'sqltest/utils/eventVerifier';
import { Emitter } from 'vs/base/common/event';
import { AccountPicker } from 'sql/platform/accounts/browser/accountPicker';
import { AccountPickerService } from 'sql/platform/accounts/browser/accountPickerService';
import { AccountPickerViewModel } from 'sql/platform/accounts/common/accountPickerViewModel';
import { TestAccountManagementService } from 'sql/platform/accounts/test/common/testAccountManagementService';
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
// SUITE STATE /////////////////////////////////////////////////////////////
let mockAddAccountCompleteEmitter: Emitter<void>;
let mockAddAccountErrorEmitter: Emitter<string>;
let mockAddAccountStartEmitter: Emitter<void>;
let mockOnAccountSelectionChangeEvent: Emitter<azdata.Account>;
// TESTS ///////////////////////////////////////////////////////////////////
suite('Account picker service tests', () => {
setup(() => {
// Setup event mocks for the account picker service
mockAddAccountCompleteEmitter = new Emitter<void>();
mockAddAccountErrorEmitter = new Emitter<string>();
mockAddAccountStartEmitter = new Emitter<void>();
mockOnAccountSelectionChangeEvent = new Emitter<azdata.Account>();
});
test('Construction - Events are properly defined', () => {
// Setup:
// ... Create instantiation service
let instantiationService = createInstantiationService();
// ... Create instance of the service and reder account picker
let service = new AccountPickerService(instantiationService);
service.renderAccountPicker(TypeMoq.It.isAny());
// Then:
// ... All the events for the view models should be properly initialized
assert.notEqual(service.addAccountCompleteEvent, undefined);
assert.notEqual(service.addAccountErrorEvent, undefined);
assert.notEqual(service.addAccountStartEvent, undefined);
assert.notEqual(service.onAccountSelectionChangeEvent, undefined);
// ... All the events should properly fire
let evAddAccountCompleteEvent = new EventVerifierSingle<void>();
service.addAccountCompleteEvent(evAddAccountCompleteEvent.eventHandler);
mockAddAccountCompleteEmitter.fire();
evAddAccountCompleteEvent.assertFired();
let errorMsg = 'Error';
let evAddAccountErrorEvent = new EventVerifierSingle<string>();
service.addAccountErrorEvent(evAddAccountErrorEvent.eventHandler);
mockAddAccountErrorEmitter.fire(errorMsg);
evAddAccountErrorEvent.assertFired(errorMsg);
let evAddAccountStartEvent = new EventVerifierSingle<void>();
service.addAccountStartEvent(evAddAccountStartEvent.eventHandler);
mockAddAccountStartEmitter.fire();
evAddAccountStartEvent.assertFired();
let account = {
key: { providerId: 'azure', accountId: 'account1' },
name: 'Account 1',
displayInfo: {
contextualDisplayName: 'Microsoft Account',
accountType: 'microsoft',
displayName: 'Account 1',
userId: 'user@email.com'
},
properties: [],
isStale: false
};
let evOnAccountSelectionChangeEvent = new EventVerifierSingle<azdata.Account>();
service.onAccountSelectionChangeEvent(evOnAccountSelectionChangeEvent.eventHandler);
mockOnAccountSelectionChangeEvent.fire(account);
evOnAccountSelectionChangeEvent.assertFired(account);
});
});
function createInstantiationService(): InstantiationService {
// Create a mock account picker view model
let providerId = 'azure';
let accountPickerViewModel = new AccountPickerViewModel(providerId, new TestAccountManagementService());
let mockAccountViewModel = TypeMoq.Mock.ofInstance(accountPickerViewModel);
let mockEvent = new Emitter<any>();
mockAccountViewModel.setup(x => x.updateAccountListEvent).returns(() => mockEvent.event);
// Create a mocked out instantiation service
let instantiationService = TypeMoq.Mock.ofType(InstantiationService, TypeMoq.MockBehavior.Strict);
instantiationService.setup(x => x.createInstance(TypeMoq.It.isValue(AccountPickerViewModel), TypeMoq.It.isAny()))
.returns(() => mockAccountViewModel.object);
// Create a mock account picker
let accountPicker = new AccountPicker(null, null, instantiationService.object, null);
let mockAccountDialog = TypeMoq.Mock.ofInstance(accountPicker);
mockAccountDialog.setup(x => x.addAccountCompleteEvent)
.returns(() => mockAddAccountCompleteEmitter.event);
mockAccountDialog.setup(x => x.addAccountErrorEvent)
.returns((msg) => mockAddAccountErrorEmitter.event);
mockAccountDialog.setup(x => x.addAccountStartEvent)
.returns(() => mockAddAccountStartEmitter.event);
mockAccountDialog.setup(x => x.onAccountSelectionChangeEvent)
.returns((account) => mockOnAccountSelectionChangeEvent.event);
mockAccountDialog.setup(x => x.render(TypeMoq.It.isAny()))
.returns((container) => undefined);
mockAccountDialog.setup(x => x.createAccountPickerComponent());
instantiationService.setup(x => x.createInstance(TypeMoq.It.isValue(AccountPicker), TypeMoq.It.isAny()))
.returns(() => mockAccountDialog.object);
return instantiationService.object;
}

View File

@@ -0,0 +1,139 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as TypeMoq from 'typemoq';
import { Emitter } from 'vs/base/common/event';
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
import { AutoOAuthDialog } from 'sql/platform/accounts/browser/autoOAuthDialog';
import { AutoOAuthDialogController } from 'sql/platform/accounts/browser/autoOAuthDialogController';
import { TestAccountManagementService } from 'sql/platform/accounts/test/common/testAccountManagementService';
import { TestErrorMessageService } from 'sql/platform/errorMessage/test/common/testErrorMessageService';
import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService';
// TESTS ///////////////////////////////////////////////////////////////////
suite('auto OAuth dialog controller tests', () => {
let instantiationService: TypeMoq.Mock<InstantiationService>;
let mockAutoOAuthDialog: TypeMoq.Mock<AutoOAuthDialog>;
let mockAccountManagementService: TypeMoq.Mock<TestAccountManagementService>;
let mockErrorMessageService: TypeMoq.Mock<TestErrorMessageService>;
let autoOAuthDialogController: AutoOAuthDialogController;
let mockOnCancelEvent: Emitter<void>;
let mockOnAddAccountEvent: Emitter<void>;
let mockOnCloseEvent: Emitter<void>;
let providerId = 'azure';
let title = 'Add Account';
let message = 'This is the dialog description';
let userCode = 'abcde';
let uri = 'uri';
setup(() => {
mockOnCancelEvent = new Emitter<void>();
mockOnAddAccountEvent = new Emitter<void>();
mockOnCloseEvent = new Emitter<void>();
// Create a mock auto OAuth dialog
let autoOAuthDialog = new AutoOAuthDialog(null, null, null, null, new MockContextKeyService(), null, undefined);
mockAutoOAuthDialog = TypeMoq.Mock.ofInstance(autoOAuthDialog);
mockAutoOAuthDialog.setup(x => x.onCancel).returns(() => mockOnCancelEvent.event);
mockAutoOAuthDialog.setup(x => x.onHandleAddAccount).returns(() => mockOnAddAccountEvent.event);
mockAutoOAuthDialog.setup(x => x.onCloseEvent).returns(() => mockOnCloseEvent.event);
mockAutoOAuthDialog.setup(x => x.render());
mockAutoOAuthDialog.setup(x => x.open(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()));
mockAutoOAuthDialog.setup(x => x.close()).callback(() => {
mockOnCloseEvent.fire();
});
// Create a mocked out instantiation service
instantiationService = TypeMoq.Mock.ofType(InstantiationService, TypeMoq.MockBehavior.Strict);
instantiationService.setup(x => x.createInstance(TypeMoq.It.isValue(AutoOAuthDialog)))
.returns(() => mockAutoOAuthDialog.object);
// Create a mocked account management service
let accountManagementTestService = new TestAccountManagementService();
mockAccountManagementService = TypeMoq.Mock.ofInstance(accountManagementTestService);
mockAccountManagementService.setup(x => x.copyUserCodeAndOpenBrowser(TypeMoq.It.isAny(), TypeMoq.It.isAny()));
// Create a mocked error message service
let errorMessageServiceStub = new TestErrorMessageService();
mockErrorMessageService = TypeMoq.Mock.ofInstance(errorMessageServiceStub);
mockErrorMessageService.setup(x => x.showDialog(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()));
// Create a mocked auto OAuth dialog controller
autoOAuthDialogController = new AutoOAuthDialogController(instantiationService.object, mockAccountManagementService.object, mockErrorMessageService.object);
});
test('Open auto OAuth when the flyout is already open, return an error', (done) => {
// If: Open auto OAuth dialog first time
autoOAuthDialogController.openAutoOAuthDialog(providerId, title, message, userCode, uri);
// Then: It should open the flyout successfully
mockAutoOAuthDialog.verify(x => x.open(title, message, userCode, uri), TypeMoq.Times.once());
mockErrorMessageService.verify(x => x.showDialog(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.never());
// If: a oauth flyout is already open
autoOAuthDialogController.openAutoOAuthDialog(providerId, title, message, userCode, uri)
.then(success => done('Failure: Expected error on 2nd dialog open'), error => done());
// Then: An error dialog should have been opened
mockErrorMessageService.verify(x => x.showDialog(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once());
});
test('Close auto OAuth dialog successfully', () => {
let title = 'Add Account';
let message = 'This is the dialog description';
let userCode = 'abcde';
let uri = 'uri';
autoOAuthDialogController.openAutoOAuthDialog(providerId, title, message, userCode, uri);
// If: closeAutoOAuthDialog is called
autoOAuthDialogController.closeAutoOAuthDialog();
// Then: it should close the dialog
mockAutoOAuthDialog.verify(x => x.close(), TypeMoq.Times.once());
});
test('Open and close auto OAuth dialog multiple times should work properly', () => {
let title = 'Add Account';
let message = 'This is the dialog description';
let userCode = 'abcde';
let uri = 'uri';
autoOAuthDialogController.openAutoOAuthDialog(providerId, title, message, userCode, uri);
autoOAuthDialogController.closeAutoOAuthDialog();
// If: Open the flyout second time
autoOAuthDialogController.openAutoOAuthDialog(providerId, title, message, userCode, uri);
// Then: It should open the flyout twice successfully
mockAutoOAuthDialog.verify(x => x.open(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.exactly(2));
mockErrorMessageService.verify(x => x.showDialog(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.never());
});
test('Copy and open button in auto OAuth dialog should work properly', () => {
let title = 'Add Account';
let message = 'This is the dialog description';
let userCode = 'abcde';
let uri = 'uri';
autoOAuthDialogController.openAutoOAuthDialog(providerId, title, message, userCode, uri);
// If: the 'copy & open' button in auto Oauth dialog is selected
mockOnAddAccountEvent.fire();
// Then: copyUserCodeAndOpenBrowser should get called
mockAccountManagementService.verify(x => x.copyUserCodeAndOpenBrowser(userCode, uri), TypeMoq.Times.once());
});
// TODO: Test for cancel button
});

View File

@@ -0,0 +1,256 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as azdata from 'azdata';
import * as TypeMoq from 'typemoq';
import { Emitter } from 'vs/base/common/event';
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
import { FirewallRuleDialog } from 'sql/platform/accounts/browser/firewallRuleDialog';
import { FirewallRuleViewModel } from 'sql/platform/accounts/common/firewallRuleViewModel';
import { FirewallRuleDialogController } from 'sql/platform/accounts/browser/firewallRuleDialogController';
import { TestAccountManagementService } from 'sql/platform/accounts/test/common/testAccountManagementService';
import { TestResourceProvider } from 'sql/workbench/services/resourceProvider/test/common/testResourceProviderService';
import { TestErrorMessageService } from 'sql/platform/errorMessage/test/common/testErrorMessageService';
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
import { Deferred } from 'sql/base/common/promise';
import { mssqlProviderName } from 'sql/platform/connection/common/constants';
import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService';
// TESTS ///////////////////////////////////////////////////////////////////
suite('Firewall rule dialog controller tests', () => {
let connectionProfile: IConnectionProfile;
let account: azdata.Account;
let IPAddress = '250.222.155.198';
let mockOnAddAccountErrorEvent: Emitter<string>;
let mockOnCreateFirewallRule: Emitter<void>;
let instantiationService: TypeMoq.Mock<InstantiationService>;
let mockFirewallRuleViewModel: TypeMoq.Mock<FirewallRuleViewModel>;
let mockFirewallRuleDialog: TypeMoq.Mock<FirewallRuleDialog>;
setup(() => {
account = {
key: { providerId: 'azure', accountId: 'account1' },
displayInfo: {
contextualDisplayName: 'Microsoft Account',
accountType: 'microsoft',
displayName: 'Account 1',
userId: 'user@email.com'
},
properties: [],
isStale: false
};
mockOnAddAccountErrorEvent = new Emitter<string>();
mockOnCreateFirewallRule = new Emitter<void>();
// Create a mock firewall rule view model
let firewallRuleViewModel = new FirewallRuleViewModel();
mockFirewallRuleViewModel = TypeMoq.Mock.ofInstance(firewallRuleViewModel);
mockFirewallRuleViewModel.setup(x => x.updateDefaultValues(TypeMoq.It.isAny()))
.returns((ipAddress) => undefined);
mockFirewallRuleViewModel.object.selectedAccount = account;
mockFirewallRuleViewModel.object.isIPAddressSelected = true;
// Create a mocked out instantiation service
instantiationService = TypeMoq.Mock.ofType(InstantiationService, TypeMoq.MockBehavior.Strict);
instantiationService.setup(x => x.createInstance(TypeMoq.It.isValue(FirewallRuleViewModel)))
.returns(() => mockFirewallRuleViewModel.object);
// Create a mock account picker
let firewallRuleDialog = new FirewallRuleDialog(null, null, null, instantiationService.object, null, null, new MockContextKeyService(), null, null, undefined);
mockFirewallRuleDialog = TypeMoq.Mock.ofInstance(firewallRuleDialog);
let mockEvent = new Emitter<any>();
mockFirewallRuleDialog.setup(x => x.onCancel)
.returns(() => mockEvent.event);
mockFirewallRuleDialog.setup(x => x.onCreateFirewallRule)
.returns(() => mockOnCreateFirewallRule.event);
mockFirewallRuleDialog.setup(x => x.onAddAccountErrorEvent)
.returns((msg) => mockOnAddAccountErrorEvent.event);
mockFirewallRuleDialog.setup(x => x.render());
mockFirewallRuleDialog.setup(x => x.open());
mockFirewallRuleDialog.setup(x => x.close());
instantiationService.setup(x => x.createInstance(TypeMoq.It.isValue(FirewallRuleDialog)))
.returns(() => mockFirewallRuleDialog.object);
connectionProfile = {
connectionName: 'new name',
serverName: 'new server',
databaseName: 'database',
userName: 'user',
password: 'password',
authenticationType: '',
savePassword: true,
groupFullName: 'g2/g2-2',
groupId: 'group id',
getOptionsKey: undefined,
matches: undefined,
providerName: mssqlProviderName,
options: {},
saveProfile: true,
id: undefined
};
});
test('Add Account Failure - Error Message Shown', () => {
// ... Create a mock instance of the error message service
let errorMessageServiceStub = new TestErrorMessageService();
let mockErrorMessageService = TypeMoq.Mock.ofInstance(errorMessageServiceStub);
mockErrorMessageService.setup(x => x.showDialog(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()));
// ... Create instance of the controller with an opened dialog
let controller = new FirewallRuleDialogController(instantiationService.object, null, null, mockErrorMessageService.object);
controller.openFirewallRuleDialog(connectionProfile, IPAddress, 'resourceID');
// If: The firewall rule dialog reports a failure
mockOnAddAccountErrorEvent.fire('Error message');
// Then: An error dialog should have been opened
mockErrorMessageService.verify(x => x.showDialog(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once());
});
test('create firewall rule success', (done) => {
let deferredPromise = new Deferred();
mockFirewallRuleDialog.setup(x => x.onServiceComplete())
.callback(() => {
deferredPromise.resolve(true);
});
// ... Create a mock instance of the account management test service
let mockAccountManagementService = getMockAccountManagementService(true);
// ... Create a mock instance of the resource provider
let mockResourceProvider = getMockResourceProvider(true, { result: true, errorMessage: '' });
// ... Create instance of the controller with an opened dialog
let controller = new FirewallRuleDialogController(instantiationService.object, mockResourceProvider.object, mockAccountManagementService.object, null);
controller.openFirewallRuleDialog(connectionProfile, IPAddress, 'resourceID');
// If: The firewall rule dialog's create firewall rule get fired
mockOnCreateFirewallRule.fire();
// Then: it should get security token from account management service and call create firewall rule in resource provider
deferredPromise.promise.then(() => {
mockAccountManagementService.verify(x => x.getSecurityToken(TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once());
mockResourceProvider.verify(x => x.createFirewallRule(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once());
mockFirewallRuleDialog.verify(x => x.close(), TypeMoq.Times.once());
mockFirewallRuleDialog.verify(x => x.onServiceComplete(), TypeMoq.Times.once());
done();
});
});
test('create firewall rule fails during getSecurity', (done) => {
let deferredPromise = new Deferred();
// ... Create a mock instance of the error message service
let mockErrorMessageService = getMockErrorMessageService(deferredPromise);
// ... Create a mock instance of the account management test service
let mockAccountManagementService = getMockAccountManagementService(false);
// ... Create a mock instance of the resource provider
let mockResourceProvider = getMockResourceProvider(true, { result: true, errorMessage: '' });
// ... Create instance of the controller with an opened dialog
let controller = new FirewallRuleDialogController(instantiationService.object, mockResourceProvider.object, mockAccountManagementService.object, mockErrorMessageService.object);
controller.openFirewallRuleDialog(connectionProfile, IPAddress, 'resourceID');
// If: The firewall rule dialog's create firewall rule get fired
mockOnCreateFirewallRule.fire();
// Then: it should get security token from account management service and an error dialog should have been opened
deferredPromise.promise.then(() => {
mockAccountManagementService.verify(x => x.getSecurityToken(TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once());
mockErrorMessageService.verify(x => x.showDialog(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once());
mockResourceProvider.verify(x => x.createFirewallRule(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.never());
done();
});
});
test('create firewall rule fails during createFirewallRule in ResourceProvider - result is false', (done) => {
let deferredPromise = new Deferred();
// ... Create a mock instance of the error message service
let mockErrorMessageService = getMockErrorMessageService(deferredPromise);
// ... Create a mock instance of the account management test service
let mockAccountManagementService = getMockAccountManagementService(true);
// ... Create a mock instance of the resource provider
let mockResourceProvider = getMockResourceProvider(true, { result: false, errorMessage: '' });
// ... Create instance of the controller with an opened dialog
let controller = new FirewallRuleDialogController(instantiationService.object, mockResourceProvider.object, mockAccountManagementService.object, mockErrorMessageService.object);
controller.openFirewallRuleDialog(connectionProfile, IPAddress, 'resourceID');
// If: The firewall rule dialog's create firewall rule get fired
mockOnCreateFirewallRule.fire();
// Then: it should get security token from account management service and an error dialog should have been opened
deferredPromise.promise.then(() => {
mockAccountManagementService.verify(x => x.getSecurityToken(TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once());
mockResourceProvider.verify(x => x.createFirewallRule(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once());
mockErrorMessageService.verify(x => x.showDialog(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once());
done();
});
});
test('create firewall rule fails during createFirewallRule in ResourceProvider - reject promise', (done) => {
let deferredPromise = new Deferred();
// ... Create a mock instance of the error message service
let mockErrorMessageService = getMockErrorMessageService(deferredPromise);
// ... Create a mock instance of the account management test service
let mockAccountManagementService = getMockAccountManagementService(true);
// ... Create a mock instance of the resource provider
let mockResourceProvider = getMockResourceProvider(false);
// ... Create instance of the controller with an opened dialog
let controller = new FirewallRuleDialogController(instantiationService.object, mockResourceProvider.object, mockAccountManagementService.object, mockErrorMessageService.object);
controller.openFirewallRuleDialog(connectionProfile, IPAddress, 'resourceID');
// If: The firewall rule dialog's create firewall rule get fired
mockOnCreateFirewallRule.fire();
// Then: it should get security token from account management service and an error dialog should have been opened
deferredPromise.promise.then(() => {
mockAccountManagementService.verify(x => x.getSecurityToken(TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once());
mockResourceProvider.verify(x => x.createFirewallRule(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once());
mockErrorMessageService.verify(x => x.showDialog(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once());
done();
});
});
});
function getMockAccountManagementService(resolveSecurityToken: boolean): TypeMoq.Mock<TestAccountManagementService> {
let accountManagementTestService = new TestAccountManagementService();
let mockAccountManagementService = TypeMoq.Mock.ofInstance(accountManagementTestService);
mockAccountManagementService.setup(x => x.getSecurityToken(TypeMoq.It.isAny(), TypeMoq.It.isAny()))
.returns(() => resolveSecurityToken ? Promise.resolve({}) : Promise.reject(null).then());
return mockAccountManagementService;
}
function getMockResourceProvider(resolveCreateFirewallRule: boolean, response?: azdata.CreateFirewallRuleResponse): TypeMoq.Mock<TestResourceProvider> {
let resourceProviderStub = new TestResourceProvider();
let mockResourceProvider = TypeMoq.Mock.ofInstance(resourceProviderStub);
mockResourceProvider.setup(x => x.createFirewallRule(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()))
.returns(() => resolveCreateFirewallRule ? Promise.resolve(response) : Promise.reject(null).then());
return mockResourceProvider;
}
function getMockErrorMessageService(deferredPromise: Deferred<{}>): TypeMoq.Mock<TestErrorMessageService> {
let errorMessageServiceStub = new TestErrorMessageService();
let mockErrorMessageService = TypeMoq.Mock.ofInstance(errorMessageServiceStub);
mockErrorMessageService.setup(x => x.showDialog(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).callback(() => {
deferredPromise.resolve(true);
});
return mockErrorMessageService;
}

View File

@@ -0,0 +1,190 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import * as azdata from 'azdata';
import * as TypeMoq from 'typemoq';
import { AddAccountAction, RemoveAccountAction } from 'sql/platform/accounts/common/accountActions';
import { TestAccountManagementService } from 'sql/platform/accounts/test/common/testAccountManagementService';
// import { MessageServiceStub } from 'sqltest/stubs/messageServiceStub';
import { TestErrorMessageService } from 'sql/platform/errorMessage/test/common/testErrorMessageService';
let testAccount = <azdata.Account>{
key: {
providerId: 'azure',
accountId: 'testAccount'
},
displayInfo: {
accountType: 'test',
displayName: 'Test Account',
contextualDisplayName: 'Azure Account'
},
isStale: false
};
suite('Account Management Dialog Actions Tests', () => {
test('AddAccount - Success', (done) => {
done();
// // Setup: Create an AddAccountAction object
// let param = 'azure';
// let mocks = createAddAccountAction(true, true, param);
// // If: I run the action when it will resolve
// mocks.action.run()
// .then(result => {
// // Then:
// // ... I should have gotten true back
// assert.ok(result);
// // ... The account management service should have gotten a add account request
// mocks.accountMock.verify(x => x.addAccount(param), TypeMoq.Times.once());
// })
// .then(
// () => done(),
// err => done(err)
// );
});
// test('AddAccount - Failure', (done) => {
// // // Setup: Create an AddAccountAction object
// // let param = 'azure';
// // let mocks = createAddAccountAction(false, true, param);
// // // If: I run the action when it will reject
// // mocks.action.run().then(result => {
// // // Then:
// // // ... The result should be false since the operation failed
// // assert.ok(!result);
// // // ... The account management service should have gotten a add account request
// // mocks.accountMock.verify(x => x.addAccount(param), TypeMoq.Times.once());
// // done();
// // }, error => {
// // // Should fail as rejected actions cause the debugger to crash
// // done(error);
// // });
// });
// test('RemoveAccount - Confirm Success', (done) => {
// // // Setup: Create an AddAccountAction object
// // let ams = getMockAccountManagementService(true);
// // let ms = getMockMessageService(true);
// // let es = getMockErrorMessageService();
// // let action = new RemoveAccountAction(testAccount, ms.object, es.object, ams.object);
// // // If: I run the action when it will resolve
// // action.run()
// // .then(result => {
// // // Then:
// // // ... I should have gotten true back
// // assert.ok(result);
// // // ... A confirmation dialog should have opened
// // ms.verify(x => x.confirm(TypeMoq.It.isAny()), TypeMoq.Times.once());
// // // ... The account management service should have gotten a remove account request
// // ams.verify(x => x.removeAccount(TypeMoq.It.isValue(testAccount.key)), TypeMoq.Times.once());
// // })
// // .then(
// // () => done(),
// // err => done(err)
// // );
// });
// test('RemoveAccount - Declined Success', (done) => {
// // // Setup: Create an AddAccountAction object
// // let ams = getMockAccountManagementService(true);
// // let ms = getMockMessageService(false);
// // let es = getMockErrorMessageService();
// // let action = new RemoveAccountAction(testAccount, ms.object, es.object, ams.object);
// // // If: I run the action when it will resolve
// // action.run()
// // .then(result => {
// // try {
// // // Then:
// // // ... I should have gotten false back
// // assert.ok(!result);
// // // ... A confirmation dialog should have opened
// // ms.verify(x => x.confirm(TypeMoq.It.isAny()), TypeMoq.Times.once());
// // // ... The account management service should not have gotten a remove account request
// // ams.verify(x => x.removeAccount(TypeMoq.It.isAny()), TypeMoq.Times.never());
// // done();
// // } catch (e) {
// // done(e);
// // }
// // });
// });
// test('RemoveAccount - Failure', (done) => {
// // // Setup: Create an AddAccountAction object
// // let ams = getMockAccountManagementService(false);
// // let ms = getMockMessageService(true);
// // let es = getMockErrorMessageService();
// // let action = new RemoveAccountAction(testAccount, ms.object, es.object, ams.object);
// // // If: I run the action when it will reject
// // action.run().then(result => {
// // // Then:
// // // ... The result should be false since the operation failed
// // assert.ok(!result);
// // // ... The account management service should have gotten a remove account request
// // ams.verify(x => x.removeAccount(TypeMoq.It.isValue(testAccount.key)), TypeMoq.Times.once());
// // done();
// // }, error => {
// // // Should fail as rejected actions cause the debugger to crash
// // done(error);
// // });
// });
});
// function createAddAccountAction(resolve: boolean, confirm: boolean, param: string): IAddActionMocks {
// let ams = getMockAccountManagementService(resolve);
// let mockMessageService = getMockMessageService(confirm);
// let mockErrorMessageService = getMockErrorMessageService();
// return {
// accountMock: ams,
// messageMock: mockMessageService,
// errorMessageMock: mockErrorMessageService,
// action: new AddAccountAction(param, mockMessageService.object,
// mockErrorMessageService.object, ams.object)
// };
// }
// function getMockAccountManagementService(resolve: boolean): TypeMoq.Mock<AccountManagementTestService> {
// let mockAccountManagementService = TypeMoq.Mock.ofType(AccountManagementTestService);
// mockAccountManagementService.setup(x => x.addAccount(TypeMoq.It.isAnyString()))
// .returns(resolve ? () => Promise.resolve(null) : () => Promise.reject(null));
// mockAccountManagementService.setup(x => x.removeAccount(TypeMoq.It.isAny()))
// .returns(resolve ? () => Promise.resolve(true) : () => Promise.reject(null).then());
// return mockAccountManagementService;
// }
// function getMockMessageService(confirm: boolean): TypeMoq.Mock<MessageServiceStub> {
// let mockMessageService = TypeMoq.Mock.ofType(MessageServiceStub);
// mockMessageService.setup(x => x.confirm(TypeMoq.It.isAny()))
// .returns(() => undefined);
// return mockMessageService;
// }
// 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;
// }
// interface IAddActionMocks
// {
// accountMock: TypeMoq.Mock<AccountManagementTestService>;
// messageMock: TypeMoq.Mock<MessageServiceStub>;
// errorMessageMock: TypeMoq.Mock<ErrorMessageServiceStub>;
// action: AddAccountAction;
// }

View File

@@ -0,0 +1,149 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as azdata from 'azdata';
import * as assert from 'assert';
import * as TypeMoq from 'typemoq';
import { EventVerifierSingle } from 'sqltest/utils/eventVerifier';
import { Emitter } from 'vs/base/common/event';
import { AccountPickerViewModel } from 'sql/platform/accounts/common/accountPickerViewModel';
import { UpdateAccountListEventParams } from 'sql/platform/accounts/common/eventTypes';
import { TestAccountManagementService } from 'sql/platform/accounts/test/common/testAccountManagementService';
// SUITE STATE /////////////////////////////////////////////////////////////
let mockUpdateAccountEmitter: Emitter<UpdateAccountListEventParams>;
let providers: azdata.AccountProviderMetadata[];
let accounts: azdata.Account[];
suite('Account picker view model tests', () => {
setup(() => {
providers = [{
id: 'azure',
displayName: 'Azure'
}];
let account1 = {
key: { providerId: 'azure', accountId: 'account1' },
name: 'Account 1',
displayInfo: {
contextualDisplayName: 'Microsoft Account',
accountType: 'microsoft',
displayName: 'Account 1',
userId: 'user@email.com'
},
properties: [],
isStale: false
};
let account2 = {
key: { providerId: 'azure', accountId: 'account2' },
name: 'Account 2',
displayInfo: {
contextualDisplayName: 'Work/School Account',
accountType: 'microsoft',
displayName: 'Account 2',
userId: 'user@email.com'
},
properties: [],
isStale: true
};
accounts = [account1, account2];
// Setup event mocks
mockUpdateAccountEmitter = new Emitter<UpdateAccountListEventParams>();
});
test('Construction - Events are properly defined', () => {
// If: I create an account picker viewmodel
let mockAccountManagementService = getMockAccountManagementService(false, false);
let vm = new AccountPickerViewModel('azure', mockAccountManagementService.object);
// Then:
// ... The event for the view models should be properly initialized
assert.notEqual(vm.updateAccountListEvent, undefined);
// ... The event should properly fire
let argUpdateAccounts: UpdateAccountListEventParams = { providerId: providers[0].id, accountList: accounts };
let evUpdateAccounts = new EventVerifierSingle<UpdateAccountListEventParams>();
vm.updateAccountListEvent(evUpdateAccounts.eventHandler);
mockUpdateAccountEmitter.fire(argUpdateAccounts);
evUpdateAccounts.assertFired(argUpdateAccounts);
});
test('Initialize - Success', done => {
// Setup: Create a viewmodel with event handlers
let mockAccountManagementService = getMockAccountManagementService(true, true);
let evUpdateAccounts = new EventVerifierSingle<UpdateAccountListEventParams>();
let vm = getViewModel(mockAccountManagementService.object, evUpdateAccounts);
// If: I initialize the view model
vm.initialize()
.then(results => {
// Then:
// ... None of the events should have fired
evUpdateAccounts.assertNotFired();
// ... The account management service should have been called
mockAccountManagementService.verify(x => x.getAccountsForProvider(TypeMoq.It.isAny()), TypeMoq.Times.once());
// ... The results that were returned should be an array of account
assert.ok(Array.isArray(results));
assert.equal(results.length, 2);
assert.equal(results, accounts);
}).then(
() => done(),
err => done(err)
);
});
test('Initialize - Get accounts fails expects empty array', done => {
// Setup: Create a mock account management service that rejects the promise
let mockAccountManagementService = getMockAccountManagementService(true, false);
let evUpdateAccounts = new EventVerifierSingle<UpdateAccountListEventParams>();
let vm = getViewModel(mockAccountManagementService.object, evUpdateAccounts);
// If: I initialize the view model
vm.initialize()
.then(result => {
// Then:
// ... None of the events should have fired
evUpdateAccounts.assertNotFired();
// ... The account management service should have been called
mockAccountManagementService.verify(x => x.getAccountsForProvider(TypeMoq.It.isAny()), TypeMoq.Times.once());
// ... The results should be an empty array
assert.ok(Array.isArray(result));
assert.equal(result.length, 0);
assert.equal(result, []);
}).then(
() => done(),
err => done()
);
});
});
function getMockAccountManagementService(resolveProviders: boolean, resolveAccounts: boolean): TypeMoq.Mock<TestAccountManagementService> {
let mockAccountManagementService = TypeMoq.Mock.ofType(TestAccountManagementService);
mockAccountManagementService.setup(x => x.getAccountProviderMetadata())
.returns(() => resolveProviders ? Promise.resolve(providers) : Promise.reject(null).then());
mockAccountManagementService.setup(x => x.getAccountsForProvider(TypeMoq.It.isAny()))
.returns(() => resolveAccounts ? Promise.resolve(accounts) : Promise.reject(null).then());
mockAccountManagementService.setup(x => x.updateAccountListEvent)
.returns(() => mockUpdateAccountEmitter.event);
return mockAccountManagementService;
}
function getViewModel(
ams: TestAccountManagementService,
evUpdate: EventVerifierSingle<UpdateAccountListEventParams>
): AccountPickerViewModel {
let vm = new AccountPickerViewModel('azure', ams);
vm.updateAccountListEvent(evUpdate.eventHandler);
return vm;
}

View File

@@ -0,0 +1,440 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import * as azdata from 'azdata';
import AccountStore from 'sql/platform/accounts/common/accountStore';
import { EventVerifierSingle } from 'sqltest/utils/eventVerifier';
suite('Account Store Tests', () => {
test('AddOrUpdate - Uninitialized memento', done => {
// Setup: Create account store w/o initialized memento
let memento = {};
let as = new AccountStore(memento);
// If: I add an account to the store
as.addOrUpdate(account1)
.then(result => {
// Then:
// ... I should have gotten back a result indicating the account was added
assert.ok(result.accountAdded);
assert.ok(!result.accountModified);
assertAccountEqual(result.changedAccount, account1);
// ... The memento should have been initialized and account added
assert.ok(Array.isArray(memento[AccountStore.MEMENTO_KEY]));
assert.equal(memento[AccountStore.MEMENTO_KEY].length, 1);
assertAccountEqual(memento[AccountStore.MEMENTO_KEY][0], account1);
})
.then(
() => done(),
e => done(e)
);
});
test('AddOrUpdate - Adds to accounts', done => {
// Setup: Create account store with initialized memento with accounts
let memento = {};
memento[AccountStore.MEMENTO_KEY] = [];
let as = new AccountStore(memento);
// If: I add an account to the store
as.addOrUpdate(account1)
.then(result => {
// Then:
// ... I should have gotten back a result indicating the account was added
assert.ok(result.accountAdded);
assert.ok(!result.accountModified);
assertAccountEqual(result.changedAccount, account1);
// ... The memento should have the account added
assert.ok(Array.isArray(memento[AccountStore.MEMENTO_KEY]));
assert.equal(memento[AccountStore.MEMENTO_KEY].length, 1);
assertAccountEqual(memento[AccountStore.MEMENTO_KEY][0], account1);
})
.then(
() => done(),
e => done(e)
);
});
test('AddOrUpdate - Updates account', done => {
// Setup: Create account store with initialized memento with accounts
let memento = getTestMemento();
let as = new AccountStore(memento);
// If: I add an account to the store that already exists
let param = <azdata.Account>{
key: account2.key,
displayInfo: account1.displayInfo,
isStale: account1.isStale
};
as.addOrUpdate(param)
.then(result => {
// Then:
// ... I should have gotten back a result indicating the account was updated
assert.ok(result.accountModified);
assert.ok(!result.accountAdded);
assertAccountEqual(result.changedAccount, param);
// ... The memento should have been initialized and account updated
assert.ok(Array.isArray(memento[AccountStore.MEMENTO_KEY]));
assert.equal(memento[AccountStore.MEMENTO_KEY].length, 2);
assertAccountEqual(memento[AccountStore.MEMENTO_KEY][0], account1);
assertAccountEqual(memento[AccountStore.MEMENTO_KEY][1], param);
})
.then(
() => done(),
e => done(e)
);
});
test('GetAccountsByProvider - Uninitialized memento', done => {
// Setup: Create account store w/o initialized memento
let memento = {};
let as = new AccountStore(memento);
// If: I get accounts by provider
as.getAccountsByProvider('azure')
.then(result => {
// Then:
// ... I should get back an empty array
assert.ok(Array.isArray(result));
assert.equal(result.length, 0);
// ... Memento should not have been written
assert.equal(Object.keys(memento).length, 0);
})
.then(
() => done(),
e => done(e)
);
});
test('GetAccountsByProvider - No accounts', done => {
// Setup: Create account store with initialized memento with accounts
let memento = {};
memento[AccountStore.MEMENTO_KEY] = [];
let as = new AccountStore(memento);
// If: I get accounts when there aren't any accounts
as.getAccountsByProvider('azure')
.then(result => {
// Then: I should get back an empty array
assert.ok(Array.isArray(result));
assert.equal(result.length, 0);
})
.then(
() => done(),
e => done(e)
);
});
test('GetAccountsByProvider - Accounts, but no accounts for provider', done => {
// Setup: Create account store with initialized memento with accounts
let memento = getTestMemento();
let as = new AccountStore(memento);
// If: I get accounts by provider that doesn't have accounts
as.getAccountsByProvider('cloudycloud')
.then(result => {
// Then: I should get back an empty array
assert.ok(Array.isArray(result));
assert.equal(result.length, 0);
})
.then(
() => done(),
e => done(e)
);
});
test('GetAccountsByProvider - Accounts for provider', done => {
// Setup: Create account store with initialized memento with accounts
let memento = getTestMemento();
let as = new AccountStore(memento);
// If: I get accounts by provider that has accounts
as.getAccountsByProvider('azure')
.then(result => {
// Then: I should get the accounts
assert.ok(Array.isArray(result));
assert.equal(result.length, 2);
assertAccountEqual(result[0], memento[AccountStore.MEMENTO_KEY][0]);
assertAccountEqual(result[1], memento[AccountStore.MEMENTO_KEY][1]);
})
.then(
() => done(),
e => done(e)
);
});
test('GetAllAccounts - Uninitialized memento', done => {
// Setup: Create account store w/o initialized memento
let memento = {};
let as = new AccountStore(memento);
// If: I get accounts
as.getAllAccounts()
.then(result => {
// Then:
// ... I should get back an empty array
assert.ok(Array.isArray(result));
assert.equal(result.length, 0);
// ... Memento should not have been written
assert.equal(Object.keys(memento).length, 0);
})
.then(
() => done(),
e => done(e)
);
});
test('GetAllAccounts - No accounts', done => {
// Setup: Create account store with initialized memento with accounts
let memento = {};
memento[AccountStore.MEMENTO_KEY] = [];
let as = new AccountStore(memento);
// If: I get accounts when there aren't any accounts
as.getAllAccounts()
.then(result => {
// Then: I should get back an empty array
assert.ok(Array.isArray(result));
assert.equal(result.length, 0);
})
.then(
() => done(),
e => done(e)
);
});
test('GetAllAccounts - Accounts', done => {
// Setup: Create account store with initialized memento with accounts
let memento = getTestMemento();
let as = new AccountStore(memento);
// If: I get accounts
as.getAllAccounts()
.then(result => {
// Then: I should get the accounts
assert.ok(Array.isArray(result));
assert.equal(result.length, 2);
assertAccountEqual(result[0], memento[AccountStore.MEMENTO_KEY][0]);
assertAccountEqual(result[1], memento[AccountStore.MEMENTO_KEY][1]);
})
.then(
() => done(),
e => done(e)
);
});
test('Remove - Uninitialized menento', done => {
// Setup: Create account store w/o initialized memento
let memento = {};
let as = new AccountStore(memento);
// If: I remove an account when there's an uninitialized memento
as.remove(account1.key)
.then(result => {
// Then:
// ... I should get back false (no account removed)
assert.ok(!result);
// ... The memento should have been initialized
assert.ok(Array.isArray(memento[AccountStore.MEMENTO_KEY]));
assert.equal(memento[AccountStore.MEMENTO_KEY].length, 0);
})
.then(
() => done(),
e => done(e)
);
});
test('Remove - Account does not exist', done => {
// Setup: Create account store with initialized memento with accounts
let memento = {};
memento[AccountStore.MEMENTO_KEY] = [];
let as = new AccountStore(memento);
// If: I remove an account that doesn't exist
as.remove({ providerId: 'cloudyCloud', accountId: 'testyTest' })
.then(result => {
// Then:
// ... I should get back false (no account removed)
assert.ok(!result);
// ... The memento should still be empty
assert.ok(Array.isArray(memento[AccountStore.MEMENTO_KEY]));
assert.equal(memento[AccountStore.MEMENTO_KEY].length, 0);
})
.then(
() => done(),
e => done(e)
);
});
test('Remove - Account exists', done => {
// Setup: Create account store with initialized memento with accounts
let memento = getTestMemento();
let as = new AccountStore(memento);
// If: I remove an account that does exist
as.remove(account1.key)
.then(result => {
// Then:
// ... I should get back true (account removed)
assert.ok(result);
// ... The memento should have removed the first account
assert.ok(Array.isArray(memento[AccountStore.MEMENTO_KEY]));
assert.equal(memento[AccountStore.MEMENTO_KEY].length, 1);
assertAccountEqual(memento[AccountStore.MEMENTO_KEY][0], account2);
})
.then(
() => done(),
e => done(e)
);
});
test('Update - Uninitialized menento', done => {
// Setup:
// ... Create account store w/o initialized memento
let memento = {};
let as = new AccountStore(memento);
// ... Create a callback that we can verify was called
let updateCallback = new EventVerifierSingle<azdata.Account>();
// If: I update an account
as.update(account1.key, updateCallback.eventHandler)
.then(result => {
// Then:
// ... I should get back false (account did not change)
assert.ok(!result);
// ... The memento should have been initialized
assert.ok(Array.isArray(memento[AccountStore.MEMENTO_KEY]));
assert.equal(memento[AccountStore.MEMENTO_KEY].length, 0);
// ... The callback shouldn't have been called
updateCallback.assertNotFired();
})
.then(
() => done(),
e => done(e)
);
});
test('Update - Account does not exist', done => {
// Setup: Create account store with initialized memento with accounts
let memento = {};
memento[AccountStore.MEMENTO_KEY] = [];
let as = new AccountStore(memento);
// ... Create a callback that we can verify was called
let updateCallback = new EventVerifierSingle<azdata.Account>();
// If: I update an account that doesn't exist
as.update({ accountId: 'testyTest', providerId: 'cloudyCloud' }, updateCallback.eventHandler)
.then(result => {
// Then:
// ... I should get back false (account did not change)
assert.ok(!result);
// ... The memento should still be empty
assert.ok(Array.isArray(memento[AccountStore.MEMENTO_KEY]));
assert.equal(memento[AccountStore.MEMENTO_KEY].length, 0);
// ... The callback shouldn't have been called
updateCallback.assertNotFired();
})
.then(
() => done(),
e => done(e)
);
});
test('Update - Account exists', done => {
// Setup: Create account store with initialized memento with accounts
let memento = getTestMemento();
let as = new AccountStore(memento);
// ... Create a callback to update the account
let newDisplayName = 'Display Name Changed!';
let updateCallback = (arg: azdata.Account) => {
arg.displayInfo.displayName = newDisplayName;
};
// If: I update an account that exists
as.update(account1.key, updateCallback)
.then(result => {
// Then:
// ... I should get back true (account did change)
assert.ok(result);
// ... The memento still contains two accounts
assert.ok(Array.isArray(memento[AccountStore.MEMENTO_KEY]));
assert.equal(memento[AccountStore.MEMENTO_KEY].length, 2);
// ... Account 1 should have been updated
assert.equal(memento[AccountStore.MEMENTO_KEY][0].displayInfo.displayName, newDisplayName);
// ... Account 2 should have stayed the same
assertAccountEqual(memento[AccountStore.MEMENTO_KEY][1], account2);
})
.then(
() => done(),
e => done(e)
);
});
// TODO: Test to make sure operations occur sequentially
});
// TODO: Reinstate contextual logo once UI changes are checked in
const account1 = <azdata.Account>{
key: {
providerId: 'azure',
accountId: 'testAccount1'
},
displayInfo: {
displayName: 'Test Account 1',
accountType: 'test',
contextualDisplayName: 'Azure Account'
},
isStale: false
};
const account2 = <azdata.Account>{
key: {
providerId: 'azure',
accountId: 'testAccount2'
},
displayInfo: {
displayName: 'Test Account 2',
accountType: 'test',
contextualDisplayName: 'Azure Account'
},
isStale: false
};
function getTestMemento() {
let memento = {};
memento[AccountStore.MEMENTO_KEY] = [account1, account2];
return memento;
}
function assertAccountEqual(a: azdata.Account, b: azdata.Account) {
assert.equal(a.key.providerId, b.key.providerId);
assert.equal(a.key.accountId, b.key.accountId);
assert.equal(a.displayInfo.contextualDisplayName, b.displayInfo.contextualDisplayName);
assert.equal(a.displayInfo.accountType, b.displayInfo.accountType);
assert.equal(a.displayInfo.displayName, b.displayInfo.displayName);
assert.equal(a.isStale, b.isStale);
}

View File

@@ -0,0 +1,224 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import * as azdata from 'azdata';
import * as TypeMoq from 'typemoq';
import { EventVerifierSingle } from 'sqltest/utils/eventVerifier';
import { Emitter } from 'vs/base/common/event';
import { AccountViewModel } from 'sql/platform/accounts/common/accountViewModel';
import { AccountProviderAddedEventParams, UpdateAccountListEventParams } from 'sql/platform/accounts/common/eventTypes';
import { TestAccountManagementService } from 'sql/platform/accounts/test/common/testAccountManagementService';
// SUITE STATE /////////////////////////////////////////////////////////////
let mockAddProviderEmitter: Emitter<AccountProviderAddedEventParams>;
let mockRemoveProviderEmitter: Emitter<azdata.AccountProviderMetadata>;
let mockUpdateAccountEmitter: Emitter<UpdateAccountListEventParams>;
let providers: azdata.AccountProviderMetadata[];
let accounts: azdata.Account[];
suite('Account Management Dialog ViewModel Tests', () => {
suiteSetup(() => {
providers = [{
id: 'azure',
displayName: 'Azure'
}];
let account1 = {
key: { providerId: 'azure', accountId: 'account1' },
name: 'Account 1',
displayInfo: {
contextualDisplayName: 'Microsoft Account',
accountType: 'microsoft',
displayName: 'Account 1',
userId: 'user@email.com'
},
properties: [],
isStale: false
};
let account2 = {
key: { providerId: 'azure', accountId: 'account2' },
name: 'Account 2',
displayInfo: {
contextualDisplayName: 'Work/School Account',
accountType: 'work_school',
displayName: 'Account 2',
userId: 'user@email.com'
},
properties: [],
isStale: true
};
accounts = [account1, account2];
// Setup event mocks for the account management service
mockAddProviderEmitter = new Emitter<AccountProviderAddedEventParams>();
mockRemoveProviderEmitter = new Emitter<azdata.AccountProviderMetadata>();
mockUpdateAccountEmitter = new Emitter<UpdateAccountListEventParams>();
});
test('Construction - Events are properly defined', () => {
// If: I create an account viewmodel
let mockAccountManagementService = getMockAccountManagementService(false, false);
let vm = new AccountViewModel(mockAccountManagementService.object);
// Then:
// ... All the events for the view models should be properly initialized
assert.notEqual(vm.addProviderEvent, undefined);
assert.notEqual(vm.removeProviderEvent, undefined);
assert.notEqual(vm.updateAccountListEvent, undefined);
// ... All the events should properly fire
let argAddProvider: AccountProviderAddedEventParams = { addedProvider: providers[0], initialAccounts: [] };
let evAddProvider = new EventVerifierSingle<AccountProviderAddedEventParams>();
vm.addProviderEvent(evAddProvider.eventHandler);
mockAddProviderEmitter.fire(argAddProvider);
evAddProvider.assertFired(argAddProvider);
let argRemoveProvider = providers[0];
let evRemoveProvider = new EventVerifierSingle<azdata.AccountProviderMetadata>();
vm.removeProviderEvent(evRemoveProvider.eventHandler);
mockRemoveProviderEmitter.fire(argRemoveProvider);
evRemoveProvider.assertFired(argRemoveProvider);
let argUpdateAccounts: UpdateAccountListEventParams = { providerId: providers[0].id, accountList: accounts };
let evUpdateAccounts = new EventVerifierSingle<UpdateAccountListEventParams>();
vm.updateAccountListEvent(evUpdateAccounts.eventHandler);
mockUpdateAccountEmitter.fire(argUpdateAccounts);
evUpdateAccounts.assertFired(argUpdateAccounts);
});
test('Initialize - Success', done => {
// Setup: Create a viewmodel with event handlers
let mockAccountManagementService = getMockAccountManagementService(true, true);
let evAddProvider = new EventVerifierSingle<AccountProviderAddedEventParams>();
let evRemoveProvider = new EventVerifierSingle<azdata.AccountProviderMetadata>();
let evUpdateAccounts = new EventVerifierSingle<UpdateAccountListEventParams>();
let vm = getViewModel(mockAccountManagementService.object, evAddProvider, evRemoveProvider, evUpdateAccounts);
// If: I initialize the view model
vm.initialize()
.then(results => {
// Then:
// ... None of the events should have fired
assertNoEventsFired(evAddProvider, evRemoveProvider, evUpdateAccounts);
// ... The account management service should have been called
mockAccountManagementService.verify(x => x.getAccountProviderMetadata(), TypeMoq.Times.once());
mockAccountManagementService.verify(x => x.getAccountsForProvider(TypeMoq.It.isAny()), TypeMoq.Times.once());
// ... The results that were returned should be an array of account provider added event params
assert.ok(Array.isArray(results));
assert.equal(results.length, 1);
assert.equal(results[0].addedProvider, providers[0]);
assert.equal(results[0].initialAccounts, accounts);
}).then(
() => done(),
err => done(err)
);
});
test('Initialize - Get providers fails', done => {
// Setup: Create a mock account management service that rejects looking up providers
let mockAccountManagementService = getMockAccountManagementService(false, true);
let evAddProvider = new EventVerifierSingle<AccountProviderAddedEventParams>();
let evRemoveProvider = new EventVerifierSingle<azdata.AccountProviderMetadata>();
let evUpdateAccounts = new EventVerifierSingle<UpdateAccountListEventParams>();
let vm = getViewModel(mockAccountManagementService.object, evAddProvider, evRemoveProvider, evUpdateAccounts);
// If: I initialize the view model
vm.initialize()
.then(results => {
// Then
// ... None of the events should have fired
assertNoEventsFired(evAddProvider, evRemoveProvider, evUpdateAccounts);
// ... The account management service should have been called for providers, but not accounts
mockAccountManagementService.verify(x => x.getAccountProviderMetadata(), TypeMoq.Times.once());
mockAccountManagementService.verify(x => x.getAccountsForProvider(TypeMoq.It.isAny()), TypeMoq.Times.never());
// ... The results that were returned should be an empty array
assert.ok(Array.isArray(results));
assert.equal(results.length, 0);
})
.then(
() => done(),
err => done(err)
);
});
test('Initialize - Get accounts fails', done => {
// Setup: Create a mock account management service that rejects the promise
let mockAccountManagementService = getMockAccountManagementService(true, false);
let evAddProvider = new EventVerifierSingle<AccountProviderAddedEventParams>();
let evRemoveProvider = new EventVerifierSingle<azdata.AccountProviderMetadata>();
let evUpdateAccounts = new EventVerifierSingle<UpdateAccountListEventParams>();
let vm = getViewModel(mockAccountManagementService.object, evAddProvider, evRemoveProvider, evUpdateAccounts);
// If: I initialize the view model
vm.initialize()
.then(result => {
// Then:
// ... None of the events should have fired
assertNoEventsFired(evAddProvider, evRemoveProvider, evUpdateAccounts);
// ... The account management service should have been called
mockAccountManagementService.verify(x => x.getAccountProviderMetadata(), TypeMoq.Times.once());
mockAccountManagementService.verify(x => x.getAccountsForProvider(TypeMoq.It.isAny()), TypeMoq.Times.once());
// ... The results should include the provider
assert.ok(Array.isArray(result));
assert.equal(result.length, 1);
assert.equal(result[0].addedProvider, providers[0]);
assert.equal(result[0].initialAccounts, accounts);
}).then(
() => done(),
err => done()
);
});
});
function getMockAccountManagementService(resolveProviders: boolean, resolveAccounts: boolean): TypeMoq.Mock<TestAccountManagementService> {
let mockAccountManagementService = TypeMoq.Mock.ofType(TestAccountManagementService);
mockAccountManagementService.setup(x => x.getAccountProviderMetadata())
.returns(() => resolveProviders ? Promise.resolve(providers) : Promise.reject(null).then());
mockAccountManagementService.setup(x => x.getAccountsForProvider(TypeMoq.It.isAny()))
.returns(() => resolveAccounts ? Promise.resolve(accounts) : Promise.reject(null).then());
mockAccountManagementService.setup(x => x.addAccountProviderEvent)
.returns(() => mockAddProviderEmitter.event);
mockAccountManagementService.setup(x => x.removeAccountProviderEvent)
.returns(() => mockRemoveProviderEmitter.event);
mockAccountManagementService.setup(x => x.updateAccountListEvent)
.returns(() => mockUpdateAccountEmitter.event);
return mockAccountManagementService;
}
function getViewModel(
ams: TestAccountManagementService,
evAdd: EventVerifierSingle<AccountProviderAddedEventParams>,
evRemove: EventVerifierSingle<azdata.AccountProviderMetadata>,
evUpdate: EventVerifierSingle<UpdateAccountListEventParams>
): AccountViewModel {
let vm = new AccountViewModel(ams);
vm.addProviderEvent(evAdd.eventHandler);
vm.removeProviderEvent(evRemove.eventHandler);
vm.updateAccountListEvent(evUpdate.eventHandler);
return vm;
}
function assertNoEventsFired(
evAdd: EventVerifierSingle<AccountProviderAddedEventParams>,
evRemove: EventVerifierSingle<azdata.AccountProviderMetadata>,
evUpdate: EventVerifierSingle<UpdateAccountListEventParams>
): void {
evAdd.assertNotFired();
evRemove.assertNotFired();
evUpdate.assertNotFired();
}

View File

@@ -0,0 +1,43 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { FirewallRuleViewModel } from 'sql/platform/accounts/common/firewallRuleViewModel';
suite('Firewall rule view model tests', () => {
let viewModel: FirewallRuleViewModel;
setup(() => {
viewModel = new FirewallRuleViewModel();
});
test('update default values to 250.222.155.198 should calculate the correct default subnet IP range', () => {
let IPAddress = '250.222.155.198';
viewModel.updateDefaultValues(IPAddress);
assert.equal(IPAddress, viewModel.defaultIPAddress);
assert.equal('250.222.155.0', viewModel.defaultFromSubnetIPRange);
assert.equal('250.222.155.255', viewModel.defaultToSubnetIPRange);
});
test('update default values to 250.222.155.0 should calculate the correct default subnet IP range', () => {
let IPAddress = '250.222.155.2';
viewModel.updateDefaultValues(IPAddress);
assert.equal(IPAddress, viewModel.defaultIPAddress);
assert.equal('250.222.155.0', viewModel.defaultFromSubnetIPRange);
assert.equal('250.222.155.255', viewModel.defaultToSubnetIPRange);
});
test('subnet IP range should return the correct values', () => {
let IPAddress = '250.222.155.198';
viewModel.updateDefaultValues(IPAddress);
assert.equal('250.222.155.0', viewModel.fromSubnetIPRange);
assert.equal('250.222.155.255', viewModel.toSubnetIPRange);
viewModel.fromSubnetIPRange = '250.222.155.100';
viewModel.toSubnetIPRange = '250.222.155.220';
assert.equal('250.222.155.100', viewModel.fromSubnetIPRange);
assert.equal('250.222.155.220', viewModel.toSubnetIPRange);
});
});

View File

@@ -0,0 +1,103 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as azdata from 'azdata';
import { Event } from 'vs/base/common/event';
import { IAccountManagementService } from 'sql/platform/accounts/common/interfaces';
import { AccountProviderAddedEventParams, UpdateAccountListEventParams } from 'sql/platform/accounts/common/eventTypes';
export class TestAccountManagementService implements IAccountManagementService {
_serviceBrand: any;
public get addAccountProviderEvent(): Event<AccountProviderAddedEventParams> { return () => { return undefined; }; }
public get removeAccountProviderEvent(): Event<azdata.AccountProviderMetadata> { return () => { return undefined; }; }
public get updateAccountListEvent(): Event<UpdateAccountListEventParams> { return () => { return undefined; }; }
accountUpdated(account: azdata.Account): Thenable<void> {
return undefined;
}
addAccount(providerId: string): Thenable<void> {
return undefined;
}
beginAutoOAuthDeviceCode(title: string, message: string, userCode: string, uri: string): Thenable<void> {
return undefined;
}
cancelAutoOAuthDeviceCode(providerId: string): void {
return undefined;
}
endAutoOAuthDeviceCode(): void {
return undefined;
}
copyUserCodeAndOpenBrowser(userCode: string, uri: string): void {
return undefined;
}
getAccountProviderMetadata(): Thenable<azdata.AccountProviderMetadata[]> {
return undefined;
}
getAccountsForProvider(providerId: string): Thenable<azdata.Account[]> {
return undefined;
}
getSecurityToken(account: azdata.Account, resource: azdata.AzureResource): Thenable<{}> {
return undefined;
}
removeAccount(accountKey: azdata.AccountKey): Thenable<boolean> {
return undefined;
}
refreshAccount(account: azdata.Account): Thenable<azdata.Account> {
return undefined;
}
openAccountListDialog(): Promise<any> {
return undefined;
}
registerProvider(providerMetadata: azdata.AccountProviderMetadata, provider: azdata.AccountProvider): void {
return undefined;
}
shutdown(): void {
return undefined;
}
unregisterProvider(providerMetadata: azdata.AccountProviderMetadata): void {
return undefined;
}
}
export class AccountProviderStub implements azdata.AccountProvider {
autoOAuthCancelled(): Thenable<void> {
return Promise.resolve();
}
clear(account: azdata.AccountKey): Thenable<void> {
return Promise.resolve();
}
getSecurityToken(account: azdata.Account, resource: azdata.AzureResource): Thenable<{}> {
return Promise.resolve({});
}
initialize(storedAccounts: azdata.Account[]): Thenable<azdata.Account[]> {
return Promise.resolve(storedAccounts);
}
prompt(): Thenable<azdata.Account> {
return Promise.resolve(undefined);
}
refresh(account: azdata.Account): Thenable<azdata.Account> {
return Promise.resolve(account);
}
}