Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: switch to new manifest handlers #11879

Merged
merged 1 commit into from
Jun 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions packages/vscode-extension/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,12 @@ import { showError } from "./error/common";
import { TreeViewCommand } from "./treeview/treeViewCommand";
import { signOutM365, signOutAzure } from "./utils/accountUtils";
import { cmpAccountsHandler, createAccountHandler } from "./handlers/accountHandlers";
import {
buildPackageHandler,
publishInDeveloperPortalHandler,
updatePreviewManifest,
validateManifestHandler,
} from "./handlers/manifestHandlers";

export async function activate(context: vscode.ExtensionContext) {
process.env[FeatureFlags.ChatParticipant] = (
Expand Down Expand Up @@ -547,12 +553,7 @@ function registerTreeViewCommandsInLifecycle(context: vscode.ExtensionContext) {
registerInCommandController(context, CommandKeys.Provision, provisionHandler, "provision");

// Zip Teams metadata package
registerInCommandController(
context,
"fx-extension.build",
handlers.buildPackageHandler,
"buildPackage"
);
registerInCommandController(context, "fx-extension.build", buildPackageHandler, "buildPackage");

// Deploy to the cloud
registerInCommandController(context, CommandKeys.Deploy, deployHandler, "deploy");
Expand All @@ -564,7 +565,7 @@ function registerTreeViewCommandsInLifecycle(context: vscode.ExtensionContext) {
registerInCommandController(
context,
"fx-extension.publishInDeveloperPortal",
handlers.publishInDeveloperPortalHandler,
publishInDeveloperPortalHandler,
"publishInDeveloperPortal"
);

Expand Down Expand Up @@ -596,13 +597,13 @@ function registerTeamsFxCommands(context: vscode.ExtensionContext) {

const updateManifestCmd = vscode.commands.registerCommand(
"fx-extension.updatePreviewFile",
(...args) => Correlator.run(handlers.updatePreviewManifest, args)
(...args) => Correlator.run(updatePreviewManifest, args)
);
context.subscriptions.push(updateManifestCmd);

const validateManifestCmd = vscode.commands.registerCommand(
"fx-extension.validateManifest",
(...args) => Correlator.run(handlers.validateManifestHandler, args)
(...args) => Correlator.run(validateManifestHandler, args)
);
context.subscriptions.push(validateManifestCmd);

Expand Down
161 changes: 0 additions & 161 deletions packages/vscode-extension/src/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,16 +173,6 @@ export async function treeViewPreviewHandler(...args: any[]): Promise<Result<nul
return ok(null);
}

export async function validateManifestHandler(args?: any[]): Promise<Result<null, FxError>> {
ExtTelemetry.sendTelemetryEvent(
TelemetryEvent.ValidateManifestStart,
getTriggerFromProperty(args)
);

const inputs = getSystemInputs();
return await runCommand(Stage.validateApplication, inputs);
}

/**
* Ask user to select environment, local is included
*/
Expand All @@ -208,118 +198,6 @@ export async function askTargetEnvironment(): Promise<Result<string, FxError>> {
}
}

export async function buildPackageHandler(...args: unknown[]): Promise<Result<unknown, FxError>> {
ExtTelemetry.sendTelemetryEvent(TelemetryEvent.BuildStart, getTriggerFromProperty(args));
return await runCommand(Stage.createAppPackage);
}

let lastAppPackageFile: string | undefined;

export async function publishInDeveloperPortalHandler(
...args: unknown[]
): Promise<Result<null, FxError>> {
ExtTelemetry.sendTelemetryEvent(
TelemetryEvent.PublishInDeveloperPortalStart,
getTriggerFromProperty(args)
);
const workspacePath = workspaceUri?.fsPath;
const zipDefaultFolder: string | undefined = path.join(
workspacePath!,
BuildFolderName,
AppPackageFolderName
);

let files: string[] = [];
if (await fs.pathExists(zipDefaultFolder)) {
files = await fs.readdir(zipDefaultFolder);
files = files
.filter((file) => path.extname(file).toLowerCase() === ".zip")
.map((file) => {
return path.join(zipDefaultFolder, file);
});
}
while (true) {
const selectFileConfig: SelectFileConfig = {
name: "appPackagePath",
title: localize("teamstoolkit.publishInDevPortal.selectFile.title"),
placeholder: localize("teamstoolkit.publishInDevPortal.selectFile.placeholder"),
filters: {
"Zip files": ["zip"],
},
};
if (lastAppPackageFile && fs.existsSync(lastAppPackageFile)) {
selectFileConfig.default = lastAppPackageFile;
} else {
selectFileConfig.possibleFiles = files.map((file) => {
const appPackageFilename = path.basename(file);
const appPackageFilepath = path.dirname(file);
return {
id: file,
label: `$(file) ${appPackageFilename}`,
description: appPackageFilepath,
};
});
}
const selectFileResult = await VS_CODE_UI.selectFile(selectFileConfig);
if (selectFileResult.isErr()) {
ExtTelemetry.sendTelemetryErrorEvent(
TelemetryEvent.PublishInDeveloperPortal,
selectFileResult.error,
getTriggerFromProperty(args)
);
return ok(null);
}
if (
(lastAppPackageFile && selectFileResult.value.result === lastAppPackageFile) ||
(!lastAppPackageFile && files.indexOf(selectFileResult.value.result!) !== -1)
) {
// user selected file in options
lastAppPackageFile = selectFileResult.value.result;
break;
}
// final confirmation
lastAppPackageFile = selectFileResult.value.result!;
const appPackageFilename = path.basename(lastAppPackageFile);
const appPackageFilepath = path.dirname(lastAppPackageFile);
const confirmOption: SingleSelectConfig = {
options: [
{
id: "yes",
label: `$(file) ${appPackageFilename}`,
description: appPackageFilepath,
},
],
name: "confirm",
title: localize("teamstoolkit.publishInDevPortal.selectFile.title"),
placeholder: localize("teamstoolkit.publishInDevPortal.confirmFile.placeholder"),
step: 2,
};
const confirm = await VS_CODE_UI.selectOption(confirmOption);
if (confirm.isErr()) {
ExtTelemetry.sendTelemetryErrorEvent(
TelemetryEvent.PublishInDeveloperPortal,
confirm.error,
getTriggerFromProperty(args)
);
return ok(null);
}
if (confirm.value.type === "success") {
break;
}
}
const inputs = getSystemInputs();
inputs["appPackagePath"] = lastAppPackageFile;
const res = await runCommand(Stage.publishInDeveloperPortal, inputs);
if (res.isErr()) {
ExtTelemetry.sendTelemetryErrorEvent(
TelemetryEvent.PublishInDeveloperPortal,
res.error,
getTriggerFromProperty(args)
);
}
return res;
}

export function openFolderHandler(...args: unknown[]): Promise<Result<unknown, FxError>> {
const scheme = "file://";
ExtTelemetry.sendTelemetryEvent(TelemetryEvent.OpenFolder, {
Expand Down Expand Up @@ -1255,45 +1133,6 @@ export async function openConfigStateFile(args: any[]): Promise<any> {
});
}

export async function updatePreviewManifest(args: any[]): Promise<any> {
ExtTelemetry.sendTelemetryEvent(
TelemetryEvent.UpdatePreviewManifestStart,
getTriggerFromProperty(args && args.length > 1 ? [args[1]] : undefined)
);
let env: string | undefined;
if (args && args.length > 0) {
const filePath = args[0].fsPath as string;
if (!filePath.endsWith("manifest.template.json")) {
const envReg = /manifest\.(\w+)\.json$/;
const result = envReg.exec(filePath);
if (result && result.length >= 2) {
env = result[1];
}
}
}

const inputs = getSystemInputs();
const result = await runCommand(Stage.deployTeams, inputs);

if (!args || args.length === 0) {
const workspacePath = workspaceUri?.fsPath;
const inputs = getSystemInputs();
inputs.ignoreEnvInfo = true;
const env = await core.getSelectedEnv(inputs);
if (env.isErr()) {
ExtTelemetry.sendTelemetryErrorEvent(TelemetryEvent.UpdatePreviewManifest, env.error);
return err(env.error);
}
const manifestPath = `${
workspacePath as string
}/${AppPackageFolderName}/${BuildFolderName}/manifest.${env.value as string}.json`;
void workspace.openTextDocument(manifestPath).then((document) => {
void window.showTextDocument(document);
});
}
return result;
}

export async function copilotPluginAddAPIHandler(args: any[]) {
// Telemetries are handled in runCommand()
const inputs = getSystemInputs();
Expand Down
127 changes: 1 addition & 126 deletions packages/vscode-extension/test/extension/handlers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ import * as vscode from "vscode";
import { AzureAccountManager } from "../../src/commonlib/azureLogin";
import { signedIn, signedOut } from "../../src/commonlib/common/constant";
import VsCodeLogInstance, { VsCodeLogProvider } from "../../src/commonlib/log";
import M365TokenInstance, { M365Login } from "../../src/commonlib/m365Login";
import M365TokenInstance from "../../src/commonlib/m365Login";
import { DeveloperPortalHomeLink, GlobalKey } from "../../src/constants";
import { PanelType } from "../../src/controls/PanelType";
import { WebviewPanel } from "../../src/controls/webviewPanel";
Expand Down Expand Up @@ -102,37 +102,6 @@ describe("handlers", () => {
sandbox.restore();
});

it("buildPackageHandler()", async () => {
sandbox.stub(globalVariables, "core").value(new MockCore());
sandbox.stub(globalVariables.core, "createAppPackage").resolves(err(new UserCancelError()));
sandbox.stub(ExtTelemetry, "sendTelemetryEvent");
const sendTelemetryErrorEvent = sandbox.stub(ExtTelemetry, "sendTelemetryErrorEvent");

await handlers.buildPackageHandler();

// should show error for invalid project
sinon.assert.calledOnce(sendTelemetryErrorEvent);
});

it("validateManifestHandler() - app package", async () => {
sandbox.stub(globalVariables, "core").value(new MockCore());
sandbox.stub(ExtTelemetry, "sendTelemetryEvent");
sandbox.stub(ExtTelemetry, "sendTelemetryErrorEvent");
sandbox.stub(localizeUtils, "localize").returns("");
sandbox.stub(projectSettingsHelper, "isValidProject").returns(true);
sandbox.stub(systemEnvUtils, "getSystemInputs").returns({} as Inputs);
const validateApplication = sandbox.spy(globalVariables.core, "validateApplication");

sandbox.stub(vsc_ui, "VS_CODE_UI").value({
selectOption: () => {
return Promise.resolve(ok({ type: "success", result: "validateAgainstPackage" }));
},
});

await handlers.validateManifestHandler();
sinon.assert.calledOnce(validateApplication);
});

it("API ME: copilotPluginAddAPIHandler()", async () => {
sandbox.stub(globalVariables, "core").value(new MockCore());
const addAPIHanlder = sandbox.spy(globalVariables.core, "copilotPluginAddAPI");
Expand Down Expand Up @@ -1282,80 +1251,6 @@ describe("handlers", () => {
});
});

describe("publishInDeveloperPortalHandler", async () => {
const sandbox = sinon.createSandbox();

beforeEach(() => {
sandbox.stub(globalVariables, "workspaceUri").value(vscode.Uri.file("path"));
});

afterEach(() => {
sandbox.restore();
});

it("publish in developer portal - success", async () => {
sandbox.stub(globalVariables, "core").value(new MockCore());
sandbox.stub(vsc_ui, "VS_CODE_UI").value(new VsCodeUI(<vscode.ExtensionContext>{}));
sandbox
.stub(vsc_ui.VS_CODE_UI, "selectFile")
.resolves(ok({ type: "success", result: "test.zip" }));
const publish = sandbox.spy(globalVariables.core, "publishInDeveloperPortal");
sandbox
.stub(vsc_ui.VS_CODE_UI, "selectOption")
.resolves(ok({ type: "success", result: "test.zip" }));
sandbox.stub(ExtTelemetry, "sendTelemetryEvent");
sandbox.stub(ExtTelemetry, "sendTelemetryErrorEvent");
sandbox.stub(vscode.commands, "executeCommand");
sandbox.stub(fs, "pathExists").resolves(true);
sandbox.stub(fs, "readdir").resolves(["test.zip", "test.json"] as any);

const res = await handlers.publishInDeveloperPortalHandler();
if (res.isErr()) {
console.log(res.error);
}
chai.assert.isTrue(publish.calledOnce);
chai.assert.isTrue(res.isOk());
});

it("publish in developer portal - cancelled", async () => {
sandbox.stub(globalVariables, "core").value(new MockCore());
sandbox.stub(vsc_ui, "VS_CODE_UI").value(new VsCodeUI(<vscode.ExtensionContext>{}));
sandbox
.stub(vsc_ui.VS_CODE_UI, "selectFile")
.resolves(ok({ type: "success", result: "test2.zip" }));
const publish = sandbox.spy(globalVariables.core, "publishInDeveloperPortal");
sandbox.stub(vsc_ui.VS_CODE_UI, "selectOption").resolves(err(new UserCancelError("VSC")));
sandbox.stub(ExtTelemetry, "sendTelemetryEvent");
sandbox.stub(ExtTelemetry, "sendTelemetryErrorEvent");
sandbox.stub(vscode.commands, "executeCommand");
sandbox.stub(fs, "pathExists").resolves(true);
sandbox.stub(fs, "readdir").resolves(["test.zip", "test.json"] as any);

const res = await handlers.publishInDeveloperPortalHandler();
if (res.isErr()) {
console.log(res.error);
}
chai.assert.isTrue(publish.notCalled);
chai.assert.isTrue(res.isOk());
});

it("select file error", async () => {
sandbox.stub(globalVariables, "core").value(new MockCore());
sandbox.stub(vsc_ui, "VS_CODE_UI").value(new VsCodeUI(<vscode.ExtensionContext>{}));
sandbox.stub(vsc_ui.VS_CODE_UI, "selectFile").resolves(err(new UserCancelError("VSC")));
const publish = sandbox.spy(globalVariables.core, "publishInDeveloperPortal");
sandbox.stub(ExtTelemetry, "sendTelemetryEvent");
sandbox.stub(ExtTelemetry, "sendTelemetryErrorEvent");
sandbox.stub(vscode.commands, "executeCommand");
sandbox.stub(fs, "pathExists").resolves(true);
sandbox.stub(fs, "readdir").resolves(["test.zip", "test.json"] as any);

const res = await handlers.publishInDeveloperPortalHandler();
chai.assert.isTrue(res.isOk());
chai.assert.isFalse(publish.calledOnce);
});
});

describe("openAppManagement", async () => {
const sandbox = sinon.createSandbox();

Expand Down Expand Up @@ -1742,26 +1637,6 @@ describe("handlers", () => {
chai.assert.equal(actualPath, path.delimiter);
});
});

describe("others", function () {
const sandbox = sinon.createSandbox();
afterEach(() => {
sandbox.restore();
});

it("updatePreviewManifest", async () => {
sandbox.stub(globalVariables, "core").value(new MockCore());
sandbox.stub(ExtTelemetry, "sendTelemetryEvent");
sandbox.stub(ExtTelemetry, "sendTelemetryErrorEvent");
const openTextDocumentStub = sandbox
.stub(vscode.workspace, "openTextDocument")
.returns(Promise.resolve("" as any));

await handlers.updatePreviewManifest([]);

chai.assert.isTrue(openTextDocumentStub.calledOnce);
});
});
});

describe("openPreviewAadFile", () => {
Expand Down
Loading