diff --git a/.gitignore b/.gitignore index e6fd29f2b..cd87b7054 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,6 @@ telemetry-generated # tasks copy them to the correct location, but leave the originals where # we do not want them checked in l10n/package.nls.*.json + +# Code Coverage Output +.nyc_output/ diff --git a/package.json b/package.json index 679829610..ecadf0b2c 100644 --- a/package.json +++ b/package.json @@ -191,10 +191,6 @@ "title": "Open in Power Pages", "when": "never" }, - { - "command": "extension.createChatView", - "title": "Create Chat View" - }, { "command": "pacCLI.openDocumentation", "category": "Power Platform CLI", diff --git a/src/client/extension.ts b/src/client/extension.ts index 2f023c292..20e04ccfc 100644 --- a/src/client/extension.ts +++ b/src/client/extension.ts @@ -9,10 +9,9 @@ import * as vscode from "vscode"; import { AppTelemetryConfigUtility } from "../common/pp-tooling-telemetry-node"; import { vscodeExtAppInsightsResourceProvider } from "../common/telemetry-generated/telemetryConfiguration"; import { ITelemetryData } from "../common/TelemetryData"; -import { CliAcquisition, ICliAcquisitionContext } from "./lib/CliAcquisition"; +import { CliAcquisition } from "./lib/CliAcquisition"; import { PacTerminal } from "./lib/PacTerminal"; import { PortalWebView } from "./PortalWebView"; -import { ITelemetry } from "../common/OneDSLoggerTelemetry/telemetry/ITelemetry"; import { LanguageClient, @@ -46,6 +45,7 @@ import { AadIdKey, EnvIdKey, TenantIdKey } from "../common/OneDSLoggerTelemetry/ import { PowerPagesAppName, PowerPagesClientName } from "../common/ecs-features/constants"; import { ECSFeaturesClient } from "../common/ecs-features/ecsFeatureClient"; import { getECSOrgLocationValue } from "../common/utilities/Utils"; +import { CliAcquisitionContext } from "./lib/CliAcquisitionContext"; let client: LanguageClient; let _context: vscode.ExtensionContext; @@ -473,70 +473,3 @@ function showNotificationForCopilot(telemetry: TelemetryReporter, telemetryData: } } - -// allow for DI without direct reference to vscode's d.ts file: that definintions file is being generated at VS Code runtime -class CliAcquisitionContext implements ICliAcquisitionContext { - public constructor( - private readonly _context: vscode.ExtensionContext, - private readonly _telemetry: ITelemetry - ) { } - - public get extensionPath(): string { - return this._context.extensionPath; - } - public get globalStorageLocalPath(): string { - return this._context.globalStorageUri.fsPath; - } - public get telemetry(): ITelemetry { - return this._telemetry; - } - - showInformationMessage(message: string, ...items: string[]): void { - vscode.window.showInformationMessage(message, ...items); - } - - showErrorMessage(message: string, ...items: string[]): void { - vscode.window.showErrorMessage(message, ...items); - } - - showCliPreparingMessage(version: string): void { - vscode.window.showInformationMessage( - vscode.l10n.t({ - message: "Preparing pac CLI (v{0})...", - args: [version], - comment: ["{0} represents the version number"] - }) - ); - } - - showCliReadyMessage(): void { - vscode.window.showInformationMessage( - vscode.l10n.t('The pac CLI is ready for use in your VS Code terminal!')); - } - - showCliInstallFailedError(err: string): void { - vscode.window.showErrorMessage( - vscode.l10n.t({ - message: "Cannot install pac CLI: {0}", - args: [err], - comment: ["{0} represents the error message returned from the exception"] - }) - ); - } - - showGeneratorInstallingMessage(version: string): void { - vscode.window.showInformationMessage( - vscode.l10n.t({ - message: "Installing Power Pages generator(v{0})...", - args: [version], - comment: ["{0} represents the version number"] - })) - } - - locDotnetNotInstalledOrInsufficient(): string { - return vscode.l10n.t({ - message: "dotnet sdk 6.0 or greater must be installed", - comment: ["Do not translate 'dotnet' or 'sdk'"] - }); - } -} diff --git a/src/client/lib/CliAcquisition.ts b/src/client/lib/CliAcquisition.ts index 531e7ef2a..2642f0127 100644 --- a/src/client/lib/CliAcquisition.ts +++ b/src/client/lib/CliAcquisition.ts @@ -10,31 +10,17 @@ import * as fs from 'fs-extra'; import * as glob from 'glob'; import * as os from 'os'; import { Extract } from 'unzip-stream' -import { ITelemetry } from '../../common/OneDSLoggerTelemetry/telemetry/ITelemetry'; import find from 'find-process'; import { spawnSync } from 'child_process'; import commandExists from 'command-exists'; import { oneDSLoggerWrapper } from '../../common/OneDSLoggerTelemetry/oneDSLoggerWrapper'; - -// allow for DI without direct reference to vscode's d.ts file: that definintions file is being generated at VS Code runtime -export interface ICliAcquisitionContext { - readonly extensionPath: string; - readonly globalStorageLocalPath: string; - readonly telemetry: ITelemetry; - showInformationMessage(message: string, ...items: string[]): void; - showErrorMessage(message: string, ...items: string[]): void; - showCliPreparingMessage(version: string): void; - showCliReadyMessage(): void; - showCliInstallFailedError(err: string): void; - locDotnetNotInstalledOrInsufficient(): string; -} +import { ICliAcquisitionContext } from './CliAcquisitionContext'; export interface IDisposable { dispose(): void; } export class CliAcquisition implements IDisposable { - private readonly _context: ICliAcquisitionContext; private readonly _cliPath: string; private readonly _cliVersion: string; @@ -241,4 +227,3 @@ export class CliAcquisition implements IDisposable { } } } - diff --git a/src/client/lib/CliAcquisitionContext.ts b/src/client/lib/CliAcquisitionContext.ts new file mode 100644 index 000000000..77a165d23 --- /dev/null +++ b/src/client/lib/CliAcquisitionContext.ts @@ -0,0 +1,86 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + */ + +import * as vscode from 'vscode'; +import { ITelemetry } from '../../common/OneDSLoggerTelemetry/telemetry/ITelemetry'; + +export interface ICliAcquisitionContext { + readonly extensionPath: string; + readonly globalStorageLocalPath: string; + readonly telemetry: ITelemetry; + showInformationMessage(message: string, ...items: string[]): void; + showErrorMessage(message: string, ...items: string[]): void; + showCliPreparingMessage(version: string): void; + showCliReadyMessage(): void; + showCliInstallFailedError(err: string): void; + locDotnetNotInstalledOrInsufficient(): string; +} + +// allow for DI without direct reference to vscode's d.ts file: that definintions file is being generated at VS Code runtime +export class CliAcquisitionContext implements ICliAcquisitionContext { + public constructor( + private readonly _context: vscode.ExtensionContext, + private readonly _telemetry: ITelemetry + ) { } + + public get extensionPath(): string { + return this._context.extensionPath; + } + public get globalStorageLocalPath(): string { + return this._context.globalStorageUri.fsPath; + } + public get telemetry(): ITelemetry { + return this._telemetry; + } + + showInformationMessage(message: string, ...items: string[]): void { + vscode.window.showInformationMessage(message, ...items); + } + + showErrorMessage(message: string, ...items: string[]): void { + vscode.window.showErrorMessage(message, ...items); + } + + showCliPreparingMessage(version: string): void { + vscode.window.showInformationMessage( + vscode.l10n.t({ + message: "Preparing pac CLI (v{0})...", + args: [version], + comment: ["{0} represents the version number"] + }) + ); + } + + showCliReadyMessage(): void { + vscode.window.showInformationMessage( + vscode.l10n.t('The pac CLI is ready for use in your VS Code terminal!')); + } + + showCliInstallFailedError(err: string): void { + vscode.window.showErrorMessage( + vscode.l10n.t({ + message: "Cannot install pac CLI: {0}", + args: [err], + comment: ["{0} represents the error message returned from the exception"] + }) + ); + } + + showGeneratorInstallingMessage(version: string): void { + vscode.window.showInformationMessage( + vscode.l10n.t({ + message: "Installing Power Pages generator(v{0})...", + args: [version], + comment: ["{0} represents the version number"] + })) + } + + locDotnetNotInstalledOrInsufficient(): string { + return vscode.l10n.t({ + message: "dotnet sdk 6.0 or greater must be installed", + comment: ["Do not translate 'dotnet' or 'sdk'"] + }); + } +} diff --git a/src/client/lib/GeneratorAcquisition.ts b/src/client/lib/GeneratorAcquisition.ts index 9321d673d..e07c9aeb5 100644 --- a/src/client/lib/GeneratorAcquisition.ts +++ b/src/client/lib/GeneratorAcquisition.ts @@ -11,7 +11,7 @@ import * as fs from 'fs-extra'; import * as os from 'os'; import * as path from 'path'; import { PORTAL_YEOMAN_GENERATOR_PACKAGE_NAME, PORTAL_YEOMAN_GENERATOR_PACKAGE_TARBALL_NAME } from '../../common/constants'; -import { ICliAcquisitionContext } from './CliAcquisition'; +import { ICliAcquisitionContext } from './CliAcquisitionContext'; import { glob } from 'glob'; import commandExists from 'command-exists'; import { oneDSLoggerWrapper } from '../../common/OneDSLoggerTelemetry/oneDSLoggerWrapper'; diff --git a/src/client/test/Integration/CliAcquisition.test.ts b/src/client/test/Integration/CliAcquisition.test.ts index 0280144f3..7b2368710 100644 --- a/src/client/test/Integration/CliAcquisition.test.ts +++ b/src/client/test/Integration/CliAcquisition.test.ts @@ -5,7 +5,8 @@ import * as fs from 'fs-extra'; import * as path from 'path'; -import { CliAcquisition, ICliAcquisitionContext } from '../../lib/CliAcquisition'; +import { CliAcquisition } from '../../lib/CliAcquisition'; +import { ICliAcquisitionContext } from '../../lib/CliAcquisitionContext'; import { expect } from 'chai'; import { ITelemetry } from '../../../common/OneDSLoggerTelemetry/telemetry/ITelemetry'; import { NoopTelemetryInstance } from '../../telemetry/NoopTelemetry'; diff --git a/src/client/test/Integration/CliAcquisitionContext.test.ts b/src/client/test/Integration/CliAcquisitionContext.test.ts new file mode 100644 index 000000000..b6f7b8089 --- /dev/null +++ b/src/client/test/Integration/CliAcquisitionContext.test.ts @@ -0,0 +1,125 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + */ + +import * as vscode from 'vscode'; +import { ITelemetry } from '../../../common/OneDSLoggerTelemetry/telemetry/ITelemetry'; +import { CliAcquisitionContext } from '../../lib/CliAcquisitionContext'; +import { expect } from 'chai'; +import sinon from 'sinon'; + +describe('CliAcquisitionContext', () => { + let context: vscode.ExtensionContext; + let telemetry: ITelemetry; + let showInformationMessageSpy: sinon.SinonSpy; + let showErrorMessageSpy: sinon.SinonSpy; + + beforeEach(() => { + context = { + extensionPath: 'testExtensionPath', + globalStorageUri: { + fsPath: 'testGlobalStorageUri' + } + } as vscode.ExtensionContext; + + telemetry = {} as ITelemetry; + + showInformationMessageSpy = sinon.spy(vscode.window, "showInformationMessage"); + showErrorMessageSpy = sinon.spy(vscode.window, "showErrorMessage"); + }); + + afterEach(() => { + showInformationMessageSpy.restore(); + showErrorMessageSpy.restore(); + }); + + it('should return the extension path', () => { + const cliAcquisitionContext = new CliAcquisitionContext(context, telemetry); + + expect(cliAcquisitionContext.extensionPath).to.equal('testExtensionPath'); + }); + + it('should return the global storage local path', () => { + const cliAcquisitionContext = new CliAcquisitionContext(context, telemetry); + + expect(cliAcquisitionContext.globalStorageLocalPath).to.equal('testGlobalStorageUri'); + }); + + it('should return the telemetry', () => { + const cliAcquisitionContext = new CliAcquisitionContext(context, telemetry); + + expect(cliAcquisitionContext.telemetry).to.equal(telemetry); + }); + + it('should show information message', () => { + const message = 'testMessage'; + const cliAcquisitionContext = new CliAcquisitionContext(context, telemetry); + + cliAcquisitionContext.showInformationMessage(message); + + const showInformationMessageArgs = showInformationMessageSpy.getCalls()[0].args; + + expect(showInformationMessageArgs[0]).eq("testMessage"); + }); + + it('should show error message', () => { + const message = 'testMessage'; + const cliAcquisitionContext = new CliAcquisitionContext(context, telemetry); + + cliAcquisitionContext.showErrorMessage(message); + + const showErrorMessageArgs = showErrorMessageSpy.getCalls()[0].args; + + expect(showErrorMessageArgs[0]).eq("testMessage"); + }); + + it('should show cli preparing message', () => { + const version = 'testVersion'; + const cliAcquisitionContext = new CliAcquisitionContext(context, telemetry); + + cliAcquisitionContext.showCliPreparingMessage(version); + + const showInformationMessageArgs = showInformationMessageSpy.getCalls()[0].args; + + expect(showInformationMessageArgs[0]).eq("Preparing pac CLI (vtestVersion)..."); + }); + + it('should show cli ready message', () => { + const cliAcquisitionContext = new CliAcquisitionContext(context, telemetry); + + cliAcquisitionContext.showCliReadyMessage(); + + const showInformationMessageArgs = showInformationMessageSpy.getCalls()[0].args; + + expect(showInformationMessageArgs[0]).eq("The pac CLI is ready for use in your VS Code terminal!"); + }); + + it('should show cli install failed error', () => { + const err = 'testError'; + const cliAcquisitionContext = new CliAcquisitionContext(context, telemetry); + + cliAcquisitionContext.showCliInstallFailedError(err); + + const showErrorMessageArgs = showErrorMessageSpy.getCalls()[0].args; + + expect(showErrorMessageArgs[0]).eq("Cannot install pac CLI: testError"); + }); + + it('should show generator installing message', () => { + const version = 'testVersion'; + const cliAcquisitionContext = new CliAcquisitionContext(context, telemetry); + + cliAcquisitionContext.showGeneratorInstallingMessage(version); + + const showInformationMessageArgs = showInformationMessageSpy.getCalls()[0].args; + + expect(showInformationMessageArgs[0]).eq("Installing Power Pages generator(vtestVersion)..."); + }); + + it('should return loc dotnet not installed or insufficient', () => { + const cliAcquisitionContext = new CliAcquisitionContext(context, telemetry); + + expect(cliAcquisitionContext.locDotnetNotInstalledOrInsufficient()).eq("dotnet sdk 6.0 or greater must be installed"); + }); +}); diff --git a/src/web/client/dal/concurrencyHandler.ts b/src/web/client/dal/concurrencyHandler.ts index 41ca6f28c..0bca09d39 100644 --- a/src/web/client/dal/concurrencyHandler.ts +++ b/src/web/client/dal/concurrencyHandler.ts @@ -26,7 +26,7 @@ export class ConcurrencyHandler { this.handleRequest.name, this._bulkhead.executionSlots.toString(), ); - throw new Error(ERROR_CONSTANTS.SUBURI_EMPTY); + throw new Error(ERROR_CONSTANTS.BULKHEAD_LIMITS_EXCEEDED); } else { throw e; }