-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
perf(openapi): upload improvements (#518)
* chore(deps): install ora * chore: add ora to dependabot and reformat * feat: add spinner for file validation * feat: initial registry upload function * refactor: move ora opts into shared function * refactor: use shared ora opts in new function also * feat: first pass at rewriting openapi command to support new flow - also i realphabetized the imports * chore: making the spinners spin * test: refactor existing tests to work with new flow * test: add coverage for if registry endpoint fails * chore: test coverage in ora opts * chore: spinner language
- Loading branch information
1 parent
6dc896c
commit e1aeac0
Showing
8 changed files
with
551 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,6 +43,8 @@ const getCommandOutput = () => { | |
return [console.warn.mock.calls.join('\n\n'), console.info.mock.calls.join('\n\n')].filter(Boolean).join('\n\n'); | ||
}; | ||
|
||
const getRandomRegistryId = () => Math.random().toString(36).substring(2); | ||
|
||
describe('rdme openapi', () => { | ||
beforeAll(() => nock.disableNetConnect()); | ||
|
||
|
@@ -69,14 +71,18 @@ describe('rdme openapi', () => { | |
['OpenAPI 3.1', 'json', '3.1', 'OpenAPI'], | ||
['OpenAPI 3.1', 'yaml', '3.1', 'OpenAPI'], | ||
])('should support uploading a %s definition (format: %s)', async (_, format, specVersion, type) => { | ||
const registryUUID = getRandomRegistryId(); | ||
|
||
const mock = getApiNock() | ||
.post('/api/v1/api-registry', body => body.match('form-data; name="spec"')) | ||
.reply(201, { registryUUID, spec: { openapi: specVersion } }) | ||
.get('/api/v1/api-specification') | ||
.basicAuth({ user: key }) | ||
.reply(200, []) | ||
.get(`/api/v1/version/${version}`) | ||
.basicAuth({ user: key }) | ||
.reply(200, { version: '1.0.0' }) | ||
.post('/api/v1/api-specification', body => body.match('form-data; name="spec"')) | ||
.post('/api/v1/api-specification', { registryUUID }) | ||
.basicAuth({ user: key }) | ||
.reply(201, { _id: 1 }, { location: exampleRefLocation }); | ||
|
||
|
@@ -98,17 +104,21 @@ describe('rdme openapi', () => { | |
it('should discover and upload an API definition if none is provided', async () => { | ||
promptHandler.createOasPrompt.mockResolvedValue({ option: 'create' }); | ||
|
||
const registryUUID = getRandomRegistryId(); | ||
|
||
const mock = getApiNock() | ||
.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' } }) | ||
.post('/api/v1/version') | ||
.basicAuth({ user: key }) | ||
.reply(200, { from: '1.0.1', version: '1.0.1' }) | ||
.get('/api/v1/api-specification') | ||
.basicAuth({ user: key }) | ||
.reply(200, []) | ||
.post('/api/v1/api-specification', body => body.match('form-data; name="spec"')) | ||
.post('/api/v1/api-specification', { registryUUID }) | ||
.delayConnection(1000) | ||
.basicAuth({ user: key }) | ||
.reply(201, { _id: 1 }, { location: exampleRefLocation }); | ||
|
@@ -139,8 +149,12 @@ describe('rdme openapi', () => { | |
['OpenAPI 3.1', 'json', '3.1', 'OpenAPI'], | ||
['OpenAPI 3.1', 'yaml', '3.1', 'OpenAPI'], | ||
])('should support updating a %s definition (format: %s)', async (_, format, specVersion, type) => { | ||
const registryUUID = getRandomRegistryId(); | ||
|
||
const mock = getApiNock() | ||
.put(`/api/v1/api-specification/${id}`, body => body.match('form-data; name="spec"')) | ||
.post('/api/v1/api-registry', body => body.match('form-data; name="spec"')) | ||
.reply(201, { registryUUID, spec: { openapi: specVersion } }) | ||
.put(`/api/v1/api-specification/${id}`, { registryUUID }) | ||
.basicAuth({ user: key }) | ||
.reply(201, { _id: 1 }, { location: exampleRefLocation }); | ||
|
||
|
@@ -159,8 +173,12 @@ describe('rdme openapi', () => { | |
}); | ||
|
||
it('should return warning if providing `id` and `version`', async () => { | ||
const registryUUID = getRandomRegistryId(); | ||
|
||
const mock = getApiNock() | ||
.put(`/api/v1/api-specification/${id}`, body => body.match('form-data; name="spec"')) | ||
.post('/api/v1/api-registry', body => body.match('form-data; name="spec"')) | ||
.reply(201, { registryUUID, spec: { openapi: '3.0.0' } }) | ||
.put(`/api/v1/api-specification/${id}`, { registryUUID }) | ||
.basicAuth({ user: key }) | ||
.reply(201, { _id: 1 }, { location: exampleRefLocation }); | ||
|
||
|
@@ -217,17 +235,21 @@ describe('rdme openapi', () => { | |
newVersion: '1.0.1', | ||
}); | ||
|
||
const registryUUID = getRandomRegistryId(); | ||
|
||
const mock = getApiNock() | ||
.get('/api/v1/version') | ||
.basicAuth({ user: key }) | ||
.reply(200, [{ version: '1.0.0' }]) | ||
.post('/api/v1/version') | ||
.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' } }) | ||
.get('/api/v1/api-specification') | ||
.basicAuth({ user: key }) | ||
.reply(200, []) | ||
.post('/api/v1/api-specification', body => body.match('form-data; name="spec"')) | ||
.post('/api/v1/api-specification', { registryUUID }) | ||
.basicAuth({ user: key }) | ||
.reply(201, { _id: 1 }, { location: exampleRefLocation }); | ||
|
||
|
@@ -241,19 +263,22 @@ describe('rdme openapi', () => { | |
|
||
it('should bundle and upload the expected content', async () => { | ||
let requestBody = null; | ||
const registryUUID = getRandomRegistryId(); | ||
const mock = getApiNock() | ||
.get('/api/v1/api-specification') | ||
.basicAuth({ user: key }) | ||
.reply(200, []) | ||
.get(`/api/v1/version/${version}`) | ||
.basicAuth({ user: key }) | ||
.reply(200, { version: '1.0.0' }) | ||
.post('/api/v1/api-specification', body => { | ||
.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(201, { _id: 1 }, { location: exampleRefLocation }); | ||
|
||
|
@@ -270,19 +295,22 @@ describe('rdme openapi', () => { | |
|
||
it('should use specified working directory and upload the expected content', async () => { | ||
let requestBody = null; | ||
const registryUUID = getRandomRegistryId(); | ||
const mock = getApiNock() | ||
.get('/api/v1/api-specification') | ||
.basicAuth({ user: key }) | ||
.reply(200, []) | ||
.get(`/api/v1/version/${version}`) | ||
.basicAuth({ user: key }) | ||
.reply(200, { version: '1.0.0' }) | ||
.post('/api/v1/api-specification', body => { | ||
.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(201, { _id: 1 }, { location: exampleRefLocation }); | ||
|
||
|
@@ -367,14 +395,18 @@ describe('rdme openapi', () => { | |
help: 'If you need help, email [email protected] and mention log "fake-metrics-uuid".', | ||
}; | ||
|
||
const registryUUID = getRandomRegistryId(); | ||
|
||
const mock = getApiNock() | ||
.get(`/api/v1/version/${version}`) | ||
.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' } }) | ||
.get('/api/v1/api-specification') | ||
.basicAuth({ user: key }) | ||
.reply(200, []) | ||
.post('/api/v1/api-specification', body => body.match('form-data; name="spec"')) | ||
.post('/api/v1/api-specification', { registryUUID }) | ||
.delayConnection(1000) | ||
.basicAuth({ user: key }) | ||
.reply(500, errorObject); | ||
|
@@ -390,6 +422,32 @@ describe('rdme openapi', () => { | |
return mock.done(); | ||
}); | ||
|
||
it('should throw an error if registry upload fails', async () => { | ||
const errorObject = { | ||
error: 'INTERNAL_ERROR', | ||
message: 'Unknown error (Registry is offline? lol idk)', | ||
suggestion: '...a suggestion to resolve the issue...', | ||
help: 'If you need help, email [email protected] and mention log "fake-metrics-uuid".', | ||
}; | ||
|
||
const mock = getApiNock() | ||
.get(`/api/v1/version/${version}`) | ||
.basicAuth({ user: key }) | ||
.reply(200, { version: '1.0.0' }) | ||
.post('/api/v1/api-registry', body => body.match('form-data; name="spec"')) | ||
.reply(400, errorObject); | ||
|
||
await expect( | ||
openapi.run({ | ||
spec: './__tests__/__fixtures__/swagger-with-invalid-extensions.json', | ||
key, | ||
version, | ||
}) | ||
).rejects.toStrictEqual(new APIError(errorObject)); | ||
|
||
return mock.done(); | ||
}); | ||
|
||
it('should error if API errors', async () => { | ||
const errorObject = { | ||
error: 'SPEC_VERSION_NOTFOUND', | ||
|
@@ -399,14 +457,18 @@ describe('rdme openapi', () => { | |
help: 'If you need help, email [email protected] and mention log "fake-metrics-uuid".', | ||
}; | ||
|
||
const registryUUID = getRandomRegistryId(); | ||
|
||
const mock = getApiNock() | ||
.get(`/api/v1/version/${version}`) | ||
.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' } }) | ||
.get('/api/v1/api-specification') | ||
.basicAuth({ user: key }) | ||
.reply(200, []) | ||
.post('/api/v1/api-specification', body => body.match('form-data; name="spec"')) | ||
.post('/api/v1/api-specification', { registryUUID }) | ||
.delayConnection(1000) | ||
.basicAuth({ user: key }) | ||
.reply(400, errorObject); | ||
|
@@ -419,14 +481,18 @@ describe('rdme openapi', () => { | |
}); | ||
|
||
it('should error if API errors (generic upload error)', async () => { | ||
const registryUUID = getRandomRegistryId(); | ||
|
||
const mock = getApiNock() | ||
.get(`/api/v1/version/${version}`) | ||
.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' } }) | ||
.get('/api/v1/api-specification') | ||
.basicAuth({ user: key }) | ||
.reply(200, []) | ||
.post('/api/v1/api-specification', body => body.match('form-data; name="spec"')) | ||
.post('/api/v1/api-specification', { registryUUID }) | ||
.delayConnection(1000) | ||
.basicAuth({ user: key }) | ||
.reply(400, 'some non-JSON upload error'); | ||
|
@@ -439,14 +505,18 @@ describe('rdme openapi', () => { | |
}); | ||
|
||
it('should error if API errors (request timeout)', async () => { | ||
const registryUUID = getRandomRegistryId(); | ||
|
||
const mock = getApiNock() | ||
.get(`/api/v1/version/${version}`) | ||
.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' } }) | ||
.get('/api/v1/api-specification') | ||
.basicAuth({ user: key }) | ||
.reply(200, []) | ||
.post('/api/v1/api-specification', body => body.match('form-data; name="spec"')) | ||
.post('/api/v1/api-specification', { registryUUID }) | ||
.delayConnection(1000) | ||
.basicAuth({ user: key }) | ||
.reply(400, '<html></html>'); | ||
|
Oops, something went wrong.