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

fix: inform user to generate an API key before debugging the API ME/API Plugin with API Key auth templates #11992

Merged
merged 8 commits into from
Jul 17, 2024
Merged
3 changes: 3 additions & 0 deletions packages/vscode-extension/package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,9 @@
"teamstoolkit.handlers.provisionDescription": "[%s] is successfully created at [local address](%s). Continue to provision and then you can preview the app.",
"teamstoolkit.handlers.provisionDescription.fallback": "[%s] is successfully created at %s. Continue to provision and then you can preview the app.",
"teamstoolkit.handlers.provisionTitle": "Provision",
"teamstoolkit.handlers.manualStepRequired": "[%s] is created at [local address](%s). Follow the instructions in README file to preview your app.",
"teamstoolkit.handlers.manualStepRequired.fallback": "[%s] is created at %s. Follow the instructions in README file to preview your app.",
"teamstoolkit.handlers.manualStepRequiredTitle": "Open README",
"teamstoolkit.handlers.referLinkForMoreDetails": "Please refer to this link for more details: ",
"teamstoolkit.handlers.reportIssue": "Report Issue",
"teamstoolkit.handlers.similarIssues": "Similar Issues",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,9 @@ export enum TelemetryEvent {
ShowProvisionNotification = "show-provision-notification",
ClickProvision = "click-provision",

ShowManualStepRequiredNotification = "show-manual-step-required-notification",
ClickReadManualStep = "click-read-manual-step",

ShowLocalDebugNotification = "show-local-debug-notification",
ShowLocalPreviewNotification = "show-local-preview-notification",
ClickLocalDebug = "click-local-debug",
Expand Down
30 changes: 29 additions & 1 deletion packages/vscode-extension/src/utils/autoOpenHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { getAppName } from "./appDefinitionUtils";
import { getLocalDebugMessageTemplate } from "./commonUtils";
import { localize } from "./localizeUtils";
import { VS_CODE_UI } from "../qm/vsc_ui";
import { openReadMeHandler } from "../handlers/readmeHandlers";

export async function showLocalDebugMessage() {
const shouldShowLocalDebugMessage = (await globalStateGet(
Expand All @@ -44,13 +45,40 @@ export async function showLocalDebugMessage() {
}

const hasLocalEnv = await fs.pathExists(path.join(workspaceUri!.fsPath, "teamsapp.local.yml"));
const hasKeyGenJsFile = await fs.pathExists(path.join(workspaceUri!.fsPath, "/src/keyGen.js"));
const hasKeyGenTsFile = await fs.pathExists(path.join(workspaceUri!.fsPath, "/src/keyGen.ts"));

const appName = (await getAppName()) ?? localize("teamstoolkit.handlers.fallbackAppName");
const isWindows = process.platform === "win32";
const folderLink = encodeURI(workspaceUri!.toString());
const openFolderCommand = `command:fx-extension.openFolder?%5B%22${folderLink}%22%5D`;

if (hasLocalEnv) {
if (hasKeyGenJsFile || hasKeyGenTsFile) {
const openReadMe = {
title: localize("teamstoolkit.handlers.manualStepRequiredTitle"),
run: async (): Promise<void> => {
await openReadMeHandler([TelemetryTriggerFrom.Notification]);
},
};
ExtTelemetry.sendTelemetryEvent(TelemetryEvent.ShowManualStepRequiredNotification);
const message = isWindows
? util.format(
localize("teamstoolkit.handlers.manualStepRequired"),
appName,
openFolderCommand
)
: util.format(
localize("teamstoolkit.handlers.manualStepRequired.fallback"),
appName,
workspaceUri?.fsPath
);
void vscode.window.showInformationMessage(message, openReadMe).then((selection) => {
if (selection?.title === localize("teamstoolkit.handlers.manualStepRequiredTitle")) {
ExtTelemetry.sendTelemetryEvent(TelemetryEvent.ClickReadManualStep);
void selection.run();
}
});
} else if (hasLocalEnv) {
const localDebug = {
title: localize("teamstoolkit.handlers.localDebugTitle"),
run: async (): Promise<void> => {
Expand Down
225 changes: 219 additions & 6 deletions packages/vscode-extension/test/utils/autoOpenHelper.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import * as appDefinitionUtils from "../../src/utils/appDefinitionUtils";
import { ok } from "@microsoft/teamsfx-api";
import { ExtTelemetry } from "../../src/telemetry/extTelemetry";
import { showLocalDebugMessage } from "../../src/utils/autoOpenHelper";
import * as readmeHandlers from "../../src/handlers/readmeHandlers";

describe("autoOpenHelper", () => {
const sandbox = sinon.createSandbox();
Expand All @@ -21,7 +22,7 @@ describe("autoOpenHelper", () => {
sandbox.stub(vscode.workspace, "workspaceFolders").value([{ uri: vscode.Uri.file("test") }]);
sandbox.stub(vscode.workspace, "openTextDocument");
sandbox.stub(process, "platform").value("win32");
sandbox.stub(fs, "pathExists").resolves(true);
sandbox.stub(fs, "pathExists").onFirstCall().resolves(true);
const runLocalDebug = sandbox.stub(runIconHandlers, "selectAndDebug").resolves(ok(null));

sandbox.stub(globalState, "globalStateGet").callsFake(async (key: string) => {
Expand Down Expand Up @@ -55,7 +56,7 @@ describe("autoOpenHelper", () => {
sandbox.stub(vscode.workspace, "workspaceFolders").value([{ uri: vscode.Uri.file("test") }]);
sandbox.stub(vscode.workspace, "openTextDocument");
sandbox.stub(process, "platform").value("linux");
sandbox.stub(fs, "pathExists").resolves(true);
sandbox.stub(fs, "pathExists").onFirstCall().resolves(true);
const runLocalDebug = sandbox.stub(runIconHandlers, "selectAndDebug").resolves(ok(null));

sandbox.stub(globalState, "globalStateGet").callsFake(async (key: string) => {
Expand Down Expand Up @@ -89,7 +90,7 @@ describe("autoOpenHelper", () => {
sandbox.stub(vscode.workspace, "workspaceFolders").value([{ uri: vscode.Uri.file("test") }]);
sandbox.stub(vscode.workspace, "openTextDocument");
sandbox.stub(process, "platform").value("win32");
sandbox.stub(fs, "pathExists").resolves(true);
sandbox.stub(fs, "pathExists").onFirstCall().resolves(true);
const runLocalDebug = sandbox.stub(runIconHandlers, "selectAndDebug").resolves(ok(null));

sandbox.stub(globalState, "globalStateGet").callsFake(async (key: string) => {
Expand Down Expand Up @@ -120,7 +121,7 @@ describe("autoOpenHelper", () => {
sandbox.stub(vscode.workspace, "workspaceFolders").value([{ uri: vscode.Uri.file("test") }]);
sandbox.stub(vscode.workspace, "openTextDocument");
sandbox.stub(process, "platform").value("win32");
sandbox.stub(fs, "pathExists").resolves(false);
sandbox.stub(fs, "pathExists").onFirstCall().resolves(false);

sandbox.stub(globalState, "globalStateGet").callsFake(async (key: string) => {
if (key === "ShowLocalDebugMessage") {
Expand Down Expand Up @@ -155,7 +156,7 @@ describe("autoOpenHelper", () => {
sandbox.stub(appDefinitionUtils, "getAppName").resolves("");
sandbox.stub(vscode.workspace, "openTextDocument");
sandbox.stub(process, "platform").value("linux");
sandbox.stub(fs, "pathExists").resolves(false);
sandbox.stub(fs, "pathExists").onFirstCall().resolves(false);

sandbox.stub(globalState, "globalStateGet").callsFake(async (key: string) => {
if (key === "ShowLocalDebugMessage") {
Expand Down Expand Up @@ -189,7 +190,7 @@ describe("autoOpenHelper", () => {
sandbox.stub(vscode.workspace, "workspaceFolders").value([{ uri: vscode.Uri.file("test") }]);
sandbox.stub(vscode.workspace, "openTextDocument");
sandbox.stub(process, "platform").value("win32");
sandbox.stub(fs, "pathExists").resolves(false);
sandbox.stub(fs, "pathExists").onFirstCall().resolves(false);

sandbox.stub(globalState, "globalStateGet").callsFake(async (key: string) => {
if (key === "ShowLocalDebugMessage") {
Expand All @@ -215,4 +216,216 @@ describe("autoOpenHelper", () => {
chai.assert.isTrue(showMessageStub.called);
chai.assert.isFalse(executeCommandStub.called);
});

it("showLocalDebugMessage() - generate an API key manually (TS - windows)", async () => {
sandbox.stub(vscode.workspace, "workspaceFolders").value([{ uri: vscode.Uri.file("test") }]);
sandbox.stub(vscode.workspace, "openTextDocument");
sandbox.stub(process, "platform").value("win32");
sandbox
.stub(fs, "pathExists")
.onFirstCall()
.resolves(true)
.onSecondCall()
.resolves(true)
.onThirdCall()
.resolves(false);
const openReadMeHandlerStub = sandbox
.stub(readmeHandlers, "openReadMeHandler")
.resolves(ok(null));

sandbox.stub(globalState, "globalStateGet").callsFake(async (key: string) => {
if (key === "ShowLocalDebugMessage") {
return true;
} else {
return false;
}
});
sandbox.stub(globalState, "globalStateUpdate");
sandbox.stub(ExtTelemetry, "sendTelemetryEvent");
sandbox.stub(globalVariables, "workspaceUri").value(vscode.Uri.file("test"));
const showMessageStub = sandbox
.stub(vscode.window, "showInformationMessage")
.callsFake(
(title: string, options: vscode.MessageOptions, ...items: vscode.MessageItem[]) => {
return Promise.resolve({
title: "Open README",
run: (options as any).run,
} as vscode.MessageItem);
}
);

await showLocalDebugMessage();

chai.assert.isTrue(showMessageStub.called);
chai.assert.isTrue(openReadMeHandlerStub.called);
});

it("showLocalDebugMessage() - generate an API key manually (TS - windows) not clicked", async () => {
sandbox.stub(vscode.workspace, "workspaceFolders").value([{ uri: vscode.Uri.file("test") }]);
sandbox.stub(vscode.workspace, "openTextDocument");
sandbox.stub(process, "platform").value("win32");
sandbox
.stub(fs, "pathExists")
.onFirstCall()
.resolves(true)
.onSecondCall()
.resolves(true)
.onThirdCall()
.resolves(false);
const openReadMeHandlerStub = sandbox
.stub(readmeHandlers, "openReadMeHandler")
.resolves(ok(null));

sandbox.stub(globalState, "globalStateGet").callsFake(async (key: string) => {
if (key === "ShowLocalDebugMessage") {
return true;
} else {
return false;
}
});
sandbox.stub(globalState, "globalStateUpdate");
sandbox.stub(ExtTelemetry, "sendTelemetryEvent");
sandbox.stub(globalVariables, "workspaceUri").value(vscode.Uri.file("test"));
const showMessageStub = sandbox
.stub(vscode.window, "showInformationMessage")
.callsFake(
(title: string, options: vscode.MessageOptions, ...items: vscode.MessageItem[]) => {
return Promise.resolve({
title: "Not Open README",
run: (options as any).run,
} as vscode.MessageItem);
}
);

await showLocalDebugMessage();

chai.assert.isTrue(showMessageStub.called);
chai.assert.isFalse(openReadMeHandlerStub.called);
});

it("showLocalDebugMessage() - generate an API key manually (TS - windows - non selection)", async () => {
sandbox.stub(vscode.workspace, "workspaceFolders").value([{ uri: vscode.Uri.file("test") }]);
sandbox.stub(vscode.workspace, "openTextDocument");
sandbox.stub(process, "platform").value("win32");
sandbox
.stub(fs, "pathExists")
.onFirstCall()
.resolves(true)
.onSecondCall()
.resolves(true)
.onThirdCall()
.resolves(false);
const openReadMeHandlerStub = sandbox
.stub(readmeHandlers, "openReadMeHandler")
.resolves(ok(null));

sandbox.stub(globalState, "globalStateGet").callsFake(async (key: string) => {
if (key === "ShowLocalDebugMessage") {
return true;
} else {
return false;
}
});
sandbox.stub(globalState, "globalStateUpdate");
sandbox.stub(ExtTelemetry, "sendTelemetryEvent");
sandbox.stub(globalVariables, "workspaceUri").value(vscode.Uri.file("test"));
const showMessageStub = sandbox
.stub(vscode.window, "showInformationMessage")
.callsFake(
(title: string, options: vscode.MessageOptions, ...items: vscode.MessageItem[]) => {
return Promise.resolve(undefined);
}
);

await showLocalDebugMessage();

chai.assert.isTrue(showMessageStub.called);
chai.assert.isFalse(openReadMeHandlerStub.called);
});

it("showLocalDebugMessage() - generate an API key manually (JS - windows)", async () => {
sandbox.stub(vscode.workspace, "workspaceFolders").value([{ uri: vscode.Uri.file("test") }]);
sandbox.stub(vscode.workspace, "openTextDocument");
sandbox.stub(process, "platform").value("win32");
sandbox
.stub(fs, "pathExists")
.onFirstCall()
.resolves(true)
.onSecondCall()
.resolves(false)
.onThirdCall()
.resolves(true);
const openReadMeHandlerStub = sandbox
.stub(readmeHandlers, "openReadMeHandler")
.resolves(ok(null));

sandbox.stub(globalState, "globalStateGet").callsFake(async (key: string) => {
if (key === "ShowLocalDebugMessage") {
return true;
} else {
return false;
}
});
sandbox.stub(globalState, "globalStateUpdate");
sandbox.stub(ExtTelemetry, "sendTelemetryEvent");
sandbox.stub(globalVariables, "workspaceUri").value(vscode.Uri.file("test"));
const showMessageStub = sandbox
.stub(vscode.window, "showInformationMessage")
.callsFake(
(title: string, options: vscode.MessageOptions, ...items: vscode.MessageItem[]) => {
return Promise.resolve({
title: "Open README",
run: (options as any).run,
} as vscode.MessageItem);
}
);

await showLocalDebugMessage();

chai.assert.isTrue(showMessageStub.called);
chai.assert.isTrue(openReadMeHandlerStub.called);
});

it("showLocalDebugMessage() - generate an API key manually (JS - non windows)", async () => {
sandbox.stub(vscode.workspace, "workspaceFolders").value([{ uri: vscode.Uri.file("test") }]);
sandbox.stub(vscode.workspace, "openTextDocument");
sandbox.stub(process, "platform").value("linux");
sandbox
.stub(fs, "pathExists")
.onFirstCall()
.resolves(true)
.onSecondCall()
.resolves(false)
.onThirdCall()
.resolves(true);
const openReadMeHandlerStub = sandbox
.stub(readmeHandlers, "openReadMeHandler")
.resolves(ok(null));

sandbox.stub(globalState, "globalStateGet").callsFake(async (key: string) => {
if (key === "ShowLocalDebugMessage") {
return true;
} else {
return false;
}
});
sandbox.stub(globalState, "globalStateUpdate");
sandbox.stub(ExtTelemetry, "sendTelemetryEvent");
sandbox.stub(globalVariables, "workspaceUri").value(vscode.Uri.file("test"));
const showMessageStub = sandbox
.stub(vscode.window, "showInformationMessage")
.callsFake(
(title: string, options: vscode.MessageOptions, ...items: vscode.MessageItem[]) => {
return Promise.resolve({
title: "Open README",
run: (options as any).run,
} as vscode.MessageItem);
}
);

await showLocalDebugMessage();

chai.assert.isTrue(showMessageStub.called);
chai.assert.isTrue(openReadMeHandlerStub.called);
});
});
Loading