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

test: more enhancements #1190

Merged
merged 18 commits into from
Mar 5, 2025
Merged
Show file tree
Hide file tree
Changes from 14 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
77 changes: 77 additions & 0 deletions __tests__/commands/__snapshots__/login.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`rdme login > should bypass prompts and post to /login on the API if passing in every opt (no 2FA) 1`] = `
{
"result": "Successfully logged in as [email protected] to the subdomain project.",
"stderr": "",
"stdout": "",
}
`;

exports[`rdme login > should bypass prompts and post to /login on the API if passing in every opt 1`] = `
{
"result": "Successfully logged in as [email protected] to the subdomain project.",
"stderr": "",
"stdout": "",
}
`;

exports[`rdme login > should error if email is invalid 1`] = `
{
"error": [Error: You must provide a valid email address.],
"stderr": "",
"stdout": "",
}
`;

exports[`rdme login > should error if invalid credentials are given 1`] = `
{
"error": [APIv1Error: Either your email address or password is incorrect

If you need help, email [email protected] and mention log "fake-metrics-uuid".],
"stderr": "",
"stdout": "",
}
`;

exports[`rdme login > should error if no project provided 1`] = `
{
"error": [Error: No project subdomain provided. Please use \`--project\`.],
"stderr": "",
"stdout": "",
}
`;

exports[`rdme login > should error if trying to access a project that is not yours 1`] = `
{
"error": [APIv1Error: The project (unauthorized-project) can't be found.

If you need help, email [email protected]],
"stderr": "",
"stdout": "",
}
`;

exports[`rdme login > should make additional prompt for token if login requires 2FA 1`] = `
{
"result": "Successfully logged in as [email protected] to the subdomain project.",
"stderr": "",
"stdout": "",
}
`;

exports[`rdme login > should post to /login on the API 1`] = `
{
"result": "Successfully logged in as [email protected] to the subdomain project.",
"stderr": "",
"stdout": "",
}
`;

exports[`rdme login > should post to /login on the API if passing in project via opt 1`] = `
{
"result": "Successfully logged in as [email protected] to the subdomain project.",
"stderr": "",
"stdout": "",
}
`;
17 changes: 17 additions & 0 deletions __tests__/commands/__snapshots__/logout.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`rdme logout > should log the user out 1`] = `
{
"result": "You have logged out of ReadMe. Please use \`rdme login\` to login again.",
"stderr": "",
"stdout": "",
}
`;

exports[`rdme logout > should report the user as logged out if they aren't logged in 1`] = `
{
"result": "You have logged out of ReadMe. Please use \`rdme login\` to login again.",
"stderr": "",
"stdout": "",
}
`;
17 changes: 17 additions & 0 deletions __tests__/commands/__snapshots__/whoami.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`rdme whoami > should error if user is not authenticated 1`] = `
{
"error": [Error: Please login using \`rdme login\`.],
"stderr": "",
"stdout": "",
}
`;

exports[`rdme whoami > should return the authenticated user 1`] = `
{
"result": "You are currently logged in as [email protected] to the subdomain project.",
"stderr": "",
"stdout": "",
}
`;
33 changes: 14 additions & 19 deletions __tests__/commands/login.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ import prompts from 'prompts';
import { describe, beforeAll, afterEach, it, expect } from 'vitest';

import Command from '../../src/commands/login.js';
import { APIv1Error } from '../../src/lib/apiError.js';
import configStore from '../../src/lib/configstore.js';
import { getAPIv1Mock } from '../helpers/get-api-mock.js';
import { runCommandAndReturnResult } from '../helpers/oclif.js';
import { runCommand, type OclifOutput } from '../helpers/oclif.js';

const apiKey = 'abcdefg';
const email = '[email protected]';
Expand All @@ -14,30 +13,30 @@ const project = 'subdomain';
const token = '123456';

describe('rdme login', () => {
let run: (args?: string[]) => Promise<string>;
let run: (args?: string[]) => OclifOutput;

beforeAll(() => {
run = runCommandAndReturnResult(Command);
run = runCommand(Command);
});

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

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

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

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

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

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

mock.done();

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

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

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

mock.done();

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

await expect(run(['--email', email, '--password', password, '--project', project, '--otp', token])).resolves.toBe(
'Successfully logged in as [email protected] to the subdomain project.',
);
await expect(
run(['--email', email, '--password', password, '--project', project, '--otp', token]),
).resolves.toMatchSnapshot();

mock.done();

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

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

mock.done();

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

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

await expect(run()).rejects.toStrictEqual(new APIv1Error(errorResponse));
await expect(run()).resolves.toMatchSnapshot();

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

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

mock.done();

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

await expect(run()).rejects.toStrictEqual(new APIv1Error(errorResponse));
await expect(run()).resolves.toMatchSnapshot();

mock.done();
});
Expand Down
15 changes: 5 additions & 10 deletions __tests__/commands/logout.test.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { describe, afterEach, beforeAll, it, expect } from 'vitest';

