mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-23 09:35:39 -05:00
@@ -5,7 +5,10 @@
|
||||
"ignorePatterns": [
|
||||
"**/generated/**",
|
||||
"**/node_modules/**",
|
||||
"**/test/**"
|
||||
"**/test/**",
|
||||
"constants.js",
|
||||
"localizedConstants.js",
|
||||
"extension.js"
|
||||
],
|
||||
"reports": [
|
||||
"cobertura",
|
||||
|
||||
@@ -103,13 +103,6 @@ export function getDatabaseStateDisplayText(state: string): string {
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens an input box prompting the user to enter in the name of a resource to delete
|
||||
* @param namespace The namespace of the resource to delete
|
||||
* @param name The name of the resource to delete
|
||||
* @returns Promise resolving to true if the user confirmed the name, false if the input box was closed for any other reason
|
||||
*/
|
||||
|
||||
/**
|
||||
* Opens an input box prompting and validating the user's input.
|
||||
* @param options Options for the input box
|
||||
@@ -173,9 +166,9 @@ export async function promptForResourceDeletion(namespace: string, name: string)
|
||||
* Opens an input box prompting the user to enter and confirm a password
|
||||
* @param validate A function that accepts the password and returns an error message if it's invalid
|
||||
* @returns Promise resolving to the password if it passed validation,
|
||||
* or false if the input box was closed for any other reason
|
||||
* or undefined if the input box was closed for any other reason
|
||||
*/
|
||||
export async function promptAndConfirmPassword(validate: (input: string) => string): Promise<string | false> {
|
||||
export async function promptAndConfirmPassword(validate: (input: string) => string): Promise<string | undefined> {
|
||||
const title = loc.resetPassword;
|
||||
const options: vscode.InputBoxOptions = {
|
||||
prompt: loc.enterNewPassword,
|
||||
@@ -190,7 +183,7 @@ export async function promptAndConfirmPassword(validate: (input: string) => stri
|
||||
return promptInputBox(title, options);
|
||||
}
|
||||
|
||||
return false;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -198,7 +191,7 @@ export async function promptAndConfirmPassword(validate: (input: string) => stri
|
||||
* @param error The error object
|
||||
*/
|
||||
export function getErrorMessage(error: any): string {
|
||||
if (error?.body?.reason) {
|
||||
if (error.body?.reason) {
|
||||
// For HTTP Errors with a body pull out the reason message since that's usually the most helpful
|
||||
return error.body.reason;
|
||||
} else if (error.message) {
|
||||
|
||||
85
extensions/arc/src/test/common/date.test.ts
Normal file
85
extensions/arc/src/test/common/date.test.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as should from 'should';
|
||||
import 'mocha';
|
||||
import { fromNow } from '../../common/date';
|
||||
|
||||
describe('fromNow Method Tests', function () {
|
||||
it('Future date', function (): void {
|
||||
should(fromNow(new Date().getTime() + 60000)).startWith('in');
|
||||
});
|
||||
|
||||
it('Now', function (): void {
|
||||
should(fromNow(new Date())).equal('now');
|
||||
});
|
||||
|
||||
it('< 1 min ago', function (): void {
|
||||
// 30 sec
|
||||
should(fromNow(new Date().getTime() - 30000)).endWith('secs');
|
||||
should(fromNow(new Date().getTime() - 30000, true)).endWith('secs ago');
|
||||
});
|
||||
|
||||
it('< 1 hr ago', function (): void {
|
||||
// 1.5 min
|
||||
should(fromNow(new Date().getTime() - 90 * 1000)).endWith('min');
|
||||
should(fromNow(new Date().getTime() - 90 * 1000, true)).endWith('min ago');
|
||||
|
||||
// 5 min
|
||||
should(fromNow(new Date().getTime() - 5 * 60 * 1000)).endWith('mins');
|
||||
should(fromNow(new Date().getTime() - 5 * 60 * 1000, true)).endWith('mins ago');
|
||||
});
|
||||
|
||||
it('< 1 day ago', function (): void {
|
||||
// 1.5 hrs
|
||||
should(fromNow(new Date().getTime() - 90 * 60 * 1000)).endWith('hr');
|
||||
should(fromNow(new Date().getTime() - 90 * 60 * 1000, true)).endWith('hr ago');
|
||||
|
||||
// 5 hrs
|
||||
should(fromNow(new Date().getTime() - 5 * 60 * 60 * 1000)).endWith('hrs');
|
||||
should(fromNow(new Date().getTime() - 5 * 60 * 60 * 1000, true)).endWith('hrs ago');
|
||||
});
|
||||
|
||||
it('< 1 week ago', function (): void {
|
||||
// 30 hours
|
||||
should(fromNow(new Date().getTime() - 30 * 60 * 60 * 1000)).endWith('day');
|
||||
should(fromNow(new Date().getTime() - 30 * 60 * 60 * 1000, true)).endWith('day ago');
|
||||
|
||||
// 3 days
|
||||
should(fromNow(new Date().getTime() - 3 * 24 * 60 * 60 * 1000)).endWith('days');
|
||||
should(fromNow(new Date().getTime() - 3 * 24 * 60 * 60 * 1000, true)).endWith('days ago');
|
||||
});
|
||||
|
||||
it('< 1 month ago', function (): void {
|
||||
// 10 days
|
||||
should(fromNow(new Date().getTime() - 10 * 24 * 60 * 60 * 1000)).endWith('wk');
|
||||
should(fromNow(new Date().getTime() - 10 * 24 * 60 * 60 * 1000, true)).endWith('wk ago');
|
||||
|
||||
// 20 days
|
||||
should(fromNow(new Date().getTime() - 20 * 24 * 60 * 60 * 1000)).endWith('wks');
|
||||
should(fromNow(new Date().getTime() - 20 * 24 * 60 * 60 * 1000, true)).endWith('wks ago');
|
||||
});
|
||||
|
||||
it('< 1 year ago', function (): void {
|
||||
// 45 days
|
||||
should(fromNow(new Date().getTime() - 45 * 24 * 60 * 60 * 1000)).endWith('mo');
|
||||
should(fromNow(new Date().getTime() - 45 * 24 * 60 * 60 * 1000, true)).endWith('mo ago');
|
||||
|
||||
// 90 days
|
||||
should(fromNow(new Date().getTime() - 90 * 24 * 60 * 60 * 1000)).endWith('mos');
|
||||
should(fromNow(new Date().getTime() - 90 * 24 * 60 * 60 * 1000, true)).endWith('mos ago');
|
||||
});
|
||||
|
||||
it('> 1 year ago', function (): void {
|
||||
// 400 days
|
||||
should(fromNow(new Date().getTime() - 400 * 24 * 60 * 60 * 1000)).endWith('yr');
|
||||
should(fromNow(new Date().getTime() - 400 * 24 * 60 * 60 * 1000, true)).endWith('yr ago');
|
||||
|
||||
// 1000
|
||||
should(fromNow(new Date().getTime() - 1000 * 24 * 60 * 60 * 1000)).endWith('yrs');
|
||||
should(fromNow(new Date().getTime() - 1000 * 24 * 60 * 60 * 1000, true)).endWith('yrs ago');
|
||||
});
|
||||
|
||||
});
|
||||
@@ -6,13 +6,15 @@
|
||||
import * as vscode from 'vscode';
|
||||
import * as should from 'should';
|
||||
import 'mocha';
|
||||
import { resourceTypeToDisplayName, parseEndpoint, parseInstanceName, getAzurecoreApi, getResourceTypeIcon, getConnectionModeDisplayText, getDatabaseStateDisplayText, promptForResourceDeletion } from '../../common/utils';
|
||||
import { resourceTypeToDisplayName, parseEndpoint, parseInstanceName, getAzurecoreApi, getResourceTypeIcon, getConnectionModeDisplayText, getDatabaseStateDisplayText, promptForResourceDeletion, promptAndConfirmPassword, getErrorMessage } from '../../common/utils';
|
||||
|
||||
import * as loc from '../../localizedConstants';
|
||||
import { ResourceType, IconPathHelper, Connectionmode as ConnectionMode } from '../../constants';
|
||||
import { MockInputBox } from '../stubs';
|
||||
import { HttpError } from '../../controller/generated/v1/api';
|
||||
import { IncomingMessage } from 'http';
|
||||
|
||||
describe('resourceTypeToDisplayName Method Tests', function(): void {
|
||||
describe('resourceTypeToDisplayName Method Tests', function (): void {
|
||||
it('Display Name should be correct for valid ResourceType', function (): void {
|
||||
should(resourceTypeToDisplayName(ResourceType.dataControllers)).equal(loc.dataControllersType);
|
||||
should(resourceTypeToDisplayName(ResourceType.postgresInstances)).equal(loc.pgSqlType);
|
||||
@@ -32,7 +34,7 @@ describe('resourceTypeToDisplayName Method Tests', function(): void {
|
||||
});
|
||||
});
|
||||
|
||||
describe('parseEndpoint Method Tests', function(): void {
|
||||
describe('parseEndpoint Method Tests', function (): void {
|
||||
it('Should parse valid endpoint correctly', function (): void {
|
||||
should(parseEndpoint('127.0.0.1:1337')).deepEqual({ ip: '127.0.0.1', port: '1337' });
|
||||
});
|
||||
@@ -64,13 +66,13 @@ describe('parseInstanceName Method Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('getAzurecoreApi Method Tests', function() {
|
||||
describe('getAzurecoreApi Method Tests', function () {
|
||||
it('Should get azurecore API correctly', function (): void {
|
||||
should(getAzurecoreApi()).not.be.undefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('getResourceTypeIcon Method Tests', function() {
|
||||
describe('getResourceTypeIcon Method Tests', function () {
|
||||
it('Correct icons should be returned for valid ResourceTypes', function (): void {
|
||||
should(getResourceTypeIcon(ResourceType.sqlManagedInstances)).equal(IconPathHelper.miaa, 'Unexpected MIAA icon');
|
||||
should(getResourceTypeIcon(ResourceType.postgresInstances)).equal(IconPathHelper.postgres, 'Unexpected Postgres icon');
|
||||
@@ -87,7 +89,7 @@ describe('getResourceTypeIcon Method Tests', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('getConnectionModeDisplayText Method Tests', function() {
|
||||
describe('getConnectionModeDisplayText Method Tests', function () {
|
||||
it('Display Name should be correct for valid ResourceType', function (): void {
|
||||
should(getConnectionModeDisplayText(ConnectionMode.connected)).equal(loc.connected);
|
||||
should(getConnectionModeDisplayText(ConnectionMode.disconnected)).equal(loc.disconnected);
|
||||
@@ -106,7 +108,7 @@ describe('getConnectionModeDisplayText Method Tests', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('getDatabaseStateDisplayText Method Tests', function() {
|
||||
describe('getDatabaseStateDisplayText Method Tests', function () {
|
||||
it('State should be correct for valid states', function (): void {
|
||||
should(getDatabaseStateDisplayText('ONLINE')).equal(loc.online);
|
||||
should(getDatabaseStateDisplayText('OFFLINE')).equal(loc.offline);
|
||||
@@ -162,3 +164,125 @@ describe('promptForResourceDeletion Method Tests', function (): void {
|
||||
should(mockInputBox.validationMessage).be.equal('', 'Validation message should be empty after new value entered');
|
||||
});
|
||||
});
|
||||
|
||||
describe('promptAndConfirmPassword Method Tests', function (): void {
|
||||
let mockInputBox: MockInputBox;
|
||||
before(function (): void {
|
||||
vscode.window.createInputBox = () => {
|
||||
return mockInputBox;
|
||||
};
|
||||
});
|
||||
|
||||
beforeEach(function (): void {
|
||||
mockInputBox = new MockInputBox();
|
||||
});
|
||||
|
||||
it('Resolves with expected string when passwords match', function (done): void {
|
||||
const password = 'MyPassword';
|
||||
promptAndConfirmPassword((_: string) => { return ''; }).then(value => {
|
||||
if (value === password) {
|
||||
done();
|
||||
} else {
|
||||
done(new Error(`Return value '${value}' did not match expected value '${password}'`));
|
||||
}
|
||||
});
|
||||
mockInputBox.value = password;
|
||||
mockInputBox.triggerAccept().then( () => {
|
||||
mockInputBox.value = password;
|
||||
mockInputBox.triggerAccept();
|
||||
});
|
||||
});
|
||||
|
||||
it('Resolves with undefined when first input box closed early', function (done): void {
|
||||
promptAndConfirmPassword((_: string) => { return ''; }).then(value => {
|
||||
if (value === undefined) {
|
||||
done();
|
||||
} else {
|
||||
done(new Error('Return value was expected to be undefined'));
|
||||
}
|
||||
});
|
||||
mockInputBox.hide();
|
||||
});
|
||||
|
||||
it('Resolves with undefined when second input box closed early', function (done): void {
|
||||
const password = 'MyPassword';
|
||||
promptAndConfirmPassword((_: string) => { return ''; }).then(value => {
|
||||
if (value === undefined) {
|
||||
done();
|
||||
} else {
|
||||
done(new Error('Return value was expected to be undefined'));
|
||||
}
|
||||
});
|
||||
mockInputBox.value = password;
|
||||
mockInputBox.triggerAccept().then( () => {
|
||||
mockInputBox.hide();
|
||||
});
|
||||
});
|
||||
|
||||
it('Error message displayed when validation callback returns error message', function (done): void {
|
||||
const testError = 'Test Error';
|
||||
promptAndConfirmPassword((_: string) => { return testError; }).catch(err => done(err));
|
||||
mockInputBox.value = '';
|
||||
mockInputBox.triggerAccept().then( () => {
|
||||
if(mockInputBox.validationMessage === testError) {
|
||||
done();
|
||||
} else {
|
||||
done(new Error(`Validation message '${mockInputBox.validationMessage}' was expected to be '${testError}'`));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('Error message displayed when passwords do not match', function (done): void {
|
||||
promptAndConfirmPassword((_: string) => { return ''; }).catch(err => done(err));
|
||||
mockInputBox.value = 'MyPassword';
|
||||
mockInputBox.triggerAccept().then( () => {
|
||||
mockInputBox.value = 'WrongPassword';
|
||||
mockInputBox.triggerAccept().then( () => {
|
||||
if(mockInputBox.validationMessage === loc.thePasswordsDoNotMatch) {
|
||||
done();
|
||||
} else {
|
||||
done(new Error(`Validation message '${mockInputBox.validationMessage} was not the expected message`));
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getErrorMessage Method Tests', function () {
|
||||
it('HttpError with reason', function (): void {
|
||||
const httpReason = 'Test Reason';
|
||||
should(getErrorMessage(new HttpError(<IncomingMessage>{ }, { reason: 'Test Reason' }))).equal(httpReason);
|
||||
});
|
||||
|
||||
it('HttpError with status message', function (): void {
|
||||
const httpStatusMessage = 'Test Status Message';
|
||||
should(getErrorMessage(new HttpError(<IncomingMessage>{ statusMessage: httpStatusMessage}, { }))).containEql(`(${httpStatusMessage})`);
|
||||
});
|
||||
|
||||
it('Error with message', function (): void {
|
||||
const errorMessage = 'Test Message';
|
||||
const error = new Error(errorMessage);
|
||||
should(getErrorMessage(error)).equal(errorMessage);
|
||||
});
|
||||
|
||||
it('Error with no message', function (): void {
|
||||
const error = new Error();
|
||||
should(getErrorMessage(error)).equal(error);
|
||||
});
|
||||
});
|
||||
|
||||
describe('parseInstanceName Method Tests', function () {
|
||||
it('2 part name', function (): void {
|
||||
const name = 'MyName';
|
||||
should(parseInstanceName(`MyNamespace_${name}`)).equal(name);
|
||||
});
|
||||
|
||||
it('1 part name', function (): void {
|
||||
const name = 'MyName';
|
||||
should(parseInstanceName(name)).equal(name);
|
||||
});
|
||||
|
||||
it('Invalid name', function (): void {
|
||||
should(() => parseInstanceName('Some_Invalid_Name')).throwError();
|
||||
});
|
||||
});
|
||||
|
||||
31
extensions/arc/src/test/controller/auth.test.ts
Normal file
31
extensions/arc/src/test/controller/auth.test.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import * as should from 'should';
|
||||
import 'mocha';
|
||||
import { BasicAuth } from '../../controller/auth';
|
||||
|
||||
describe('BasicAuth Method Tests', function () {
|
||||
|
||||
it('Options applied correctly', async function (): Promise<void> {
|
||||
const username = 'MyUsername';
|
||||
const password = 'MyPassword';
|
||||
let ignoreSslVerification = true;
|
||||
const auth = new BasicAuth(username, password);
|
||||
const requestOptions = {} as any;
|
||||
// We don't need this to be actual valid options since we're just checking the ones applied
|
||||
auth.applyToRequest(requestOptions);
|
||||
await vscode.workspace.getConfiguration('arc').update('ignoreSslVerification', ignoreSslVerification, vscode.ConfigurationTarget.Global);
|
||||
should(requestOptions.auth).deepEqual({ username: username, password: password });
|
||||
should(requestOptions.agentOptions).deepEqual({ rejectUnauthorized: !ignoreSslVerification });
|
||||
|
||||
ignoreSslVerification = false;
|
||||
await vscode.workspace.getConfiguration('arc').update('ignoreSslVerification', ignoreSslVerification, vscode.ConfigurationTarget.Global);
|
||||
auth.applyToRequest(requestOptions);
|
||||
should(requestOptions.agentOptions).deepEqual({ rejectUnauthorized: !ignoreSslVerification });
|
||||
});
|
||||
|
||||
});
|
||||
Reference in New Issue
Block a user