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 codebase to async/await – spo sitedesign get until spo sitedesign task get, Closes #5106 #5128

Closed
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
176 changes: 142 additions & 34 deletions src/m365/spo/commands/sitedesign/sitedesign-get.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,27 @@ import { sinonUtil } from '../../../../utils/sinonUtil.js';
import { spo } from '../../../../utils/spo.js';
import commands from '../../commands.js';
import command from './sitedesign-get.js';
import { settingsNames } from '../../../../settingsNames.js';

describe(commands.SITEDESIGN_GET, () => {
let cli: Cli;
let log: string[];
let logger: Logger;
let loggerLogSpy: sinon.SinonSpy;
let commandInfo: CommandInfo;

before(() => {
sinon.stub(auth, 'restoreAuth').callsFake(() => Promise.resolve());
sinon.stub(telemetry, 'trackEvent').callsFake(() => { });
sinon.stub(pid, 'getProcessName').callsFake(() => '');
sinon.stub(session, 'getId').callsFake(() => '');
sinon.stub(spo, 'getRequestDigest').callsFake(() => Promise.resolve({
cli = Cli.getInstance();
sinon.stub(auth, 'restoreAuth').resolves();
sinon.stub(telemetry, 'trackEvent').returns();
sinon.stub(pid, 'getProcessName').returns('');
sinon.stub(session, 'getId').returns('');
sinon.stub(spo, 'getRequestDigest').resolves({
FormDigestValue: 'ABC',
FormDigestTimeoutSeconds: 1800,
FormDigestExpiresAt: new Date(),
WebFullUrl: 'https://contoso.sharepoint.com'
}));
});
auth.service.connected = true;
auth.service.spoUrl = 'https://contoso.sharepoint.com';
commandInfo = Cli.getCommandInfo(command);
Expand All @@ -54,7 +57,9 @@ describe(commands.SITEDESIGN_GET, () => {

afterEach(() => {
sinonUtil.restore([
request.post
request.post,
cli.getSettingWithDefaultValue,
Cli.handleMultipleResultsFound
]);
});

Expand All @@ -65,19 +70,19 @@ describe(commands.SITEDESIGN_GET, () => {
});

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

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

it('fails to get site design when it does not exists', async () => {
sinon.stub(request, 'post').callsFake((opts) => {
sinon.stub(request, 'post').callsFake(async (opts) => {
if ((opts.url as string).indexOf(`/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GetSiteDesigns`) > -1) {
return Promise.resolve({ value: [] });
return { value: [] };
}
return Promise.reject('The specified site design does not exist');
throw 'The specified site design does not exist';
});

await assert.rejects(command.action(logger, {
Expand All @@ -89,9 +94,17 @@ describe(commands.SITEDESIGN_GET, () => {
});

it('fails when multiple site designs with same title exists', async () => {
sinon.stub(request, 'post').callsFake((opts) => {
sinon.stub(cli, 'getSettingWithDefaultValue').callsFake((settingName, defaultValue) => {
if (settingName === settingsNames.prompt) {
return false;
}

return defaultValue;
});

sinon.stub(request, 'post').callsFake(async (opts) => {
if ((opts.url as string).indexOf(`/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GetSiteDesigns`) > -1) {
return Promise.resolve({
return {
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#teams",
"@odata.count": 2,
"value": [
Expand Down Expand Up @@ -142,27 +155,124 @@ describe(commands.SITEDESIGN_GET, () => {
"Version": 1
}
]
}
);
};
}
return Promise.reject('Invalid request');
throw 'Invalid request';
});

await assert.rejects(command.action(logger, {
options: {
debug: true,
title: 'Contoso Site Design'
}
} as any), new CommandError('Multiple site designs with title Contoso Site Design found: ca360b7e-1946-4292-b854-e0ad904f1055, 88ff1405-35d0-4880-909a-97693822d261'));
} as any), new CommandError(`Multiple site designs with title 'Contoso Site Design' found. Found: ca360b7e-1946-4292-b854-e0ad904f1055, 88ff1405-35d0-4880-909a-97693822d261.`));
});

it('handles selecting single result when multiple site designs with the specified title found and cli is set to prompt', async () => {
sinon.stub(request, 'post').callsFake(async (opts) => {
if ((opts.url as string).indexOf(`/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GetSiteDesigns`) > -1) {
return {
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#teams",
"@odata.count": 2,
"value": [
{
"Description": null,
"DesignPackageId": "00000000-0000-0000-0000-000000000000",
"DesignType": "0",
"IsDefault": false,
"IsOutOfBoxTemplate": false,
"IsTenantAdminOnly": false,
"PreviewImageAltText": null,
"PreviewImageUrl": null,
"RequiresGroupConnected": false,
"RequiresTeamsConnected": false,
"RequiresYammerConnected": false,
"SiteScriptIds": [
"3aff9f82-fe6c-42d3-803f-8951d26ed854"
],
"SupportedWebTemplates": [],
"TemplateFeatures": [],
"ThumbnailUrl": null,
"Title": "Contoso Site Design",
"WebTemplate": "68",
"Id": "ca360b7e-1946-4292-b854-e0ad904f1055",
"Version": 1
},
{
"Description": null,
"DesignPackageId": "00000000-0000-0000-0000-000000000000",
"DesignType": "0",
"IsDefault": false,
"IsOutOfBoxTemplate": false,
"IsTenantAdminOnly": false,
"PreviewImageAltText": null,
"PreviewImageUrl": null,
"RequiresGroupConnected": false,
"RequiresTeamsConnected": false,
"RequiresYammerConnected": false,
"SiteScriptIds": [
"3aff9f82-fe6c-42d3-803f-8951d26ed854"
],
"SupportedWebTemplates": [],
"TemplateFeatures": [],
"ThumbnailUrl": null,
"Title": "Contoso Site Design",
"WebTemplate": "68",
"Id": "88ff1405-35d0-4880-909a-97693822d261",
"Version": 1
}
]
};
}

if ((opts.url as string).indexOf(`/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GetSiteDesignMetadata`) > -1 &&
JSON.stringify(opts.data) === JSON.stringify({
id: 'ca360b7e-1946-4292-b854-e0ad904f1055'
})) {
return {
"Description": null,
"IsDefault": false,
"PreviewImageAltText": null,
"PreviewImageUrl": null,
"SiteScriptIds": [
"449c0c6d-5380-4df2-b84b-622e0ac8ec24"
],
"Title": "Contoso REST",
"WebTemplate": "64",
"Id": "ca360b7e-1946-4292-b854-e0ad904f1055",
"Version": 1
};
}

throw 'Invalid request';
});


sinon.stub(Cli, 'handleMultipleResultsFound').resolves({ Id: 'ca360b7e-1946-4292-b854-e0ad904f1055' });

await command.action(logger, { options: { title: 'Contoso Site Design' } });
assert(loggerLogSpy.calledWith({
"Description": null,
"IsDefault": false,
"PreviewImageAltText": null,
"PreviewImageUrl": null,
"SiteScriptIds": [
"449c0c6d-5380-4df2-b84b-622e0ac8ec24"
],
"Title": "Contoso REST",
"WebTemplate": "64",
"Id": "ca360b7e-1946-4292-b854-e0ad904f1055",
"Version": 1
}));
});

it('gets information about the specified site design by id', async () => {
sinon.stub(request, 'post').callsFake((opts) => {
sinon.stub(request, 'post').callsFake(async (opts) => {
if ((opts.url as string).indexOf(`/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GetSiteDesignMetadata`) > -1 &&
JSON.stringify(opts.data) === JSON.stringify({
id: 'ca360b7e-1946-4292-b854-e0ad904f1055'
})) {
return Promise.resolve({
return {
"Description": null,
"IsDefault": false,
"PreviewImageAltText": null,
Expand All @@ -174,10 +284,10 @@ describe(commands.SITEDESIGN_GET, () => {
"WebTemplate": "64",
"Id": "ca360b7e-1946-4292-b854-e0ad904f1055",
"Version": 1
});
};
}

return Promise.reject('Invalid request');
throw 'Invalid request';
});

await command.action(logger, { options: { id: 'ca360b7e-1946-4292-b854-e0ad904f1055' } });
Expand All @@ -197,9 +307,9 @@ describe(commands.SITEDESIGN_GET, () => {
});

it('gets information about the specified site design by title', async () => {
sinon.stub(request, 'post').callsFake((opts) => {
sinon.stub(request, 'post').callsFake(async (opts) => {
if ((opts.url as string).indexOf(`/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GetSiteDesigns`) > -1) {
return Promise.resolve({
return {
"value": [
{
"Description": null,
Expand All @@ -225,14 +335,14 @@ describe(commands.SITEDESIGN_GET, () => {
"Version": 1
}
]
});
};
}

if ((opts.url as string).indexOf(`/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GetSiteDesignMetadata`) > -1 &&
JSON.stringify(opts.data) === JSON.stringify({
id: 'ca360b7e-1946-4292-b854-e0ad904f1055'
})) {
return Promise.resolve({
return {
"Description": null,
"IsDefault": false,
"PreviewImageAltText": null,
Expand All @@ -244,10 +354,10 @@ describe(commands.SITEDESIGN_GET, () => {
"WebTemplate": "68",
"Id": "ca360b7e-1946-4292-b854-e0ad904f1055",
"Version": 1
});
};
}

return Promise.reject('Invalid request');
throw 'Invalid request';
});

await command.action(logger, { options: { title: 'Contoso Site Design' } });
Expand All @@ -267,12 +377,12 @@ describe(commands.SITEDESIGN_GET, () => {
});

it('gets information about the specified site design (debug)', async () => {
sinon.stub(request, 'post').callsFake((opts) => {
sinon.stub(request, 'post').callsFake(async (opts) => {
if ((opts.url as string).indexOf(`/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GetSiteDesignMetadata`) > -1 &&
JSON.stringify(opts.data) === JSON.stringify({
id: 'ca360b7e-1946-4292-b854-e0ad904f1055'
})) {
return Promise.resolve({
return {
"Description": null,
"IsDefault": false,
"PreviewImageAltText": null,
Expand All @@ -284,10 +394,10 @@ describe(commands.SITEDESIGN_GET, () => {
"WebTemplate": "64",
"Id": "ca360b7e-1946-4292-b854-e0ad904f1055",
"Version": 1
});
};
}

return Promise.reject('Invalid request');
throw 'Invalid request';
});

await command.action(logger, { options: { debug: true, id: 'ca360b7e-1946-4292-b854-e0ad904f1055' } });
Expand All @@ -307,9 +417,7 @@ describe(commands.SITEDESIGN_GET, () => {
});

it('correctly handles error when site design not found', async () => {
sinon.stub(request, 'post').callsFake(() => {
return Promise.reject({ error: { 'odata.error': { message: { value: 'File Not Found.' } } } });
});
sinon.stub(request, 'post').rejects({ error: { 'odata.error': { message: { value: 'File Not Found.' } } } });

await assert.rejects(command.action(logger, { options: { id: 'ca360b7e-1946-4292-b854-e0ad904f1055' } } as any), new CommandError('File Not Found.'));
});
Expand Down
34 changes: 18 additions & 16 deletions src/m365/spo/commands/sitedesign/sitedesign-get.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Cli } from '../../../../cli/Cli.js';
import { Logger } from '../../../../cli/Logger.js';
import GlobalOptions from '../../../../GlobalOptions.js';
import request from '../../../../request.js';
import request, { CliRequestOptions } from '../../../../request.js';
import { formatting } from '../../../../utils/formatting.js';
import { spo } from '../../../../utils/spo.js';
import { validation } from '../../../../utils/validation.js';
import SpoCommand from '../../../base/SpoCommand.js';
Expand Down Expand Up @@ -72,34 +74,34 @@ class SpoSiteDesignGetCommand extends SpoCommand {
);
}

private getSiteDesignId(args: CommandArgs, spoUrl: string): Promise<string> {
private async getSiteDesignId(args: CommandArgs, spoUrl: string): Promise<string> {
if (args.options.id) {
return Promise.resolve(args.options.id);
return args.options.id;
}

const requestOptions: any = {
const requestOptions: CliRequestOptions = {
url: `${spoUrl}/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GetSiteDesigns`,
headers: {
accept: 'application/json;odata=nometadata'
},
responseType: 'json'
};

return request
.post<{ value: SiteDesign[] }>(requestOptions)
.then(response => {
const matchingSiteDesigns: SiteDesign[] = response.value.filter(x => x.Title === args.options.title);
const response: { value: SiteDesign[] } = await request.post<{ value: SiteDesign[] }>(requestOptions);

if (matchingSiteDesigns.length === 0) {
return Promise.reject(`The specified site design does not exist`);
}
const matchingSiteDesigns: SiteDesign[] = response.value.filter(x => x.Title === args.options.title);

if (matchingSiteDesigns.length > 1) {
return Promise.reject(`Multiple site designs with title ${args.options.title} found: ${matchingSiteDesigns.map(x => x.Id).join(', ')}`);
}
if (matchingSiteDesigns.length === 0) {
throw `The specified site design does not exist`;
}

return Promise.resolve(matchingSiteDesigns[0].Id);
});
if (matchingSiteDesigns.length > 1) {
const resultAsKeyValuePair = formatting.convertArrayToHashTable('Id', matchingSiteDesigns);
const result = await Cli.handleMultipleResultsFound<{ Id: string }>(`Multiple site designs with title '${args.options.title}' found.`, resultAsKeyValuePair);
return result.Id;
}

return matchingSiteDesigns[0].Id;
}

public async commandAction(logger: Logger, args: CommandArgs): Promise<void> {
Expand Down
Loading