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

New command: m365 pp website get, Closes #6259 #6486

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 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
153 changes: 153 additions & 0 deletions docs/docs/cmd/pp/website/website-get.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import Global from '/docs/cmd/_global.mdx';
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# pp website get

Gets information about the specified Power Pages websites.
nicodecleyre marked this conversation as resolved.
Show resolved Hide resolved

## Usage

```sh
m365 pp website get [options]
```

## Options

```md definition-list
`--url [url]`
nicodecleyre marked this conversation as resolved.
Show resolved Hide resolved
: The URL of the website to retrieve. Specify either `url`, `name` or `id`.

`-n, --name [name]`
: The name of the website to retrieve. Specify either `url`, `name` or `id`.

`-i, --id [id]`
: The WebSiteId (GUID) of the website to retrieve. Specify either `url`, `name` or `id`.
nicodecleyre marked this conversation as resolved.
Show resolved Hide resolved

`-e, --environmentName <environmentName>`
: The name of the environment for which to retrieve Power Pages website from.
nicodecleyre marked this conversation as resolved.
Show resolved Hide resolved
```

<Global />

## Examples

Retrieve Demo Power Pages website by name in the given environment using `name`.

```sh
m365 pp website get --name Demo --environmentName Default-d87a7535-dd31-4437-bfe1-95340acd55c5
```

Retrieve Demo Power Pages website by name in the given environment using `id`.

```sh
m365 pp website get --id 4916bb2c-91e1-4716-91d5-b6171928fac9 --environmentName Default-d87a7535-dd31-4437-bfe1-95340acd55c5
```

Retrieve Demo Power Pages website by name in the given environment using `url`.

```sh
m365 pp website get --url https://site-0uaq9.powerappsportals.com --environmentName Default-d87a7535-dd31-4437-bfe1-95340acd55c5
```

## Response

<Tabs>
<TabItem value="JSON">

```json
{
"@odata.metadata": "https://api.powerplatform.com/powerpages/environments/Default-727dc1e9-3cd1-4d1f-8102-ab5c936e52f0/websites/$metadata#Websites",
"id": "4916bb2c-91e1-4716-91d5-b6171928fac9",
"name": "Site 1",
"createdOn": "2024-10-27T12:00:03",
"templateName": "DefaultPortalTemplate",
"websiteUrl": "https://site-0uaq9.powerappsportals.com",
"tenantId": "727dc1e9-3cd1-4d1f-8102-ab5c936e52f0",
"dataverseInstanceUrl": "https://org0cd4b2b9.crm4.dynamics.com/",
"environmentName": "Contoso (default)",
"environmentId": "Default-727dc1e9-3cd1-4d1f-8102-ab5c936e52f0",
"dataverseOrganizationId": "2d58aeac-74d4-4939-98d1-e05a70a655ba",
"selectedBaseLanguage": 1033,
"customHostNames": [],
"websiteRecordId": "5eb107a6-5ac2-4e1c-a3b9-d5c21bbc10ce",
"subdomain": "site-0uaq9",
"packageInstallStatus": "Installed",
"type": "Trial",
"trialExpiringInDays": 86,
"suspendedWebsiteDeletingInDays": 93,
"packageVersion": "9.6.9.39",
"isEarlyUpgradeEnabled": false,
"isCustomErrorEnabled": true,
"applicationUserAadAppId": "3f57aca7-5051-41b2-989d-26da8af7a53e",
"ownerId": "33469a62-c3af-4cfe-b893-854eceab96da",
"status": "OperationComplete",
"siteVisibility": "private",
"dataModel": "Enhanced"
}
```

</TabItem>
<TabItem value="Text">

```text
id : 4916bb2c-91e1-4716-91d5-b6171928fac9
name : Site 1
siteVisibility: private
status : OperationComplete
subdomain : site-0uaq9
tenantId : 727dc1e9-3cd1-4d1f-8102-ab5c936e52f0
type : Trial
websiteUrl : https://site-0uaq9.powerappsportals.com
```

</TabItem>
<TabItem value="CSV">

