-
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.
feat: sending a custom rdme user agent with all requests (#436)
* feat: adding an rdme-specific user agent to all api calls * feat: consolidating the cleanHeaders library into the new fetch lib * fix: standardizing a variable name * fix: pr feedback
- Loading branch information
Showing
23 changed files
with
239 additions
and
182 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,3 @@ | ||
{ | ||
"extends": ["@readme/eslint-config/testing"], | ||
"env": { | ||
"jest": true | ||
}, | ||
"rules": { | ||
"jest/expect-expect": [ | ||
"error", | ||
{ | ||
"assertFunctionNames": [ | ||
"expect", | ||
"getNockWithVersionHeader.**.reply", | ||
"nock.**.reply" | ||
] | ||
} | ||
], | ||
|
||
"jest/no-conditional-expect": "off" | ||
} | ||
"extends": ["@readme/eslint-config/testing"] | ||
} |
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 |
---|---|---|
|
@@ -7,6 +7,8 @@ const crypto = require('crypto'); | |
const frontMatter = require('gray-matter'); | ||
|
||
const APIError = require('../../src/lib/apiError'); | ||
const getApiNock = require('../get-api-nock'); | ||
const { userAgent } = require('../get-api-nock'); | ||
|
||
const DocsCommand = require('../../src/cmds/docs'); | ||
const DocsEditCommand = require('../../src/cmds/docs/edit'); | ||
|
@@ -24,6 +26,7 @@ function getNockWithVersionHeader(v) { | |
return nock(config.get('host'), { | ||
reqheaders: { | ||
'x-readme-version': v, | ||
'User-Agent': userAgent, | ||
}, | ||
}); | ||
} | ||
|
@@ -106,7 +109,7 @@ describe('rdme docs', () => { | |
.basicAuth({ user: key }) | ||
.reply(200, { category, slug: anotherDoc.slug, body: anotherDoc.doc.content }); | ||
|
||
const versionMock = nock(config.get('host')) | ||
const versionMock = getApiNock() | ||
.get(`/api/v1/version/${version}`) | ||
.basicAuth({ user: key }) | ||
.reply(200, { version }); | ||
|
@@ -140,7 +143,7 @@ describe('rdme docs', () => { | |
.basicAuth({ user: key }) | ||
.reply(200, { category, slug: anotherDoc.slug, lastUpdatedHash: anotherDoc.hash }); | ||
|
||
const versionMock = nock(config.get('host')) | ||
const versionMock = getApiNock() | ||
.get(`/api/v1/version/${version}`) | ||
.basicAuth({ user: key }) | ||
.reply(200, { version }); | ||
|
@@ -158,7 +161,7 @@ describe('rdme docs', () => { | |
}); | ||
|
||
describe('new docs', () => { | ||
it('should create new doc', () => { | ||
it('should create new doc', async () => { | ||
const slug = 'new-doc'; | ||
const doc = frontMatter(fs.readFileSync(path.join(fixturesDir, `/new-docs/${slug}.md`))); | ||
const hash = hashFileContents(fs.readFileSync(path.join(fixturesDir, `/new-docs/${slug}.md`))); | ||
|
@@ -178,16 +181,24 @@ describe('rdme docs', () => { | |
.basicAuth({ user: key }) | ||
.reply(201, { slug, body: doc.content, ...doc.data, lastUpdatedHash: hash }); | ||
|
||
const versionMock = nock(config.get('host')) | ||
const versionMock = getApiNock() | ||
.get(`/api/v1/version/${version}`) | ||
.basicAuth({ user: key }) | ||
.reply(200, { version }); | ||
|
||
return docs.run({ folder: './__tests__/__fixtures__/new-docs', key, version }).then(() => { | ||
getMock.done(); | ||
postMock.done(); | ||
versionMock.done(); | ||
}); | ||
await expect(docs.run({ folder: './__tests__/__fixtures__/new-docs', key, version })).resolves.toStrictEqual([ | ||
{ | ||
slug: 'new-doc', | ||
body: '\nBody\n', | ||
category: '5ae122e10fdf4e39bb34db6f', | ||
title: 'This is the document title', | ||
lastUpdatedHash: 'a23046c1e9d8ab47f8875ae7c5e429cb95be1c48', | ||
}, | ||
]); | ||
|
||
getMock.done(); | ||
postMock.done(); | ||
versionMock.done(); | ||
}); | ||
|
||
it('should fail if any docs are invalid', async () => { | ||
|
@@ -247,7 +258,7 @@ describe('rdme docs', () => { | |
.basicAuth({ user: key }) | ||
.reply(400, errorObject); | ||
|
||
const versionMock = nock(config.get('host')) | ||
const versionMock = getApiNock() | ||
.get(`/api/v1/version/${version}`) | ||
.basicAuth({ user: key }) | ||
.reply(200, { version }); | ||
|
@@ -270,12 +281,12 @@ describe('rdme docs', () => { | |
}); | ||
|
||
describe('slug metadata', () => { | ||
it('should use provided slug', () => { | ||
it('should use provided slug', async () => { | ||
const slug = 'new-doc-slug'; | ||
const doc = frontMatter(fs.readFileSync(path.join(fixturesDir, `/slug-docs/${slug}.md`))); | ||
const hash = hashFileContents(fs.readFileSync(path.join(fixturesDir, `/slug-docs/${slug}.md`))); | ||
|
||
const getMock = getNockWithVersionHeader(version) | ||
const getMock = getApiNock() | ||
.get(`/api/v1/docs/${doc.data.slug}`) | ||
.basicAuth({ user: key }) | ||
.reply(404, { | ||
|
@@ -285,21 +296,29 @@ describe('rdme docs', () => { | |
help: 'If you need help, email [email protected] and mention log "fake-metrics-uuid".', | ||
}); | ||
|
||
const postMock = getNockWithVersionHeader(version) | ||
const postMock = getApiNock() | ||
.post('/api/v1/docs', { slug, body: doc.content, ...doc.data, lastUpdatedHash: hash }) | ||
.basicAuth({ user: key }) | ||
.reply(201, { slug: doc.data.slug, body: doc.content, ...doc.data, lastUpdatedHash: hash }); | ||
|
||
const versionMock = nock(config.get('host')) | ||
const versionMock = getApiNock() | ||
.get(`/api/v1/version/${version}`) | ||
.basicAuth({ user: key }) | ||
.reply(200, { version }); | ||
|
||
return docs.run({ folder: './__tests__/__fixtures__/slug-docs', key, version }).then(() => { | ||
getMock.done(); | ||
postMock.done(); | ||
versionMock.done(); | ||
}); | ||
await expect(docs.run({ folder: './__tests__/__fixtures__/slug-docs', key, version })).resolves.toStrictEqual([ | ||
{ | ||
slug: 'marc-actually-wrote-a-test', | ||
body: '\nBody\n', | ||
category: 'CATEGORY_ID', | ||
title: 'This is the document title', | ||
lastUpdatedHash: 'c9cb7cc26e90775548e1d182ae7fcaa0eaba96bc', | ||
}, | ||
]); | ||
|
||
getMock.done(); | ||
postMock.done(); | ||
versionMock.done(); | ||
}); | ||
}); | ||
}); | ||
|
@@ -336,10 +355,7 @@ describe('rdme docs:edit', () => { | |
.basicAuth({ user: key }) | ||
.reply(200, { category, slug }); | ||
|
||
const versionMock = nock(config.get('host')) | ||
.get(`/api/v1/version/${version}`) | ||
.basicAuth({ user: key }) | ||
.reply(200, { version }); | ||
const versionMock = getApiNock().get(`/api/v1/version/${version}`).basicAuth({ user: key }).reply(200, { version }); | ||
|
||
function mockEditor(filename, cb) { | ||
expect(filename).toBe(`${slug}.md`); | ||
|
@@ -368,12 +384,9 @@ describe('rdme docs:edit', () => { | |
help: 'If you need help, email [email protected] and mention log "fake-metrics-uuid".', | ||
}; | ||
|
||
const getMock = nock(config.get('host')).get(`/api/v1/docs/${slug}`).reply(404, errorObject); | ||
const getMock = getApiNock().get(`/api/v1/docs/${slug}`).reply(404, errorObject); | ||
|
||
const versionMock = nock(config.get('host')) | ||
.get(`/api/v1/version/${version}`) | ||
.basicAuth({ user: key }) | ||
.reply(200, { version }); | ||
const versionMock = getApiNock().get(`/api/v1/version/${version}`).basicAuth({ user: key }).reply(200, { version }); | ||
|
||
await expect(docsEdit.run({ slug, key, version: '1.0.0' })).rejects.toThrow(new APIError(errorObject)); | ||
|
||
|
@@ -392,14 +405,9 @@ describe('rdme docs:edit', () => { | |
help: 'If you need help, email [email protected] and mention log "fake-metrics-uuid".', | ||
}; | ||
|
||
const getMock = nock(config.get('host')).get(`/api/v1/docs/${slug}`).reply(200, { body }); | ||
|
||
const putMock = nock(config.get('host')).put(`/api/v1/docs/${slug}`).reply(400, errorObject); | ||
|
||
const versionMock = nock(config.get('host')) | ||
.get(`/api/v1/version/${version}`) | ||
.basicAuth({ user: key }) | ||
.reply(200, { version }); | ||
const getMock = getApiNock().get(`/api/v1/docs/${slug}`).reply(200, { body }); | ||
const putMock = getApiNock().put(`/api/v1/docs/${slug}`).reply(400, errorObject); | ||
const versionMock = getApiNock().get(`/api/v1/version/${version}`).basicAuth({ user: key }).reply(200, { version }); | ||
|
||
function mockEditor(filename, cb) { | ||
return cb(0); | ||
|
@@ -419,7 +427,7 @@ describe('rdme docs:edit', () => { | |
const slug = 'getting-started'; | ||
const body = 'abcdef'; | ||
|
||
const getMock = nock(config.get('host')) | ||
const getMock = getApiNock() | ||
.get(`/api/v1/docs/${slug}`) | ||
.reply(200, { body }) | ||
.get(`/api/v1/version/${version}`) | ||
|
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 |
---|---|---|
@@ -1,8 +1,8 @@ | ||
const nock = require('nock'); | ||
const config = require('config'); | ||
const configStore = require('../../src/lib/configstore'); | ||
const Command = require('../../src/cmds/login'); | ||
const APIError = require('../../src/lib/apiError'); | ||
const getApiNock = require('../get-api-nock'); | ||
|
||
const cmd = new Command(); | ||
|
||
|
@@ -32,7 +32,7 @@ describe('rdme login', () => { | |
it('should post to /login on the API', async () => { | ||
const apiKey = 'abcdefg'; | ||
|
||
const mock = nock(config.get('host')).post('/api/v1/login', { email, password, project }).reply(200, { apiKey }); | ||
const mock = getApiNock().post('/api/v1/login', { email, password, project }).reply(200, { apiKey }); | ||
|
||
await expect(cmd.run({ email, password, project })).resolves.toMatchSnapshot(); | ||
|
||
|
@@ -52,7 +52,7 @@ describe('rdme login', () => { | |
help: 'If you need help, email [email protected] and mention log "fake-metrics-uuid".', | ||
}; | ||
|
||
const mock = nock(config.get('host')).post('/api/v1/login', { email, password, project }).reply(401, errorResponse); | ||
const mock = getApiNock().post('/api/v1/login', { email, password, project }).reply(401, errorResponse); | ||
|
||
await expect(cmd.run({ email, password, project })).rejects.toStrictEqual(new APIError(errorResponse)); | ||
mock.done(); | ||
|
@@ -66,7 +66,7 @@ describe('rdme login', () => { | |
help: 'If you need help, email [email protected] and mention log "fake-metrics-uuid".', | ||
}; | ||
|
||
const mock = nock(config.get('host')).post('/api/v1/login', { email, password, project }).reply(401, errorResponse); | ||
const mock = getApiNock().post('/api/v1/login', { email, password, project }).reply(401, errorResponse); | ||
|
||
await expect(cmd.run({ email, password, project })).rejects.toStrictEqual(new APIError(errorResponse)); | ||
mock.done(); | ||
|
@@ -75,9 +75,7 @@ describe('rdme login', () => { | |
it('should send 2fa token if provided', async () => { | ||
const token = '123456'; | ||
|
||
const mock = nock(config.get('host')) | ||
.post('/api/v1/login', { email, password, project, token }) | ||
.reply(200, { apiKey: '123' }); | ||
const mock = getApiNock().post('/api/v1/login', { email, password, project, token }).reply(200, { apiKey: '123' }); | ||
|
||
await expect(cmd.run({ email, password, project, token })).resolves.toMatchSnapshot(); | ||
mock.done(); | ||
|
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 |
---|---|---|
|
@@ -6,6 +6,7 @@ const promptHandler = require('../../src/lib/prompts'); | |
const SwaggerCommand = require('../../src/cmds/swagger'); | ||
const OpenAPICommand = require('../../src/cmds/openapi'); | ||
const APIError = require('../../src/lib/apiError'); | ||
const getApiNock = require('../get-api-nock'); | ||
|
||
const openapi = new OpenAPICommand(); | ||
const swagger = new SwaggerCommand(); | ||
|
@@ -62,7 +63,7 @@ describe('rdme openapi', () => { | |
['OpenAPI 3.1', 'json', '3.1'], | ||
['OpenAPI 3.1', 'yaml', '3.1'], | ||
])('should support uploading a %s definition (format: %s)', async (_, format, specVersion) => { | ||
const mock = nock(config.get('host')) | ||
const mock = getApiNock() | ||
.get('/api/v1/api-specification') | ||
.basicAuth({ user: key }) | ||
.reply(200, []) | ||
|
@@ -89,7 +90,7 @@ describe('rdme openapi', () => { | |
it('should discover and upload an API definition if none is provided', async () => { | ||
promptHandler.createOasPrompt.mockResolvedValue({ option: 'create' }); | ||
|
||
const mock = nock(config.get('host')) | ||
const mock = getApiNock() | ||
.get('/api/v1/version') | ||
.basicAuth({ user: key }) | ||
.reply(200, [{ version }]) | ||
|
@@ -130,7 +131,7 @@ describe('rdme openapi', () => { | |
['OpenAPI 3.1', 'json', '3.1'], | ||
['OpenAPI 3.1', 'yaml', '3.1'], | ||
])('should support updating a %s definition (format: %s)', async (_, format, specVersion) => { | ||
const mock = nock(config.get('host')) | ||
const mock = getApiNock() | ||
.put(`/api/v1/api-specification/${id}`, body => body.match('form-data; name="spec"')) | ||
.basicAuth({ user: key }) | ||
.reply(201, { _id: 1 }, { location: exampleRefLocation }); | ||
|
@@ -148,7 +149,7 @@ describe('rdme openapi', () => { | |
}); | ||
|
||
it('should still support `token`', async () => { | ||
const mock = nock(config.get('host')) | ||
const mock = getApiNock() | ||
.put(`/api/v1/api-specification/${id}`, body => body.match('form-data; name="spec"')) | ||
.basicAuth({ user: key }) | ||
.reply(201, { _id: 1 }, { location: exampleRefLocation }); | ||
|
@@ -172,7 +173,7 @@ describe('rdme openapi', () => { | |
}); | ||
|
||
it('should return warning if providing `id` and `version`', async () => { | ||
const mock = nock(config.get('host')) | ||
const mock = getApiNock() | ||
.put(`/api/v1/api-specification/${id}`, body => body.match('form-data; name="spec"')) | ||
.basicAuth({ user: key }) | ||
.reply(201, { _id: 1 }, { location: exampleRefLocation }); | ||
|
@@ -211,7 +212,7 @@ describe('rdme openapi', () => { | |
], | ||
}; | ||
|
||
const mock = nock(config.get('host')).get(`/api/v1/version/${invalidVersion}`).reply(404, errorObject); | ||
const mock = getApiNock().get(`/api/v1/version/${invalidVersion}`).reply(404, errorObject); | ||
|
||
await expect( | ||
openapi.run({ | ||
|
@@ -230,7 +231,7 @@ describe('rdme openapi', () => { | |
newVersion: '1.0.1', | ||
}); | ||
|
||
const mock = nock(config.get('host')) | ||
const mock = getApiNock() | ||
.get('/api/v1/version') | ||
.basicAuth({ user: key }) | ||
.reply(200, [{ version: '1.0.0' }]) | ||
|
@@ -254,7 +255,7 @@ describe('rdme openapi', () => { | |
|
||
it('should bundle and upload the expected content', async () => { | ||
let requestBody = null; | ||
const mock = nock(config.get('host')) | ||
const mock = getApiNock() | ||
.get('/api/v1/api-specification') | ||
.basicAuth({ user: key }) | ||
.reply(200, []) | ||
|
@@ -304,7 +305,7 @@ describe('rdme openapi', () => { | |
], | ||
}; | ||
|
||
const mock = nock(config.get('host')).get('/api/v1/version').reply(401, errorObject); | ||
const mock = getApiNock().get('/api/v1/version').reply(401, errorObject); | ||
|
||
await expect( | ||
openapi.run({ key, spec: require.resolve('@readme/oas-examples/3.1/json/petstore.json') }) | ||
|
@@ -314,7 +315,7 @@ describe('rdme openapi', () => { | |
}); | ||
|
||
it('should error if no file was provided or able to be discovered', async () => { | ||
const mock = nock(config.get('host')) | ||
const mock = getApiNock() | ||
.get(`/api/v1/version/${version}`) | ||
.basicAuth({ user: key }) | ||
.reply(200, { version: '1.0.0' }); | ||
|
@@ -344,7 +345,7 @@ describe('rdme openapi', () => { | |
help: 'If you need help, email [email protected] and mention log "fake-metrics-uuid".', | ||
}; | ||
|
||
const mock = nock(config.get('host')) | ||
const mock = getApiNock() | ||
.get(`/api/v1/version/${version}`) | ||
.basicAuth({ user: key }) | ||
.reply(200, { version: '1.0.0' }) | ||
|
@@ -376,7 +377,7 @@ describe('rdme openapi', () => { | |
help: 'If you need help, email [email protected] and mention log "fake-metrics-uuid".', | ||
}; | ||
|
||
const mock = nock(config.get('host')) | ||
const mock = getApiNock() | ||
.get(`/api/v1/version/${version}`) | ||
.basicAuth({ user: key }) | ||
.reply(200, { version: '1.0.0' }) | ||
|
@@ -396,7 +397,7 @@ describe('rdme openapi', () => { | |
}); | ||
|
||
it('should error if API errors (generic upload error)', async () => { | ||
const mock = nock(config.get('host')) | ||
const mock = getApiNock() | ||
.get(`/api/v1/version/${version}`) | ||
.basicAuth({ user: key }) | ||
.reply(200, { version: '1.0.0' }) | ||
|
@@ -416,7 +417,7 @@ describe('rdme openapi', () => { | |
}); | ||
|
||
it('should error if API errors (request timeout)', async () => { | ||
const mock = nock(config.get('host')) | ||
const mock = getApiNock() | ||
.get(`/api/v1/version/${version}`) | ||
.basicAuth({ user: key }) | ||
.reply(200, { version: '1.0.0' }) | ||
|
Oops, something went wrong.