CMS Extension - 2 (#4908)

* first set of changes to experiment the registration of cms related apis

* Adding cms service entry to workbench

* Adding basic functionality for add remove reg servers and group

* Returning relative path as part of RegServerResult as string

* initial extension

* cleaned building with connecting to server

* get list of registered servers

* progress with registered servers tree

* cms base node with server selection

* removed unused services

* replaced azure stuff with cms

* removed cmsResourceService

* list servers progress

* Removing the cms apis from core. Having mssql extension expose them for cms extension

* create server working fine

* initial expansion and nodes

* Propogating the backend name changes to apis

* initial cms extension working

* cached connection needs change in api

* connect without dashboard in proposed

* Fixing some missing sqlops references

* add registered server bug found

* added refresh context menu option

* added payload

* server description not disabled after reject connection

* added more context actions and action icons

* added empty resource and error when same name server is added

* fixed connection issues with cms and normal connections

* added initial tests

* added cms icons

* removed azure readme

* test script revert

* fix build tests

* added more cms tests

* fixed test script

* fixed silent error when expanding servers

* added more cms tests

* removed cmsdialog from api

* cms dialog without object

* fixed theming issues

* initial connection dialog done

* can make connections

* PM asks for strings and icons

* removed search

* removed unused code and fixed 1 test

* fix connection management tests

* changed icons

* format file

* fixed hygiene

* initial cr comments

* refactored cms connection dialog

* fixed bug when switching dialogs

* localized connection provider options

* fixed cms provider name

* code review comments

* localized options in cms and mssql

* localized more options
This commit is contained in:
Aditya Bist
2019-04-29 15:16:59 -07:00
committed by GitHub
parent cbf3ca726f
commit 39772c2dbe
60 changed files with 4595 additions and 156 deletions

View File

@@ -0,0 +1,38 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as should from 'should';
import * as vscode from 'vscode';
import 'mocha';
import { CmsResourceEmptyTreeNode } from '../../../cmsResource/tree/cmsResourceEmptyTreeNode';
import { CmsResourceItemType } from '../../../cmsResource/constants';
describe('CmsResourceEmptyTreeNode.info', function(): void {
it('Should be correct.', async function(): Promise<void> {
const label = 'Add Central Management Server...';
const treeNode = new CmsResourceEmptyTreeNode();
let children = await treeNode.getChildren();
should.equal(0, children.length);
should(treeNode.nodePathValue).equal('message_cmsTreeNode');
const treeItem = await treeNode.getTreeItem();
should(treeItem.label).equal(label);
should(treeItem.contextValue).equal(CmsResourceItemType.cmsEmptyNodeContainer);
should(treeItem.collapsibleState).equal(vscode.TreeItemCollapsibleState.None);
should(treeItem.command).not.undefined();
should(treeItem.command.title).equal(label);
should(treeItem.command.command).equal('cms.resource.registerCMSServer');
const nodeInfo = treeNode.getNodeInfo();
should(nodeInfo.isLeaf).true();
should(nodeInfo.label).equal(label);
should(nodeInfo.nodeType).equal(CmsResourceItemType.cmsEmptyNodeContainer);
should(nodeInfo.iconType).equal(CmsResourceItemType.cmsEmptyNodeContainer);
});
});

View File

@@ -0,0 +1,62 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as TypeMoq from 'typemoq';
import * as should from 'should';
import * as vscode from 'vscode';
import 'mocha';
import { AppContext } from '../../../appContext';
import { ApiWrapper } from '../../../apiWrapper';
import { CmsResourceItemType } from '../../../cmsResource/constants';
import { ServerGroupTreeNode } from '../../../cmsResource/tree/serverGroupTreeNode';
import { ICmsResourceTreeChangeHandler } from '../../../cmsResource/tree/treeChangeHandler';
import { cmsResource } from '../../../cmsResource/cms-resource';
// Mock services
let mockAppContext: AppContext;
let mockExtensionContext: TypeMoq.IMock<vscode.ExtensionContext>;
let mockApiWrapper: TypeMoq.IMock<ApiWrapper>;
let mockTreeChangeHandler: TypeMoq.IMock<ICmsResourceTreeChangeHandler>;
let mockResourceTreeDataProvider1: TypeMoq.IMock<cmsResource.ICmsResourceTreeDataProvider>;
let mockResourceProvider1: TypeMoq.IMock<cmsResource.ICmsResourceProvider>;
describe('ServerGroupTreeNode.info', function(): void {
beforeEach(() => {
mockExtensionContext = TypeMoq.Mock.ofType<vscode.ExtensionContext>();
mockApiWrapper = TypeMoq.Mock.ofType<ApiWrapper>();
mockAppContext = new AppContext(mockExtensionContext.object, mockApiWrapper.object);
mockTreeChangeHandler = TypeMoq.Mock.ofType<ICmsResourceTreeChangeHandler>();
mockResourceTreeDataProvider1 = TypeMoq.Mock.ofType<cmsResource.ICmsResourceTreeDataProvider>();
mockResourceTreeDataProvider1.setup((o) => o.getChildren()).returns(() => Promise.resolve([TypeMoq.Mock.ofType<cmsResource.ICmsResourceNode>().object]));
mockResourceTreeDataProvider1.setup((o) => o.getTreeItem(TypeMoq.It.isAny())).returns(() => Promise.resolve(TypeMoq.It.isAny()));
mockResourceProvider1 = TypeMoq.Mock.ofType<cmsResource.ICmsResourceProvider>();
mockResourceProvider1.setup((o) => o.providerId).returns(() => 'mockResourceProvider1');
mockResourceProvider1.setup((o) => o.getTreeDataProvider()).returns(() => mockResourceTreeDataProvider1.object);
});
it('Should be correct.', async function(): Promise<void> {
const label = 'test';
const treeNode = new ServerGroupTreeNode('test', 'test', 'test_path', 'test_ownerUri', mockAppContext, mockTreeChangeHandler.object, null);
should(treeNode.nodePathValue).equal('cms_serverGroup_test');
should(treeNode.relativePath).equal('test_path');
const treeItem = await treeNode.getTreeItem();
should(treeItem.label).equal(label);
should(treeItem.contextValue).equal(CmsResourceItemType.serverGroup);
should(treeItem.collapsibleState).equal(vscode.TreeItemCollapsibleState.Collapsed);
should(treeItem.command).undefined();
const nodeInfo = treeNode.getNodeInfo();
should(nodeInfo.isLeaf).false();
should(nodeInfo.label).equal(label);
should(nodeInfo.nodeType).equal(CmsResourceItemType.serverGroup);
});
});

View File

@@ -0,0 +1,62 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as TypeMoq from 'typemoq';
import * as should from 'should';
import * as vscode from 'vscode';
import 'mocha';
import { AppContext } from '../../../appContext';
import { ApiWrapper } from '../../../apiWrapper';
import { CmsResourceItemType } from '../../../cmsResource/constants';
import { RegisteredServerTreeNode } from '../../../cmsResource/tree/registeredServerTreeNode';
import { ICmsResourceTreeChangeHandler } from '../../../cmsResource/tree/treeChangeHandler';
import { cmsResource } from '../../../cmsResource/cms-resource';
// Mock services
let mockAppContext: AppContext;
let mockExtensionContext: TypeMoq.IMock<vscode.ExtensionContext>;
let mockApiWrapper: TypeMoq.IMock<ApiWrapper>;
let mockTreeChangeHandler: TypeMoq.IMock<ICmsResourceTreeChangeHandler>;
let mockResourceTreeDataProvider1: TypeMoq.IMock<cmsResource.ICmsResourceTreeDataProvider>;
let mockResourceProvider1: TypeMoq.IMock<cmsResource.ICmsResourceProvider>;
describe('RegisteredServerTreeNode.info', function(): void {
beforeEach(() => {
mockExtensionContext = TypeMoq.Mock.ofType<vscode.ExtensionContext>();
mockApiWrapper = TypeMoq.Mock.ofType<ApiWrapper>();
mockAppContext = new AppContext(mockExtensionContext.object, mockApiWrapper.object);
mockTreeChangeHandler = TypeMoq.Mock.ofType<ICmsResourceTreeChangeHandler>();
mockResourceTreeDataProvider1 = TypeMoq.Mock.ofType<cmsResource.ICmsResourceTreeDataProvider>();
mockResourceTreeDataProvider1.setup((o) => o.getChildren()).returns(() => Promise.resolve([TypeMoq.Mock.ofType<cmsResource.ICmsResourceNode>().object]));
mockResourceTreeDataProvider1.setup((o) => o.getTreeItem(TypeMoq.It.isAny())).returns(() => Promise.resolve(TypeMoq.It.isAny()));
mockResourceProvider1 = TypeMoq.Mock.ofType<cmsResource.ICmsResourceProvider>();
mockResourceProvider1.setup((o) => o.providerId).returns(() => 'mockResourceProvider1');
mockResourceProvider1.setup((o) => o.getTreeDataProvider()).returns(() => mockResourceTreeDataProvider1.object);
});
it('Should be correct.', async function(): Promise<void> {
const label = 'test';
const treeNode = new RegisteredServerTreeNode('test', 'test', 'test_server', 'test_path', 'test_ownerUri', mockAppContext, mockTreeChangeHandler.object, null);
should(treeNode.nodePathValue).equal('cms_registeredServer_test');
should(treeNode.relativePath).equal('test_path');
const treeItem = await treeNode.getTreeItem();
should(treeItem.label).equal(label);
should(treeItem.contextValue).equal(CmsResourceItemType.serverGroup);
should(treeItem.collapsibleState).equal(vscode.TreeItemCollapsibleState.Collapsed);
should(treeItem.command).undefined();
const nodeInfo = treeNode.getNodeInfo();
should(nodeInfo.isLeaf).false();
should(nodeInfo.label).equal(label);
should(nodeInfo.nodeType).equal(CmsResourceItemType.serverGroup);
});
});

View File

@@ -0,0 +1,62 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as TypeMoq from 'typemoq';
import * as should from 'should';
import * as vscode from 'vscode';
import 'mocha';
import { AppContext } from '../../../appContext';
import { ApiWrapper } from '../../../apiWrapper';
import { CmsResourceItemType } from '../../../cmsResource/constants';
import { ServerGroupTreeNode } from '../../../cmsResource/tree/serverGroupTreeNode';
import { ICmsResourceTreeChangeHandler } from '../../../cmsResource/tree/treeChangeHandler';
import { cmsResource } from '../../../cmsResource/cms-resource';
// Mock services
let mockAppContext: AppContext;
let mockExtensionContext: TypeMoq.IMock<vscode.ExtensionContext>;
let mockApiWrapper: TypeMoq.IMock<ApiWrapper>;
let mockTreeChangeHandler: TypeMoq.IMock<ICmsResourceTreeChangeHandler>;
let mockResourceTreeDataProvider1: TypeMoq.IMock<cmsResource.ICmsResourceTreeDataProvider>;
let mockResourceProvider1: TypeMoq.IMock<cmsResource.ICmsResourceProvider>;
describe('ServerGroupTreeNode.info', function(): void {
beforeEach(() => {
mockExtensionContext = TypeMoq.Mock.ofType<vscode.ExtensionContext>();
mockApiWrapper = TypeMoq.Mock.ofType<ApiWrapper>();
mockAppContext = new AppContext(mockExtensionContext.object, mockApiWrapper.object);
mockTreeChangeHandler = TypeMoq.Mock.ofType<ICmsResourceTreeChangeHandler>();
mockResourceTreeDataProvider1 = TypeMoq.Mock.ofType<cmsResource.ICmsResourceTreeDataProvider>();
mockResourceTreeDataProvider1.setup((o) => o.getChildren()).returns(() => Promise.resolve([TypeMoq.Mock.ofType<cmsResource.ICmsResourceNode>().object]));
mockResourceTreeDataProvider1.setup((o) => o.getTreeItem(TypeMoq.It.isAny())).returns(() => Promise.resolve(TypeMoq.It.isAny()));
mockResourceProvider1 = TypeMoq.Mock.ofType<cmsResource.ICmsResourceProvider>();
mockResourceProvider1.setup((o) => o.providerId).returns(() => 'mockResourceProvider1');
mockResourceProvider1.setup((o) => o.getTreeDataProvider()).returns(() => mockResourceTreeDataProvider1.object);
});
it('Should be correct.', async function(): Promise<void> {
const label = 'test';
const treeNode = new ServerGroupTreeNode('test', 'test', 'test_path', 'test_ownerUri', mockAppContext, mockTreeChangeHandler.object, null);
should(treeNode.nodePathValue).equal('cms_serverGroup_test');
should(treeNode.relativePath).equal('test_path');
const treeItem = await treeNode.getTreeItem();
should(treeItem.label).equal(label);
should(treeItem.contextValue).equal(CmsResourceItemType.serverGroup);
should(treeItem.collapsibleState).equal(vscode.TreeItemCollapsibleState.Collapsed);
should(treeItem.command).undefined();
const nodeInfo = treeNode.getNodeInfo();
should(nodeInfo.isLeaf).false();
should(nodeInfo.label).equal(label);
should(nodeInfo.nodeType).equal(CmsResourceItemType.serverGroup);
});
});

View File

@@ -0,0 +1,65 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as vscode from 'vscode';
import * as should from 'should';
import * as TypeMoq from 'typemoq';
import 'mocha';
import { AppContext } from '../../../appContext';
import { ApiWrapper } from '../../../apiWrapper';
import { CmsResourceTreeProvider } from '../../../cmsResource/tree/treeProvider';
import { CmsResourceMessageTreeNode } from '../../../cmsResource/messageTreeNode';
import { CmsResourceEmptyTreeNode } from '../../../cmsResource/tree/cmsResourceEmptyTreeNode';
import { CmsResourceTreeNode } from '../../../cmsResource/tree/cmsResourceTreeNode';
// Mock services
let mockAppContext: AppContext;
let mockExtensionContext: TypeMoq.IMock<vscode.ExtensionContext>;
let mockApiWrapper: TypeMoq.IMock<ApiWrapper>;
describe('CmsResourceTreeProvider.getChildren', function (): void {
beforeEach(() => {
mockExtensionContext = TypeMoq.Mock.ofType<vscode.ExtensionContext>();
mockApiWrapper = TypeMoq.Mock.ofType<ApiWrapper>();
mockAppContext = new AppContext(mockExtensionContext.object, mockApiWrapper.object);
});
it('Should not be initialized.', async function (): Promise<void> {
const treeProvider = new CmsResourceTreeProvider(mockAppContext);
should.notEqual(treeProvider.isSystemInitialized, true);
const children = await treeProvider.getChildren(undefined);
should.equal(children.length, 1);
should.equal(children[0].parent, undefined);
should.equal(children[0] instanceof CmsResourceMessageTreeNode, true);
});
it('Should not be loading after initialized.'), async function (): Promise<void> {
const treeProvider = new CmsResourceTreeProvider(mockAppContext);
treeProvider.isSystemInitialized = true;
should.equal(true, treeProvider.isSystemInitialized);
mockApiWrapper.setup(x => x.registeredCmsServers).returns(null);
const children = await treeProvider.getChildren(undefined);
should.equal(children[0] instanceof CmsResourceEmptyTreeNode, true);
};
it('Should show CMS nodes if there are cached servers'), async function (): Promise<void> {
const treeProvider = new CmsResourceTreeProvider(mockAppContext);
treeProvider.isSystemInitialized = true;
mockApiWrapper.setup(x => x.registeredCmsServers).returns(() => {
return [{
name: 'name',
description: 'description',
ownerUri: 'ownerUri',
connection: null
}];
});
const children = await treeProvider.getChildren(undefined);
should.equal(children[0] instanceof CmsResourceTreeNode, true);
};
});