Skip to content
Open
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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,5 @@ docs/.env.production.local

docs/npm-debug.log*
docs/yarn-debug.log*
docs/yarn-error.log*
docs/yarn-error.log*
.impeccable/
26 changes: 22 additions & 4 deletions src/m365/planner/commands/roster/roster-add.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import assert from 'assert';
import sinon from 'sinon';
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 request from '../../../../request.js';
Expand All @@ -10,17 +12,19 @@ import { session } from '../../../../utils/session.js';
import { powerPlatform } from '../../../../utils/powerPlatform.js';
import { sinonUtil } from '../../../../utils/sinonUtil.js';
import commands from '../../commands.js';
import command from './roster-add.js';
import command, { options } from './roster-add.js';

describe(commands.ROSTER_ADD, () => {
const rosterResponse = {
id: "8bc07d47-c06f-41e1-8f00-1c113c8f6067",
id: '8bc07d47-c06f-41e1-8f00-1c113c8f6067',
assignedSensitivityLabel: null
};

let log: string[];
let logger: Logger;
let loggerLogSpy: sinon.SinonSpy;
let commandInfo: CommandInfo;
let commandOptionsSchema: typeof options;

before(() => {
sinon.stub(auth, 'restoreAuth').resolves();
Expand All @@ -32,6 +36,8 @@ describe(commands.ROSTER_ADD, () => {
accessToken: 'abc',
expiresOn: new Date()
};
commandInfo = cli.getCommandInfo(command);
commandOptionsSchema = commandInfo.command.getSchemaToParse() as typeof options;
});

beforeEach(() => {
Expand Down Expand Up @@ -70,6 +76,18 @@ describe(commands.ROSTER_ADD, () => {
assert.notStrictEqual(command.description, null);
});

it('passes validation with no options', () => {
const actual = commandOptionsSchema.safeParse({});
assert.strictEqual(actual.success, true);
});

it('fails validation with unknown options', () => {
const actual = commandOptionsSchema.safeParse({
unknownOption: 'value'
});
assert.strictEqual(actual.success, false);
});

it('adds a new roster', async () => {
sinon.stub(request, 'post').callsFake(async opts => {
if (opts.url === 'https://graph.microsoft.com/beta/planner/rosters') {
Expand All @@ -79,15 +97,15 @@ describe(commands.ROSTER_ADD, () => {
throw `Invalid request ${opts.url}`;
});

await command.action(logger, { options: { verbose: true } });
await command.action(logger, { options: commandOptionsSchema.parse({ verbose: true }) });
assert(loggerLogSpy.calledWith(rosterResponse));
});

it('correctly handles random API error', async () => {
sinon.stub(request, 'post').rejects(new Error('An error has occurred'));

await assert.rejects(command.action(logger, {
options: {}
options: commandOptionsSchema.parse({})
}), new CommandError('An error has occurred'));
});
});
11 changes: 9 additions & 2 deletions src/m365/planner/commands/roster/roster-add.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { z } from 'zod';
import { globalOptionsZod } from '../../../../Command.js';
import { Logger } from '../../../../cli/Logger.js';
import request, { CliRequestOptions } from '../../../../request.js';
import GraphCommand from '../../../base/GraphCommand.js';
import commands from '../../commands.js';

export const options = globalOptionsZod.strict();

class PlannerRosterAddCommand extends GraphCommand {
public get name(): string {
return commands.ROSTER_ADD;
Expand All @@ -12,6 +16,10 @@ class PlannerRosterAddCommand extends GraphCommand {
return 'Creates a new Microsoft Planner Roster';
}

public get schema(): z.ZodType | undefined {
return options;
}

public async commandAction(logger: Logger): Promise<void> {
if (this.verbose) {
await logger.logToStderr('Creating a new Microsoft Planner Roster');
Expand All @@ -34,7 +42,6 @@ class PlannerRosterAddCommand extends GraphCommand {
this.handleRejectedODataJsonPromise(err);
}
}

}

export default new PlannerRosterAddCommand();
export default new PlannerRosterAddCommand();
35 changes: 28 additions & 7 deletions src/m365/planner/commands/roster/roster-get.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import assert from 'assert';
import sinon from 'sinon';
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 request from '../../../../request.js';
Expand All @@ -9,25 +11,29 @@ 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 './roster-get.js';
import command, { options } from './roster-get.js';

describe(commands.ROSTER_GET, () => {
const id = '8bc07d47-c06f-41e1-8f00-1c113c8f6067';
const rosterGetResponse = {
"id": id,
"assignedSensitivityLabel": null
id: id,
assignedSensitivityLabel: null
};

let log: any[];
let logger: Logger;
let loggerLogSpy: sinon.SinonSpy;
let commandInfo: CommandInfo;
let commandOptionsSchema: typeof options;

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

beforeEach(() => {
Expand Down Expand Up @@ -65,6 +71,21 @@ describe(commands.ROSTER_GET, () => {
assert.notStrictEqual(command.description, null);
});

it('passes validation with valid id', () => {
const actual = commandOptionsSchema.safeParse({
id
});
assert.strictEqual(actual.success, true);
});

it('fails validation with unknown options', () => {
const actual = commandOptionsSchema.safeParse({
id,
unknownOption: 'value'
});
assert.strictEqual(actual.success, false);
});

it('retrieves Microsoft Planner Roster by specified id', async () => {
sinon.stub(request, 'get').callsFake(async (opts) => {
if (opts.url === `https://graph.microsoft.com/beta/planner/rosters/${id}`) {
Expand All @@ -74,7 +95,7 @@ describe(commands.ROSTER_GET, () => {
throw 'Invalid request';
});

await command.action(logger, { options: { id: id, verbose: true } });
await command.action(logger, { options: commandOptionsSchema.parse({ id, verbose: true }) });
assert(loggerLogSpy.calledWith(rosterGetResponse));
});

Expand All @@ -89,10 +110,10 @@ describe(commands.ROSTER_GET, () => {
});

await assert.rejects(command.action(logger, {
options: {
options: commandOptionsSchema.parse({
debug: true,
id: id
}
id
})
}), new CommandError(errorMessage));
});
});
35 changes: 12 additions & 23 deletions src/m365/planner/commands/roster/roster-get.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import { z } from 'zod';
import { globalOptionsZod } from '../../../../Command.js';
import { Logger } from '../../../../cli/Logger.js';
import GlobalOptions from '../../../../GlobalOptions.js';
import request, { CliRequestOptions } from '../../../../request.js';
import GraphCommand from '../../../base/GraphCommand.js';
import commands from '../../commands.js';

export const options = z.strictObject({
...globalOptionsZod.shape,
id: z.string()
});

declare type Options = z.infer<typeof options>;

interface CommandArgs {
options: Options;
}

interface Options extends GlobalOptions {
id: string;
}

class PlannerRosterGetCommand extends GraphCommand {
public get name(): string {
return commands.ROSTER_GET;
Expand All @@ -21,23 +25,8 @@ class PlannerRosterGetCommand extends GraphCommand {
return 'Retrieve information about a specific Microsoft Planner Roster';
}

constructor() {
super();

this.#initOptions();
this.#initTypes();
}

#initOptions(): void {
this.options.unshift(
{
option: '--id <id>'
}
);
}

#initTypes(): void {
this.types.string.push('id');
public get schema(): z.ZodType | undefined {
return options;
}

public async commandAction(logger: Logger, args: CommandArgs): Promise<void> {
Expand All @@ -63,4 +52,4 @@ class PlannerRosterGetCommand extends GraphCommand {
}
}

export default new PlannerRosterGetCommand();
export default new PlannerRosterGetCommand();
Loading
Loading