```csv
@odata.metadata,id,name,createdOn,templateName,websiteUrl,tenantId,dataverseInstanceUrl,environmentName,environmentId,dataverseOrganizationId,selectedBaseLanguage,websiteRecordId,subdomain,packageInstallStatus,type,trialExpiringInDays,suspendedWebsiteDeletingInDays,packageVersion,isEarlyUpgradeEnabled,isCustomErrorEnabled,applicationUserAadAppId,ownerId,status,siteVisibility,dataModel
https://api.powerplatform.com/powerpages/environments/Default-727dc1e9-3cd1-4d1f-8102-ab5c936e52f0/websites/$metadata#Websites,4916bb2c-91e1-4716-91d5-b6171928fac9,Site 1,2024-10-27T12:00:03,DefaultPortalTemplate,https://site-0uaq9.powerappsportals.com,727dc1e9-3cd1-4d1f-8102-ab5c936e52f0,https://org0cd4b2b9.crm4.dynamics.com/,Contoso (default),Default-727dc1e9-3cd1-4d1f-8102-ab5c936e52f0,2d58aeac-74d4-4939-98d1-e05a70a655ba,1033,5eb107a6-5ac2-4e1c-a3b9-d5c21bbc10ce,site-0uaq9,Installed,Trial,86,93,9.6.9.39,0,1,3f57aca7-5051-41b2-989d-26da8af7a53e,33469a62-c3af-4cfe-b893-854eceab96da,OperationComplete,private,Enhanced
```

</TabItem>
<TabItem value="Markdown">

```md
# pp website get --debug "false" --verbose "false" --name "Site 1" --environmentName "Default-727dc1e9-3cd1-4d1f-8102-ab5c936e52f0"

Date: 27/10/2024

## Site 1 (4916bb2c-91e1-4716-91d5-b6171928fac9)

Property | Value
---------|-------
@odata.metadata | https://api.powerplatform.com/powerpages/environments/Default-727dc1e9-3cd1-4d1f-8102-ab5c936e52f0/websites/$metadata#Websites
id | 4916bb2c-91e1-4716-91d5-b6171928fac9
name | Site 1
createdOn | 2024-10-27T12:00:03
templateName | DefaultPortalTemplate
websiteUrl | https://site-0uaq9.powerappsportals.com
tenantId | 727dc1e9-3cd1-4d1f-8102-ab5c936e52f0
dataverseInstanceUrl | https://org0cd4b2b9.crm4.dynamics.com/
environmentName | Contoso (default)
environmentId | Default-727dc1e9-3cd1-4d1f-8102-ab5c936e52f0
dataverseOrganizationId | 2d58aeac-74d4-4939-98d1-e05a70a655ba
selectedBaseLanguage | 1033
websiteRecordId | 5eb107a6-5ac2-4e1c-a3b9-d5c21bbc10ce
subdomain | site-0uaq9
packageInstallStatus | Installed
type | Trial
trialExpiringInDays | 86
suspendedWebsiteDeletingInDays | 93
packageVersion | 9.6.9.39
isEarlyUpgradeEnabled | false
isCustomErrorEnabled | true
applicationUserAadAppId | 3f57aca7-5051-41b2-989d-26da8af7a53e
ownerId | 33469a62-c3af-4cfe-b893-854eceab96da
status | OperationComplete
siteVisibility | private
dataModel | Enhanced
```

</TabItem>
</Tabs>
9 changes: 9 additions & 0 deletions docs/src/config/sidebars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1799,6 +1799,15 @@ const sidebars: SidebarsConfig = {
id: 'cmd/pp/tenant/tenant-settings-set'
}
]
},
{
website: [
{
type: 'doc',
label: 'website get',
id: 'cmd/pp/website/website-get'
}
]
}
]
},
Expand Down
3 changes: 2 additions & 1 deletion src/m365/pp/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,6 @@ export default {
SOLUTION_PUBLISHER_LIST: `${prefix} solution publisher list`,
SOLUTION_PUBLISHER_REMOVE: `${prefix} solution publisher remove`,
TENANT_SETTINGS_LIST: `${prefix} tenant settings list`,
TENANT_SETTINGS_SET: `${prefix} tenant settings set`
TENANT_SETTINGS_SET: `${prefix} tenant settings set`,
WEBSITE_GET: `${prefix} website get`
};
212 changes: 212 additions & 0 deletions src/m365/pp/commands/website/website-get.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
import assert from 'assert';
import sinon from 'sinon';
import { z } from 'zod';
import auth from '../../../../Auth.js';
import { cli } from '../../../../cli/cli.js';
import { CommandInfo } from '../../../../cli/CommandInfo.js';
import { Logger } from '../../../../cli/Logger.js';
import { CommandError } from '../../../../Command.js';
import { telemetry } from '../../../../telemetry.js';
import { pid } from '../../../../utils/pid.js';
import { session } from '../../../../utils/session.js';
import { sinonUtil } from '../../../../utils/sinonUtil.js';
import commands from '../../commands.js';
import command from './website-get.js';
import { powerPlatform } from '../../../../utils/powerPlatform.js';
import { accessToken } from '../../../../utils/accessToken.js';

