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

feat: minor refactor of how we debug and log out data in commands #563

Merged
merged 25 commits into from
Aug 10, 2022
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
8a5619c
docs: add some JSDocs for getProjectVersion
kanadgupta Aug 5, 2022
a39abe7
fix(openapi): add trailing period to param description
kanadgupta Aug 5, 2022
36e74dd
refactor: consolidate version opt descriptions
kanadgupta Aug 5, 2022
4be032d
test: update snapshots
kanadgupta Aug 5, 2022
f937dc1
feat: initial pass at CI version handling
kanadgupta Aug 8, 2022
f2fb63d
feat: initial pass at `useSpecVersion` flag
kanadgupta Aug 8, 2022
313505c
test: fix snapshots
kanadgupta Aug 8, 2022
8ebaf2c
test: fix test
kanadgupta Aug 8, 2022
6f87f80
test: add coverage for various version edge cases
kanadgupta Aug 8, 2022
8b445fb
test: use different file
kanadgupta Aug 8, 2022
ea5dff1
chore(openapi): alphabetize opts
kanadgupta Aug 8, 2022
6925bd4
chore: use info statement instead of debug
kanadgupta Aug 8, 2022
bfba671
chore: use info emoji in logger
kanadgupta Aug 9, 2022
ab9c956
test: fix tests
kanadgupta Aug 9, 2022
2172213
chore: attempt to merge
kanadgupta Aug 9, 2022
ae493f1
fix: import paths for versionOpt
kanadgupta Aug 9, 2022
f979f5b
fix: some merge issues
kanadgupta Aug 9, 2022
07cddf9
fix: lint
kanadgupta Aug 9, 2022
26d9f9f
test: fix one more test jeez
kanadgupta Aug 9, 2022
2cd9847
Merge branch 'main' into kanad/rm-4984-if-run-in-ci-environment-just-…
kanadgupta Aug 9, 2022
695438b
fix: trailing period
kanadgupta Aug 9, 2022
ab3fad6
fix: version arg refactors
erunion Aug 9, 2022
54ddc0a
feat: minor refactor of how we debug and log out data in commands
erunion Aug 9, 2022
a66095f
chore(deps-dev): bumping eslint-config to v10
erunion Aug 10, 2022
2efc978
Merge branch 'main' into feat/minor-refactors
kanadgupta Aug 10, 2022
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
9 changes: 0 additions & 9 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,6 @@
*/
"class-methods-use-this": ["error", { "exceptMethods": ["run"] }],

"import/order": ["error", {
Copy link
Member Author

Choose a reason for hiding this comment

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

Moved into our core standards and tagged a major release of that pkg. readmeio/standards@edffdbe

"alphabetize": {
"order": "asc",
"caseInsensitive": true
},
"groups": ["type", "builtin", "external", "internal", "parent", "sibling", "index", "object"],
"newlines-between": "always"
}],

