From 05e8d78150a57b07dd3654164f4dc4f02b4b557d Mon Sep 17 00:00:00 2001 From: Kanad Gupta Date: Tue, 30 Aug 2022 10:41:56 -0500 Subject: [PATCH] fix(openapi): stricter tests, `create` flag edge case (#585) --- __tests__/cmds/openapi/index.test.ts | 85 ++++++++++++++++++++++------ __tests__/helpers/get-api-mock.ts | 2 +- src/cmds/openapi/index.ts | 2 +- 3 files changed, 71 insertions(+), 18 deletions(-) diff --git a/__tests__/cmds/openapi/index.test.ts b/__tests__/cmds/openapi/index.test.ts index f71070a4a..6725cfafe 100644 --- a/__tests__/cmds/openapi/index.test.ts +++ b/__tests__/cmds/openapi/index.test.ts @@ -83,7 +83,9 @@ describe('rdme openapi', () => { .reply(200, []) .get(`/api/v1/version/${version}`) .basicAuth({ user: key }) - .reply(200, { version: '1.0.0' }) + .reply(200, { version: '1.0.0' }); + + const postMock = getAPIMockWithVersionHeader(version) .post('/api/v1/api-specification', { registryUUID }) .basicAuth({ user: key }) .reply(201, { _id: 1 }, { location: exampleRefLocation }); @@ -100,6 +102,7 @@ describe('rdme openapi', () => { expect(console.info).toHaveBeenCalledTimes(0); + postMock.done(); return mock.done(); }); @@ -207,11 +210,17 @@ describe('rdme openapi', () => { }); it('should create a new spec via `--create` flag and ignore `--id`', async () => { + prompts.inject(['update', version]); const registryUUID = getRandomRegistryId(); const mock = getAPIMock() + .get('/api/v1/version') + .basicAuth({ user: key }) + .reply(200, [{ version }]) .post('/api/v1/api-registry', body => body.match('form-data; name="spec"')) - .reply(201, { registryUUID, spec: { openapi: '3.0.0' } }) + .reply(201, { registryUUID, spec: { openapi: '3.0.0' } }); + + const postMock = getAPIMockWithVersionHeader(version) .post('/api/v1/api-specification', { registryUUID }) .delayConnection(1000) .basicAuth({ user: key }) @@ -235,6 +244,7 @@ describe('rdme openapi', () => { expect(output).toMatch(/the `--id` parameter will be ignored/i); + postMock.done(); return mock.done(); }); @@ -254,7 +264,9 @@ describe('rdme openapi', () => { .reply(201, { registryUUID, spec: { openapi: '3.0.0' } }) .get('/api/v1/api-specification') .basicAuth({ user: key }) - .reply(200, []) + .reply(200, []); + + const postMock = getAPIMockWithVersionHeader(version) .post('/api/v1/api-specification', { registryUUID }) .basicAuth({ user: key }) .reply(201, { _id: 1 }, { location: exampleRefLocation }); @@ -267,6 +279,7 @@ describe('rdme openapi', () => { expect(requestBody).toMatchSnapshot(); + postMock.done(); return mock.done(); }); @@ -283,7 +296,9 @@ describe('rdme openapi', () => { return body.match('form-data; name="spec"'); }) - .reply(201, { registryUUID, spec: { openapi: '3.0.0' } }) + .reply(201, { registryUUID, spec: { openapi: '3.0.0' } }); + + const mockWithHeader = getAPIMockWithVersionHeader(version) .get('/api/v1/api-specification') .basicAuth({ user: key }) .reply(200, []) @@ -306,6 +321,7 @@ describe('rdme openapi', () => { expect(requestBody).toMatchSnapshot(); + mockWithHeader.done(); return mock.done(); }); @@ -342,7 +358,9 @@ describe('rdme openapi', () => { const mock = getAPIMock() .post('/api/v1/api-registry', body => body.match('form-data; name="spec"')) - .reply(201, { registryUUID, spec: { openapi: specVersion } }) + .reply(201, { registryUUID, spec: { openapi: specVersion } }); + + const putMock = getAPIMockWithVersionHeader(version) .put(`/api/v1/api-specification/${id}`, { registryUUID }) .basicAuth({ user: key }) .reply(201, { _id: 1 }, { location: exampleRefLocation }); @@ -358,15 +376,19 @@ describe('rdme openapi', () => { }) ).resolves.toBe(successfulUpdate(spec, type)); + putMock.done(); return mock.done(); }); it('should return warning if providing `id` and `version`', async () => { + expect.assertions(4); const registryUUID = getRandomRegistryId(); const mock = getAPIMock() .post('/api/v1/api-registry', body => body.match('form-data; name="spec"')) - .reply(201, { registryUUID, spec: { openapi: '3.0.0' } }) + .reply(201, { registryUUID, spec: { openapi: '3.0.0' } }); + + const putMock = getAPIMockWithVersionHeader(version) .put(`/api/v1/api-specification/${id}`, { registryUUID }) .basicAuth({ user: key }) .reply(201, { _id: 1 }, { location: exampleRefLocation }); @@ -382,6 +404,7 @@ describe('rdme openapi', () => { expect(output).toMatch(/the `--version` option will be ignored/i); + putMock.done(); return mock.done(); }); @@ -491,6 +514,7 @@ describe('rdme openapi', () => { }); it('should warn if providing both `update` and `id`', async () => { + expect.assertions(5); const registryUUID = getRandomRegistryId(); const mock = getAPIMock() @@ -499,7 +523,11 @@ describe('rdme openapi', () => { .put('/api/v1/api-specification/spec1', { registryUUID }) .delayConnection(1000) .basicAuth({ user: key }) - .reply(201, { _id: 1 }, { location: exampleRefLocation }); + .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( @@ -538,7 +566,9 @@ describe('rdme openapi', () => { return body.match('form-data; name="spec"'); }) - .reply(201, { registryUUID, spec: { openapi: '3.0.0' } }) + .reply(201, { registryUUID, spec: { openapi: '3.0.0' } }); + + const mockWithHeader = getAPIMockWithVersionHeader(version) .get('/api/v1/api-specification') .basicAuth({ user: key }) .reply(200, []) @@ -553,6 +583,7 @@ describe('rdme openapi', () => { await expect(openapi.run({ spec, key, version })).resolves.toBe(successfulUpload(spec)); + mockWithHeader.done(); return mock.done(); }); @@ -571,7 +602,9 @@ describe('rdme openapi', () => { return body.match('form-data; name="spec"'); }) - .reply(201, { registryUUID, spec: { openapi: '3.0.0' } }) + .reply(201, { registryUUID, spec: { openapi: '3.0.0' } }); + + const mockWithHeader = getAPIMockWithVersionHeader(specVersion) .get('/api/v1/api-specification') .basicAuth({ user: key }) .reply(200, []) @@ -586,6 +619,7 @@ describe('rdme openapi', () => { await expect(openapi.run({ spec, key, version, useSpecVersion: true })).resolves.toBe(successfulUpload(spec)); + mockWithHeader.done(); return mock.done(); }); @@ -660,7 +694,8 @@ describe('rdme openapi', () => { }); it('should request a version list if version is not found', async () => { - prompts.inject(['create', '1.0.1']); + const selectedVersion = '1.0.1'; + prompts.inject(['create', selectedVersion]); const registryUUID = getRandomRegistryId(); @@ -672,7 +707,9 @@ describe('rdme openapi', () => { .basicAuth({ user: key }) .reply(200, { from: '1.0.0', version: '1.0.1' }) .post('/api/v1/api-registry', body => body.match('form-data; name="spec"')) - .reply(201, { registryUUID, spec: { openapi: '3.0.0' } }) + .reply(201, { registryUUID, spec: { openapi: '3.0.0' } }); + + const mockWithHeader = getAPIMockWithVersionHeader(selectedVersion) .get('/api/v1/api-specification') .basicAuth({ user: key }) .reply(200, []) @@ -684,6 +721,7 @@ describe('rdme openapi', () => { await expect(openapi.run({ spec, key })).resolves.toBe(successfulUpload(spec, 'Swagger')); + mockWithHeader.done(); return mock.done(); }); }); @@ -765,7 +803,9 @@ describe('rdme openapi', () => { .basicAuth({ user: key }) .reply(200, { version: '1.0.0' }) .post('/api/v1/api-registry', body => body.match('form-data; name="spec"')) - .reply(201, { registryUUID, spec: { openapi: '3.0.0' } }) + .reply(201, { registryUUID, spec: { openapi: '3.0.0' } }); + + const mockWithHeader = getAPIMockWithVersionHeader(version) .get('/api/v1/api-specification') .basicAuth({ user: key }) .reply(200, []) @@ -782,6 +822,7 @@ describe('rdme openapi', () => { }) ).rejects.toStrictEqual(new APIError(errorObject)); + mockWithHeader.done(); return mock.done(); }); @@ -797,7 +838,9 @@ describe('rdme openapi', () => { const mock = getAPIMock() .post('/api/v1/api-registry', body => body.match('form-data; name="spec"')) - .reply(201, { registryUUID, spec: { openapi: '3.0.0' } }) + .reply(201, { registryUUID, spec: { openapi: '3.0.0' } }); + + const putMock = getAPIMockWithVersionHeader(version) .put(`/api/v1/api-specification/${id}`, { registryUUID }) .delayConnection(1000) .basicAuth({ user: key }) @@ -812,6 +855,7 @@ describe('rdme openapi', () => { }) ).rejects.toStrictEqual(new APIError(errorObject)); + putMock.done(); return mock.done(); }); @@ -857,7 +901,9 @@ describe('rdme openapi', () => { .basicAuth({ user: key }) .reply(200, { version: '1.0.0' }) .post('/api/v1/api-registry', body => body.match('form-data; name="spec"')) - .reply(201, { registryUUID, spec: { openapi: '3.0.0' } }) + .reply(201, { registryUUID, spec: { openapi: '3.0.0' } }); + + const mockWithHeader = getAPIMockWithVersionHeader(version) .get('/api/v1/api-specification') .basicAuth({ user: key }) .reply(200, []) @@ -870,6 +916,7 @@ describe('rdme openapi', () => { openapi.run({ spec: require.resolve('@readme/oas-examples/2.0/json/petstore.json'), key, version }) ).rejects.toStrictEqual(new APIError(errorObject)); + mockWithHeader.done(); return mock.done(); }); @@ -881,7 +928,9 @@ describe('rdme openapi', () => { .basicAuth({ user: key }) .reply(200, { version: '1.0.0' }) .post('/api/v1/api-registry', body => body.match('form-data; name="spec"')) - .reply(201, { registryUUID, spec: { openapi: '3.0.0' } }) + .reply(201, { registryUUID, spec: { openapi: '3.0.0' } }); + + const mockWithHeader = getAPIMockWithVersionHeader(version) .get('/api/v1/api-specification') .basicAuth({ user: key }) .reply(200, []) @@ -898,6 +947,7 @@ describe('rdme openapi', () => { ) ); + mockWithHeader.done(); return mock.done(); }); @@ -909,7 +959,9 @@ describe('rdme openapi', () => { .basicAuth({ user: key }) .reply(200, { version: '1.0.0' }) .post('/api/v1/api-registry', body => body.match('form-data; name="spec"')) - .reply(201, { registryUUID, spec: { openapi: '3.0.0' } }) + .reply(201, { registryUUID, spec: { openapi: '3.0.0' } }); + + const mockWithHeader = getAPIMockWithVersionHeader(version) .get('/api/v1/api-specification') .basicAuth({ user: key }) .reply(200, []) @@ -926,6 +978,7 @@ describe('rdme openapi', () => { ) ); + mockWithHeader.done(); return mock.done(); }); }); diff --git a/__tests__/helpers/get-api-mock.ts b/__tests__/helpers/get-api-mock.ts index 40bf6b6c1..e363f6482 100644 --- a/__tests__/helpers/get-api-mock.ts +++ b/__tests__/helpers/get-api-mock.ts @@ -12,7 +12,7 @@ export default function getAPIMock(reqHeaders = {}) { }); } -export function getAPIMockWithVersionHeader(v) { +export function getAPIMockWithVersionHeader(v: string) { return getAPIMock({ 'x-readme-version': v, }); diff --git a/src/cmds/openapi/index.ts b/src/cmds/openapi/index.ts index ae12b2735..5a30e548a 100644 --- a/src/cmds/openapi/index.ts +++ b/src/cmds/openapi/index.ts @@ -126,7 +126,7 @@ export default class OpenAPICommand extends Command { selectedVersion = specVersion; } - if (!id) { + if (create || !id) { selectedVersion = await getProjectVersion(selectedVersion, key, true); }