const environment = 'Default-727dc1e9-3cd1-4d1f-8102-ab5c936e52f0';
const powerPageResponse = {
"@odata.metadata": "https://api.powerplatform.com/powerpages/environments/Default-727dc1e9-3cd1-4d1f-8102-ab5c936e52f0/websites/$metadata#Websites",
"id": "4916bb2c-91e1-4716-91d5-b6171928fac9",
"name": "Site 1",
"createdOn": "2024-10-27T12:00:03",
"templateName": "DefaultPortalTemplate",
"websiteUrl": "https://site-0uaq9.powerappsportals.com",
"tenantId": "727dc1e9-3cd1-4d1f-8102-ab5c936e52f0",
"dataverseInstanceUrl": "https://org0cd4b2b9.crm4.dynamics.com/",
"environmentName": "Contoso (default)",
"environmentId": "Default-727dc1e9-3cd1-4d1f-8102-ab5c936e52f0",
"dataverseOrganizationId": "2d58aeac-74d4-4939-98d1-e05a70a655ba",
"selectedBaseLanguage": 1033,
"customHostNames": [],
"websiteRecordId": "5eb107a6-5ac2-4e1c-a3b9-d5c21bbc10ce",
"subdomain": "site-0uaq9",
"packageInstallStatus": "Installed",
"type": "Trial",
"trialExpiringInDays": 86,
"suspendedWebsiteDeletingInDays": 93,
"packageVersion": "9.6.9.39",
"isEarlyUpgradeEnabled": false,
"isCustomErrorEnabled": true,
"applicationUserAadAppId": "3f57aca7-5051-41b2-989d-26da8af7a53e",
"ownerId": "33469a62-c3af-4cfe-b893-854eceab96da",
"status": "OperationComplete",
"siteVisibility": "private",
"dataModel": "Enhanced"
};

