Skip to content

Commit

Permalink
Adds interactivity for planner commands. Closes #5902
Browse files Browse the repository at this point in the history
  • Loading branch information
milanholemans authored and martinlingstuyl committed May 6, 2024
1 parent 8348e18 commit c50e1c9
Show file tree
Hide file tree
Showing 34 changed files with 655 additions and 791 deletions.
83 changes: 11 additions & 72 deletions src/m365/planner/commands/bucket/bucket-add.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,43 +28,7 @@ describe(commands.BUCKET_ADD, () => {
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#groups",
"value": [
{
"id": "0d0402ee-970f-4951-90b5-2f24519d2e40",
"deletedDateTime": null,
"classification": null,
"createdDateTime": "2021-06-08T11:04:45Z",
"creationOptions": [],
"description": "My Planner Group",
"displayName": "My Planner Group",
"expirationDateTime": null,
"groupTypes": [
"Unified"
],
"isAssignableToRole": null,
"mail": "MyPlannerGroup@contoso.onmicrosoft.com",
"mailEnabled": true,
"mailNickname": "My Planner Group",
"membershipRule": null,
"membershipRuleProcessingState": null,
"onPremisesDomainName": null,
"onPremisesLastSyncDateTime": null,
"onPremisesNetBiosName": null,
"onPremisesSamAccountName": null,
"onPremisesSecurityIdentifier": null,
"onPremisesSyncEnabled": null,
"preferredDataLocation": null,
"preferredLanguage": null,
"proxyAddresses": [
"SPO:SPO_e13f6193-fb01-43e8-8e8d-557796b82ebf@SPO_cc6fafe9-dd93-497c-b521-1d971b1471c7",
"SMTP:MyPlannerGroup@contoso.onmicrosoft.com"
],
"renewedDateTime": "2021-06-08T11:04:45Z",
"resourceBehaviorOptions": [],
"resourceProvisioningOptions": [],
"securityEnabled": false,
"securityIdentifier": "S-1-12-1-218366702-1230083855-573552016-1076796785",
"theme": null,
"visibility": "Private",
"onPremisesProvisioningErrors": []
"id": "0d0402ee-970f-4951-90b5-2f24519d2e40"
}
]
};
Expand All @@ -74,47 +38,22 @@ describe(commands.BUCKET_ADD, () => {
"@odata.count": 2,
"value": [
{
"@odata.etag": "W/\"JzEtUGxhbiAgQEBAQEBAQEBAQEBAQEBASCc=\"",
"createdDateTime": "2021-06-08T12:24:57.3312829Z",
"owner": "f3f985d0-a4e0-4891-83f6-08d88bf44e5e",
"title": "My Planner Plan",
"id": "iVPMIgdku0uFlou-KLNg6MkAE1O2",
"createdBy": {
"user": {
"displayName": null,
"id": "73829066-5f0a-4745-8f72-12a17bacadea"
},
"application": {
"displayName": null,
"id": "09abbdfd-ed25-47ee-a2d9-a627aa1c90f3"
}
}
"id": "iVPMIgdku0uFlou-KLNg6MkAE1O2"
},
{
"@odata.etag": "W/\"JzEtUGxhbiAgQEBAQEBAQEBAQEBAQEBASCc=\"",
"createdDateTime": "2021-06-08T12:25:09.3751058Z",
"owner": "f3f985d0-a4e0-4891-83f6-08d88bf44e5e",
"title": "Sample Plan",
"id": "uO1bj3fdekKuMitpeJqaj8kADBxO",
"createdBy": {
"user": {
"displayName": null,
"id": "73829066-5f0a-4745-8f72-12a17bacadea"
},
"application": {
"displayName": null,
"id": "09abbdfd-ed25-47ee-a2d9-a627aa1c90f3"
}
}
"id": "uO1bj3fdekKuMitpeJqaj8kADBxO"
}
]
};

const planResponse = {
value: [{
id: 'iVPMIgdku0uFlou-KLNg6MkAE1O2',
title: 'My Planner Plan'
}]
value: [
{
id: 'iVPMIgdku0uFlou-KLNg6MkAE1O2'
}
]
};

let log: string[];
Expand Down Expand Up @@ -147,13 +86,13 @@ describe(commands.BUCKET_ADD, () => {
throw 'Invalid request';
});
sinon.stub(request, 'get').callsFake(async (opts) => {
if (opts.url === `https://graph.microsoft.com/beta/planner/rosters/RuY-PSpdw02drevnYDTCJpgAEfoI/plans`) {
if (opts.url === `https://graph.microsoft.com/beta/planner/rosters/RuY-PSpdw02drevnYDTCJpgAEfoI/plans?$select=id`) {
return planResponse;
}
if (opts.url === `https://graph.microsoft.com/v1.0/groups?$filter=displayName eq '${formatting.encodeQueryParameter('My Planner Group')}'`) {
if (opts.url === `https://graph.microsoft.com/v1.0/groups?$filter=displayName eq '${formatting.encodeQueryParameter('My Planner Group')}'&$select=id`) {
return groupByDisplayNameResponse;
}
if (opts.url === `https://graph.microsoft.com/v1.0/groups/0d0402ee-970f-4951-90b5-2f24519d2e40/planner/plans`) {
if (opts.url === `https://graph.microsoft.com/v1.0/groups/0d0402ee-970f-4951-90b5-2f24519d2e40/planner/plans?$select=id,title`) {
return plansInOwnerGroup;
}
throw 'Invalid request';
Expand Down
11 changes: 4 additions & 7 deletions src/m365/planner/commands/bucket/bucket-add.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ class PlannerBucketAddCommand extends GraphCommand {
const requestOptions: CliRequestOptions = {
url: `${this.resource}/v1.0/planner/buckets`,
headers: {
'accept': 'application/json;odata.metadata=none'
accept: 'application/json;odata.metadata=none'
},
responseType: 'json',
data: {
Expand All @@ -141,21 +141,18 @@ class PlannerBucketAddCommand extends GraphCommand {

if (args.options.planTitle) {
const groupId: string = await this.getGroupId(args);
const plan = await planner.getPlanByTitle(args.options.planTitle, groupId);
return plan.id!;
return planner.getPlanIdByTitle(args.options.planTitle, groupId);
}

const plan = await planner.getPlanByRosterId(args.options.rosterId!);
return plan.id!;
return planner.getPlanIdByRosterId(args.options.rosterId!);
}

private async getGroupId(args: CommandArgs): Promise<string> {
if (args.options.ownerGroupId) {
return args.options.ownerGroupId;
}

const group = await entraGroup.getGroupByDisplayName(args.options.ownerGroupName!);
return group.id!;
return entraGroup.getGroupIdByDisplayName(args.options.ownerGroupName!);
}
}

Expand Down
29 changes: 11 additions & 18 deletions src/m365/planner/commands/bucket/bucket-get.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,10 @@ describe(commands.BUCKET_GET, () => {
const multipleGroupResponse = {
"value": [
{
"id": validOwnerGroupId,
"displayName": validOwnerGroupName
"id": validOwnerGroupId
},
{
"id": validOwnerGroupId,
"displayName": validOwnerGroupName
"id": validOwnerGroupId
}
]
};
Expand All @@ -59,28 +57,24 @@ describe(commands.BUCKET_GET, () => {
const singleBucketByNameResponse = {
"value": [
{
"@odata.etag": "W/\"JzEtQnVja2V0QEBAQEBAQEBAQEBAQEBARCc=\"",
"name": validBucketName,
"id": validBucketId
}
]
};

const singleBucketByIdResponse = {
"@odata.etag": "W/\"JzEtQnVja2V0QEBAQEBAQEBAQEBAQEBARCc=\"",
"name": validBucketName,
"id": validBucketId
};

const multipleBucketByNameResponse = {
"value": [
{
"@odata.etag": "W/\"JzEtQnVja2V0QEBAQEBAQEBAQEBAQEBARCc=\"",
"name": validBucketName,
"id": validBucketId
},
{
"@odata.etag": "W/\"JzEtQnVja2V0QEBAQEBAQEBAQEBAQEBARCc=\"",
"name": validBucketName,
"id": validBucketId
}
Expand Down Expand Up @@ -263,7 +257,7 @@ describe(commands.BUCKET_GET, () => {
it('fails validation when no groups found', async () => {
sinon.stub(request, 'get').callsFake(async (opts) => {

if (opts.url === `https://graph.microsoft.com/v1.0/groups?$filter=displayName eq '${formatting.encodeQueryParameter(validOwnerGroupName)}'`) {
if (opts.url === `https://graph.microsoft.com/v1.0/groups?$filter=displayName eq '${formatting.encodeQueryParameter(validOwnerGroupName)}'&$select=id`) {
return { "value": [] };
}

Expand All @@ -290,7 +284,7 @@ describe(commands.BUCKET_GET, () => {

sinon.stub(request, 'get').callsFake(async (opts) => {

if (opts.url === `https://graph.microsoft.com/v1.0/groups?$filter=displayName eq '${formatting.encodeQueryParameter(validOwnerGroupName)}'`) {
if (opts.url === `https://graph.microsoft.com/v1.0/groups?$filter=displayName eq '${formatting.encodeQueryParameter(validOwnerGroupName)}'&$select=id`) {
return multipleGroupResponse;
}

Expand All @@ -308,7 +302,6 @@ describe(commands.BUCKET_GET, () => {

it('fails validation when no buckets found', async () => {
sinon.stub(request, 'get').callsFake(async (opts) => {

if (opts.url === `https://graph.microsoft.com/v1.0/planner/plans/${validPlanId}/buckets`) {
return { "value": [] };
}
Expand All @@ -321,7 +314,7 @@ describe(commands.BUCKET_GET, () => {
name: validBucketName,
planId: validPlanId
}
}), new CommandError(`The specified bucket ${validBucketName} does not exist`));
}), new CommandError(`The specified bucket '${validBucketName}' does not exist.`));
});

it('fails validation when multiple buckets found', async () => {
Expand Down Expand Up @@ -352,10 +345,10 @@ describe(commands.BUCKET_GET, () => {

it('handles selecting single result when multiple groups with the specified name found and cli is set to prompt', async () => {
sinon.stub(request, 'get').callsFake(async (opts) => {
if (opts.url === `https://graph.microsoft.com/v1.0/groups?$filter=displayName eq '${formatting.encodeQueryParameter(validOwnerGroupName)}'`) {
if (opts.url === `https://graph.microsoft.com/v1.0/groups?$filter=displayName eq '${formatting.encodeQueryParameter(validOwnerGroupName)}'&$select=id`) {
return singleGroupResponse;
}
if (opts.url === `https://graph.microsoft.com/v1.0/groups/${validOwnerGroupId}/planner/plans`) {
if (opts.url === `https://graph.microsoft.com/v1.0/groups/${validOwnerGroupId}/planner/plans?$select=id,title`) {
return singlePlanResponse;
}
if (opts.url === `https://graph.microsoft.com/v1.0/planner/plans/${validPlanId}/buckets`) {
Expand Down Expand Up @@ -399,10 +392,10 @@ describe(commands.BUCKET_GET, () => {
it('correctly gets bucket by name', async () => {
sinon.stub(request, 'get').callsFake(async (opts) => {

if (opts.url === `https://graph.microsoft.com/v1.0/groups?$filter=displayName eq '${formatting.encodeQueryParameter(validOwnerGroupName)}'`) {
if (opts.url === `https://graph.microsoft.com/v1.0/groups?$filter=displayName eq '${formatting.encodeQueryParameter(validOwnerGroupName)}'&$select=id`) {
return singleGroupResponse;
}
if (opts.url === `https://graph.microsoft.com/v1.0/groups/${validOwnerGroupId}/planner/plans`) {
if (opts.url === `https://graph.microsoft.com/v1.0/groups/${validOwnerGroupId}/planner/plans?$select=id,title`) {
return singlePlanResponse;
}
if (opts.url === `https://graph.microsoft.com/v1.0/planner/plans/${validPlanId}/buckets`) {
Expand All @@ -427,7 +420,7 @@ describe(commands.BUCKET_GET, () => {
it('correctly gets bucket by plan title and owner group ID', async () => {
sinon.stub(request, 'get').callsFake(async (opts) => {

if (opts.url === `https://graph.microsoft.com/v1.0/groups/${validOwnerGroupId}/planner/plans`) {
if (opts.url === `https://graph.microsoft.com/v1.0/groups/${validOwnerGroupId}/planner/plans?$select=id,title`) {
return singlePlanResponse;
}
if (opts.url === `https://graph.microsoft.com/v1.0/planner/plans/${validPlanId}/buckets`) {
Expand All @@ -451,7 +444,7 @@ describe(commands.BUCKET_GET, () => {

it('correctly gets bucket by roster id', async () => {
sinon.stub(request, 'get').callsFake(async (opts) => {
if (opts.url === `https://graph.microsoft.com/beta/planner/rosters/${validRosterId}/plans`) {
if (opts.url === `https://graph.microsoft.com/beta/planner/rosters/${validRosterId}/plans?$select=id`) {
return planResponse;
}
if (opts.url === `https://graph.microsoft.com/v1.0/planner/plans/${validPlanId}/buckets`) {
Expand Down
42 changes: 7 additions & 35 deletions src/m365/planner/commands/bucket/bucket-get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import { planner } from '../../../../utils/planner.js';
import { validation } from '../../../../utils/validation.js';
import GraphCommand from '../../../base/GraphCommand.js';
import commands from '../../commands.js';
import { cli } from '../../../../cli/cli.js';
import { formatting } from '../../../../utils/formatting.js';

interface CommandArgs {
options: Options;
Expand Down Expand Up @@ -137,45 +135,22 @@ class PlannerBucketGetCommand extends GraphCommand {

public async commandAction(logger: Logger, args: CommandArgs): Promise<void> {
try {
const bucketId = await this.getBucketId(args);
const bucket = await this.getBucketById(bucketId);
const bucket = await this.getBucket(args);
await logger.log(bucket);
}
catch (err: any) {
this.handleRejectedODataJsonPromise(err);
}
}

private async getBucketId(args: CommandArgs): Promise<string> {
private async getBucket(args: CommandArgs): Promise<PlannerBucket> {
const { id, name } = args.options;
if (id) {
return id;
return this.getBucketById(id);
}

const planId = await this.getPlanId(args);
const requestOptions: CliRequestOptions = {
url: `${this.resource}/v1.0/planner/plans/${planId}/buckets`,
headers: {
accept: 'application/json;odata.metadata=none'
},
responseType: 'json'
};

const buckets = await request.get<{ value: PlannerBucket[] }>(requestOptions);

const filteredBuckets = buckets.value.filter(b => name!.toLowerCase() === b.name!.toLowerCase());

if (!filteredBuckets.length) {
throw `The specified bucket ${name} does not exist`;
}

if (filteredBuckets.length > 1) {
const resultAsKeyValuePair = formatting.convertArrayToHashTable('id', filteredBuckets);
const result = await cli.handleMultipleResultsFound<PlannerBucket>(`Multiple buckets with name '${name}' found.`, resultAsKeyValuePair);
return result.id!.toString();
}

return filteredBuckets[0].id!.toString();
return planner.getBucketByTitle(name!, planId);
}

private async getPlanId(args: CommandArgs): Promise<string> {
Expand All @@ -187,12 +162,10 @@ class PlannerBucketGetCommand extends GraphCommand {

if (planTitle) {
const groupId: string = await this.getGroupId(args);
const plan = await planner.getPlanByTitle(planTitle, groupId);
return plan.id!;
return planner.getPlanIdByTitle(planTitle, groupId);
}

const plan = await planner.getPlanByRosterId(rosterId!);
return plan.id!;
return planner.getPlanIdByRosterId(rosterId!);
}

private async getBucketById(id: string): Promise<PlannerBucket> {
Expand All @@ -214,8 +187,7 @@ class PlannerBucketGetCommand extends GraphCommand {
return ownerGroupId;
}

const group = await entraGroup.getGroupByDisplayName(ownerGroupName!);
return group.id!;
return entraGroup.getGroupIdByDisplayName(ownerGroupName!);
}
}

Expand Down
Loading

0 comments on commit c50e1c9

Please sign in to comment.