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

[Power Pages][Actions Hub] Update "Change environment" option to match Figma #1130

Merged
merged 8 commits into from
Feb 19, 2025
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ import { Constants } from './Constants';
import { oneDSLoggerWrapper } from '../../../common/OneDSLoggerTelemetry/oneDSLoggerWrapper';
import { PacTerminal } from '../../lib/PacTerminal';
import { SUCCESS } from '../../../common/constants';
import { OrgListOutput } from '../../pac/PacTypes';
import { AuthInfo, OrgListOutput } from '../../pac/PacTypes';
import { extractAuthInfo } from '../commonUtility';
import { showProgressWithNotification } from '../../../common/utilities/Utils';
import PacContext from '../../pac/PacContext';
@@ -73,15 +73,16 @@ export const showEnvironmentDetails = async () => {
}
};

const getEnvironmentList = async (pacTerminal: PacTerminal): Promise<{ label: string, description: string }[]> => {
const getEnvironmentList = async (pacTerminal: PacTerminal, authInfo: AuthInfo): Promise<{ label: string, description: string, detail: string }[]> => {
const pacWrapper = pacTerminal.getWrapper();
const envListOutput = await pacWrapper.orgList();
if (envListOutput && envListOutput.Status === SUCCESS && envListOutput.Results) {
const envList = envListOutput.Results as OrgListOutput[];
return envList.map((env) => {
return {
label: env.FriendlyName,
description: env.EnvironmentUrl
detail: env.EnvironmentUrl,
description: authInfo.OrganizationFriendlyName === env.FriendlyName ? Constants.Strings.CURRENT : ""
}
});
}
@@ -94,14 +95,14 @@ export const switchEnvironment = async (pacTerminal: PacTerminal) => {
const authInfo = PacContext.AuthInfo;

if (authInfo) {
const selectedEnv = await vscode.window.showQuickPick(getEnvironmentList(pacTerminal),
const selectedEnv = await vscode.window.showQuickPick(getEnvironmentList(pacTerminal, authInfo),
{
placeHolder: vscode.l10n.t(Constants.Strings.SELECT_ENVIRONMENT)
}
);

if (selectedEnv) {
await showProgressWithNotification(Constants.Strings.CHANGING_ENVIRONMENT, async () => await pacWrapper.orgSelect(selectedEnv.description));
if (selectedEnv && selectedEnv.label !== authInfo.OrganizationFriendlyName) {
await showProgressWithNotification(Constants.Strings.CHANGING_ENVIRONMENT, async () => await pacWrapper.orgSelect(selectedEnv.detail));
}
}
}
Original file line number Diff line number Diff line change
@@ -24,6 +24,7 @@ import { SiteTreeItem } from '../../../../power-pages/actions-hub/tree-items/Sit
import { WebsiteStatus } from '../../../../power-pages/actions-hub/models/WebsiteStatus';
import { IWebsiteInfo } from '../../../../power-pages/actions-hub/models/IWebsiteInfo';
import * as WebsiteUtils from '../../../../../common/utilities/WebsiteUtil';
import * as Utils from '../../../../../common/utilities/Utils';

describe('ActionsHubCommandHandlers', () => {
let sandbox: sinon.SinonSandbox;
@@ -216,6 +217,8 @@ describe('ActionsHubCommandHandlers', () => {
let mockOrgList: sinon.SinonStub;
let mockOrgSelect: sinon.SinonStub;
let mockShowQuickPick: sinon.SinonStub;
let mockPacContext: sinon.SinonStub;
let mockShowProgressNotification: sinon.SinonStub;

const mockEnvList = [
{
@@ -239,23 +242,92 @@ describe('ActionsHubCommandHandlers', () => {
orgSelect: mockOrgSelect
});
mockShowQuickPick = sandbox.stub(vscode.window, 'showQuickPick');
mockPacContext = sinon.stub(PacContext, 'AuthInfo').get(() => ({
OrganizationFriendlyName: 'Dev Environment'
}));
mockShowProgressNotification = sinon.stub(Utils, 'showProgressWithNotification').callsFake(async (title: string, task: (progress: vscode.Progress<{
message?: string;
increment?: number;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
}>) => Promise<any>) => await task({} as unknown as vscode.Progress<{ message?: string; increment?: number }>));
});

afterEach(() => {
mockPacContext.get(() => mockAuthInfo);
mockShowProgressNotification.restore();
});

it('should switch environment successfully when env is selected', async () => {
mockOrgList.resolves({
Status: 'Success',
Results: mockEnvList
});
mockShowQuickPick.resolves({
label: 'Prod Environment',
detail: 'https://prod.crm.dynamics.com'
});
mockOrgSelect.resolves();

await switchEnvironment(mockPacTerminal as unknown as PacTerminal);

expect(mockOrgList.calledOnce).to.be.true;
expect(mockShowQuickPick.calledOnce).to.be.true;

const envList = await mockShowQuickPick.firstCall.args[0];
expect(envList).to.deep.equal([
{
label: 'Dev Environment',
detail: 'https://dev.crm.dynamics.com',
description: 'Current'
},
{
label: 'Prod Environment',
detail: 'https://prod.crm.dynamics.com',
description: ''
}
]);

expect(mockShowQuickPick.firstCall.args[1]).to.deep.equal({
placeHolder: 'Select an environment'
});
expect(mockShowProgressNotification.calledOnce, "Switch environment notification was not called").to.be.true;
expect(mockShowProgressNotification.firstCall.args[0]).to.equal('Changing environment...');
expect(mockOrgSelect.calledOnce, "Org select function was not called").to.be.true;
expect(mockOrgSelect.firstCall.args[0]).to.equal('https://prod.crm.dynamics.com');
});

it('should not switch environment when current environment is selected', async () => {
mockOrgList.resolves({
Status: 'Success',
Results: mockEnvList
});
mockShowQuickPick.resolves({
label: 'Dev Environment',
description: 'https://dev.crm.dynamics.com'
detail: 'https://dev.crm.dynamics.com'
});
mockOrgSelect.resolves();

await switchEnvironment(mockPacTerminal as unknown as PacTerminal);

expect(mockOrgList.calledOnce).to.be.true;
expect(mockShowQuickPick.calledOnce).to.be.true;

const envList = await mockShowQuickPick.firstCall.args[0];
expect(envList).to.deep.equal([
{
label: 'Dev Environment',
detail: 'https://dev.crm.dynamics.com',
description: 'Current'
},
{
label: 'Prod Environment',
detail: 'https://prod.crm.dynamics.com',
description: ''
}
]);

expect(mockShowProgressNotification.calledOnce, "Switch environment notification was called").to.be.false;
expect(mockOrgSelect.calledOnce, "Org select function was called").to.be.false;
});
});

Original file line number Diff line number Diff line change
@@ -114,35 +114,6 @@ describe("ActionsHubTreeDataProvider", () => {
});

describe('getChildren', () => {
it("should return environment group tree item with default name when no auth info is available", async () => {
const mockActiveSites = [
{ Name: "Foo", WebsiteRecordId: 'foo', WebsiteUrl: "https://foo.com" }
] as IWebsiteDetails[];
const mockInactiveSites = [
{ Name: "Bar", WebsiteRecordId: 'Bar', WebsiteUrl: "https://bar.com" }
] as IWebsiteDetails[];
sinon.stub(CommandHandlers, 'fetchWebsites').resolves({ activeSites: mockActiveSites, inactiveSites: mockInactiveSites });

PacContext['_authInfo'] = null;
const provider = ActionsHubTreeDataProvider.initialize(context, pacTerminal);
const result = await provider.getChildren();

expect(result).to.not.be.null;
expect(result).to.not.be.undefined;
expect(result).to.have.lengthOf(0);
});

it("should call element.getChildren when an element is passed", async () => {
const element = new SiteTreeItem({} as IWebsiteInfo);
const provider = ActionsHubTreeDataProvider.initialize(context, pacTerminal);
const getChildrenStub = sinon.stub(element, "getChildren").resolves([]);

const result = await provider.getChildren(element);

expect(getChildrenStub.calledOnce).to.be.true;
expect(result).to.deep.equal([]);
});

it("should return environment and other sites group tree items when auth info and Artemis context are available", async () => {
const mockActiveSites = [
{ Name: "Foo", WebsiteRecordId: 'foo', WebsiteUrl: "https://foo.com" }
@@ -195,6 +166,7 @@ describe("ActionsHubTreeDataProvider", () => {
sinon.stub(PacContext, "AuthInfo").get(() => null);

const provider = ActionsHubTreeDataProvider.initialize(context, pacTerminal);
provider["_loadWebsites"] = false;
const result = await provider.getChildren();

expect(result).to.be.an('array').that.is.empty;
@@ -219,6 +191,7 @@ describe("ActionsHubTreeDataProvider", () => {
it("should call element.getChildren when an element is passed", async () => {
const element = new SiteTreeItem({} as IWebsiteInfo);
const provider = ActionsHubTreeDataProvider.initialize(context, pacTerminal);
sinon.stub(CommandHandlers, 'fetchWebsites').resolves({ activeSites: [], inactiveSites: [] });
provider["_loadWebsites"] = false;
const getChildrenStub = sinon.stub(element, "getChildren").resolves([]);

Loading