Skip to content

Commit

Permalink
Refactor Actions Hub and Preview Site initialization logic (#1115)
Browse files Browse the repository at this point in the history
  • Loading branch information
priyanshu92 authored Feb 10, 2025
1 parent 02a86fd commit 8902752
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 58 deletions.
33 changes: 24 additions & 9 deletions src/client/power-pages/actions-hub/ActionsHub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ import { EnableActionsHub } from "../../../common/ecs-features/ecsFeatureGates";
import { ActionsHubTreeDataProvider } from "./ActionsHubTreeDataProvider";
import { oneDSLoggerWrapper } from "../../../common/OneDSLoggerTelemetry/oneDSLoggerWrapper";
import { PacTerminal } from "../../lib/PacTerminal";
import { Constants } from "./Constants";

export class ActionsHub {
private static _isInitialized = false;

static isEnabled(): boolean {
const enableActionsHub = ECSFeaturesClient.getConfig(EnableActionsHub).enableActionsHub

Expand All @@ -21,18 +25,29 @@ export class ActionsHub {
}

static async initialize(context: vscode.ExtensionContext, pacTerminal: PacTerminal): Promise<void> {
const isActionsHubEnabled = ActionsHub.isEnabled();
if (ActionsHub._isInitialized) {
return;
}

oneDSLoggerWrapper.getLogger().traceInfo("EnableActionsHub", {
isEnabled: isActionsHubEnabled.toString()
});
try {
const isActionsHubEnabled = ActionsHub.isEnabled();

vscode.commands.executeCommand("setContext", "microsoft.powerplatform.pages.actionsHubEnabled", isActionsHubEnabled);
oneDSLoggerWrapper.getLogger().traceInfo("EnableActionsHub", {
isEnabled: isActionsHubEnabled.toString()
});

if (!isActionsHubEnabled) {
return;
}
vscode.commands.executeCommand("setContext", "microsoft.powerplatform.pages.actionsHubEnabled", isActionsHubEnabled);

ActionsHubTreeDataProvider.initialize(context, pacTerminal);
if (!isActionsHubEnabled) {
return;
}

ActionsHubTreeDataProvider.initialize(context, pacTerminal);
ActionsHub._isInitialized = true;
oneDSLoggerWrapper.getLogger().traceInfo(Constants.EventNames.ACTIONS_HUB_INITIALIZED);
} catch (exception) {
const exceptionError = exception as Error;
oneDSLoggerWrapper.getLogger().traceError(Constants.EventNames.ACTIONS_HUB_INITIALIZATION_FAILED, exceptionError.message, exceptionError);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,7 @@ export class ActionsHubTreeDataProvider implements vscode.TreeDataProvider<Actio
}

public static initialize(context: vscode.ExtensionContext, pacTerminal: PacTerminal): ActionsHubTreeDataProvider {
const actionsHubTreeDataProvider = new ActionsHubTreeDataProvider(context, pacTerminal);
oneDSLoggerWrapper.getLogger().traceInfo(Constants.EventNames.ACTIONS_HUB_INITIALIZED);

return actionsHubTreeDataProvider;
return new ActionsHubTreeDataProvider(context, pacTerminal);
}

getTreeItem(element: ActionsHubTreeItem): vscode.TreeItem | Thenable<vscode.TreeItem> {
Expand Down
5 changes: 5 additions & 0 deletions src/client/power-pages/preview-site/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,8 @@ export const Messages = {
AUTHENTICATING: vscode.l10n.t("Authenticating..."),
UNABLE_TO_CLEAR_CACHE: vscode.l10n.t("Unable to clear cache"),
};

export const Events = {
PREVIEW_SITE_INITIALIZED: "PreviewSiteInitialized",
PREVIEW_SITE_INITIALIZATION_FAILED: "PreviewSiteInitializationFailed"
}
53 changes: 38 additions & 15 deletions src/client/power-pages/preview-site/PreviewSite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { getWorkspaceFolders, showProgressWithNotification } from '../../../comm
import { PacTerminal } from '../../lib/PacTerminal';
import { initializeOrgDetails } from '../../../common/utilities/OrgHandlerUtils';
import { ArtemisService } from '../../../common/services/ArtemisService';
import { Messages } from './Constants';
import { Events, Messages } from './Constants';
import { dataverseAuthentication } from '../../../common/services/AuthenticationProvider';
import { IOrgDetails } from '../../../common/chat-participants/powerpages/PowerPagesChatParticipantTypes';
import { IArtemisServiceResponse } from '../../../common/services/Interfaces';
Expand All @@ -27,6 +27,7 @@ export const SITE_PREVIEW_COMMAND_ID = "microsoft.powerplatform.pages.preview-si

export class PreviewSite {
private static _websiteUrl: string | undefined = undefined;
private static _isInitialized = false;

static isSiteRuntimePreviewEnabled(): boolean {
const enableSiteRuntimePreview = ECSFeaturesClient.getConfig(EnableSiteRuntimePreview).enableSiteRuntimePreview
Expand All @@ -45,23 +46,45 @@ export class PreviewSite {
pacTerminal: PacTerminal,
context: vscode.ExtensionContext
): Promise<void> {
const isSiteRuntimePreviewEnabled = PreviewSite.isSiteRuntimePreviewEnabled();
try {
const isSiteRuntimePreviewEnabled = PreviewSite.isSiteRuntimePreviewEnabled();

oneDSLoggerWrapper.getLogger().traceInfo("EnableSiteRuntimePreview", {
isEnabled: isSiteRuntimePreviewEnabled.toString(),
websiteURL: PreviewSite.getSiteUrl() || "undefined"
});
oneDSLoggerWrapper.getLogger().traceInfo("EnableSiteRuntimePreview", {
isEnabled: isSiteRuntimePreviewEnabled.toString(),
websiteURL: PreviewSite.getSiteUrl() || "undefined"
});

if (artemisResponse !== null && isSiteRuntimePreviewEnabled) {
context.subscriptions.push(
vscode.commands.registerCommand(
SITE_PREVIEW_COMMAND_ID,
async () => await PreviewSite.handlePreviewRequest(pacTerminal)
)
);
if (artemisResponse !== null && isSiteRuntimePreviewEnabled) {
context.subscriptions.push(
vscode.commands.registerCommand(
SITE_PREVIEW_COMMAND_ID,
async () => await PreviewSite.handlePreviewRequest(pacTerminal)
)
);

await PreviewSite.loadSiteUrl(workspaceFolders, artemisResponse?.stamp, orgDetails.EnvironmentId);
await vscode.commands.executeCommand("setContext", "microsoft.powerplatform.pages.siteRuntimePreviewEnabled", true);
if (artemisResponse !== null && isSiteRuntimePreviewEnabled) {
// Load the site URL every time org is changed
await PreviewSite.loadSiteUrl(workspaceFolders, artemisResponse?.stamp, orgDetails.EnvironmentId);

// Register the command only once during first initialization
if (!PreviewSite._isInitialized) {
context.subscriptions.push(
vscode.commands.registerCommand(
SITE_PREVIEW_COMMAND_ID,
async () => await PreviewSite.handlePreviewRequest(pacTerminal)
)
);
await vscode.commands.executeCommand("setContext", "microsoft.powerplatform.pages.siteRuntimePreviewEnabled", true);
}
}
}

await PreviewSite.loadSiteUrl(workspaceFolders, artemisResponse?.stamp, orgDetails.EnvironmentId);
await vscode.commands.executeCommand("setContext", "microsoft.powerplatform.pages.siteRuntimePreviewEnabled", true);
PreviewSite._isInitialized = true;
} catch (exception) {
const exceptionError = exception as Error;
oneDSLoggerWrapper.getLogger().traceError(Events.PREVIEW_SITE_INITIALIZATION_FAILED, exceptionError.message, exceptionError);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ import { ECSFeaturesClient } from "../../../../../common/ecs-features/ecsFeature
import { oneDSLoggerWrapper } from "../../../../../common/OneDSLoggerTelemetry/oneDSLoggerWrapper";
import { ActionsHubTreeDataProvider } from "../../../../power-pages/actions-hub/ActionsHubTreeDataProvider";
import { PacWrapper } from "../../../../pac/PacWrapper";
import { Constants } from "../../../../power-pages/actions-hub/Constants";

describe("ActionsHub", () => {
let getConfigStub: sinon.SinonStub;
let executeCommandStub: sinon.SinonStub;
let traceInfoStub: sinon.SinonStub;
let traceErrorStub: sinon.SinonStub;
let fakeContext: vscode.ExtensionContext;
let fakePacWrapper: sinon.SinonStubbedInstance<PacWrapper>;
let fakePacTerminal: sinon.SinonStubbedInstance<PacTerminal>;
Expand All @@ -28,10 +30,11 @@ describe("ActionsHub", () => {
fakePacTerminal = sinon.createStubInstance(PacTerminal, { getWrapper: fakePacWrapper });
executeCommandStub = sinon.stub(vscode.commands, "executeCommand");
traceInfoStub = sinon.stub();
traceErrorStub = sinon.stub();
sinon.stub(oneDSLoggerWrapper, "getLogger").returns({
traceInfo: traceInfoStub,
traceWarning: sinon.stub(),
traceError: sinon.stub(),
traceError: traceErrorStub,
featureUsage: sinon.stub()
});
});
Expand Down Expand Up @@ -59,39 +62,77 @@ describe("ActionsHub", () => {
});

describe("initialize", () => {
describe("when ActionsHub is enabled", () => {
it("should set context to true and return early if isEnabled returns true", async () => {
getConfigStub.returns({ enableActionsHub: true });
await ActionsHub.initialize(fakeContext, fakePacTerminal);
expect(traceInfoStub.calledWith("EnableActionsHub", { isEnabled: "true" })).to.be.true;
expect(executeCommandStub.calledWith("setContext", "microsoft.powerplatform.pages.actionsHubEnabled", true)).to.be.true;
describe("when already initialized", () => {
beforeEach(() => {
ActionsHub["_isInitialized"] = true;
});

it("should initialize ActionsHubTreeDataProvider", async () => {
getConfigStub.returns({ enableActionsHub: true });
const actionsHubTreeDataProviderStub = sinon.stub(ActionsHubTreeDataProvider, 'initialize');

it("should return early", async () => {
await ActionsHub.initialize(fakeContext, fakePacTerminal);
expect(actionsHubTreeDataProviderStub.calledWith(fakeContext)).to.be.true;

actionsHubTreeDataProviderStub.restore();
expect(executeCommandStub.called).to.be.false;
});
});

describe("when ActionsHub is disabled", () => {
it("should set context to false and return early if isEnabled returns false", async () => {
getConfigStub.returns({ enableActionsHub: false });
await ActionsHub.initialize(fakeContext, fakePacTerminal);
expect(traceInfoStub.calledWith("EnableActionsHub", { isEnabled: "false" })).to.be.true;
expect(executeCommandStub.calledWith("setContext", "microsoft.powerplatform.pages.actionsHubEnabled", false)).to.be.true;
describe("when not already initialized", () => {
beforeEach(() => {
ActionsHub["_isInitialized"] = false;
});

it("should not initialize ActionsHubTreeDataProvider", () => {
getConfigStub.returns({ enableActionsHub: false });
const actionsHubTreeDataProviderStub = sinon.stub(ActionsHubTreeDataProvider, 'initialize');
describe("when ActionsHub is enabled", () => {
let actionsHubTreeDataProviderStub: sinon.SinonStub;

beforeEach(() => {
getConfigStub.returns({ enableActionsHub: true });
actionsHubTreeDataProviderStub = sinon.stub(ActionsHubTreeDataProvider, 'initialize');
});

it("should set context to true and return early if isEnabled returns true", async () => {
await ActionsHub.initialize(fakeContext, fakePacTerminal);
expect(traceInfoStub.calledWith("EnableActionsHub", { isEnabled: "true" })).to.be.true;
expect(executeCommandStub.calledWith("setContext", "microsoft.powerplatform.pages.actionsHubEnabled", true)).to.be.true;
});

it("should initialize ActionsHubTreeDataProvider", async () => {
await ActionsHub.initialize(fakeContext, fakePacTerminal);
expect(actionsHubTreeDataProviderStub.calledWith(fakeContext)).to.be.true;

actionsHubTreeDataProviderStub.restore();
});

it("should initialize and log initialization event", async () => {
await ActionsHub.initialize(fakeContext, fakePacTerminal);

expect(traceInfoStub.calledWith(Constants.EventNames.ACTIONS_HUB_INITIALIZED)).to.be.true;
});

it("should log error if an exception is thrown during initialization", async () => {
const fakeError = new Error("fake error");
actionsHubTreeDataProviderStub.throws(fakeError);

await ActionsHub.initialize(fakeContext, fakePacTerminal);

expect(traceErrorStub.calledWith(Constants.EventNames.ACTIONS_HUB_INITIALIZATION_FAILED, fakeError.message, fakeError)).to.be.true;
});
});

describe("when ActionsHub is disabled", () => {
let actionsHubTreeDataProviderStub: sinon.SinonStub;

beforeEach(() => {
getConfigStub.returns({ enableActionsHub: false });
actionsHubTreeDataProviderStub = sinon.stub(ActionsHubTreeDataProvider, 'initialize');
});

it("should set context to false and return early if isEnabled returns false", async () => {
await ActionsHub.initialize(fakeContext, fakePacTerminal);
expect(traceInfoStub.calledWith("EnableActionsHub", { isEnabled: "false" })).to.be.true;
expect(executeCommandStub.calledWith("setContext", "microsoft.powerplatform.pages.actionsHubEnabled", false)).to.be.true;
});

ActionsHub.initialize(fakeContext, fakePacTerminal);
expect(actionsHubTreeDataProviderStub.called).to.be.false;
it("should not initialize ActionsHubTreeDataProvider", async () => {
await ActionsHub.initialize(fakeContext, fakePacTerminal);
expect(actionsHubTreeDataProviderStub.called).to.be.false;
});
});
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,6 @@ describe("ActionsHubTreeDataProvider", () => {
});

describe('initialize', () => {
it("should initialize and log initialization event", () => {
ActionsHubTreeDataProvider.initialize(context, pacTerminal);
expect(traceInfoStub.calledWith(Constants.EventNames.ACTIONS_HUB_INITIALIZED)).to.be.true;
});

it("should register refresh command", () => {
// Initialize
const actionsHubTreeDataProvider = ActionsHubTreeDataProvider.initialize(context, pacTerminal);
Expand Down

0 comments on commit 8902752

Please sign in to comment.