Skip to content

Commit

Permalink
feat: sending a custom rdme user agent with all requests (#436)
Browse files Browse the repository at this point in the history
* 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
erunion authored Feb 2, 2022
1 parent 8daf569 commit bec8c36
Show file tree
Hide file tree
Showing 23 changed files with 239 additions and 182 deletions.
19 changes: 1 addition & 18 deletions __tests__/.eslintrc
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"]
}
82 changes: 45 additions & 37 deletions __tests__/cmds/docs.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand All @@ -24,6 +26,7 @@ function getNockWithVersionHeader(v) {
return nock(config.get('host'), {
reqheaders: {
'x-readme-version': v,
'User-Agent': userAgent,
},
});
}
Expand Down Expand Up @@ -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 });
Expand Down Expand Up @@ -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 });
Expand All @@ -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`)));
Expand All @@ -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 () => {
Expand Down Expand Up @@ -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 });
Expand All @@ -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, {
Expand All @@ -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();
});
});
});
Expand Down Expand Up @@ -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`);
Expand Down Expand Up @@ -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));

Expand All @@ -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);
Expand All @@ -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}`)
Expand Down
12 changes: 5 additions & 7 deletions __tests__/cmds/login.test.js
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();

Expand Down Expand Up @@ -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();

Expand All @@ -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();
Expand All @@ -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();
Expand All @@ -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();
Expand Down
29 changes: 15 additions & 14 deletions __tests__/cmds/openapi.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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, [])
Expand All @@ -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 }])
Expand Down Expand Up @@ -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 });
Expand All @@ -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 });
Expand All @@ -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 });
Expand Down Expand Up @@ -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({
Expand All @@ -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' }])
Expand All @@ -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, [])
Expand Down Expand Up @@ -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') })
Expand All @@ -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' });
Expand Down Expand Up @@ -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' })
Expand Down Expand Up @@ -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' })
Expand All @@ -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' })
Expand All @@ -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' })
Expand Down
Loading

0 comments on commit bec8c36

Please sign in to comment.