mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-22 01:25:38 -05:00
Add datavirtualization extension (#21594)
* initial * cleanup * Add typings ref * fix compile * remove unused * add missing * another unused * Use newer vscodetestcover * newer dataprotocol * format * cleanup ignores * fix out path * fix entry point * more cleanup * Move into src folder * Handle service client log messages * remove unused
This commit is contained in:
28
extensions/datavirtualization/src/test/index.ts
Normal file
28
extensions/datavirtualization/src/test/index.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as IstanbulTestRunner from '@microsoft/vscodetestcover';
|
||||
let testRunner: any = IstanbulTestRunner;
|
||||
|
||||
// You can directly control Mocha options by uncommenting the following lines
|
||||
// See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options for more info
|
||||
testRunner.configure(
|
||||
// Mocha Options
|
||||
{
|
||||
ui: 'bdd', // the TDD UI is being used in extension.test.ts (suite, test, etc.)
|
||||
reporter: 'pm-mocha-jenkins-reporter',
|
||||
reporterOptions: {
|
||||
junit_report_name: 'Extension Tests',
|
||||
junit_report_path: __dirname + '/../../test-reports/extension_tests.xml',
|
||||
junit_report_stack: 1
|
||||
},
|
||||
useColors: true // colored output from test results
|
||||
},
|
||||
// Coverage configuration options
|
||||
{
|
||||
coverConfig: '../../coverconfig.json'
|
||||
});
|
||||
|
||||
module.exports = testRunner;
|
||||
47
extensions/datavirtualization/src/test/mockFileSource.ts
Normal file
47
extensions/datavirtualization/src/test/mockFileSource.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as fs from 'fs';
|
||||
|
||||
import { IFileSource, IFile } from '../fileSources';
|
||||
|
||||
export class MockFileSource implements IFileSource {
|
||||
filesToReturn: Map<string, IFile[]>;
|
||||
constructor() {
|
||||
this.filesToReturn = new Map<string, IFile[]>();
|
||||
}
|
||||
enumerateFiles(filePath: string): Promise<IFile[]> {
|
||||
let files: IFile[] = this.filesToReturn.get(filePath);
|
||||
return Promise.resolve(files);
|
||||
}
|
||||
|
||||
mkdir(dirName: string, remoteBasePath: string): Promise<void> {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
writeFile(localFile: IFile, remoteDir: string): Promise<string> {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
delete(filePath: string): Promise<void> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
readFile(filePath: string, maxBytes?: number): Promise<Buffer> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
readFileLines(path: string, maxLines: number): Promise<Buffer> {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
createReadStream(filePath: string): fs.ReadStream {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
exists(filePath: string): Promise<boolean> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
}
|
||||
1263
extensions/datavirtualization/src/test/stubs.ts
Normal file
1263
extensions/datavirtualization/src/test/stubs.ts
Normal file
File diff suppressed because it is too large
Load Diff
563
extensions/datavirtualization/src/test/tableFromFile.test.ts
Normal file
563
extensions/datavirtualization/src/test/tableFromFile.test.ts
Normal file
@@ -0,0 +1,563 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as TypeMoq from 'typemoq';
|
||||
import * as should from 'should';
|
||||
import * as path from 'path';
|
||||
import * as azdata from 'azdata';
|
||||
import { VirtualizeDataMockEnv, MockDataSourceService, MockInputBoxComponent, MockDropdownComponent, MockTextComponent, MockLoadingComponent, MockDeclarativeTableComponent, MockTableComponent, MockConnectionProfile, MockButtonComponent } from './stubs';
|
||||
import { TableFromFileWizard } from '../wizards/tableFromFile/tableFromFileWizard';
|
||||
import { ImportDataModel } from '../wizards/tableFromFile/api/models';
|
||||
import { FileConfigPage, FileConfigPageUiElements } from '../wizards/tableFromFile/pages/fileConfigPage';
|
||||
import { ProsePreviewPage, ProsePreviewPageUiElements } from '../wizards/tableFromFile/pages/prosePreviewPage';
|
||||
import { ModifyColumnsPage, ModifyColumnsPageUiElements } from '../wizards/tableFromFile/pages/modifyColumnsPage';
|
||||
import { SummaryPage, SummaryPageUiElements } from '../wizards/tableFromFile/pages/summaryPage';
|
||||
import { FileNode } from '../hdfsProvider';
|
||||
import { DataSourceInstance } from '../services/contracts';
|
||||
import { stripUrlPathSlashes } from '../utils';
|
||||
import { DataSourceType, delimitedTextFileType } from '../constants';
|
||||
|
||||
describe('Table From File Wizard:', function () {
|
||||
let env = new VirtualizeDataMockEnv();
|
||||
let appContext = env.getMockedAppContext();
|
||||
let service = new MockDataSourceService();
|
||||
|
||||
let mockWizard = TypeMoq.Mock.ofType(TableFromFileWizard, undefined, undefined, appContext, service);
|
||||
|
||||
describe('File Config Page Tests', function () {
|
||||
let mockPage = env.getMockedWizardPage();
|
||||
let model = <ImportDataModel>{};
|
||||
|
||||
let mockService = TypeMoq.Mock.ofType(MockDataSourceService);
|
||||
let page = new FileConfigPage(mockWizard.object, mockPage, model, undefined, mockService.object);
|
||||
let ui: FileConfigPageUiElements = {
|
||||
fileTextBox: new MockTextComponent(),
|
||||
serverTextBox: new MockTextComponent(),
|
||||
databaseDropdown: new MockDropdownComponent(),
|
||||
dataSourceDropdown: new MockDropdownComponent(),
|
||||
tableNameTextBox: new MockInputBoxComponent(),
|
||||
schemaDropdown: new MockDropdownComponent(),
|
||||
databaseLoader: new MockLoadingComponent(),
|
||||
dataSourceLoader: new MockLoadingComponent(),
|
||||
schemaLoader: new MockLoadingComponent(),
|
||||
fileFormatNameTextBox: new MockInputBoxComponent(),
|
||||
refreshButton: new MockButtonComponent()
|
||||
};
|
||||
page.setUi(ui);
|
||||
|
||||
model.allDatabases = ['TestDb'];
|
||||
model.serverConn = new MockConnectionProfile();
|
||||
|
||||
mockService.setup(s => s.createDataSourceWizardSession(TypeMoq.It.isAny())).returns(() => service.createDataSourceWizardSession(undefined));
|
||||
mockService.setup(s => s.getDatabaseInfo(TypeMoq.It.isAny())).returns(() => service.getDatabaseInfo(undefined));
|
||||
|
||||
let onPageEnterTest = async function (tableName: string) {
|
||||
(<any>page).pageSetupComplete = false;
|
||||
await page.onPageEnter();
|
||||
|
||||
should(ui.fileTextBox.value).be.equal(model.parentFile.filePath);
|
||||
should(ui.serverTextBox.value).be.equal(model.serverConn.serverName);
|
||||
should(ui.databaseDropdown.value).be.equal('TestDb');
|
||||
should(ui.dataSourceDropdown.value).be.equal('TestSource');
|
||||
should(ui.tableNameTextBox.value).be.equal(tableName);
|
||||
should(ui.schemaDropdown.value).be.equal('TestSchema');
|
||||
should(ui.fileFormatNameTextBox.value).be.equal(`FileFormat_${tableName}`);
|
||||
|
||||
should(ui.databaseLoader.loading).be.false();
|
||||
should(ui.databaseDropdown.enabled).be.true();
|
||||
|
||||
should(ui.dataSourceLoader.loading).be.false();
|
||||
should(ui.schemaLoader.loading).be.false();
|
||||
should(ui.refreshButton.enabled).be.true();
|
||||
|
||||
should(model.sessionId).be.equal('TestSessionId');
|
||||
should(model.allDatabases.length).be.equal(1);
|
||||
should(model.allDatabases[0]).be.equal('TestDb');
|
||||
should(model.fileType).be.equal('TXT');
|
||||
should(model.database).be.equal('TestDb');
|
||||
should(model.existingDataSource).be.equal('TestSource');
|
||||
should(model.table).be.equal(tableName);
|
||||
should(model.existingSchema).be.equal('TestSchema');
|
||||
should(model.newSchema).be.undefined();
|
||||
should(model.fileFormat).be.equal(`FileFormat_${tableName}`);
|
||||
};
|
||||
|
||||
let mockFileNode = TypeMoq.Mock.ofType(FileNode);
|
||||
model.proseParsingFile = mockFileNode.object;
|
||||
|
||||
it('OnPageEnter Test', async function () {
|
||||
// With file
|
||||
let tableName = 'TestFile';
|
||||
model.parentFile = {
|
||||
isFolder: false,
|
||||
filePath: path.join('BaseDir', 'AnotherDir', `${tableName}.csv`)
|
||||
};
|
||||
mockFileNode.setup(node => node.hdfsPath).returns(() => model.parentFile.filePath);
|
||||
await onPageEnterTest(tableName);
|
||||
|
||||
// With existing session
|
||||
model.sessionId = 'OldTestId';
|
||||
model.allDatabases = ['OldTestDb1', 'OldTestDb2'];
|
||||
mockService.setup(s => s.disposeWizardSession(TypeMoq.It.isAny())).returns(() => Promise.resolve(true));
|
||||
await onPageEnterTest(tableName);
|
||||
mockService.verify(s => s.disposeWizardSession(TypeMoq.It.isAny()), TypeMoq.Times.once());
|
||||
|
||||
// With folder
|
||||
tableName = 'CsvTest';
|
||||
model.parentFile = {
|
||||
isFolder: true,
|
||||
filePath: path.join('BaseDir', 'AnotherDir', tableName)
|
||||
};
|
||||
mockFileNode.setup(node => node.hdfsPath).returns(() => path.join(model.parentFile.filePath, 'TestFile.csv'));
|
||||
await onPageEnterTest(tableName);
|
||||
});
|
||||
|
||||
it('OnPageLeave Test', async function () {
|
||||
model.existingDataSource = undefined;
|
||||
(await page.onPageLeave(true)).should.be.false();
|
||||
|
||||
model.existingDataSource = '';
|
||||
(await page.onPageLeave(true)).should.be.false();
|
||||
|
||||
model.existingDataSource = 'TestSource';
|
||||
model.existingSchema = undefined;
|
||||
(await page.onPageLeave(true)).should.be.false();
|
||||
|
||||
model.existingSchema = '';
|
||||
(await page.onPageLeave(true)).should.be.false();
|
||||
|
||||
model.existingSchema = 'TestSchema';
|
||||
(await page.onPageLeave(true)).should.be.true();
|
||||
|
||||
model.existingSchema = undefined;
|
||||
model.newSchema = 'NewTestSchema';
|
||||
(await page.onPageLeave(true)).should.be.true();
|
||||
|
||||
model.fileFormat = 'TestExternalFileFormat';
|
||||
(await page.onPageLeave(true)).should.be.false();
|
||||
|
||||
model.fileFormat = 'NotAnExistingFileFormat';
|
||||
(await page.onPageLeave(true)).should.be.true();
|
||||
|
||||
// Existing table, but using new schema
|
||||
model.table = 'TestExternalTable';
|
||||
(await page.onPageLeave(true)).should.be.true();
|
||||
|
||||
model.existingSchema = 'TestSchema';
|
||||
model.newSchema = undefined;
|
||||
model.table = 'TestExternalTable';
|
||||
(await page.onPageLeave(true)).should.be.false();
|
||||
|
||||
model.table = 'NotAnExistingFileTable';
|
||||
(await page.onPageLeave(true)).should.be.true();
|
||||
|
||||
ui.databaseLoader.loading = true;
|
||||
(await page.onPageLeave(false)).should.be.false();
|
||||
|
||||
ui.databaseLoader.loading = false;
|
||||
ui.dataSourceLoader.loading = true;
|
||||
(await page.onPageLeave(false)).should.be.false();
|
||||
|
||||
ui.dataSourceLoader.loading = false;
|
||||
ui.schemaLoader.loading = true;
|
||||
(await page.onPageLeave(false)).should.be.false();
|
||||
|
||||
ui.schemaLoader.loading = false;
|
||||
(await page.onPageLeave(false)).should.be.true();
|
||||
});
|
||||
|
||||
it('Data Sources Test', async function () {
|
||||
let dbInfo = await service.getDatabaseInfo(undefined);
|
||||
let sessionInfo = await service.createDataSourceWizardSession(undefined);
|
||||
model.parentFile = {
|
||||
isFolder: false,
|
||||
filePath: path.join('BaseDir', 'AnotherDir', 'TestFile.csv')
|
||||
};
|
||||
let setupMocks = () => {
|
||||
mockService.setup(s => s.getDatabaseInfo(TypeMoq.It.isAny())).returns(() => Promise.resolve(dbInfo));
|
||||
mockService.setup(s => s.createDataSourceWizardSession(TypeMoq.It.isAny())).returns(() => Promise.resolve(sessionInfo));
|
||||
mockFileNode.setup(node => node.hdfsPath).returns(() => model.parentFile.filePath);
|
||||
};
|
||||
let testDataSource = (productVersion: string, dataSourceName: string, dataSourceLocation: string) => {
|
||||
should(model.versionInfo.productLevel).be.equal(productVersion);
|
||||
should(model.existingDataSource).be.undefined();
|
||||
should(model.newDataSource).not.be.undefined();
|
||||
should(model.newDataSource.name).be.equal(dataSourceName);
|
||||
should(model.newDataSource.location).be.equal(dataSourceLocation);
|
||||
should(model.newDataSource.authenticationType).be.undefined();
|
||||
should(model.newDataSource.credentialName).be.undefined();
|
||||
should(model.newDataSource.username).be.undefined();
|
||||
};
|
||||
let testNewCtp24Source = (dataSourceName: string = 'SqlStoragePool') => {
|
||||
testDataSource('CTP2.4', dataSourceName, 'sqlhdfs://service-master-pool:50070/');
|
||||
};
|
||||
let testNewCtp25Source = (dataSourceName: string = 'SqlStoragePool') => {
|
||||
testDataSource('CTP2.5', dataSourceName, 'sqlhdfs://nmnode-0-svc:50070/');
|
||||
};
|
||||
let testNewCtp3Source = (dataSourceName: string = 'SqlStoragePool') => {
|
||||
testDataSource('CTP3.0', dataSourceName, 'sqlhdfs://controller-svc:8080/default');
|
||||
};
|
||||
|
||||
setupMocks();
|
||||
await (<any>page).refreshPage();
|
||||
should(model.versionInfo.productLevel).be.equal('CTP3.1');
|
||||
should(model.existingDataSource).be.equal('TestSource');
|
||||
should(model.newDataSource).be.undefined();
|
||||
|
||||
sessionInfo.productLevel = 'CTP2.4';
|
||||
setupMocks();
|
||||
await (<any>page).refreshPage();
|
||||
testNewCtp24Source();
|
||||
|
||||
sessionInfo.productLevel = 'CTP2.5';
|
||||
setupMocks();
|
||||
await (<any>page).refreshPage();
|
||||
testNewCtp25Source();
|
||||
|
||||
dbInfo.databaseInfo.externalDataSources = [];
|
||||
sessionInfo.productLevel = 'CTP3.0';
|
||||
setupMocks();
|
||||
await (<any>page).refreshPage();
|
||||
testNewCtp3Source();
|
||||
|
||||
dbInfo.databaseInfo.externalDataSources = [<DataSourceInstance>{
|
||||
name: 'RandomSource',
|
||||
location: 'sqlhdfs://NotARealSource:50070/'
|
||||
}, <DataSourceInstance>{
|
||||
name: 'SqlStoragePool',
|
||||
location: 'sqlhdfs://NotARealSource:50070/'
|
||||
}, <DataSourceInstance>{
|
||||
name: 'SqlStoragePool1',
|
||||
location: 'sqlhdfs://NotARealSource1:8080/default'
|
||||
}, <DataSourceInstance>{
|
||||
name: 'SqlStoragePool2',
|
||||
location: 'sqlhdfs://NotARealSource2:8080/default'
|
||||
}];
|
||||
setupMocks();
|
||||
await (<any>page).refreshPage();
|
||||
testNewCtp3Source('SqlStoragePool3');
|
||||
|
||||
sessionInfo.productLevel = 'CTP2.4';
|
||||
setupMocks();
|
||||
await (<any>page).refreshPage();
|
||||
testNewCtp24Source('SqlStoragePool3');
|
||||
|
||||
sessionInfo.serverMajorVersion = 1000;
|
||||
sessionInfo.productLevel = 'NotARealCtpVersion';
|
||||
setupMocks();
|
||||
await (<any>page).refreshPage();
|
||||
// Default to the latest version's data source location
|
||||
testDataSource(sessionInfo.productLevel, 'SqlStoragePool3', 'sqlhdfs://controller-svc/default');
|
||||
});
|
||||
|
||||
it('Refresh Test', async function () {
|
||||
let dbInfo = await service.getDatabaseInfo(undefined);
|
||||
let sessionInfo = await service.createDataSourceWizardSession(undefined);
|
||||
model.parentFile = {
|
||||
isFolder: false,
|
||||
filePath: path.join('BaseDir', 'AnotherDir', 'TestFile.csv')
|
||||
};
|
||||
let setupMocks = () => {
|
||||
mockService.setup(s => s.getDatabaseInfo(TypeMoq.It.isAny())).returns(() => Promise.resolve(dbInfo));
|
||||
mockService.setup(s => s.createDataSourceWizardSession(TypeMoq.It.isAny())).returns(() => Promise.resolve(sessionInfo));
|
||||
mockFileNode.setup(node => node.hdfsPath).returns(() => model.parentFile.filePath);
|
||||
};
|
||||
setupMocks();
|
||||
|
||||
let testStr = 'RefreshTestStr';
|
||||
await (<any>page).refreshPage();
|
||||
should(model.database).not.be.equal(testStr);
|
||||
should(model.existingDataSource).not.be.equal(testStr);
|
||||
should(model.table).not.be.equal(testStr);
|
||||
should(model.existingSchema).not.be.equal(testStr);
|
||||
should(model.fileFormat).not.be.equal(`FileFormat_${testStr}`);
|
||||
|
||||
sessionInfo.databaseList = [{ name: testStr, hasMasterKey: false }];
|
||||
dbInfo.databaseInfo.externalDataSources[0].name = testStr;
|
||||
model.parentFile = {
|
||||
isFolder: false,
|
||||
filePath: path.join('BaseDir', 'AnotherDir', `${testStr}.csv`)
|
||||
};
|
||||
dbInfo.databaseInfo.schemaList = [testStr];
|
||||
setupMocks();
|
||||
|
||||
await (<any>page).refreshPage();
|
||||
should(model.database).be.equal(testStr);
|
||||
should(model.existingDataSource).be.equal(testStr);
|
||||
should(model.table).be.equal(testStr);
|
||||
should(model.existingSchema).be.equal(testStr);
|
||||
should(model.fileFormat).be.equal(`FileFormat_${testStr}`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Preview Page Tests', function () {
|
||||
let mockPage = env.getMockedWizardPage();
|
||||
let fileNodeMock = TypeMoq.Mock.ofType(FileNode);
|
||||
let model = <ImportDataModel>{};
|
||||
model.proseParsingFile = fileNodeMock.object;
|
||||
|
||||
fileNodeMock.setup(f => f.getFileLinesAsString(TypeMoq.It.isAny())).returns(() => Promise.resolve(service.proseTestData));
|
||||
|
||||
let page = new ProsePreviewPage(mockWizard.object, mockPage, model, undefined, service);
|
||||
let ui: ProsePreviewPageUiElements = {
|
||||
table: new MockTableComponent(),
|
||||
loading: new MockLoadingComponent()
|
||||
};
|
||||
page.setUi(ui);
|
||||
|
||||
it('OnPageEnter Test', async function () {
|
||||
await page.onPageEnter();
|
||||
|
||||
should(ui.loading.loading).be.false();
|
||||
|
||||
should(model.columnDelimiter).be.equal(',');
|
||||
should(model.firstRow).be.equal(2);
|
||||
should(model.quoteCharacter).be.equal('"');
|
||||
|
||||
should(ui.table.columns.length).be.equal(2);
|
||||
should(ui.table.columns[0]).be.equal('TestId');
|
||||
should(ui.table.columns[1]).be.equal('TestStr');
|
||||
|
||||
should(ui.table.data.length).be.equal(1);
|
||||
should(ui.table.data[0].length).be.equal(2);
|
||||
should(ui.table.data[0][0]).be.equal('1');
|
||||
should(ui.table.data[0][1]).be.equal('abc');
|
||||
});
|
||||
|
||||
it('OnPageEnter Error Test', async function () {
|
||||
let errorMockWizard = TypeMoq.Mock.ofType(TableFromFileWizard, undefined, undefined, appContext, service);
|
||||
let errorFileNodeMock = TypeMoq.Mock.ofType(FileNode);
|
||||
let errorModel = <ImportDataModel>{};
|
||||
errorModel.proseParsingFile = errorFileNodeMock.object;
|
||||
|
||||
let errorMsg = 'Expected Test Error';
|
||||
errorFileNodeMock.setup(f => f.getFileLinesAsString(TypeMoq.It.isAny())).throws(new Error(errorMsg));
|
||||
errorMockWizard.setup(w => w.showErrorMessage(TypeMoq.It.isValue(errorMsg)));
|
||||
|
||||
let errorPage = new ProsePreviewPage(errorMockWizard.object, mockPage, errorModel, undefined, service);
|
||||
errorMockWizard.verify((w => w.showErrorMessage(TypeMoq.It.isValue(errorMsg))), TypeMoq.Times.never());
|
||||
|
||||
errorPage.setUi({
|
||||
table: new MockTableComponent(),
|
||||
loading: new MockLoadingComponent()
|
||||
});
|
||||
await errorPage.onPageEnter();
|
||||
|
||||
errorMockWizard.verify((w => w.showErrorMessage(TypeMoq.It.isValue(errorMsg))), TypeMoq.Times.once());
|
||||
});
|
||||
|
||||
it('OnPageLeave Test', async function () {
|
||||
(await page.onPageLeave(true)).should.be.true();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Modify Columns Page Tests', function () {
|
||||
let mockPage = env.getMockedWizardPage();
|
||||
let model = <ImportDataModel>{};
|
||||
|
||||
let page = new ModifyColumnsPage(mockWizard.object, mockPage, model, undefined, service);
|
||||
let ui: ModifyColumnsPageUiElements = {
|
||||
table: new MockDeclarativeTableComponent,
|
||||
loading: new MockLoadingComponent,
|
||||
text: new MockTextComponent()
|
||||
};
|
||||
page.setUi(ui);
|
||||
|
||||
model.proseColumns = [{
|
||||
columnName: 'TestId',
|
||||
dataType: 'int',
|
||||
collationName: undefined,
|
||||
isNullable: false
|
||||
}, {
|
||||
columnName: 'TestStr',
|
||||
dataType: 'varchar(50)',
|
||||
collationName: undefined,
|
||||
isNullable: true
|
||||
}];
|
||||
|
||||
it('OnPageEnter Test', async function () {
|
||||
await page.onPageEnter();
|
||||
|
||||
should(ui.loading.loading).be.false();
|
||||
|
||||
should(ui.table.data.length).be.equal(2);
|
||||
should(ui.table.data[0][0]).be.equal('TestId');
|
||||
should(ui.table.data[0][1]).be.equal('int');
|
||||
should(ui.table.data[0][2]).be.equal(false);
|
||||
should(ui.table.data[1][0]).be.equal('TestStr');
|
||||
should(ui.table.data[1][1]).be.equal('varchar(50)');
|
||||
should(ui.table.data[1][2]).be.equal(true);
|
||||
});
|
||||
|
||||
it('OnPageLeave Test', async function () {
|
||||
(await page.onPageLeave(true)).should.be.true();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Summary Page Tests', function () {
|
||||
let mockPage = env.getMockedWizardPage();
|
||||
let model = <ImportDataModel>{};
|
||||
|
||||
let page = new SummaryPage(mockWizard.object, mockPage, model, undefined, service);
|
||||
let ui: SummaryPageUiElements = {
|
||||
table: new MockTableComponent()
|
||||
};
|
||||
page.setUi(ui);
|
||||
|
||||
it('OnPageEnter Test', async function () {
|
||||
model.serverConn = <azdata.connection.ConnectionProfile>{
|
||||
providerId: undefined,
|
||||
connectionId: undefined,
|
||||
serverName: 'TestServer'
|
||||
};
|
||||
model.database = 'TestDb';
|
||||
model.table = 'TestTable';
|
||||
model.existingSchema = 'dbo';
|
||||
model.fileFormat = 'TestFileFormat';
|
||||
model.parentFile = {
|
||||
isFolder: false,
|
||||
filePath: path.join('BaseDir', 'AnotherDir', 'TestTable.csv')
|
||||
};
|
||||
|
||||
mockWizard.setup(w => w.changeDoneButtonLabel(TypeMoq.It.isValue('Virtualize Data')));
|
||||
mockWizard.setup(w => w.setGenerateScriptVisibility(TypeMoq.It.isValue(true)));
|
||||
|
||||
await page.onPageEnter();
|
||||
|
||||
mockWizard.verify(w => w.changeDoneButtonLabel(TypeMoq.It.isValue('Virtualize Data')), TypeMoq.Times.once());
|
||||
mockWizard.verify(w => w.setGenerateScriptVisibility(TypeMoq.It.isValue(true)), TypeMoq.Times.once());
|
||||
|
||||
should(ui.table.data[0][1]).be.equal(model.serverConn.serverName);
|
||||
should(ui.table.data[1][1]).be.equal(model.database);
|
||||
should(ui.table.data[2][1]).be.equal(model.table);
|
||||
should(ui.table.data[3][1]).be.equal(model.existingSchema);
|
||||
should(ui.table.data[4][1]).be.equal(model.fileFormat);
|
||||
should(ui.table.data[5][1]).be.equal(model.parentFile.filePath);
|
||||
});
|
||||
|
||||
it('OnPageLeave Test', async function () {
|
||||
mockWizard.setup(w => w.changeDoneButtonLabel(TypeMoq.It.isValue('Next')));
|
||||
mockWizard.setup(w => w.setGenerateScriptVisibility(TypeMoq.It.isValue(false)));
|
||||
|
||||
(await page.onPageLeave(true)).should.be.true();
|
||||
|
||||
mockWizard.verify(w => w.changeDoneButtonLabel(TypeMoq.It.isValue('Next')), TypeMoq.Times.once());
|
||||
mockWizard.verify(w => w.setGenerateScriptVisibility(TypeMoq.It.isValue(false)), TypeMoq.Times.once());
|
||||
});
|
||||
});
|
||||
|
||||
describe('Utilities Tests', function () {
|
||||
it('Generate Input From Model Test', function () {
|
||||
let input = TableFromFileWizard.generateInputFromModel(undefined);
|
||||
should(input).be.undefined();
|
||||
|
||||
let model = <ImportDataModel>{
|
||||
sessionId: 'TestId',
|
||||
columnDelimiter: ',',
|
||||
database: 'TestDatabase',
|
||||
fileFormat: 'FileFormat_TestTable',
|
||||
firstRow: 1,
|
||||
newDataSource: {
|
||||
name: 'SqlStoragePool',
|
||||
location: 'sqlhdfs://controller-svc:8080/default/',
|
||||
authenticationType: undefined,
|
||||
username: undefined,
|
||||
credentialName: undefined
|
||||
},
|
||||
newSchema: 'TestSchema',
|
||||
parentFile: {
|
||||
filePath: 'test/TestTable.csv',
|
||||
isFolder: false
|
||||
},
|
||||
proseColumns: [{
|
||||
collationName: undefined,
|
||||
columnName: 'column1',
|
||||
dataType: 'nvarchar(50)',
|
||||
isNullable: true,
|
||||
}],
|
||||
quoteCharacter: '\"',
|
||||
table: 'TestTable'
|
||||
};
|
||||
|
||||
input = TableFromFileWizard.generateInputFromModel(model);
|
||||
should(input).not.be.undefined();
|
||||
should(input.sessionId).be.equal(model.sessionId);
|
||||
should(input.destDatabaseName).be.equal(model.database);
|
||||
should(input.sourceServerType).be.equal(DataSourceType.SqlHDFS);
|
||||
|
||||
should(input.externalTableInfoList).not.be.undefined();
|
||||
should(input.externalTableInfoList.length).be.equal(1);
|
||||
|
||||
let tableInfo = input.externalTableInfoList[0];
|
||||
should(tableInfo.externalTableName).not.be.undefined();
|
||||
should(tableInfo.externalTableName.length).be.equal(2);
|
||||
should(tableInfo.externalTableName[0]).be.equal(model.newSchema);
|
||||
should(tableInfo.externalTableName[1]).be.equal(model.table);
|
||||
|
||||
should(tableInfo.columnDefinitionList).not.be.undefined();
|
||||
should(tableInfo.columnDefinitionList.length).be.equal(1);
|
||||
let columnInfo = tableInfo.columnDefinitionList[0];
|
||||
let proseInfo = model.proseColumns[0];
|
||||
should(columnInfo.collationName).be.equal(proseInfo.collationName);
|
||||
should(columnInfo.columnName).be.equal(proseInfo.columnName);
|
||||
should(columnInfo.dataType).be.equal(proseInfo.dataType);
|
||||
should(columnInfo.isNullable).be.equal(proseInfo.isNullable);
|
||||
|
||||
should(tableInfo.sourceTableLocation).not.be.undefined();
|
||||
should(tableInfo.sourceTableLocation.length).be.equal(1);
|
||||
should(tableInfo.sourceTableLocation[0]).be.equal(model.parentFile.filePath);
|
||||
|
||||
should(tableInfo.fileFormat).not.be.undefined();
|
||||
should(tableInfo.fileFormat.formatName).be.equal(model.fileFormat);
|
||||
should(tableInfo.fileFormat.formatType).be.equal(delimitedTextFileType);
|
||||
should(tableInfo.fileFormat.fieldTerminator).be.equal(model.columnDelimiter);
|
||||
should(tableInfo.fileFormat.stringDelimiter).be.equal(model.quoteCharacter);
|
||||
should(tableInfo.fileFormat.firstRow).be.equal(model.firstRow);
|
||||
|
||||
should(input.newDataSourceName).be.equal(model.newDataSource.name);
|
||||
should(input.sourceServerName).be.equal('controller-svc:8080/default/');
|
||||
should(input.existingDataSourceName).be.undefined();
|
||||
|
||||
should(input.newSchemas).not.be.undefined();
|
||||
should(input.newSchemas.length).be.equal(1);
|
||||
should(input.newSchemas[0]).be.equal(model.newSchema);
|
||||
});
|
||||
|
||||
it('Remove URL Path Slashes Test', function () {
|
||||
let testPath = undefined;
|
||||
should(stripUrlPathSlashes(testPath)).be.equal('');
|
||||
|
||||
testPath = '';
|
||||
should(stripUrlPathSlashes(testPath)).be.equal('');
|
||||
|
||||
testPath = '//////////';
|
||||
should(stripUrlPathSlashes(testPath)).be.equal('');
|
||||
|
||||
testPath = 'a/';
|
||||
should(stripUrlPathSlashes(testPath)).be.equal('a');
|
||||
|
||||
testPath = 'testPath';
|
||||
should(stripUrlPathSlashes(testPath)).be.equal('testPath');
|
||||
|
||||
testPath = '/testPath';
|
||||
should(stripUrlPathSlashes(testPath)).be.equal('testPath');
|
||||
|
||||
testPath = '/testPath/testPath2';
|
||||
should(stripUrlPathSlashes(testPath)).be.equal('testPath/testPath2');
|
||||
|
||||
testPath = 'testPath/testPath2';
|
||||
should(stripUrlPathSlashes(testPath)).be.equal('testPath/testPath2');
|
||||
|
||||
testPath = 'testPath/testPath2///';
|
||||
should(stripUrlPathSlashes(testPath)).be.equal('testPath/testPath2');
|
||||
|
||||
testPath = '/testPath/testPath2///';
|
||||
should(stripUrlPathSlashes(testPath)).be.equal('testPath/testPath2');
|
||||
|
||||
testPath = '/testPath/testPath2/testPath3/////';
|
||||
should(stripUrlPathSlashes(testPath)).be.equal('testPath/testPath2/testPath3');
|
||||
});
|
||||
});
|
||||
});
|
||||
19
extensions/datavirtualization/src/test/testUtils.ts
Normal file
19
extensions/datavirtualization/src/test/testUtils.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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';
|
||||
|
||||
export async function assertThrowsAsync(fn: Function, msg: string): Promise<void> {
|
||||
let f = () => {
|
||||
// Empty
|
||||
};
|
||||
try {
|
||||
await fn();
|
||||
} catch (e) {
|
||||
f = () => { throw e; };
|
||||
} finally {
|
||||
assert.throws(f, undefined, msg);
|
||||
}
|
||||
}
|
||||
375
extensions/datavirtualization/src/test/virtualizeData.test.ts
Normal file
375
extensions/datavirtualization/src/test/virtualizeData.test.ts
Normal file
@@ -0,0 +1,375 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 * as azdata from 'azdata';
|
||||
import * as should from 'should';
|
||||
|
||||
import { VirtualizeDataModel } from '../wizards/virtualizeData/virtualizeDataModel';
|
||||
import { CheckboxTreeNode } from '../wizards/virtualizeData/virtualizeDataTree';
|
||||
import {
|
||||
MockInputBoxComponent, MockWizard, VirtualizeDataMockEnv, MockTextComponent,
|
||||
MockDeclarativeTableComponent, MockDataSourceService, MockConnectionProfile
|
||||
} from './stubs';
|
||||
import { CreateMasterKeyPage, MasterKeyUiElements } from '../wizards/virtualizeData/createMasterKeyPage';
|
||||
import { SummaryPage, SummaryUiElements } from '../wizards/virtualizeData/summaryPage';
|
||||
import { VDIManager } from '../wizards/virtualizeData/virtualizeDataInputManager';
|
||||
import { ColumnDefinition } from '../services/contracts';
|
||||
|
||||
describe('Wizard Setup Tests', function (): void {
|
||||
it('Should set model fields after creating session.', async () => {
|
||||
let mockWizard = new MockWizard();
|
||||
mockWizard.message = undefined;
|
||||
let vdiManager = (new VirtualizeDataMockEnv()).getMockedVDIManager();
|
||||
let model = new VirtualizeDataModel(new MockConnectionProfile(), new MockDataSourceService(), new MockWizard(), vdiManager);
|
||||
await model.createSession();
|
||||
|
||||
should(model.sessionId).be.eql('TestSessionId');
|
||||
should(model.destDatabaseList.length).be.greaterThan(0);
|
||||
should(model.destDatabaseList).containEql({ name: 'TestDb', hasMasterKey: false });
|
||||
});
|
||||
});
|
||||
|
||||
describe('MasterKeyPage Tests', function (): void {
|
||||
it('[MasterKeyPage Test] MasterKeyPage should create a wizard page and register content during the initialization.', async () => {
|
||||
let env = new VirtualizeDataMockEnv();
|
||||
let mockDataModel = env.getMockedVirtualizeDataModel();
|
||||
let vdiManager = env.getMockedVDIManager();
|
||||
let appContext = env.getMockedAppContext();
|
||||
let apiWrapper = env.getApiWrapperMock();
|
||||
let wizardPage = env.getWizardPageMock();
|
||||
|
||||
let masterKeyPage = new CreateMasterKeyPage(mockDataModel, vdiManager, appContext);
|
||||
apiWrapper.verifyAll();
|
||||
wizardPage.verifyAll();
|
||||
should(masterKeyPage).not.be.null();
|
||||
});
|
||||
|
||||
it('[MasterKeyPage Test] MasterKeyPage should get data from VirtualizeDataModel when the page is opened.', async () => {
|
||||
let uiElement = new MasterKeyUiElements();
|
||||
uiElement.masterKeyPasswordInput = new MockInputBoxComponent();
|
||||
uiElement.masterKeyPasswordConfirmInput = new MockInputBoxComponent();
|
||||
|
||||
let env = new VirtualizeDataMockEnv();
|
||||
env.getMockEnvConstants().destDbMasterKeyPwd = undefined;
|
||||
|
||||
let dataModel = env.getMockedVirtualizeDataModel();
|
||||
let dataModelMock = env.getVirtualizeDataModelMock();
|
||||
let vdiManager = env.getMockedVDIManager();
|
||||
let appContext = env.getMockedAppContext();
|
||||
|
||||
let masterKeyPage = new CreateMasterKeyPage(dataModel, vdiManager, appContext);
|
||||
masterKeyPage.setUi(uiElement);
|
||||
await masterKeyPage.updatePage();
|
||||
|
||||
dataModelMock.verify(x => x.hasMasterKey(), TypeMoq.Times.once());
|
||||
should(uiElement.masterKeyPasswordInput.enabled).be.false;
|
||||
should(uiElement.masterKeyPasswordConfirmInput.enabled).be.false;
|
||||
|
||||
env.getMockEnvConstants().destDbMasterKeyPwd = 'Chanel$4700'; // [SuppressMessage("Microsoft.Security", "CS001:SecretInline", Justification="Unit test - not actually used to authenticate")]
|
||||
await masterKeyPage.updatePage();
|
||||
|
||||
should(uiElement.masterKeyPasswordInput.enabled).be.true;
|
||||
should(uiElement.masterKeyPasswordConfirmInput.enabled).be.true;
|
||||
});
|
||||
|
||||
it('[MasterKeyPage Test] MasterKeyPage should fail validation if page content is invalid.', async () => {
|
||||
let uiElement = new MasterKeyUiElements();
|
||||
uiElement.masterKeyPasswordInput = new MockInputBoxComponent();
|
||||
uiElement.masterKeyPasswordConfirmInput = new MockInputBoxComponent();
|
||||
|
||||
let env = new VirtualizeDataMockEnv();
|
||||
let dataModel = env.getMockedVirtualizeDataModel();
|
||||
let dataModelMock = env.getVirtualizeDataModelMock();
|
||||
let vdiManager = env.getMockedVDIManager();
|
||||
let vdiManagerMock = env.getVDIManagerMock();
|
||||
let appContext = env.getMockedAppContext();
|
||||
|
||||
let masterKeyPage = new CreateMasterKeyPage(dataModel, vdiManager, appContext);
|
||||
masterKeyPage.setUi(uiElement);
|
||||
|
||||
uiElement.masterKeyPasswordInput.value = 'test123';
|
||||
uiElement.masterKeyPasswordConfirmInput.value = '123test';
|
||||
|
||||
should(await masterKeyPage.validate()).be.false;
|
||||
dataModelMock.verify(x => x.showWizardError(TypeMoq.It.isAny()), TypeMoq.Times.once());
|
||||
dataModelMock.verify(x => x.validateInput(TypeMoq.It.isAny()), TypeMoq.Times.never());
|
||||
vdiManagerMock.verify(x => x.getVirtualizeDataInput(TypeMoq.It.isAny()), TypeMoq.Times.never());
|
||||
});
|
||||
|
||||
it('[MasterKeyPage Test] MasterKeyPage should pass validation if page content is valid.', async () => {
|
||||
let uiElement = new MasterKeyUiElements();
|
||||
uiElement.masterKeyPasswordInput = new MockInputBoxComponent();
|
||||
uiElement.masterKeyPasswordConfirmInput = new MockInputBoxComponent();
|
||||
|
||||
let env = new VirtualizeDataMockEnv();
|
||||
let dataModel = env.getMockedVirtualizeDataModel();
|
||||
let dataModelMock = env.getVirtualizeDataModelMock();
|
||||
let vdiManager = env.getMockedVDIManager();
|
||||
let vdiManagerMock = env.getVDIManagerMock();
|
||||
let appContext = env.getMockedAppContext();
|
||||
|
||||
let masterKeyPage = new CreateMasterKeyPage(dataModel, vdiManager, appContext);
|
||||
masterKeyPage.setUi(uiElement);
|
||||
|
||||
uiElement.masterKeyPasswordInput.value = 'test123';
|
||||
uiElement.masterKeyPasswordConfirmInput.value = 'test123';
|
||||
should(await masterKeyPage.validate()).be.true;
|
||||
|
||||
dataModelMock.verify(x => x.showWizardError(TypeMoq.It.isAny()), TypeMoq.Times.never());
|
||||
dataModelMock.verify(x => x.validateInput(TypeMoq.It.isAny()), TypeMoq.Times.once());
|
||||
vdiManagerMock.verify(x => x.getVirtualizeDataInput(TypeMoq.It.isAny()), TypeMoq.Times.once());
|
||||
});
|
||||
});
|
||||
|
||||
describe('ObjectMappingPage Tests', function (): void {
|
||||
it('[ObjectMappingPage Test] ObjectMappingPage should create a wizard page and register content during the initialization.', async () => {
|
||||
let env = new VirtualizeDataMockEnv();
|
||||
let objectMappingPage = env.getMockedObjectMappingPage();
|
||||
let apiWrapper = env.getApiWrapperMock();
|
||||
let wizardPage = env.getWizardPageMock();
|
||||
apiWrapper.verify(x => x.createWizardPage(TypeMoq.It.isAnyString()), TypeMoq.Times.once());
|
||||
wizardPage.verify(x => x.registerContent(TypeMoq.It.isAny()), TypeMoq.Times.once());
|
||||
should(objectMappingPage).not.be.undefined();
|
||||
});
|
||||
|
||||
it('[ObjectMappingPage Test] ObjectMappingPage should get data from VirtualizeDataModel when the page is opened.', async () => {
|
||||
let env = new VirtualizeDataMockEnv();
|
||||
let objectMappingPage = env.getMockedObjectMappingPage();
|
||||
await objectMappingPage.updatePage();
|
||||
let omPage = <any>objectMappingPage;
|
||||
let rootNode = omPage._treeRootNode;
|
||||
should(rootNode).not.be.undefined();
|
||||
let databaseNodes = await rootNode.getChildren();
|
||||
should(databaseNodes).not.be.undefined();
|
||||
should(databaseNodes.length > 0).be.true();
|
||||
|
||||
let dataModelMock = env.getVirtualizeDataModelMock();
|
||||
dataModelMock.verify(x => x.getSourceDatabases(TypeMoq.It.isAny()), TypeMoq.Times.atLeastOnce());
|
||||
});
|
||||
|
||||
it('[ObjectMappingPage Test] Database node should generate children, and mark them as checked when database node is checked before generating children.', async () => {
|
||||
let env = new VirtualizeDataMockEnv();
|
||||
let objectMappingPage = env.getMockedObjectMappingPage();
|
||||
await objectMappingPage.updatePage();
|
||||
let omPage = <any>objectMappingPage;
|
||||
let rootNode: CheckboxTreeNode = omPage._treeRootNode as CheckboxTreeNode;
|
||||
let databaseNodes: CheckboxTreeNode[] = await rootNode.getChildren();
|
||||
should(databaseNodes).not.be.undefined();
|
||||
should(databaseNodes.length > 0).be.true();
|
||||
|
||||
should(databaseNodes[0].hasChildren).be.false();
|
||||
await omPage.actionOnNodeCheckStatusChanged(databaseNodes[0], true);
|
||||
should(databaseNodes[0].hasChildren).be.true();
|
||||
let children: CheckboxTreeNode[] = await databaseNodes[0].getChildren();
|
||||
let tableFolderNode: CheckboxTreeNode = children[0];
|
||||
let viewFolderNode: CheckboxTreeNode = children[1];
|
||||
should(tableFolderNode.checked).be.true();
|
||||
should(viewFolderNode.checked).be.true();
|
||||
should(tableFolderNode.hasChildren).be.true();
|
||||
should(viewFolderNode.hasChildren).be.true();
|
||||
let tableNodes: CheckboxTreeNode[] = await tableFolderNode.getChildren();
|
||||
tableNodes.forEach(tableNode => {
|
||||
should(tableNode.checked).be.true();
|
||||
});
|
||||
let viewNodes: CheckboxTreeNode[] = await viewFolderNode.getChildren();
|
||||
viewNodes.forEach(viewNode => {
|
||||
should(viewNode.checked).be.true();
|
||||
});
|
||||
});
|
||||
|
||||
it('[ObjectMappingPage Test] Column definition mapping table should be updated when table or view node is selected.', async () => {
|
||||
let env = new VirtualizeDataMockEnv();
|
||||
let objectMappingPage = env.getMockedObjectMappingPage();
|
||||
await objectMappingPage.updatePage();
|
||||
let omPage = <any>objectMappingPage;
|
||||
let rootNode: CheckboxTreeNode = omPage._treeRootNode as CheckboxTreeNode;
|
||||
let databaseNodes: CheckboxTreeNode[] = await rootNode.getChildren();
|
||||
should(databaseNodes).not.be.undefined();
|
||||
should(databaseNodes.length > 0).be.true();
|
||||
let folderNodes: CheckboxTreeNode[] = await databaseNodes[0].getChildren();
|
||||
should(folderNodes).not.be.undefined();
|
||||
should(folderNodes.length === 2).be.true();
|
||||
let tableFolderNodes: CheckboxTreeNode = folderNodes[0];
|
||||
let tableNodes: CheckboxTreeNode[] = await tableFolderNodes.getChildren();
|
||||
should(tableNodes).not.be.undefined();
|
||||
should(tableNodes.length > 0).be.true();
|
||||
let viewFolderNodes: CheckboxTreeNode = folderNodes[1];
|
||||
let viewNodes: CheckboxTreeNode[] = await viewFolderNodes.getChildren();
|
||||
should(viewNodes).not.be.undefined();
|
||||
should(viewNodes.length > 0).be.true();
|
||||
|
||||
let colDefTable = omPage._columnMappingTable as azdata.DeclarativeTableComponent;
|
||||
colDefTable.updateProperties({ data: undefined });
|
||||
should(colDefTable.data).be.undefined();
|
||||
await omPage.actionOnNodeIsSelected(tableNodes[0]);
|
||||
should(colDefTable.data).not.be.undefined();
|
||||
should(colDefTable.data.length > 0).be.true();
|
||||
colDefTable.data.forEach(row => {
|
||||
should(row.length > 0).be.true();
|
||||
should(row[0] !== undefined && row[0] !== '').be.true();
|
||||
});
|
||||
|
||||
let colDefs = (await omPage._dataSourceBrowser.getColumnDefinitions((<any>tableNodes[0]).location)) as ColumnDefinition[];
|
||||
for (let i = 0; i < colDefs.length; ++i) {
|
||||
should(colDefs[i].columnName === colDefTable.data[i][0]).be.true();
|
||||
should(colDefs[i].columnName === colDefTable.data[i][1]).be.true();
|
||||
should(colDefs[i].dataType === colDefTable.data[i][2]).be.true();
|
||||
should(colDefs[i].isNullable === colDefTable.data[i][3]).be.true();
|
||||
should(colDefs[i].collationName === colDefTable.data[i][4]).be.true();
|
||||
}
|
||||
|
||||
colDefTable.updateProperties({ data: undefined });
|
||||
should(colDefTable.data).be.undefined();
|
||||
await omPage.actionOnNodeIsSelected(viewNodes[0]);
|
||||
should(colDefTable.data).not.be.undefined();
|
||||
should(colDefTable.data.length > 0).be.true();
|
||||
colDefTable.data.forEach(row => {
|
||||
should(row.length > 0).be.true();
|
||||
should(row[0] !== undefined && row[0] !== '').be.true();
|
||||
});
|
||||
|
||||
colDefs = (await omPage._dataSourceBrowser.getColumnDefinitions((<any>viewNodes[0]).location)) as ColumnDefinition[];
|
||||
for (let i = 0; i < colDefs.length; ++i) {
|
||||
should(colDefs[i].columnName === colDefTable.data[i][0]).be.true();
|
||||
should(colDefs[i].columnName === colDefTable.data[i][1]).be.true();
|
||||
should(colDefs[i].dataType === colDefTable.data[i][2]).be.true();
|
||||
should(colDefs[i].isNullable === colDefTable.data[i][3]).be.true();
|
||||
should(colDefs[i].collationName === colDefTable.data[i][4]).be.true();
|
||||
}
|
||||
});
|
||||
|
||||
it('[ObjectMappingPage Test] ObjectMappingPage should return table information for creation for checked tables', async () => {
|
||||
let env = new VirtualizeDataMockEnv();
|
||||
let objectMappingPage = env.getMockedObjectMappingPage();
|
||||
await objectMappingPage.updatePage();
|
||||
let omPage = <any>objectMappingPage;
|
||||
let rootNode: CheckboxTreeNode = omPage._treeRootNode as CheckboxTreeNode;
|
||||
let databaseNodes: CheckboxTreeNode[] = await rootNode.getChildren();
|
||||
|
||||
for (let i = 0; i < databaseNodes.length; ++i) {
|
||||
await omPage.actionOnNodeCheckStatusChanged(databaseNodes[i], true);
|
||||
}
|
||||
|
||||
let inputValues = VDIManager.getEmptyInputInstance();
|
||||
omPage.getInputValues(inputValues);
|
||||
should(inputValues).not.be.undefined();
|
||||
should(inputValues.externalTableInfoList).not.be.undefined();
|
||||
let tablesToBeCreated = inputValues.externalTableInfoList;
|
||||
should(tablesToBeCreated.length > 0).be.true();
|
||||
});
|
||||
|
||||
it('[ObjectMappingPage Test] Database nodes and table nodes should be able to expand successfully.', async () => {
|
||||
let env = new VirtualizeDataMockEnv();
|
||||
let objectMappingPage = env.getMockedObjectMappingPage();
|
||||
await objectMappingPage.updatePage();
|
||||
let omPage = <any>objectMappingPage;
|
||||
let rootNode: CheckboxTreeNode = omPage._treeRootNode as CheckboxTreeNode;
|
||||
let databaseNodes: CheckboxTreeNode[] = await rootNode.getChildren();
|
||||
should(rootNode.hasChildren).be.true();
|
||||
should(databaseNodes).not.be.undefined();
|
||||
should(databaseNodes.length > 0).be.true();
|
||||
|
||||
for (let i = 0; i < databaseNodes.length; ++i) {
|
||||
let tableNodes: CheckboxTreeNode[] = await databaseNodes[i].getChildren();
|
||||
should(databaseNodes[i].hasChildren).be.True();
|
||||
should(tableNodes).not.be.undefined();
|
||||
should(tableNodes.length > 0).be.true();
|
||||
}
|
||||
});
|
||||
|
||||
it('[ObjectMappingPage Test] Tree view should be updated every time objectMappingPage is loaded', async () => {
|
||||
let env = new VirtualizeDataMockEnv();
|
||||
let objectMappingPage = env.getMockedObjectMappingPage();
|
||||
await objectMappingPage.updatePage();
|
||||
let omPage = <any>objectMappingPage;
|
||||
|
||||
let rootNode: CheckboxTreeNode = omPage._treeRootNode as CheckboxTreeNode;
|
||||
should(rootNode.hasChildren).be.false();
|
||||
let databaseNodes: CheckboxTreeNode[] = await rootNode.getChildren();
|
||||
should(rootNode.hasChildren).be.true();
|
||||
|
||||
await objectMappingPage.updatePage();
|
||||
rootNode = omPage._treeRootNode as CheckboxTreeNode;
|
||||
should(rootNode.hasChildren).be.false();
|
||||
});
|
||||
|
||||
it('[ObjectMappingPage Test] ObjectMappingPage should show table help text when the page is updated', async () => {
|
||||
let env = new VirtualizeDataMockEnv();
|
||||
let objectMappingPage = env.getMockedObjectMappingPage();
|
||||
await objectMappingPage.updatePage();
|
||||
let omPage = <any>objectMappingPage;
|
||||
let objectMappingWrapper = omPage._objectMappingWrapper;
|
||||
should(objectMappingWrapper).not.be.undefined();
|
||||
should(objectMappingWrapper.items.length === 1).be.true();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Summary Page Tests', function (): void {
|
||||
it('[SummaryPage Test] SummaryPage should create a wizard page and register content during the initialization.', async () => {
|
||||
let env = new VirtualizeDataMockEnv();
|
||||
let dataModel = env.getMockedVirtualizeDataModel();
|
||||
let vdiManager = env.getMockedVDIManager();
|
||||
let apiContext = env.getMockedAppContext();
|
||||
let apiWrapperMock = env.getApiWrapperMock();
|
||||
let wizardPageMock = env.getWizardPageMock();
|
||||
|
||||
let summaryPage = new SummaryPage(dataModel, vdiManager, apiContext);
|
||||
wizardPageMock.verify(x => x.registerContent(TypeMoq.It.isAny()), TypeMoq.Times.once());
|
||||
apiWrapperMock.verify(x => x.createWizardPage(TypeMoq.It.isAnyString()), TypeMoq.Times.once());
|
||||
should(summaryPage).not.be.null();
|
||||
});
|
||||
|
||||
it('[SummaryPage Test] SummaryPage should get data from VirtualizeDataModel when the page is opened.', async () => {
|
||||
let uiElement = new SummaryUiElements();
|
||||
uiElement.destDBLabel = new MockTextComponent();
|
||||
uiElement.summaryTable = new MockDeclarativeTableComponent();
|
||||
|
||||
let env = new VirtualizeDataMockEnv();
|
||||
let dataModel = env.getMockedVirtualizeDataModel();
|
||||
let vdiManager = env.getMockedVDIManager();
|
||||
let apiContext = env.getMockedAppContext();
|
||||
let vdiManagerMock = env.getVDIManagerMock();
|
||||
|
||||
let summaryPage = new SummaryPage(dataModel, vdiManager, apiContext);
|
||||
summaryPage.setUi(uiElement);
|
||||
await summaryPage.updatePage();
|
||||
|
||||
vdiManagerMock.verify(x => x.getVirtualizeDataInput(TypeMoq.It.isAny()), TypeMoq.Times.once());
|
||||
|
||||
let testData = env.getMockEnvConstants();
|
||||
should(uiElement.destDBLabel.value).be.eql(testData.destDbNameSelected);
|
||||
|
||||
let summaryHasKey = function (key: string): boolean {
|
||||
return uiElement.summaryTable.data.some(row => row && row[0] === key);
|
||||
};
|
||||
let summaryHasValue = function (value: string): boolean {
|
||||
return uiElement.summaryTable.data.some(row => row && row.length > 1 && row[1] === value);
|
||||
};
|
||||
should(summaryHasValue(testData.newCredentialName)).be.true;
|
||||
should(summaryHasValue(testData.newDataSourceName)).be.true;
|
||||
should(summaryHasValue(testData.externalTableInfoList[0].externalTableName.join('.'))).be.true;
|
||||
// No value is included for the master key row, so check the row's key instead
|
||||
should(summaryHasKey('Database Master Key')).be.true;
|
||||
});
|
||||
|
||||
it('[SummaryPage Test] SummaryPage should register task operation on wizard submit.', async () => {
|
||||
let uiElement = new SummaryUiElements();
|
||||
uiElement.destDBLabel = new MockTextComponent();
|
||||
uiElement.summaryTable = new MockDeclarativeTableComponent();
|
||||
|
||||
let env = new VirtualizeDataMockEnv();
|
||||
let dataModel = env.getMockedVirtualizeDataModel();
|
||||
let vdiManager = env.getMockedVDIManager();
|
||||
let apiContext = env.getMockedAppContext();
|
||||
let wizardMock = env.getWizardMock();
|
||||
|
||||
let summaryPage = new SummaryPage(dataModel, vdiManager, apiContext);
|
||||
summaryPage.setUi(uiElement);
|
||||
|
||||
should(await summaryPage.validate()).be.true;
|
||||
wizardMock.verify(x => x.registerOperation(TypeMoq.It.isAny()), TypeMoq.Times.once());
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user