Skip to content

Commit 02bd825

Browse files
authored
test: more enhancements (#1190)
## 🧰 Changes continuing my work in #1188 with even more work to migrate over our tests to the more comprehensive `runCommand` helper: - [x] `openapi convert` - [x] `openapi inspect` - [x] `openapi reduce` - [x] `login` - [x] `logout` - [x] `whoami` the only outstanding tests using the now deprecated `runCommandAndReturnResult` helper are the changelog tests, but i'll swap those out if/when we get around to migrating that command over to APIv2. ## 🧬 QA & Testing no functional changes. do tests still pass?
1 parent f08e9c8 commit 02bd825

14 files changed

+304
-154
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2+
3+
exports[`rdme login > should bypass prompts and post to /login on the API if passing in every opt (no 2FA) 1`] = `
4+
{
5+
"result": "Successfully logged in as [email protected] to the subdomain project.",
6+
"stderr": "",
7+
"stdout": "",
8+
}
9+
`;
10+
11+
exports[`rdme login > should bypass prompts and post to /login on the API if passing in every opt 1`] = `
12+
{
13+
"result": "Successfully logged in as [email protected] to the subdomain project.",
14+
"stderr": "",
15+
"stdout": "",
16+
}
17+
`;
18+
19+
exports[`rdme login > should error if email is invalid 1`] = `
20+
{
21+
"error": [Error: You must provide a valid email address.],
22+
"stderr": "",
23+
"stdout": "",
24+
}
25+
`;
26+
27+
exports[`rdme login > should error if invalid credentials are given 1`] = `
28+
{
29+
"error": [APIv1Error: Either your email address or password is incorrect
30+
31+
If you need help, email support@readme.io and mention log "fake-metrics-uuid".],
32+
"stderr": "",
33+
"stdout": "",
34+
}
35+
`;
36+
37+
exports[`rdme login > should error if no project provided 1`] = `
38+
{
39+
"error": [Error: No project subdomain provided. Please use \`--project\`.],
40+
"stderr": "",
41+
"stdout": "",
42+
}
43+
`;
44+
45+
exports[`rdme login > should error if trying to access a project that is not yours 1`] = `
46+
{
47+
"error": [APIv1Error: The project (unauthorized-project) can't be found.
48+
49+
If you need help, email support@readme.io],
50+
"stderr": "",
51+
"stdout": "",
52+
}
53+
`;
54+
55+
exports[`rdme login > should make additional prompt for token if login requires 2FA 1`] = `
56+
{
57+
"result": "Successfully logged in as [email protected] to the subdomain project.",
58+
"stderr": "",
59+
"stdout": "",
60+
}
61+
`;
62+
63+
exports[`rdme login > should post to /login on the API 1`] = `
64+
{
65+
"result": "Successfully logged in as [email protected] to the subdomain project.",
66+
"stderr": "",
67+
"stdout": "",
68+
}
69+
`;
70+
71+
exports[`rdme login > should post to /login on the API if passing in project via opt 1`] = `
72+
{
73+
"result": "Successfully logged in as [email protected] to the subdomain project.",
74+
"stderr": "",
75+
"stdout": "",
76+
}
77+
`;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2+
3+
exports[`rdme logout > should log the user out 1`] = `
4+
{
5+
"result": "You have logged out of ReadMe. Please use \`rdme login\` to login again.",
6+
"stderr": "",
7+
"stdout": "",
8+
}
9+
`;
10+
11+
exports[`rdme logout > should report the user as logged out if they aren't logged in 1`] = `
12+
{
13+
"result": "You have logged out of ReadMe. Please use \`rdme login\` to login again.",
14+
"stderr": "",
15+
"stdout": "",
16+
}
17+
`;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2+
3+
exports[`rdme whoami > should error if user is not authenticated 1`] = `
4+
{
5+
"error": [Error: Please login using \`rdme login\`.],
6+
"stderr": "",
7+
"stdout": "",
8+
}
9+
`;
10+
11+
exports[`rdme whoami > should return the authenticated user 1`] = `
12+
{
13+
"result": "You are currently logged in as [email protected] to the subdomain project.",
14+
"stderr": "",
15+
"stdout": "",
16+
}
17+
`;

__tests__/commands/login.test.ts

+14-19
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@ import prompts from 'prompts';
22
import { describe, beforeAll, afterEach, it, expect } from 'vitest';
33

44
import Command from '../../src/commands/login.js';
5-
import { APIv1Error } from '../../src/lib/apiError.js';
65
import configStore from '../../src/lib/configstore.js';
76
import { getAPIv1Mock } from '../helpers/get-api-mock.js';
8-
import { runCommandAndReturnResult } from '../helpers/oclif.js';
7+
import { runCommand, type OclifOutput } from '../helpers/oclif.js';
98

109
const apiKey = 'abcdefg';
1110
const email = '[email protected]';
@@ -14,30 +13,30 @@ const project = 'subdomain';
1413
const token = '123456';
1514

1615
describe('rdme login', () => {
17-
let run: (args?: string[]) => Promise<string>;
16+
let run: (args?: string[]) => OclifOutput;
1817

1918
beforeAll(() => {
20-
run = runCommandAndReturnResult(Command);
19+
run = runCommand(Command);
2120
});
2221

2322
afterEach(() => configStore.clear());
2423

2524
it('should error if no project provided', () => {
2625
prompts.inject([email, password]);
27-
return expect(run()).rejects.toStrictEqual(new Error('No project subdomain provided. Please use `--project`.'));
26+
return expect(run()).resolves.toMatchSnapshot();
2827
});
2928

3029
it('should error if email is invalid', () => {
3130
prompts.inject(['this-is-not-an-email', password, project]);
32-
return expect(run()).rejects.toStrictEqual(new Error('You must provide a valid email address.'));
31+
return expect(run()).resolves.toMatchSnapshot();
3332
});
3433

3534
it('should post to /login on the API', async () => {
3635
prompts.inject([email, password, project]);
3736

3837
const mock = getAPIv1Mock().post('/api/v1/login', { email, password, project }).reply(200, { apiKey });
3938

40-
await expect(run()).resolves.toBe('Successfully logged in as [email protected] to the subdomain project.');
39+
await expect(run()).resolves.toMatchSnapshot();
4140

4241
mock.done();
4342

@@ -51,9 +50,7 @@ describe('rdme login', () => {
5150

5251
const mock = getAPIv1Mock().post('/api/v1/login', { email, password, project }).reply(200, { apiKey });
5352

54-
await expect(run(['--project', project])).resolves.toBe(
55-
'Successfully logged in as [email protected] to the subdomain project.',
56-
);
53+
await expect(run(['--project', project])).resolves.toMatchSnapshot();
5754

5855
mock.done();
5956

@@ -65,9 +62,9 @@ describe('rdme login', () => {
6562
it('should bypass prompts and post to /login on the API if passing in every opt', async () => {
6663
const mock = getAPIv1Mock().post('/api/v1/login', { email, password, project, token }).reply(200, { apiKey });
6764

68-
await expect(run(['--email', email, '--password', password, '--project', project, '--otp', token])).resolves.toBe(
69-
'Successfully logged in as [email protected] to the subdomain project.',
70-
);
65+
await expect(
66+
run(['--email', email, '--password', password, '--project', project, '--otp', token]),
67+
).resolves.toMatchSnapshot();
7168

7269
mock.done();
7370

@@ -79,9 +76,7 @@ describe('rdme login', () => {
7976
it('should bypass prompts and post to /login on the API if passing in every opt (no 2FA)', async () => {
8077
const mock = getAPIv1Mock().post('/api/v1/login', { email, password, project }).reply(200, { apiKey });
8178

82-
await expect(run(['--email', email, '--password', password, '--project', project])).resolves.toBe(
83-
'Successfully logged in as [email protected] to the subdomain project.',
84-
);
79+
await expect(run(['--email', email, '--password', password, '--project', project])).resolves.toMatchSnapshot();
8580

8681
mock.done();
8782

@@ -101,7 +96,7 @@ describe('rdme login', () => {
10196

10297
const mock = getAPIv1Mock().post('/api/v1/login', { email, password, project }).reply(401, errorResponse);
10398

104-
await expect(run()).rejects.toStrictEqual(new APIv1Error(errorResponse));
99+
await expect(run()).resolves.toMatchSnapshot();
105100

106101
mock.done();
107102
});
@@ -121,7 +116,7 @@ describe('rdme login', () => {
121116
.post('/api/v1/login', { email, password, project, token })
122117
.reply(200, { apiKey });
123118

124-
await expect(run()).resolves.toBe('Successfully logged in as [email protected] to the subdomain project.');
119+
await expect(run()).resolves.toMatchSnapshot();
125120

126121
mock.done();
127122

@@ -144,7 +139,7 @@ describe('rdme login', () => {
144139
.post('/api/v1/login', { email, password, project: projectThatIsNotYours })
145140
.reply(404, errorResponse);
146141

147-
await expect(run()).rejects.toStrictEqual(new APIv1Error(errorResponse));
142+
await expect(run()).resolves.toMatchSnapshot();
148143

149144
mock.done();
150145
});

__tests__/commands/logout.test.ts

+5-10
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
import { describe, afterEach, beforeAll, it, expect } from 'vitest';
22

3-
import pkg from '../../package.json' with { type: 'json' };
43
import Command from '../../src/commands/logout.js';
54
import configStore from '../../src/lib/configstore.js';
6-
import { runCommandAndReturnResult } from '../helpers/oclif.js';
5+
import { runCommand, type OclifOutput } from '../helpers/oclif.js';
76

87
describe('rdme logout', () => {
9-
let run: (args?: string[]) => Promise<string>;
8+
let run: (args?: string[]) => OclifOutput;
109

1110
beforeAll(() => {
12-
run = runCommandAndReturnResult(Command);
11+
run = runCommand(Command);
1312
});
1413

1514
afterEach(() => {
@@ -20,18 +19,14 @@ describe('rdme logout', () => {
2019
configStore.delete('email');
2120
configStore.delete('project');
2221

23-
return expect(run()).resolves.toBe(
24-
`You have logged out of ReadMe. Please use \`${pkg.name} login\` to login again.`,
25-
);
22+
return expect(run()).resolves.toMatchSnapshot();
2623
});
2724

2825
it('should log the user out', async () => {
2926
configStore.set('email', '[email protected]');
3027
configStore.set('project', 'subdomain');
3128

32-
await expect(run()).resolves.toBe(
33-
`You have logged out of ReadMe. Please use \`${pkg.name} login\` to login again.`,
34-
);
29+
await expect(run()).resolves.toMatchSnapshot();
3530

3631
expect(configStore.get('email')).toBeUndefined();
3732
expect(configStore.get('project')).toBeUndefined();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2+
3+
exports[`rdme openapi convert > error handling > should warn if given an OpenAPI 3.0 definition (format: json) 1`] = `
4+
{
5+
"result": "Your API definition has been converted and bundled and saved to output.json!",
6+
"stderr": "- Validating the API definition located at petstore.json...
7+
⚠️ Warning! The input file is already OpenAPI, so no conversion is necessary. Any external references will be bundled.
8+
",
9+
"stdout": "",
10+
}
11+
`;
12+
13+
exports[`rdme openapi convert > error handling > should warn if given an OpenAPI 3.0 definition (format: yaml) 1`] = `
14+
{
15+
"result": "Your API definition has been converted and bundled and saved to output.json!",
16+
"stderr": "- Validating the API definition located at petstore.yaml...
17+
⚠️ Warning! The input file is already OpenAPI, so no conversion is necessary. Any external references will be bundled.
18+
",
19+
"stdout": "",
20+
}
21+
`;
22+
23+
exports[`rdme openapi convert > should convert with no prompts via opts 1`] = `
24+
{
25+
"result": "Your API definition has been converted and bundled and saved to output.json!",
26+
"stderr": "- Validating the API definition located at petstore-simple.json...
27+
",
28+
"stdout": "",
29+
}
30+
`;

__tests__/commands/openapi/__snapshots__/inspect.test.ts.snap

+15-6
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ polymorphism:
5151
`;
5252

5353
exports[`rdme openapi inspect > feature reports > should generate a report for '@readme/oas-examples/3.0/json/readme-…' (w/ [ 'readme' ]) 1`] = `
54-
"
54+
[SoftError:
5555
x-default: You do not use this.
5656
x-readme.code-samples:
5757
· #/paths/~1x-code-samples/get/x-code-samples
@@ -73,7 +73,7 @@ x-readme.samples-languages:
7373
· node
7474
· python
7575
· shell
76-
· swift"
76+
· swift]
7777
`;
7878

7979
exports[`rdme openapi inspect > feature reports > should generate a report for '@readme/oas-examples/3.0/json/schema-…' (w/ [ 'additionalProperties', …(1) ]) 1`] = `
@@ -103,7 +103,7 @@ circularRefs:
103103
`;
104104

105105
exports[`rdme openapi inspect > feature reports > should generate a report for '@readme/oas-examples/3.0/json/schema-…' (w/ [ 'additionalProperties', …(2) ]) 1`] = `
106-
"
106+
[SoftError:
107107
additionalProperties:
108108
· #/components/schemas/BodyPart/properties/headers/additionalProperties
109109
· #/components/schemas/BodyPart/properties/mediaType/properties/parameters/additionalProperties
@@ -132,11 +132,11 @@ x-readme.code-samples: You do not use this.
132132
x-readme.headers: You do not use this.
133133
x-readme.explorer-enabled: You do not use this.
134134
x-readme.proxy-enabled: You do not use this.
135-
x-readme.samples-languages: You do not use this."
135+
x-readme.samples-languages: You do not use this.]
136136
`;
137137

138138
exports[`rdme openapi inspect > feature reports > should generate a report for '@readme/oas-examples/3.0/json/schema-…' (w/ [ 'circularRefs', 'readme' ]) 1`] = `
139-
"
139+
[SoftError:
140140
circularRefs:
141141
· #/components/schemas/BodyPart/properties/parent
142142
· #/components/schemas/MultiPart/properties/bodyParts/items
@@ -151,7 +151,7 @@ x-readme.code-samples: You do not use this.
151151
x-readme.headers: You do not use this.
152152
x-readme.explorer-enabled: You do not use this.
153153
x-readme.proxy-enabled: You do not use this.
154-
x-readme.samples-languages: You do not use this."
154+
x-readme.samples-languages: You do not use this.]
155155
`;
156156

157157
exports[`rdme openapi inspect > feature reports > should generate a report for '@readme/oas-examples/3.1/json/train-t…' (w/ [ 'commonParameters' ]) 1`] = `
@@ -161,6 +161,15 @@ commonParameters:
161161
· #/paths/~1bookings~1{bookingId}~1payment/parameters"
162162
`;
163163

164+
exports[`rdme openapi inspect > feature reports > should throw an error if an invalid feature is supplied 1`] = `
165+
{
166+
"error": [Error: Expected --feature=reamde to be one of: additionalProperties, callbacks, circularRefs, commonParameters, discriminators, links, style, polymorphism, serverVariables, webhooks, xml, readme
167+
See more help with --help],
168+
"stderr": "",
169+
"stdout": "",
170+
}
171+
`;
172+
164173
exports[`rdme openapi inspect > full reports > should generate a report for @readme/oas-examples/3.0/json/petstore.json 1`] = `
165174
"Here are some interesting things we found in your API definition. 🕵️
166175

0 commit comments

Comments
 (0)