Skip to content

Commit

Permalink
feat(GHA): add req header containing file URL (#735)
Browse files Browse the repository at this point in the history
* feat(GHA): add req header containing file URL

* test: fix coverage for ci.name

* chore: add eslint rule for importing `ci-info`

* chore: add smol jsdoc

* chore: another JSdoc

* chore: fix whitespace

* refactor: separate GHA runner setup/teardown

... into separate functions

* chore: rename variable

* chore: misc JSDocs

* chore: include sanitized headers in debug logs

* fix: normalize relative file paths

* test: a buttload of tests

* test: consolidate some CI tests

* chore: fix a JSDoc

* revert: restore a test to its original place

it's failing now but not sure why 😬

* chore: try different approach to GHA env vars

feedback: #735 (comment)

https://www.webtips.dev/how-to-mock-processenv-in-jest

* refactor: use shorthand

Co-Authored-By: Ryan Park <ryan@ryanpark.org>

* fix: better approach to normalizing file path

feedback: #735 (comment)

* chore: fix JSDoc

---------

Co-authored-by: Ryan Park <ryan@ryanpark.org>
  • Loading branch information
kanadgupta and RyanGWU82 authored Feb 1, 2023
1 parent 968c653 commit 7574752
Show file tree
Hide file tree
Showing 12 changed files with 638 additions and 109 deletions.
4 changes: 4 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@
"name": "node-fetch",
"importNames": ["default"],
"message": "Avoid using `node-fetch` directly and instead use the fetch wrapper located in `lib/fetch.ts`. See CONTRIBUTING.md for more information."
},
{
"name": "ci-info",
"message": "The `ci-info` package is difficult to test because misleading results will appear when running tests in the GitHub Actions runner. Instead of importing this package directly, create a wrapper function in `lib/isCI.ts` and import that instead."
}
]
}
Expand Down
139 changes: 133 additions & 6 deletions __tests__/cmds/docs/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import configstore from '../../../src/lib/configstore';
import getAPIMock, { getAPIMockWithVersionHeader } from '../../helpers/get-api-mock';
import { after, before } from '../../helpers/get-gha-setup';
import hashFileContents from '../../helpers/hash-file-contents';
import { after as afterGHAEnv, before as beforeGHAEnv } from '../../helpers/setup-gha-env';

const docs = new DocsCommand();
const guides = new GuidesCommand();
Expand Down Expand Up @@ -68,12 +69,6 @@ describe('rdme docs', () => {
jest.resetAllMocks();
});

it('should error in CI if no API key provided', async () => {
process.env.TEST_RDME_CI = 'true';
await expect(docs.run({})).rejects.toStrictEqual(new Error('No project API key provided. Please use `--key`.'));
delete process.env.TEST_RDME_CI;
});

it('should error if no path provided', async () => {
const versionMock = getAPIMock().get(`/api/v1/version/${version}`).basicAuth({ user: key }).reply(200, { version });

Expand Down Expand Up @@ -623,6 +618,138 @@ describe('rdme docs', () => {
versionMock.done();
});
});

