Skip to content

Commit 597492f

Browse files
tmaestriniMartinM85
authored andcommitted
Migrates 'logout' to Zod. Closes #6914
1 parent f1b4c9c commit 597492f

File tree

2 files changed

+48
-7
lines changed

2 files changed

+48
-7
lines changed

src/m365/commands/logout.spec.ts

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import assert from 'assert';
22
import sinon from 'sinon';
3+
import { z } from 'zod';
34
import auth from '../../Auth.js';
5+
import { cli } from '../../cli/cli.js';
6+
import { CommandInfo } from '../../cli/CommandInfo.js';
47
import { Logger } from '../../cli/Logger.js';
58
import { CommandError } from '../../Command.js';
69
import { telemetry } from '../../telemetry.js';
@@ -14,13 +17,18 @@ describe(commands.LOGOUT, () => {
1417
let log: string[];
1518
let logger: Logger;
1619
let authClearConnectionInfoStub: sinon.SinonStub;
20+
let commandInfo: CommandInfo;
21+
let commandOptionsSchema: z.ZodTypeAny;
1722

1823
before(() => {
1924
sinon.stub(auth, 'restoreAuth').callsFake(() => Promise.resolve());
2025
authClearConnectionInfoStub = sinon.stub(auth, 'clearConnectionInfo').callsFake(() => Promise.resolve());
2126
sinon.stub(telemetry, 'trackEvent').resolves();
2227
sinon.stub(pid, 'getProcessName').callsFake(() => '');
2328
sinon.stub(session, 'getId').callsFake(() => '');
29+
30+
commandInfo = cli.getCommandInfo(command);
31+
commandOptionsSchema = commandInfo.command.getSchemaToParse()!;
2432
});
2533

2634
beforeEach(() => {
@@ -50,21 +58,41 @@ describe(commands.LOGOUT, () => {
5058
assert.notStrictEqual(command.description, null);
5159
});
5260

61+
it('passs validation with default options', async () => {
62+
const actual = commandOptionsSchema.safeParse({});
63+
assert.strictEqual(actual.success, true);
64+
});
65+
66+
it('passs validation with unknown options', async () => {
67+
const actual = commandOptionsSchema.safeParse({ option: "value" });
68+
assert.strictEqual(actual.success, false);
69+
});
70+
71+
it('logs verbose message when verbose flag is set', async () => {
72+
await command.action(logger, { options: commandOptionsSchema.parse({ verbose: true }) });
73+
assert(log.some(msg => msg.includes('Logging out from Microsoft 365...')));
74+
});
75+
76+
it('doesn\'t log verbose message when verbose flag is not set', async () => {
77+
await command.action(logger, { options: commandOptionsSchema.parse({}) });
78+
assert(!log.some(msg => msg.includes('Logging out from Microsoft 365...')));
79+
});
80+
5381
it('logs out from Microsoft 365 when logged in', async () => {
5482
auth.connection.active = true;
55-
await command.action(logger, { options: { debug: true } });
83+
await command.action(logger, { options: commandOptionsSchema.parse({ debug: true }) });
5684
assert(!auth.connection.active);
5785
});
5886

5987
it('logs out from Microsoft 365 when not logged in', async () => {
6088
auth.connection.active = false;
61-
await command.action(logger, { options: { debug: true } });
89+
await command.action(logger, { options: commandOptionsSchema.parse({ debug: true }) });
6290
assert(!auth.connection.active);
6391
});
6492

6593
it('clears persisted connection info when logging out', async () => {
6694
auth.connection.active = true;
67-
await command.action(logger, { options: { debug: true } });
95+
await command.action(logger, { options: commandOptionsSchema.parse({ debug: true }) });
6896
assert(authClearConnectionInfoStub.called);
6997
});
7098

@@ -75,7 +103,7 @@ describe(commands.LOGOUT, () => {
75103
auth.connection.active = true;
76104

77105
try {
78-
await command.action(logger, { options: {} });
106+
await command.action(logger, { options: commandOptionsSchema.parse({}) });
79107
assert(logoutSpy.called);
80108
}
81109
finally {
@@ -92,7 +120,7 @@ describe(commands.LOGOUT, () => {
92120
auth.connection.active = true;
93121

94122
try {
95-
await command.action(logger, { options: { debug: true } });
123+
await command.action(logger, { options: commandOptionsSchema.parse({ debug: true }) });
96124
assert(logoutSpy.called);
97125
}
98126
finally {
@@ -108,7 +136,7 @@ describe(commands.LOGOUT, () => {
108136
sinon.stub(auth, 'restoreAuth').callsFake(() => Promise.reject('An error has occurred'));
109137

110138
try {
111-
await assert.rejects(command.action(logger, { options: {} } as any), new CommandError('An error has occurred'));
139+
await assert.rejects(command.action(logger, commandOptionsSchema.parse({})), new CommandError('An error has occurred'));
112140
}
113141
finally {
114142
sinonUtil.restore([

src/m365/commands/logout.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,17 @@
1+
import { z } from 'zod';
12
import auth from '../../Auth.js';
23
import { Logger } from '../../cli/Logger.js';
3-
import Command, { CommandArgs, CommandError } from '../../Command.js';
4+
import Command, { CommandError, globalOptionsZod } from '../../Command.js';
45
import commands from './commands.js';
56

7+
const options = globalOptionsZod.strict();
8+
9+
declare type Options = z.infer<typeof options>;
10+
11+
interface CommandArgs {
12+
options: Options;
13+
}
14+
615
class LogoutCommand extends Command {
716
public get name(): string {
817
return commands.LOGOUT;
@@ -12,6 +21,10 @@ class LogoutCommand extends Command {
1221
return 'Log out from Microsoft 365';
1322
}
1423

24+
public get schema(): z.ZodTypeAny | undefined {
25+
return options;
26+
}
27+
1528
public async commandAction(logger: Logger): Promise<void> {
1629
if (this.verbose) {
1730
await logger.logToStderr('Logging out from Microsoft 365...');

0 commit comments

Comments
 (0)