import pkg from '../../package.json' with { type: 'json' };
import Command from '../../src/commands/logout.js';
import configStore from '../../src/lib/configstore.js';
import { runCommandAndReturnResult } from '../helpers/oclif.js';
import { runCommand, type OclifOutput } from '../helpers/oclif.js';

describe('rdme logout', () => {
let run: (args?: string[]) => Promise<string>;
let run: (args?: string[]) => OclifOutput;

beforeAll(() => {
run = runCommandAndReturnResult(Command);
run = runCommand(Command);
});

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

return expect(run()).resolves.toBe(
`You have logged out of ReadMe. Please use \`${pkg.name} login\` to login again.`,
);
return expect(run()).resolves.toMatchSnapshot();
});

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

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

expect(configStore.get('email')).toBeUndefined();
expect(configStore.get('project')).toBeUndefined();
Expand Down
30 changes: 30 additions & 0 deletions __tests__/commands/openapi/__snapshots__/convert.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`rdme openapi convert > error handling > should warn if given an OpenAPI 3.0 definition (format: json) 1`] = `
{
"result": "Your API definition has been converted and bundled and saved to output.json!",
"stderr": "- Validating the API definition located at petstore.json...
⚠️ Warning! The input file is already OpenAPI, so no conversion is necessary. Any external references will be bundled.
",
"stdout": "",
}
`;

exports[`rdme openapi convert > error handling > should warn if given an OpenAPI 3.0 definition (format: yaml) 1`] = `
{
"result": "Your API definition has been converted and bundled and saved to output.json!",
"stderr": "- Validating the API definition located at petstore.yaml...
⚠️ Warning! The input file is already OpenAPI, so no conversion is necessary. Any external references will be bundled.
",
"stdout": "",
}
`;

exports[`rdme openapi convert > should convert with no prompts via opts 1`] = `
{
"result": "Your API definition has been converted and bundled and saved to output.json!",
"stderr": "- Validating the API definition located at petstore-simple.json...
",
"stdout": "",
}
`;
21 changes: 15 additions & 6 deletions __tests__/commands/openapi/__snapshots__/inspect.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ polymorphism:
`;

exports[`rdme openapi inspect > feature reports > should generate a report for '@readme/oas-examples/3.0/json/readme-…' (w/ [ 'readme' ]) 1`] = `
"
[SoftError:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SoftError?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

he got me. that f***ing kanad gupta boomed me.

x-default: You do not use this.
x-readme.code-samples:
· #/paths/~1x-code-samples/get/x-code-samples
Expand All @@ -73,7 +73,7 @@ x-readme.samples-languages:
· node
· python
· shell
· swift"
· swift]
`;

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

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

exports[`rdme openapi inspect > feature reports > should generate a report for '@readme/oas-examples/3.0/json/schema-…' (w/ [ 'circularRefs', 'readme' ]) 1`] = `
"
[SoftError:
circularRefs:
· #/components/schemas/MultiPart/properties/parent
· #/components/schemas/ZoneOffset/properties/rules
Expand All @@ -136,7 +136,7 @@ x-readme.code-samples: You do not use this.
x-readme.headers: You do not use this.
x-readme.explorer-enabled: You do not use this.
x-readme.proxy-enabled: You do not use this.
x-readme.samples-languages: You do not use this."
x-readme.samples-languages: You do not use this.]
`;

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

exports[`rdme openapi inspect > feature reports > should throw an error if an invalid feature is supplied 1`] = `
{
"error": [Error: Expected --feature=reamde to be one of: additionalProperties, callbacks, circularRefs, commonParameters, discriminators, links, style, polymorphism, serverVariables, webhooks, xml, readme
See more help with --help],
"stderr": "",
"stdout": "",
}
`;

exports[`rdme openapi inspect > full reports > should generate a report for @readme/oas-examples/3.0/json/petstore.json 1`] = `
"Here are some interesting things we found in your API definition. 🕵️

Expand Down
Loading
Loading