describe('command execution in GitHub Actions runner', () => {
beforeEach(beforeGHAEnv);

afterEach(afterGHAEnv);

it('should error in CI if no API key provided', () => {
return expect(docs.run({})).rejects.toStrictEqual(new Error('No project API key provided. Please use `--key`.'));
});

it('should sync new docs directory with correct headers', async () => {
const slug = 'new-doc';
const id = '1234';
const doc = frontMatter(fs.readFileSync(path.join(fullFixturesDir, `/new-docs/${slug}.md`)));
const hash = hashFileContents(fs.readFileSync(path.join(fullFixturesDir, `/new-docs/${slug}.md`)));

const getMock = getAPIMockWithVersionHeader(version)
.get(`/api/v1/docs/${slug}`)
.basicAuth({ user: key })
.reply(404, {
error: 'DOC_NOTFOUND',
message: `The doc with the slug '${slug}' couldn't be found`,
suggestion: '...a suggestion to resolve the issue...',
help: 'If you need help, email support@readme.io and mention log "fake-metrics-uuid".',
});

const postMock = getAPIMock({
'x-rdme-ci': 'GitHub Actions (test)',
'x-readme-source': 'cli-gh',
'x-readme-source-url':
'https://github.com/octocat/Hello-World/blob/ffac537e6cbbf934b08745a378932722df287a53/__tests__/__fixtures__/docs/new-docs/new-doc.md',
'x-readme-version': version,
})
.post('/api/v1/docs', { slug, body: doc.content, ...doc.data, lastUpdatedHash: hash })
.basicAuth({ user: key })
.reply(201, { slug, _id: id, body: doc.content, ...doc.data, lastUpdatedHash: hash });

const versionMock = getAPIMock()
.get(`/api/v1/version/${version}`)
.basicAuth({ user: key })
.reply(200, { version });

await expect(docs.run({ filePath: `./__tests__/${fixturesBaseDir}/new-docs`, key, version })).resolves.toBe(
`🌱 successfully created 'new-doc' (ID: 1234) with contents from __tests__/${fixturesBaseDir}/new-docs/new-doc.md`
);

getMock.done();
postMock.done();
versionMock.done();
});

it('should sync existing docs directory with correct headers', () => {
let fileContents = fs.readFileSync(path.join(fullFixturesDir, '/existing-docs/simple-doc.md'));
const simpleDoc = {
slug: 'simple-doc',
doc: frontMatter(fileContents),
hash: hashFileContents(fileContents),
};

fileContents = fs.readFileSync(path.join(fullFixturesDir, '/existing-docs/subdir/another-doc.md'));
const anotherDoc = {
slug: 'another-doc',
doc: frontMatter(fileContents),
hash: hashFileContents(fileContents),
};

expect.assertions(1);

const getMocks = getAPIMockWithVersionHeader(version)
.get('/api/v1/docs/simple-doc')
.basicAuth({ user: key })
.reply(200, { category, slug: simpleDoc.slug, lastUpdatedHash: 'anOldHash' })
.get('/api/v1/docs/another-doc')
.basicAuth({ user: key })
.reply(200, { category, slug: anotherDoc.slug, lastUpdatedHash: 'anOldHash' });

const firstUpdateMock = getAPIMock({
'x-rdme-ci': 'GitHub Actions (test)',
'x-readme-source': 'cli-gh',
'x-readme-source-url':
'https://github.com/octocat/Hello-World/blob/ffac537e6cbbf934b08745a378932722df287a53/__tests__/__fixtures__/docs/existing-docs/simple-doc.md',
'x-readme-version': version,
})
.put('/api/v1/docs/simple-doc', {
body: simpleDoc.doc.content,
lastUpdatedHash: simpleDoc.hash,
...simpleDoc.doc.data,
})
.basicAuth({ user: key })
.reply(200, {
category,
slug: simpleDoc.slug,
body: simpleDoc.doc.content,
});

const secondUpdateMock = getAPIMock({
'x-rdme-ci': 'GitHub Actions (test)',
'x-readme-source': 'cli-gh',
'x-readme-source-url':
'https://github.com/octocat/Hello-World/blob/ffac537e6cbbf934b08745a378932722df287a53/__tests__/__fixtures__/docs/existing-docs/subdir/another-doc.md',
'x-readme-version': version,
})
.put('/api/v1/docs/another-doc', {
body: anotherDoc.doc.content,
lastUpdatedHash: anotherDoc.hash,
...anotherDoc.doc.data,
})
.basicAuth({ user: key })
.reply(200, { category, slug: anotherDoc.slug, body: anotherDoc.doc.content });

const versionMock = getAPIMock()
.get(`/api/v1/version/${version}`)
.basicAuth({ user: key })
.reply(200, { version });

return docs.run({ filePath: `__tests__/${fixturesBaseDir}/existing-docs`, key, version }).then(updatedDocs => {
// All docs should have been updated because their hashes from the GET request were different from what they
// are currently.
expect(updatedDocs).toBe(
[
`✏️ successfully updated 'simple-doc' with contents from __tests__/${fixturesBaseDir}/existing-docs/simple-doc.md`,
`✏️ successfully updated 'another-doc' with contents from __tests__/${fixturesBaseDir}/existing-docs/subdir/another-doc.md`,
].join('\n')
);

getMocks.done();
firstUpdateMock.done();
secondUpdateMock.done();
versionMock.done();
});
});
});
});

describe('rdme guides', () => {
Expand Down
110 changes: 104 additions & 6 deletions __tests__/cmds/docs/single.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import DocsCommand from '../../../src/cmds/docs';
import APIError from '../../../src/lib/apiError';
import getAPIMock, { getAPIMockWithVersionHeader } from '../../helpers/get-api-mock';
import hashFileContents from '../../helpers/hash-file-contents';
import { after as afterGHAEnv, before as beforeGHAEnv } from '../../helpers/setup-gha-env';

const docs = new DocsCommand();

Expand All @@ -32,12 +33,6 @@ describe('rdme docs (single)', () => {
consoleInfoSpy.mockRestore();
});

it('should error in CI if no API key provided', async () => {
process.env.TEST_RDME_CI = 'true';
await expect(docs.run({})).rejects.toStrictEqual(new Error('No project API key provided. Please use `--key`.'));
delete process.env.TEST_RDME_CI;
});

it('should error if no file path provided', async () => {
const versionMock = getAPIMock().get(`/api/v1/version/${version}`).basicAuth({ user: key }).reply(200, { version });

Expand Down Expand Up @@ -347,4 +342,107 @@ describe('rdme docs (single)', () => {
});
});
});

