Skip to content

Commit

Permalink
fix(openapi): error handling for incorrect project and version flags (#…
Browse files Browse the repository at this point in the history
…411)

* test: fix version creation flow in nock

It doesn't make sense that the API would return v1.0.1 if that's the version the user is trying to create! So this fixes that. The test still passes ¯\_(ツ)_/¯

* fix: properly bubble up errors finding versions

also add a couple tests

* refactor: get rid of unnecessary catch statement

This is being caught by the caller function, so this isn't necessary. Also the tests yield the same result.

* refactor: another place with unnecessary catch statements

Tests still pass, so I think we're good here.
  • Loading branch information
kanadgupta authored Dec 22, 2021
1 parent 8b9ad4b commit 431a7db
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 18 deletions.
60 changes: 57 additions & 3 deletions __tests__/cmds/openapi.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,36 @@ describe('rdme openapi', () => {
});

describe('versioning', () => {
it.todo('should return a 404 if version flag not found');
it('should error if version flag sent to API returns a 404', async () => {
const invalidVersion = 'v1000';

const errorObject = {
error: 'VERSION_NOTFOUND',
message: `The version you specified (${invalidVersion}) doesn't match any of the existing versions (1.0) in ReadMe.`,
suggestion:
'You can pass the version in via the `x-readme-version` header. If you want to create a new version, do so in the Versions section inside ReadMe. Note that the version in the URL is our API version, not the version of your docs.',
docs: 'https://docs.readme.com/logs/xx-xx-xx',
help: "If you need help, email [email protected] and include the following link to your API log: 'https://docs.readme.com/logs/xx-xx-xx'.",
poem: [
'We looked high and low,',
'Searched up, down and around.',
"You'll have to give it another go,",
`Because version ${invalidVersion}'s not found!`,
],
};

const mock = nock(config.host).get(`/api/v1/version/${invalidVersion}`).reply(404, errorObject);

await expect(
openapi.run({
spec: require.resolve('@readme/oas-examples/3.1/json/petstore.json'),
key,
version: invalidVersion,
})
).rejects.toStrictEqual(new APIError(errorObject));

return mock.done();
});

it('should request a version list if version is not found', async () => {
promptHandler.generatePrompts.mockResolvedValue({
Expand All @@ -201,10 +230,10 @@ describe('rdme openapi', () => {
const mock = nock(config.host)
.get('/api/v1/version')
.basicAuth({ user: key })
.reply(200, [{ version: '1.0.1' }])
.reply(200, [{ version: '1.0.0' }])
.post('/api/v1/version')
.basicAuth({ user: key })
.reply(200, { from: '1.0.1', version: '1.0.1' })
.reply(200, { from: '1.0.0', version: '1.0.1' })
.get('/api/v1/api-specification')
.basicAuth({ user: key })
.reply(200, [])
Expand Down Expand Up @@ -256,6 +285,31 @@ describe('rdme openapi', () => {
).rejects.toThrow('No project API key provided. Please use `--key`.');
});

it('should error if invalid API key is sent and version list does not load', async () => {
const errorObject = {
error: 'APIKEY_NOTFOUND',
message: "We couldn't find your API key.",
suggestion:
"The API key you passed in (API_KEY) doesn't match any keys we have in our system. API keys must be passed in as the username part of basic auth. You can get your API key in Configuration > API Key, or in the docs.",
docs: 'https://docs.readme.com/logs/xx-xx-xx',
help: "If you need help, email [email protected] and include the following link to your API log: 'https://docs.readme.com/logs/xx-xx-xx'.",
poem: [
'The ancient gatekeeper declares:',
"'To pass, reveal your API key.'",
"'API_KEY', you start to ramble",
'Oops, you remembered it poorly!',
],
};

const mock = nock(config.host).get('/api/v1/version').reply(401, errorObject);

await expect(
openapi.run({ key, spec: require.resolve('@readme/oas-examples/3.1/json/petstore.json') })
).rejects.toStrictEqual(new APIError(errorObject));

return mock.done();
});

it('should error if no file was provided or able to be discovered', async () => {
const mock = nock(config.host)
.get(`/api/v1/version/${version}`)
Expand Down
17 changes: 4 additions & 13 deletions src/cmds/openapi.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,17 +118,10 @@ exports.run = async function (opts) {

let bundledSpec;
const oas = new OASNormalize(specPath, { colorizeErrors: true, enablePaths: true });
await oas.validate(false).catch(err => {
return Promise.reject(err);
await oas.validate(false);
await oas.bundle().then(res => {
bundledSpec = JSON.stringify(res);
});
await oas
.bundle()
.then(res => {
bundledSpec = JSON.stringify(res);
})
.catch(err => {
return Promise.reject(err);
});

// Create a temporary file to write the bundled spec to,
// which we will then stream into the form data body
Expand Down Expand Up @@ -204,9 +197,7 @@ exports.run = async function (opts) {
}

if (!id) {
selectedVersion = await getProjectVersion(version, key, true).catch(e => {
return Promise.reject(e);
});
selectedVersion = await getProjectVersion(version, key, true);
}

if (spec) {
Expand Down
5 changes: 3 additions & 2 deletions src/lib/versionSelect.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const { cleanHeaders } = require('./cleanHeaders');
const fetch = require('node-fetch');
const config = require('config');
const APIError = require('./apiError');
const { handleRes } = require('./handleRes');

async function getProjectVersion(versionFlag, key, allowNewVersion) {
try {
Expand All @@ -12,14 +13,14 @@ async function getProjectVersion(versionFlag, key, allowNewVersion) {
method: 'get',
headers: cleanHeaders(key),
})
.then(res => res.json())
.then(res => handleRes(res))
.then(res => res.version);
}

const versionList = await fetch(`${config.host}/api/v1/version`, {
method: 'get',
headers: cleanHeaders(key),
}).then(res => res.json());
}).then(res => handleRes(res));

if (allowNewVersion) {
const { option, versionSelection, newVersion } = await prompt(promptOpts.generatePrompts(versionList));
Expand Down

0 comments on commit 431a7db

Please sign in to comment.