describe(commands.WEBSITE_GET, () => {
let log: any[];
let logger: Logger;
let loggerLogSpy: sinon.SinonSpy;
let commandInfo: CommandInfo;
let commandOptionsSchema: z.ZodTypeAny;

before(() => {
sinon.stub(auth, 'restoreAuth').resolves();
sinon.stub(telemetry, 'trackEvent').returns();
sinon.stub(pid, 'getProcessName').returns('');
sinon.stub(session, 'getId').returns('');
sinon.stub(accessToken, 'assertDelegatedAccessToken').returns();
auth.connection.active = true;
commandInfo = cli.getCommandInfo(command);
commandOptionsSchema = commandInfo.command.getSchemaToParse()!;
});

beforeEach(() => {
log = [];
logger = {
log: async (msg: string) => {
log.push(msg);
},
logRaw: async (msg: string) => {
log.push(msg);
},
logToStderr: async (msg: string) => {
log.push(msg);
}
};
loggerLogSpy = sinon.spy(logger, 'log');
});

afterEach(() => {
sinonUtil.restore([
powerPlatform.getWebsiteById,
powerPlatform.getWebsiteByName,
powerPlatform.getWebsiteByUrl
]);
});

after(() => {
sinon.restore();
auth.connection.active = false;
});

it('has correct name', () => {
assert.strictEqual(command.name.startsWith(commands.WEBSITE_GET), true);
});

it('has a description', () => {
assert.notStrictEqual(command.description, null);
});

it('defines correct properties for the default output', () => {
assert.deepStrictEqual(command.defaultProperties(), ['id', 'name', 'websiteUrl', 'tenantId', 'subdomain', 'type', 'status', 'siteVisibility']);
});

it('retrieves the information for the Power Page website by url', async () => {
sinon.stub(powerPlatform, 'getWebsiteByUrl').resolves(powerPageResponse);

await command.action(logger, { options: { environmentName: environment, url: 'https://site-0uaq9.powerappsportals.com' } });
assert(loggerLogSpy.calledWith(powerPageResponse));
});

it('retrieves the information for the Power Page website by name', async () => {
sinon.stub(powerPlatform, 'getWebsiteByName').resolves(powerPageResponse);

await command.action(logger, { options: { environmentName: environment, name: 'Site 1' } });
assert(loggerLogSpy.calledWith(powerPageResponse));
});

it('retrieves the information for the Power Page website by id', async () => {
sinon.stub(powerPlatform, 'getWebsiteById').resolves(powerPageResponse);

await command.action(logger, { options: { environmentName: environment, id: '4916bb2c-91e1-4716-91d5-b6171928fac9' } });
assert(loggerLogSpy.calledWith(powerPageResponse));
});

it('correctly handles error when getting information for a site that doesn\'t exist', async () => {
sinon.stub(powerPlatform, 'getWebsiteByName').callsFake(() => { throw new Error('The specified Power Page website \'Site 1\' does not exist.'); });

await assert.rejects(command.action(logger, { options: { verbose: true, environmentName: environment, name: 'Site 1' } } as any), new CommandError('The specified Power Page website \'Site 1\' does not exist.'));
});

it('fails validation if the url option is not a valid SharePoint site URL', async () => {
const actual = commandOptionsSchema.safeParse({ environmentName: environment, url: 'https://site-0uaq9.contoso.com' });
assert.notStrictEqual(actual, true);
});

it('passes validation if the url option is a valid SharePoint site URL', async () => {
const actual = commandOptionsSchema.safeParse({ environmentName: environment, url: 'https://site-0uaq9.powerappsportals.com' });
assert.strictEqual(actual.success, true);
});

it('fails validation if url and name are used at the same time', () => {
const actual = commandOptionsSchema.safeParse({
environmentName: environment,
url: 'https://site-0uaq9.powerappsportals.com',
name: 'Site 1'
});
assert.strictEqual(actual.success, false);
});

it('fails validation if url and id are used at the same time', () => {
const actual = commandOptionsSchema.safeParse({
environmentName: environment,
url: 'https://site-0uaq9.powerappsportals.com',
id: '4916bb2c-91e1-4716-91d5-b6171928fac9'
});
assert.strictEqual(actual.success, false);
});

it('fails validation if name and id are used at the same time', () => {
const actual = commandOptionsSchema.safeParse({
environmentName: environment,
id: '4916bb2c-91e1-4716-91d5-b6171928fac9',
name: 'Site 1'
});
assert.strictEqual(actual.success, false);
});

it('passes validation with only url', () => {
const actual = commandOptionsSchema.safeParse({
environmentName: environment,
url: 'https://site-0uaq9.powerappsportals.com'
});
assert.strictEqual(actual.success, true);
});

it('passes validation with only id', () => {
const actual = commandOptionsSchema.safeParse({
environmentName: environment,
id: '4916bb2c-91e1-4716-91d5-b6171928fac9'
});
assert.strictEqual(actual.success, true);
});

it('passes validation with only name', () => {
const actual = commandOptionsSchema.safeParse({
environmentName: environment,
name: 'Site 1'
});
assert.strictEqual(actual.success, true);
});

it('fails validation if url, id, and name are all used at the same time', () => {
const actual = commandOptionsSchema.safeParse({
environmentName: environment,
url: 'https://site-0uaq9.powerappsportals.com',
id: '4916bb2c-91e1-4716-91d5-b6171928fac9',
name: 'Site 1'
});
assert.strictEqual(actual.success, false);
});

it('fails validation if neither url, id, nor name are provided', () => {
const actual = commandOptionsSchema.safeParse({
environmentName: environment
});
assert.strictEqual(actual.success, false);
});
});
Loading