describe('command execution in GitHub Actions runner', () => {
beforeEach(beforeGHAEnv);

afterEach(afterGHAEnv);

it('should error in CI if no API key provided', () => {
return expect(docs.run({})).rejects.toStrictEqual(new Error('No project API key provided. Please use `--key`.'));
});

it('should sync new doc with correct headers', async () => {
const slug = 'new-doc';
const id = '1234';
const doc = frontMatter(fs.readFileSync(path.join(fullFixturesDir, `/new-docs/${slug}.md`)));
const hash = hashFileContents(fs.readFileSync(path.join(fullFixturesDir, `/new-docs/${slug}.md`)));

const getMock = getAPIMockWithVersionHeader(version)
.get(`/api/v1/docs/${slug}`)
.basicAuth({ user: key })
.reply(404, {
error: 'DOC_NOTFOUND',
message: `The doc with the slug '${slug}' couldn't be found`,
suggestion: '...a suggestion to resolve the issue...',
help: 'If you need help, email support@readme.io and mention log "fake-metrics-uuid".',
});

const postMock = getAPIMock({
'x-rdme-ci': 'GitHub Actions (test)',
'x-readme-source': 'cli-gh',
'x-readme-source-url':
'https://github.com/octocat/Hello-World/blob/ffac537e6cbbf934b08745a378932722df287a53/__tests__/__fixtures__/docs/new-docs/new-doc.md',
'x-readme-version': version,
})
.post('/api/v1/docs', { slug, body: doc.content, ...doc.data, lastUpdatedHash: hash })
.basicAuth({ user: key })
.reply(201, { slug, _id: id, body: doc.content, ...doc.data, lastUpdatedHash: hash });

const versionMock = getAPIMock()
.get(`/api/v1/version/${version}`)
.basicAuth({ user: key })
.reply(200, { version });

await expect(
docs.run({ filePath: `./__tests__/${fixturesBaseDir}/new-docs/new-doc.md`, key, version })
).resolves.toBe(
`🌱 successfully created 'new-doc' (ID: 1234) with contents from ./__tests__/${fixturesBaseDir}/new-docs/new-doc.md`
);

getMock.done();
postMock.done();
versionMock.done();
});

it('should sync existing doc with correct headers', () => {
const fileContents = fs.readFileSync(path.join(fullFixturesDir, '/existing-docs/simple-doc.md'));
const simpleDoc = {
slug: 'simple-doc',
doc: frontMatter(fileContents),
hash: hashFileContents(fileContents),
};

const getMock = getAPIMockWithVersionHeader(version)
.get('/api/v1/docs/simple-doc')
.basicAuth({ user: key })
.reply(200, { category, slug: simpleDoc.slug, lastUpdatedHash: 'anOldHash' });

const updateMock = getAPIMock({
'x-rdme-ci': 'GitHub Actions (test)',
'x-readme-source': 'cli-gh',
'x-readme-source-url':
'https://github.com/octocat/Hello-World/blob/ffac537e6cbbf934b08745a378932722df287a53/__tests__/__fixtures__/docs/existing-docs/simple-doc.md',
'x-readme-version': version,
})
.put('/api/v1/docs/simple-doc', {
body: simpleDoc.doc.content,
lastUpdatedHash: simpleDoc.hash,
...simpleDoc.doc.data,
})
.basicAuth({ user: key })
.reply(200, {
category,
slug: simpleDoc.slug,
body: simpleDoc.doc.content,
});

const versionMock = getAPIMock()
.get(`/api/v1/version/${version}`)
.basicAuth({ user: key })
.reply(200, { version });

return docs
.run({ filePath: `__tests__/${fixturesBaseDir}/existing-docs/simple-doc.md`, key, version })
.then(updatedDocs => {
expect(updatedDocs).toBe(
`✏️ successfully updated 'simple-doc' with contents from __tests__/${fixturesBaseDir}/existing-docs/simple-doc.md`
);

getMock.done();
updateMock.done();
versionMock.done();
});
});
});
});
Loading

0 comments on commit 7574752

Please sign in to comment.