/**
* This is a small rule to prevent us from using console.log() statements in our commands.
*
Expand Down
61 changes: 61 additions & 0 deletions __tests__/__fixtures__/petstore-simple-weird-version.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{
"openapi": "3.0.0",
"info": {
"version": "1.2.3",
"title": "Single Path",
"description": "This is a slimmed down single path version of the Petstore definition."
},
"servers": [
{
"url": "https://httpbin.org"
}
],
"paths": {
"/pet/{id}": {
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "integer"
}
}
],
"put": {
"tags": ["pet"],
"summary": "Update a pet",
"description": "This operation will update a pet in the database.",
"responses": {
"400": {
"description": "Invalid id value"
}
},
"security": [
{
"apiKey": []
}
]
},
"get": {
"tags": ["pet"],
"summary": "Find a pet",
"description": "This operation will find a pet in the database.",
"responses": {
"400": {
"description": "Invalid status value"
}
},
"security": []
}
}
},
"components": {
"securitySchemes": {
"apiKey": {
"type": "http",
"scheme": "basic"
}
}
}
}
23 changes: 16 additions & 7 deletions __tests__/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ Options

--key string Project API key
--id string Unique identifier for your API definition. Use this if you're re-
uploading an existing API definition
--version string Project version
uploading an existing API definition.
--version string Project version. If running command in a CI environment and this
option is not passed, the main project version will be used.
--useSpecVersion Uses the version listed in the \`info.version\` field in the API
definition for the project version parameter.
--workingDirectory string Working directory (for usage with relative external references)
-h, --help Display this usage guide

Expand All @@ -36,8 +39,11 @@ Options

--key string Project API key
--id string Unique identifier for your API definition. Use this if you're re-
uploading an existing API definition
--version string Project version
uploading an existing API definition.
--version string Project version. If running command in a CI environment and this
option is not passed, the main project version will be used.
--useSpecVersion Uses the version listed in the \`info.version\` field in the API
definition for the project version parameter.
--workingDirectory string Working directory (for usage with relative external references)
-h, --help Display this usage guide

Expand All @@ -60,8 +66,11 @@ Options

--key string Project API key
--id string Unique identifier for your API definition. Use this if you're re-
uploading an existing API definition
--version string Project version
uploading an existing API definition.
--version string Project version. If running command in a CI environment and this
option is not passed, the main project version will be used.
--useSpecVersion Uses the version listed in the \`info.version\` field in the API
definition for the project version parameter.
--workingDirectory string Working directory (for usage with relative external references)
-h, --help Display this usage guide

Expand All @@ -83,7 +92,7 @@ Usage
Options

--key string Project API key
--version string A specific project version to view
--version string A specific project version to view.
--raw Return raw output from the API instead of in a \\"pretty\\" format.
-h, --help Display this usage guide

Expand Down
2 changes: 1 addition & 1 deletion __tests__/cmds/docs/edit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ describe('rdme docs:edit', () => {

expect(fs.existsSync(`${slug}.md`)).toBe(false);
// eslint-disable-next-line no-console
expect(console.info).toHaveBeenCalledWith('Doc successfully updated. Cleaning up local file.');
expect(console.info).toHaveBeenCalledWith('ℹ️ Doc successfully updated. Cleaning up local file.');
consoleSpy.mockRestore();
});

Expand Down
119 changes: 109 additions & 10 deletions __tests__/cmds/openapi.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ describe('rdme openapi', () => {
expect(console.info).toHaveBeenCalledTimes(1);

const output = getCommandOutput();
expect(output).toBe(chalk.yellow('We found swagger.json and are attempting to upload it.'));
expect(output).toBe(chalk.yellow('ℹ️ We found swagger.json and are attempting to upload it.'));

fs.unlinkSync('./swagger.json');
return mock.done();
Expand Down Expand Up @@ -277,6 +277,110 @@ describe('rdme openapi', () => {
});

describe('versioning', () => {
it('should use version from version param properly', async () => {
expect.assertions(2);
let requestBody = '';
const registryUUID = getRandomRegistryId();
const mock = getAPIMock()
.get(`/api/v1/version/${version}`)
.basicAuth({ user: key })
.reply(200, { version: '1.0.0' })
.post('/api/v1/api-registry', body => {
requestBody = body.substring(body.indexOf('{'), body.lastIndexOf('}') + 1);
requestBody = JSON.parse(requestBody);

return body.match('form-data; name="spec"');
})
.reply(201, { registryUUID, spec: { openapi: '3.0.0' } })
.get('/api/v1/api-specification')
.basicAuth({ user: key })
.reply(200, [])
.post('/api/v1/api-specification', { registryUUID })
.basicAuth({ user: key })
.reply(function (uri, rBody, cb) {
expect(this.req.headers['x-readme-version'][0]).toBe(version);
return cb(null, [201, { _id: 1 }, { location: exampleRefLocation }]);
});

const spec = './__tests__/__fixtures__/petstore-simple-weird-version.json';

await expect(openapi.run({ spec, key, version })).resolves.toBe(successfulUpload(spec));

return mock.done();
});

it('should use version from spec file properly', async () => {
expect.assertions(2);
const specVersion = '1.2.3';
let requestBody = '';
const registryUUID = getRandomRegistryId();
const mock = getAPIMock()
.get(`/api/v1/version/${specVersion}`)
.basicAuth({ user: key })
.reply(200, { version: specVersion })
.post('/api/v1/api-registry', body => {
requestBody = body.substring(body.indexOf('{'), body.lastIndexOf('}') + 1);
requestBody = JSON.parse(requestBody);

return body.match('form-data; name="spec"');
})
.reply(201, { registryUUID, spec: { openapi: '3.0.0' } })
.get('/api/v1/api-specification')
.basicAuth({ user: key })
.reply(200, [])
.post('/api/v1/api-specification', { registryUUID })
.basicAuth({ user: key })
.reply(function (uri, rBody, cb) {
expect(this.req.headers['x-readme-version'][0]).toBe(specVersion);
return cb(null, [201, { _id: 1 }, { location: exampleRefLocation }]);
});

const spec = './__tests__/__fixtures__/petstore-simple-weird-version.json';

await expect(openapi.run({ spec, key, version, useSpecVersion: true })).resolves.toBe(successfulUpload(spec));

return mock.done();
});

describe('CI version handling', () => {
beforeEach(() => {
process.env.TEST_CI = 'true';
});

afterEach(() => {
delete process.env.TEST_CI;
});

it('should omit version header in CI environment', async () => {
expect.assertions(2);
let requestBody = '';
const registryUUID = getRandomRegistryId();
const mock = getAPIMock()
.post('/api/v1/api-registry', body => {
requestBody = body.substring(body.indexOf('{'), body.lastIndexOf('}') + 1);
requestBody = JSON.parse(requestBody);

return body.match('form-data; name="spec"');
})
.reply(201, { registryUUID, spec: { openapi: '3.0.0' } })
.get('/api/v1/api-specification')
.basicAuth({ user: key })
.reply(200, [])
.post('/api/v1/api-specification', { registryUUID })
.basicAuth({ user: key })
.reply(function (uri, rBody, cb) {
expect(this.req.headers['x-readme-version']).toBeUndefined();
return cb(null, [201, { _id: 1 }, { location: exampleRefLocation }]);
});

const spec = './__tests__/__fixtures__/ref-oas/petstore.json';

await expect(openapi.run({ spec, key })).resolves.toBe(successfulUpload(spec));

return mock.done();
});
});

it('should error if version flag sent to API returns a 404', async () => {
const invalidVersion = 'v1000';

Expand Down Expand Up @@ -372,15 +476,10 @@ describe('rdme openapi', () => {
return mock.done();
});

it('should error if no file was provided or able to be discovered', async () => {
const mock = getAPIMock()
.get(`/api/v1/version/${version}`)
.basicAuth({ user: key })
.reply(200, { version: '1.0.0' });

await expect(openapi.run({ key, version })).rejects.toThrow(/We couldn't find an OpenAPI or Swagger definition./);

return mock.done();
it('should error if no file was provided or able to be discovered', () => {
return expect(openapi.run({ key, version })).rejects.toThrow(
/We couldn't find an OpenAPI or Swagger definition./
);
});

it('should throw an error if an invalid OpenAPI 3.0 definition is supplied', () => {
Expand Down
2 changes: 1 addition & 1 deletion __tests__/cmds/validate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ describe('rdme validate', () => {
expect(console.info).toHaveBeenCalledTimes(1);

const output = getCommandOutput();
expect(output).toBe(chalk.yellow('We found swagger.json and are attempting to validate it.'));
expect(output).toBe(chalk.yellow('ℹ️ We found swagger.json and are attempting to validate it.'));

fs.unlinkSync('./swagger.json');
});
Expand Down
4 changes: 3 additions & 1 deletion __tests__/lib/commands.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ describe('utils', () => {
}

expect(arg.description).toBe(
command.command !== 'versions' ? 'Project version' : 'A specific project version to view'
command.command !== 'versions'
? 'Project version. If running command in a CI environment and this option is not passed, the main project version will be used.'
: 'A specific project version to view.'
);
}
});
Expand Down
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
"update-notifier": "^5.1.0"
},
"devDependencies": {
"@readme/eslint-config": "^9.0.0",
"@readme/eslint-config": "^10.0.0",
"@readme/oas-examples": "^5.3.0",
"@types/cli-table": "^0.3.0",
"@types/command-line-args": "^5.2.0",
Expand Down
9 changes: 2 additions & 7 deletions src/cmds/categories/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { Headers } from 'node-fetch';
import Command, { CommandCategories } from '../../lib/baseCommand';
import fetch, { cleanHeaders, handleRes } from '../../lib/fetch';
import getCategories from '../../lib/getCategories';
import { debug } from '../../lib/logger';
import { getProjectVersion } from '../../lib/versionSelect';

interface Category {
Expand Down Expand Up @@ -38,11 +37,7 @@ export default class CategoriesCreateCommand extends Command {
type: String,
description: 'Project API key',
},
{
name: 'version',
type: String,
description: 'Project version',
},
this.getVersionArg(),
{
name: 'title',
type: String,
Expand Down Expand Up @@ -77,7 +72,7 @@ export default class CategoriesCreateCommand extends Command {

const selectedVersion = await getProjectVersion(version, key, false);

debug(`selectedVersion: ${selectedVersion}`);
Command.debug(`selectedVersion: ${selectedVersion}`);

async function matchCategory() {
const allCategories = await getCategories(key, selectedVersion);
Expand Down
Loading