From 817b8d898a0f54ed028ded3b2a53f67301d092c5 Mon Sep 17 00:00:00 2001 From: Kanad Gupta Date: Tue, 10 Dec 2024 17:33:51 -0600 Subject: [PATCH 01/12] feat!: remove all deprecated commands (#1104) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## šŸ§° Changes Removes the commands that we've deprecated in favor of bidirectional syncing. Will be merging this PR into https://github.com/readmeio/rdme/pull/1113 to collect all breaking changes as part of this PR! ## šŸ§¬ QA & Testing do tests still pass? ## āš ļø Breaking Changes BREAKING CHANGE: `categories`, `custompages`, `docs` and `versions` have now been removed. Please use a bidirectional syncing workflow instead. Read more in [our migration guide](https://github.com/readmeio/rdme/tree/v10/documentation/migration-guide.md). --- .github/workflows/docs.yml | 33 +- README.md | 7 +- __tests__/commands/categories/create.test.ts | 161 ---- __tests__/commands/categories/index.test.ts | 76 -- __tests__/commands/custompages/index.test.ts | 350 --------- __tests__/commands/custompages/single.test.ts | 291 ------- .../docs/__snapshots__/index.test.ts.snap | 124 --- .../docs/__snapshots__/multiple.test.ts.snap | 3 - __tests__/commands/docs/index.test.ts | 729 ------------------ __tests__/commands/docs/multiple.test.ts | 180 ----- __tests__/commands/docs/prune.test.ts | 172 ----- __tests__/commands/docs/single.test.ts | 443 ----------- __tests__/commands/open.test.ts | 75 -- __tests__/commands/versions/create.test.ts | 176 ----- __tests__/commands/versions/delete.test.ts | 55 -- __tests__/commands/versions/index.test.ts | 65 -- __tests__/commands/versions/update.test.ts | 388 ---------- .../lib/__snapshots__/createGHA.test.ts.snap | 328 -------- __tests__/lib/createGHA.test.ts | 13 - __tests__/lib/prompts.test.ts | 33 - documentation/commands/categories.md | 92 --- documentation/commands/custompages.md | 51 -- documentation/commands/docs.md | 110 --- documentation/commands/versions.md | 177 ----- package-lock.json | 134 ---- package.json | 10 - src/commands/categories/create.ts | 96 --- src/commands/categories/index.ts | 41 - src/commands/changelogs.ts | 15 +- src/commands/custompages.ts | 46 -- src/commands/docs/index.ts | 67 -- src/commands/docs/prune.ts | 104 --- src/commands/open.ts | 63 -- src/commands/versions/create.ts | 104 --- src/commands/versions/delete.ts | 54 -- src/commands/versions/index.ts | 58 -- src/commands/versions/update.ts | 98 --- src/index.ts | 23 - src/lib/castStringOptToBool.ts | 23 - src/lib/deleteDoc.ts | 28 - src/lib/flags.ts | 25 - src/lib/getCategories.ts | 41 - src/lib/getDocs.ts | 56 -- src/lib/prompts.ts | 72 -- src/lib/syncDocsPath.ts | 22 +- src/lib/versionSelect.ts | 12 +- 46 files changed, 34 insertions(+), 5290 deletions(-) delete mode 100644 __tests__/commands/categories/create.test.ts delete mode 100644 __tests__/commands/categories/index.test.ts delete mode 100644 __tests__/commands/custompages/index.test.ts delete mode 100644 __tests__/commands/custompages/single.test.ts delete mode 100644 __tests__/commands/docs/__snapshots__/index.test.ts.snap delete mode 100644 __tests__/commands/docs/__snapshots__/multiple.test.ts.snap delete mode 100644 __tests__/commands/docs/index.test.ts delete mode 100644 __tests__/commands/docs/multiple.test.ts delete mode 100644 __tests__/commands/docs/prune.test.ts delete mode 100644 __tests__/commands/docs/single.test.ts delete mode 100644 __tests__/commands/open.test.ts delete mode 100644 __tests__/commands/versions/create.test.ts delete mode 100644 __tests__/commands/versions/delete.test.ts delete mode 100644 __tests__/commands/versions/index.test.ts delete mode 100644 __tests__/commands/versions/update.test.ts delete mode 100644 documentation/commands/categories.md delete mode 100644 documentation/commands/custompages.md delete mode 100644 documentation/commands/docs.md delete mode 100644 documentation/commands/versions.md delete mode 100644 src/commands/categories/create.ts delete mode 100644 src/commands/categories/index.ts delete mode 100644 src/commands/custompages.ts delete mode 100644 src/commands/docs/index.ts delete mode 100644 src/commands/docs/prune.ts delete mode 100644 src/commands/open.ts delete mode 100644 src/commands/versions/create.ts delete mode 100644 src/commands/versions/delete.ts delete mode 100644 src/commands/versions/index.ts delete mode 100644 src/commands/versions/update.ts delete mode 100644 src/lib/castStringOptToBool.ts delete mode 100644 src/lib/deleteDoc.ts delete mode 100644 src/lib/getCategories.ts delete mode 100644 src/lib/getDocs.ts diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index c49ed6984..a8331530b 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -1,7 +1,10 @@ name: Sync `documentation` directory to ReadMe # Run workflow for every push -on: push +on: + push: + branches: + - main jobs: sync: @@ -40,33 +43,7 @@ jobs: regex: false include: documentation/* - # Since this workflow file is in the `rdme` repository itself, - # we need to test the GitHub Action using the current commit. - # This step builds the `rdme` action code so we can do that. - # - # This step is not required for syncing your docs to ReadMe! - - name: Rebuild GitHub Action for testing purposes - run: npm run build:gha - - # And finally, with our updated documentation, - # we run the `rdme` GitHub Action to sync the Markdown file - # in the `documentation` directory. - # Here's the page we're syncing: https://docs.readme.com/docs/rdme - - # First we're going to perform a dry run of syncing process. - # We do this on every push to ensure that an actual sync will work properly - - name: Sync docs to ReadMe (dry run) - uses: ./ - with: - rdme: docs ./documentation --key=${{ secrets.README_DEVELOPERS_API_KEY }} --version=${{ vars.README_DEVELOPERS_MAIN_VERSION }} --dryRun - - # And finally, we perform an actual sync to ReadMe if we're on the main branch - name: Sync docs to ReadMe - if: github.event_name == 'push' && github.event.ref == 'refs/heads/main' - # We use the `main` branch as ref for GitHub Action - # This is NOT recommended, as it can break your workflows without notice! - # We recommend specifying a fixed version, i.e. @8.0.0 - # Docs: https://docs.github.com/actions/using-workflows/workflow-syntax-for-github-actions#example-using-versioned-actions - uses: readmeio/rdme@main + uses: readmeio/rdme@v9 with: rdme: docs ./documentation --key=${{ secrets.README_DEVELOPERS_API_KEY }} --version=${{ vars.README_DEVELOPERS_MAIN_VERSION }} diff --git a/README.md b/README.md index 8b5d0d8f5..082a22f7b 100644 --- a/README.md +++ b/README.md @@ -167,16 +167,15 @@ npm run build && npm run build:docs # Command Topics * [`rdme autocomplete`](documentation/commands/autocomplete.md) - Display autocomplete installation instructions. -* [`rdme categories`](documentation/commands/categories.md) - List or create categories in your ReadMe developer hub. * [`rdme changelogs`](documentation/commands/changelogs.md) - Sync Markdown files to your ReadMe project as Changelog posts. -* [`rdme custompages`](documentation/commands/custompages.md) - Sync Markdown/HTML files to your ReadMe project as Custom Pages. -* [`rdme docs`](documentation/commands/docs.md) - Sync or prune Guides pages in your ReadMe developer hub. * [`rdme help`](documentation/commands/help.md) - Display help for rdme. * [`rdme login`](documentation/commands/login.md) - Login to a ReadMe project. * [`rdme logout`](documentation/commands/logout.md) - Logs the currently authenticated user out of ReadMe. * [`rdme openapi`](documentation/commands/openapi.md) - Manage your API definition (e.g., syncing, validation, analysis, conversion, etc.). Supports OpenAPI, Swagger, and Postman collections, in either JSON or YAML formats. -* [`rdme versions`](documentation/commands/versions.md) - Manage your documentation versions. * [`rdme whoami`](documentation/commands/whoami.md) - Displays the current user and project authenticated with ReadMe. + +> [!IMPORTANT] +> You'll notice that several previous `rdme` commands are no longer present. That's because this version is for projects that use [ReadMe Refactored](https://docs.readme.com/main/docs/welcome-to-readme-refactored) and [bi-directional syncing](https://docs.readme.com/main/docs/bi-directional-sync) is the recommended approach for most workflows previously managed via `rdme`. See more in [our migration guide](./documentation/migration-guide.md). diff --git a/__tests__/commands/categories/create.test.ts b/__tests__/commands/categories/create.test.ts deleted file mode 100644 index 8b16d38a7..000000000 --- a/__tests__/commands/categories/create.test.ts +++ /dev/null @@ -1,161 +0,0 @@ -import nock from 'nock'; -import { describe, beforeAll, afterEach, it, expect } from 'vitest'; - -import Command from '../../../src/commands/categories/create.js'; -import { getAPIv1Mock, getAPIv1MockWithVersionHeader } from '../../helpers/get-api-mock.js'; -import { runCommandAndReturnResult } from '../../helpers/oclif.js'; - -const key = 'API_KEY'; -const version = '1.0.0'; - -describe('rdme categories create', () => { - let run: (args?: string[]) => Promise; - - beforeAll(() => { - nock.disableNetConnect(); - run = runCommandAndReturnResult(Command); - }); - - afterEach(() => nock.cleanAll()); - - it('should error if no title provided', () => { - return expect(run(['--key', key])).rejects.toThrow('Missing 1 required arg:\ntitle'); - }); - - it('should error if categoryType is blank', () => { - return expect(run(['--key', key, 'Test Title'])).rejects.toThrow('Missing required flag categoryType'); - }); - - it('should error if categoryType is not `guide` or `reference`', () => { - return expect(run(['--key', key, 'Test Title', '--categoryType', 'test'])).rejects.toThrow( - 'Expected --categoryType=test to be one of: guide, reference', - ); - }); - - it('should create a new category if the title and type do not match and preventDuplicates=true', async () => { - const getMock = getAPIv1MockWithVersionHeader(version) - .persist() - .get('/api/v1/categories?perPage=20&page=1') - .basicAuth({ user: key }) - .reply(200, [{ title: 'Existing Category', slug: 'existing-category', type: 'guide' }], { - 'x-total-count': '1', - }); - - const postMock = getAPIv1MockWithVersionHeader(version) - .post('/api/v1/categories') - .basicAuth({ user: key }) - .reply(201, { title: 'New Category', slug: 'new-category', type: 'guide', id: '123' }); - - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - await expect( - run(['New Category', '--categoryType', 'guide', '--key', key, '--version', '1.0.0', '--preventDuplicates']), - ).resolves.toBe("šŸŒ± successfully created 'New Category' with a type of 'guide' and an id of '123'"); - - getMock.done(); - postMock.done(); - versionMock.done(); - }); - - it('should create a new category if the title matches but the type does not match and preventDuplicates=true', async () => { - const getMock = getAPIv1MockWithVersionHeader(version) - .persist() - .get('/api/v1/categories?perPage=20&page=1') - .basicAuth({ user: key }) - .reply(200, [{ title: 'Category', slug: 'category', type: 'guide' }], { - 'x-total-count': '1', - }); - - const postMock = getAPIv1MockWithVersionHeader(version) - .post('/api/v1/categories') - .basicAuth({ user: key }) - .reply(201, { title: 'Category', slug: 'category', type: 'reference', id: '123' }); - - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - await expect( - run(['--categoryType', 'reference', '--key', key, '--version', '1.0.0', '--preventDuplicates', 'Category']), - ).resolves.toBe("šŸŒ± successfully created 'Category' with a type of 'reference' and an id of '123'"); - - getMock.done(); - postMock.done(); - versionMock.done(); - }); - - it('should create a new category if the title and type match and preventDuplicates=false', async () => { - const postMock = getAPIv1MockWithVersionHeader(version) - .post('/api/v1/categories') - .basicAuth({ user: key }) - .reply(201, { title: 'Category', slug: 'category', type: 'reference', id: '123' }); - - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - await expect(run(['Category', '--categoryType', 'guide', '--key', key, '--version', '1.0.0'])).resolves.toBe( - "šŸŒ± successfully created 'Category' with a type of 'reference' and an id of '123'", - ); - - postMock.done(); - versionMock.done(); - }); - - it('should not create a new category if the title and type match and preventDuplicates=true', async () => { - const getMock = getAPIv1MockWithVersionHeader(version) - .persist() - .get('/api/v1/categories?perPage=20&page=1') - .basicAuth({ user: key }) - .reply(200, [{ title: 'Category', slug: 'category', type: 'guide', id: '123' }], { - 'x-total-count': '1', - }); - - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - await expect( - run(['Category', '--categoryType', 'guide', '--key', key, '--version', '1.0.0', '--preventDuplicates']), - ).rejects.toStrictEqual( - new Error( - "The 'Category' category with a type of 'guide' already exists with an id of '123'. A new category was not created.", - ), - ); - - getMock.done(); - versionMock.done(); - }); - - it('should not create a new category if the non case sensitive title and type match and preventDuplicates=true', async () => { - const getMock = getAPIv1MockWithVersionHeader(version) - .persist() - .get('/api/v1/categories?perPage=20&page=1') - .basicAuth({ user: key }) - .reply(200, [{ title: 'Category', slug: 'category', type: 'guide', id: '123' }], { - 'x-total-count': '1', - }); - - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - await expect( - run(['Category', '--categoryType', 'guide', '--key', key, '--version', '1.0.0', '--preventDuplicates']), - ).rejects.toStrictEqual( - new Error( - "The 'Category' category with a type of 'guide' already exists with an id of '123'. A new category was not created.", - ), - ); - - getMock.done(); - versionMock.done(); - }); -}); diff --git a/__tests__/commands/categories/index.test.ts b/__tests__/commands/categories/index.test.ts deleted file mode 100644 index f3ebb3b54..000000000 --- a/__tests__/commands/categories/index.test.ts +++ /dev/null @@ -1,76 +0,0 @@ -import nock from 'nock'; -import { describe, beforeAll, afterEach, it, expect } from 'vitest'; - -import Command from '../../../src/commands/categories/index.js'; -import { getAPIv1Mock, getAPIv1MockWithVersionHeader } from '../../helpers/get-api-mock.js'; -import { runCommandAndReturnResult } from '../../helpers/oclif.js'; - -const key = 'API_KEY'; -const version = '1.0.0'; - -describe('rdme categories', () => { - let run: (args?: string[]) => Promise; - - beforeAll(() => { - nock.disableNetConnect(); - run = runCommandAndReturnResult(Command); - }); - - afterEach(() => nock.cleanAll()); - - it('should return all categories for a single page', async () => { - const getMock = getAPIv1MockWithVersionHeader(version) - .persist() - .get('/api/v1/categories?perPage=20&page=1') - .basicAuth({ user: key }) - .reply(200, [{ title: 'One Category', slug: 'one-category', type: 'guide' }], { - 'x-total-count': '1', - }); - - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - await expect(run(['--key', key, '--version', '1.0.0'])).resolves.toBe( - JSON.stringify([{ title: 'One Category', slug: 'one-category', type: 'guide' }], null, 2), - ); - - getMock.done(); - versionMock.done(); - }); - - it('should return all categories for multiple pages', async () => { - const getMock = getAPIv1MockWithVersionHeader(version) - .persist() - .get('/api/v1/categories?perPage=20&page=1') - .basicAuth({ user: key }) - .reply(200, [{ title: 'One Category', slug: 'one-category', type: 'guide' }], { - 'x-total-count': '21', - }) - .get('/api/v1/categories?perPage=20&page=2') - .basicAuth({ user: key }) - .reply(200, [{ title: 'Another Category', slug: 'another-category', type: 'guide' }], { - 'x-total-count': '21', - }); - - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - await expect(run(['--key', key, '--version', '1.0.0'])).resolves.toBe( - JSON.stringify( - [ - { title: 'One Category', slug: 'one-category', type: 'guide' }, - { title: 'Another Category', slug: 'another-category', type: 'guide' }, - ], - null, - 2, - ), - ); - - getMock.done(); - versionMock.done(); - }); -}); diff --git a/__tests__/commands/custompages/index.test.ts b/__tests__/commands/custompages/index.test.ts deleted file mode 100644 index a0b5061d2..000000000 --- a/__tests__/commands/custompages/index.test.ts +++ /dev/null @@ -1,350 +0,0 @@ -import fs from 'node:fs'; -import path from 'node:path'; - -import chalk from 'chalk'; -import frontMatter from 'gray-matter'; -import nock from 'nock'; -import { describe, beforeAll, afterAll, beforeEach, it, expect } from 'vitest'; - -import Command from '../../../src/commands/custompages.js'; -import { APIv1Error } from '../../../src/lib/apiError.js'; -import { getAPIv1Mock } from '../../helpers/get-api-mock.js'; -import hashFileContents from '../../helpers/hash-file-contents.js'; -import { runCommandAndReturnResult } from '../../helpers/oclif.js'; - -const fixturesBaseDir = '__fixtures__/custompages'; -const fullFixturesDir = `${__dirname}./../../${fixturesBaseDir}`; -const key = 'API_KEY'; - -describe('rdme custompages', () => { - let run: (args?: string[]) => Promise; - - beforeAll(() => { - nock.disableNetConnect(); - run = runCommandAndReturnResult(Command); - }); - - afterAll(() => nock.cleanAll()); - - it('should error if no path provided', () => { - return expect(run(['--key', key])).rejects.toThrow('Missing 1 required arg:\npath'); - }); - - it('should error if the argument is not a folder', () => { - return expect(run(['--key', key, 'not-a-folder'])).rejects.toStrictEqual( - new Error("Oops! We couldn't locate a file or directory at the path you provided."), - ); - }); - - it('should error if the folder contains no markdown nor HTML files', () => { - return expect(run(['--key', key, '.github/workflows'])).rejects.toStrictEqual( - new Error( - "The directory you provided (.github/workflows) doesn't contain any of the following required files: .html, .markdown, .md.", - ), - ); - }); - - describe('existing custompages', () => { - let simpleDoc; - let anotherDoc; - - beforeEach(() => { - let fileContents = fs.readFileSync(path.join(fullFixturesDir, '/existing-docs/simple-doc.md')); - simpleDoc = { - slug: 'simple-doc', - doc: frontMatter(fileContents), - hash: hashFileContents(fileContents), - }; - - fileContents = fs.readFileSync(path.join(fullFixturesDir, '/existing-docs/subdir/another-doc.md')); - anotherDoc = { - slug: 'another-doc', - doc: frontMatter(fileContents), - hash: hashFileContents(fileContents), - }; - }); - - it('should fetch custom page and merge with what is returned', () => { - expect.assertions(1); - - const getMocks = getAPIv1Mock() - .get('/api/v1/custompages/simple-doc') - .basicAuth({ user: key }) - .reply(200, { slug: simpleDoc.slug, htmlmode: false, lastUpdatedHash: 'anOldHash' }) - .get('/api/v1/custompages/another-doc') - .basicAuth({ user: key }) - .reply(200, { slug: anotherDoc.slug, htmlmode: false, lastUpdatedHash: 'anOldHash' }); - - const updateMocks = getAPIv1Mock() - .put('/api/v1/custompages/simple-doc', { - body: simpleDoc.doc.content, - htmlmode: false, - lastUpdatedHash: simpleDoc.hash, - ...simpleDoc.doc.data, - }) - .basicAuth({ user: key }) - .reply(200, { - slug: simpleDoc.slug, - htmlmode: false, - body: simpleDoc.doc.content, - }) - .put('/api/v1/custompages/another-doc', { - body: anotherDoc.doc.content, - htmlmode: false, - lastUpdatedHash: anotherDoc.hash, - ...anotherDoc.doc.data, - }) - .basicAuth({ user: key }) - .reply(200, { slug: anotherDoc.slug, body: anotherDoc.doc.content, htmlmode: false }); - - return run([`./__tests__/${fixturesBaseDir}/existing-docs`, '--key', key]).then(updatedDocs => { - // All custompages 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(); - updateMocks.done(); - }); - }); - - it('should return custom page update info for dry run', () => { - expect.assertions(1); - - const getMocks = getAPIv1Mock() - .get('/api/v1/custompages/simple-doc') - .basicAuth({ user: key }) - .reply(200, { slug: simpleDoc.slug, lastUpdatedHash: 'anOldHash' }) - .get('/api/v1/custompages/another-doc') - .basicAuth({ user: key }) - .reply(200, { slug: anotherDoc.slug, lastUpdatedHash: 'anOldHash' }); - - return run(['--dryRun', `./__tests__/${fixturesBaseDir}/existing-docs`, '--key', key]).then(updatedDocs => { - // All custompages should have been updated because their hashes from the GET request were different from what they - // are currently. - expect(updatedDocs).toBe( - [ - `šŸŽ­ dry run! This will update 'simple-doc' with contents from __tests__/${fixturesBaseDir}/existing-docs/simple-doc.md with the following metadata: ${JSON.stringify( - simpleDoc.doc.data, - )}`, - `šŸŽ­ dry run! This will update 'another-doc' with contents from __tests__/${fixturesBaseDir}/existing-docs/subdir/another-doc.md with the following metadata: ${JSON.stringify( - anotherDoc.doc.data, - )}`, - ].join('\n'), - ); - - getMocks.done(); - }); - }); - - it('should not send requests for custompages that have not changed', () => { - expect.assertions(1); - - const getMocks = getAPIv1Mock() - .get('/api/v1/custompages/simple-doc') - .basicAuth({ user: key }) - .reply(200, { slug: simpleDoc.slug, lastUpdatedHash: simpleDoc.hash }) - .get('/api/v1/custompages/another-doc') - .basicAuth({ user: key }) - .reply(200, { slug: anotherDoc.slug, lastUpdatedHash: anotherDoc.hash }); - - return run([`./__tests__/${fixturesBaseDir}/existing-docs`, '--key', key]).then(skippedDocs => { - expect(skippedDocs).toBe( - [ - '`simple-doc` was not updated because there were no changes.', - '`another-doc` was not updated because there were no changes.', - ].join('\n'), - ); - - getMocks.done(); - }); - }); - - it('should adjust "no changes" message if in dry run', () => { - expect.assertions(1); - - const getMocks = getAPIv1Mock() - .get('/api/v1/custompages/simple-doc') - .basicAuth({ user: key }) - .reply(200, { slug: simpleDoc.slug, lastUpdatedHash: simpleDoc.hash }) - .get('/api/v1/custompages/another-doc') - .basicAuth({ user: key }) - .reply(200, { slug: anotherDoc.slug, lastUpdatedHash: anotherDoc.hash }); - - return run(['--dryRun', `./__tests__/${fixturesBaseDir}/existing-docs`, '--key', key]).then(skippedDocs => { - expect(skippedDocs).toBe( - [ - 'šŸŽ­ dry run! `simple-doc` will not be updated because there were no changes.', - 'šŸŽ­ dry run! `another-doc` will not be updated because there were no changes.', - ].join('\n'), - ); - - getMocks.done(); - }); - }); - }); - - describe('new custompages', () => { - it('should create new custom page', 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 = getAPIv1Mock() - .get(`/api/v1/custompages/${slug}`) - .basicAuth({ user: key }) - .reply(404, { - error: 'CUSTOMPAGE_NOTFOUND', - message: `The custom page 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 = getAPIv1Mock() - .post('/api/v1/custompages', { slug, body: doc.content, ...doc.data, lastUpdatedHash: hash }) - .basicAuth({ user: key }) - .reply(201, { slug, _id: id, body: doc.content, ...doc.data, lastUpdatedHash: hash }); - - await expect(run([`./__tests__/${fixturesBaseDir}/new-docs`, '--key', key])).resolves.toBe( - `šŸŒ± successfully created 'new-doc' (ID: 1234) with contents from __tests__/${fixturesBaseDir}/new-docs/new-doc.md`, - ); - - getMock.done(); - postMock.done(); - }); - - it('should create new HTML custom page', async () => { - const slug = 'new-doc'; - const id = '1234'; - const doc = frontMatter(fs.readFileSync(path.join(fullFixturesDir, `/new-docs-html/${slug}.html`))); - const hash = hashFileContents(fs.readFileSync(path.join(fullFixturesDir, `/new-docs-html/${slug}.html`))); - - const getMock = getAPIv1Mock() - .get(`/api/v1/custompages/${slug}`) - .basicAuth({ user: key }) - .reply(404, { - error: 'CUSTOMPAGE_NOTFOUND', - message: `The custom page 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 = getAPIv1Mock() - .post('/api/v1/custompages', { slug, html: doc.content, htmlmode: true, ...doc.data, lastUpdatedHash: hash }) - .basicAuth({ user: key }) - .reply(201, { slug, _id: id, html: doc.content, htmlmode: true, ...doc.data, lastUpdatedHash: hash }); - - await expect(run([`./__tests__/${fixturesBaseDir}/new-docs-html`, '--key', key])).resolves.toBe( - `šŸŒ± successfully created 'new-doc' (ID: 1234) with contents from __tests__/${fixturesBaseDir}/new-docs-html/new-doc.html`, - ); - - getMock.done(); - postMock.done(); - }); - - it('should return creation info for dry run', async () => { - const slug = 'new-doc'; - const doc = frontMatter(fs.readFileSync(path.join(fullFixturesDir, `/new-docs/${slug}.md`))); - - const getMock = getAPIv1Mock() - .get(`/api/v1/custompages/${slug}`) - .basicAuth({ user: key }) - .reply(404, { - error: 'CUSTOMPAGE_NOTFOUND', - message: `The custom page 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".', - }); - - await expect(run(['--dryRun', `./__tests__/${fixturesBaseDir}/new-docs`, '--key', key])).resolves.toBe( - `šŸŽ­ dry run! This will create 'new-doc' with contents from __tests__/${fixturesBaseDir}/new-docs/new-doc.md with the following metadata: ${JSON.stringify( - doc.data, - )}`, - ); - - getMock.done(); - }); - - it('should fail if any custompages are invalid', async () => { - const folder = 'failure-docs'; - const slug = 'new-doc'; - - const errorObject = { - error: 'CUSTOMPAGE_INVALID', - message: "We couldn't save this page (Custom page title cannot be blank).", - suggestion: 'Make sure all the data is correct, and the body is valid Markdown or HTML.', - docs: 'fake-metrics-uuid', - help: "If you need help, email support@readme.io and include the following link to your API log: 'fake-metrics-uuid'.", - }; - - const doc = frontMatter(fs.readFileSync(path.join(fullFixturesDir, `/${folder}/${slug}.md`))); - - const hash = hashFileContents(fs.readFileSync(path.join(fullFixturesDir, `/${folder}/${slug}.md`))); - - const getMocks = getAPIv1Mock() - .get(`/api/v1/custompages/${slug}`) - .basicAuth({ user: key }) - .reply(404, { - error: 'CUSTOMPAGE_NOTFOUND', - message: `The custom page 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 postMocks = getAPIv1Mock() - .post('/api/v1/custompages', { slug, body: doc.content, htmlmode: false, ...doc.data, lastUpdatedHash: hash }) - .basicAuth({ user: key }) - .reply(400, errorObject); - - const fullDirectory = `__tests__/${fixturesBaseDir}/${folder}`; - - const formattedErrorObject = { - ...errorObject, - message: `Error uploading ${chalk.underline(`${fullDirectory}/${slug}.md`)}:\n\n${errorObject.message}`, - }; - - await expect(run([`./${fullDirectory}`, '--key', key])).rejects.toStrictEqual( - new APIv1Error(formattedErrorObject), - ); - - getMocks.done(); - postMocks.done(); - }); - }); - - describe('slug metadata', () => { - it('should use provided slug', async () => { - const slug = 'new-doc-slug'; - const id = '1234'; - const doc = frontMatter(fs.readFileSync(path.join(fullFixturesDir, `/slug-docs/${slug}.md`))); - const hash = hashFileContents(fs.readFileSync(path.join(fullFixturesDir, `/slug-docs/${slug}.md`))); - - const getMock = getAPIv1Mock() - .get(`/api/v1/custompages/${doc.data.slug}`) - .basicAuth({ user: key }) - .reply(404, { - error: 'CUSTOMPAGE_NOTFOUND', - message: `The custom page 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 = getAPIv1Mock() - .post('/api/v1/custompages', { slug, body: doc.content, ...doc.data, lastUpdatedHash: hash }) - .basicAuth({ user: key }) - .reply(201, { slug: doc.data.slug, _id: id, body: doc.content, ...doc.data, lastUpdatedHash: hash }); - - await expect(run([`./__tests__/${fixturesBaseDir}/slug-docs`, '--key', key])).resolves.toBe( - `šŸŒ± successfully created 'marc-actually-wrote-a-test' (ID: 1234) with contents from __tests__/${fixturesBaseDir}/slug-docs/new-doc-slug.md`, - ); - - getMock.done(); - postMock.done(); - }); - }); -}); diff --git a/__tests__/commands/custompages/single.test.ts b/__tests__/commands/custompages/single.test.ts deleted file mode 100644 index e255b3d6c..000000000 --- a/__tests__/commands/custompages/single.test.ts +++ /dev/null @@ -1,291 +0,0 @@ -import fs from 'node:fs'; -import path from 'node:path'; - -import chalk from 'chalk'; -import frontMatter from 'gray-matter'; -import nock from 'nock'; -import { describe, beforeAll, afterAll, beforeEach, it, expect } from 'vitest'; - -import Command from '../../../src/commands/custompages.js'; -import { APIv1Error } from '../../../src/lib/apiError.js'; -import { getAPIv1Mock } from '../../helpers/get-api-mock.js'; -import hashFileContents from '../../helpers/hash-file-contents.js'; -import { runCommandAndReturnResult } from '../../helpers/oclif.js'; - -const fixturesBaseDir = '__fixtures__/custompages'; -const fullFixturesDir = `${__dirname}./../../${fixturesBaseDir}`; -const key = 'API_KEY'; - -describe('rdme custompages (single)', () => { - let run: (args?: string[]) => Promise; - - beforeAll(() => { - nock.disableNetConnect(); - run = runCommandAndReturnResult(Command); - }); - - afterAll(() => nock.cleanAll()); - - it('should error if no file path provided', () => { - return expect(run(['--key', key])).rejects.toThrow('Missing 1 required arg:\npath'); - }); - - it('should error if the argument is not a Markdown/HTML file', () => { - return expect(run(['--key', key, 'package.json'])).rejects.toStrictEqual( - new Error('Invalid file extension (.json). Must be one of the following: .html, .markdown, .md'), - ); - }); - - it('should error if file path cannot be found', () => { - return expect(run(['--key', key, 'non-existent-file.markdown'])).rejects.toStrictEqual( - new Error("Oops! We couldn't locate a file or directory at the path you provided."), - ); - }); - - describe('new custompages', () => { - it('should create new custom page', 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 = getAPIv1Mock() - .get(`/api/v1/custompages/${slug}`) - .basicAuth({ user: key }) - .reply(404, { - error: 'CUSTOMPAGE_NOTFOUND', - message: `The custom page 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 = getAPIv1Mock() - .post('/api/v1/custompages', { slug, body: doc.content, ...doc.data, lastUpdatedHash: hash }) - .basicAuth({ user: key }) - .reply(201, { slug, _id: id, body: doc.content, ...doc.data }); - - await expect(run([`./__tests__/${fixturesBaseDir}/new-docs/new-doc.md`, '--key', key])).resolves.toBe( - `šŸŒ± successfully created 'new-doc' (ID: 1234) with contents from ./__tests__/${fixturesBaseDir}/new-docs/new-doc.md`, - ); - - getMock.done(); - postMock.done(); - }); - - it('should create new HTML custom page', async () => { - const slug = 'new-doc'; - const id = '1234'; - const doc = frontMatter(fs.readFileSync(path.join(fullFixturesDir, `/new-docs-html/${slug}.html`))); - const hash = hashFileContents(fs.readFileSync(path.join(fullFixturesDir, `/new-docs-html/${slug}.html`))); - - const getMock = getAPIv1Mock() - .get(`/api/v1/custompages/${slug}`) - .basicAuth({ user: key }) - .reply(404, { - error: 'CUSTOMPAGE_NOTFOUND', - message: `The custom page 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 = getAPIv1Mock() - .post('/api/v1/custompages', { slug, html: doc.content, htmlmode: true, ...doc.data, lastUpdatedHash: hash }) - .basicAuth({ user: key }) - .reply(201, { slug, _id: id, html: doc.content, htmlmode: true, ...doc.data }); - - await expect(run([`./__tests__/${fixturesBaseDir}/new-docs-html/new-doc.html`, '--key', key])).resolves.toBe( - `šŸŒ± successfully created 'new-doc' (ID: 1234) with contents from ./__tests__/${fixturesBaseDir}/new-docs-html/new-doc.html`, - ); - - getMock.done(); - postMock.done(); - }); - - it('should return creation info for dry run', async () => { - const slug = 'new-doc'; - const doc = frontMatter(fs.readFileSync(path.join(fullFixturesDir, `/new-docs/${slug}.md`))); - - const getMock = getAPIv1Mock() - .get(`/api/v1/custompages/${slug}`) - .basicAuth({ user: key }) - .reply(404, { - error: 'CUSTOMPAGE_NOTFOUND', - message: `The custom page 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".', - }); - - await expect(run(['--dryRun', `./__tests__/${fixturesBaseDir}/new-docs/new-doc.md`, '--key', key])).resolves.toBe( - `šŸŽ­ dry run! This will create 'new-doc' with contents from ./__tests__/${fixturesBaseDir}/new-docs/new-doc.md with the following metadata: ${JSON.stringify( - doc.data, - )}`, - ); - - getMock.done(); - }); - - it('should skip if it does not contain any front matter attributes', async () => { - const filePath = `./__tests__/${fixturesBaseDir}/failure-docs/doc-sans-attributes.md`; - - await expect(run([filePath, '--key', key])).resolves.toBe( - `ā­ļø no front matter attributes found for ${filePath}, skipping`, - ); - }); - - it('should fail if some other error when retrieving page slug', async () => { - const slug = 'new-doc'; - - const errorObject = { - error: 'INTERNAL_ERROR', - message: 'Unknown error (yikes)', - suggestion: '...a suggestion to resolve the issue...', - help: 'If you need help, email support@readme.io and mention log "fake-metrics-uuid".', - }; - - const getMock = getAPIv1Mock() - .get(`/api/v1/custompages/${slug}`) - .basicAuth({ user: key }) - .reply(500, errorObject); - - const filePath = `./__tests__/${fixturesBaseDir}/failure-docs/${slug}.md`; - - const formattedErrorObject = { - ...errorObject, - message: `Error uploading ${chalk.underline(`${filePath}`)}:\n\n${errorObject.message}`, - }; - - await expect(run([filePath, '--key', key])).rejects.toStrictEqual(new APIv1Error(formattedErrorObject)); - - getMock.done(); - }); - }); - - describe('slug metadata', () => { - it('should use provided slug', async () => { - const slug = 'new-doc-slug'; - const id = '1234'; - const doc = frontMatter(fs.readFileSync(path.join(fullFixturesDir, `/slug-docs/${slug}.md`))); - const hash = hashFileContents(fs.readFileSync(path.join(fullFixturesDir, `/slug-docs/${slug}.md`))); - - const getMock = getAPIv1Mock() - .get(`/api/v1/custompages/${doc.data.slug}`) - .basicAuth({ user: key }) - .reply(404, { - error: 'CUSTOMPAGE_NOTFOUND', - message: `The custom page 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 = getAPIv1Mock() - .post('/api/v1/custompages', { slug, body: doc.content, ...doc.data, lastUpdatedHash: hash }) - .basicAuth({ user: key }) - .reply(201, { slug: doc.data.slug, _id: id, body: doc.content, ...doc.data, lastUpdatedHash: hash }); - - await expect(run([`./__tests__/${fixturesBaseDir}/slug-docs/new-doc-slug.md`, '--key', key])).resolves.toBe( - `šŸŒ± successfully created 'marc-actually-wrote-a-test' (ID: 1234) with contents from ./__tests__/${fixturesBaseDir}/slug-docs/new-doc-slug.md`, - ); - - getMock.done(); - postMock.done(); - }); - }); - - describe('existing custompages', () => { - let simpleDoc; - - beforeEach(() => { - const fileContents = fs.readFileSync(path.join(fullFixturesDir, '/existing-docs/simple-doc.md')); - simpleDoc = { - slug: 'simple-doc', - doc: frontMatter(fileContents), - hash: hashFileContents(fileContents), - }; - }); - - it('should fetch custom page and merge with what is returned', () => { - const getMock = getAPIv1Mock() - .get('/api/v1/custompages/simple-doc') - .basicAuth({ user: key }) - .reply(200, { slug: simpleDoc.slug, lastUpdatedHash: 'anOldHash' }); - - const updateMock = getAPIv1Mock() - .put('/api/v1/custompages/simple-doc', { - body: simpleDoc.doc.content, - htmlmode: false, - lastUpdatedHash: simpleDoc.hash, - ...simpleDoc.doc.data, - }) - .basicAuth({ user: key }) - .reply(200, { - slug: simpleDoc.slug, - body: simpleDoc.doc.content, - htmlmode: false, - }); - - return run([`./__tests__/${fixturesBaseDir}/existing-docs/simple-doc.md`, '--key', key]).then(updatedDocs => { - expect(updatedDocs).toBe( - `āœļø successfully updated 'simple-doc' with contents from ./__tests__/${fixturesBaseDir}/existing-docs/simple-doc.md`, - ); - - getMock.done(); - updateMock.done(); - }); - }); - - it('should return custom page update info for dry run', () => { - expect.assertions(1); - - const getMock = getAPIv1Mock() - .get('/api/v1/custompages/simple-doc') - .basicAuth({ user: key }) - .reply(200, { slug: simpleDoc.slug, lastUpdatedHash: 'anOldHash' }); - - return run(['--dryRun', `./__tests__/${fixturesBaseDir}/existing-docs/simple-doc.md`, '--key', key]).then( - updatedDocs => { - // All custompages should have been updated because their hashes from the GET request were different from what they - // are currently. - expect(updatedDocs).toBe( - [ - `šŸŽ­ dry run! This will update 'simple-doc' with contents from ./__tests__/${fixturesBaseDir}/existing-docs/simple-doc.md with the following metadata: ${JSON.stringify( - simpleDoc.doc.data, - )}`, - ].join('\n'), - ); - - getMock.done(); - }, - ); - }); - - it('should not send requests for custompages that have not changed', () => { - expect.assertions(1); - - const getMock = getAPIv1Mock() - .get('/api/v1/custompages/simple-doc') - .basicAuth({ user: key }) - .reply(200, { slug: simpleDoc.slug, lastUpdatedHash: simpleDoc.hash }); - - return run([`./__tests__/${fixturesBaseDir}/existing-docs/simple-doc.md`, '--key', key]).then(skippedDocs => { - expect(skippedDocs).toBe('`simple-doc` was not updated because there were no changes.'); - - getMock.done(); - }); - }); - - it('should adjust "no changes" message if in dry run', () => { - const getMock = getAPIv1Mock() - .get('/api/v1/custompages/simple-doc') - .basicAuth({ user: key }) - .reply(200, { slug: simpleDoc.slug, lastUpdatedHash: simpleDoc.hash }); - - return run(['--dryRun', `./__tests__/${fixturesBaseDir}/existing-docs/simple-doc.md`, '--key', key]).then( - skippedDocs => { - expect(skippedDocs).toBe('šŸŽ­ dry run! `simple-doc` will not be updated because there were no changes.'); - - getMock.done(); - }, - ); - }); - }); -}); diff --git a/__tests__/commands/docs/__snapshots__/index.test.ts.snap b/__tests__/commands/docs/__snapshots__/index.test.ts.snap deleted file mode 100644 index 3f7082f4c..000000000 --- a/__tests__/commands/docs/__snapshots__/index.test.ts.snap +++ /dev/null @@ -1,124 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`rdme docs > GHA onboarding E2E tests > should create GHA workflow with version passed as opt (github flag enabled) 1`] = ` -" -Your GitHub Actions workflow file has been created! āœØ - -Almost done! Just a couple more steps: -1. Push your newly created file (.github/workflows/docs-test-file-github-flag.yml) to GitHub šŸš€ -2. Create a GitHub secret called README_API_KEY and populate the value with your ReadMe API key (ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢I_KEY) šŸ”‘ - -šŸ” Check out GitHub's docs for more info on creating encrypted secrets (https://docs.github.com/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) - -šŸ¦‰ If you have any more questions, feel free to drop us a line! support@readme.io -" -`; - -exports[`rdme docs > GHA onboarding E2E tests > should create GHA workflow with version passed as opt (github flag enabled) 2`] = ` -"# This GitHub Actions workflow was auto-generated by the \`rdme\` cli on 2022-01-01T00:00:00.000Z -# You can view our full documentation here: https://docs.readme.com/docs/rdme -name: ReadMe GitHub Action šŸ¦‰ - -on: - push: - branches: - # This workflow will run every time you push code to the following branch: \`docs-test-branch-github-flag\` - # Check out GitHub's docs for more info on configuring this: - # https://docs.github.com/actions/using-workflows/events-that-trigger-workflows - - docs-test-branch-github-flag - -jobs: - rdme-docs: - runs-on: ubuntu-latest - steps: - - name: Check out repo šŸ“š - uses: actions/checkout@v4 - - - name: Run \`docs\` command šŸš€ - uses: readmeio/rdme@v7 - with: - rdme: docs ./__tests__/__fixtures__/docs/new-docs --key=\${{ secrets.README_API_KEY }} --version=1.0.0 -" -`; - -exports[`rdme docs > GHA onboarding E2E tests > should create GHA workflow with version passed in via opt 1`] = ` -" -Your GitHub Actions workflow file has been created! āœØ - -Almost done! Just a couple more steps: -1. Push your newly created file (.github/workflows/docs-test-file.yml) to GitHub šŸš€ -2. Create a GitHub secret called README_API_KEY and populate the value with your ReadMe API key (ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢I_KEY) šŸ”‘ - -šŸ” Check out GitHub's docs for more info on creating encrypted secrets (https://docs.github.com/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) - -šŸ¦‰ If you have any more questions, feel free to drop us a line! support@readme.io -" -`; - -exports[`rdme docs > GHA onboarding E2E tests > should create GHA workflow with version passed in via opt 2`] = ` -"# This GitHub Actions workflow was auto-generated by the \`rdme\` cli on 2022-01-01T00:00:00.000Z -# You can view our full documentation here: https://docs.readme.com/docs/rdme -name: ReadMe GitHub Action šŸ¦‰ - -on: - push: - branches: - # This workflow will run every time you push code to the following branch: \`docs-test-branch\` - # Check out GitHub's docs for more info on configuring this: - # https://docs.github.com/actions/using-workflows/events-that-trigger-workflows - - docs-test-branch - -jobs: - rdme-docs: - runs-on: ubuntu-latest - steps: - - name: Check out repo šŸ“š - uses: actions/checkout@v4 - - - name: Run \`docs\` command šŸš€ - uses: readmeio/rdme@v7 - with: - rdme: docs ./__tests__/__fixtures__/docs/new-docs --key=\${{ secrets.README_API_KEY }} --version=1.0.0 -" -`; - -exports[`rdme docs > GHA onboarding E2E tests > should create GHA workflow with version passed in via prompt 1`] = ` -" -Your GitHub Actions workflow file has been created! āœØ - -Almost done! Just a couple more steps: -1. Push your newly created file (.github/workflows/docs-test-file.yml) to GitHub šŸš€ -2. Create a GitHub secret called README_API_KEY and populate the value with your ReadMe API key (ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢I_KEY) šŸ”‘ - -šŸ” Check out GitHub's docs for more info on creating encrypted secrets (https://docs.github.com/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) - -šŸ¦‰ If you have any more questions, feel free to drop us a line! support@readme.io -" -`; - -exports[`rdme docs > GHA onboarding E2E tests > should create GHA workflow with version passed in via prompt 2`] = ` -"# This GitHub Actions workflow was auto-generated by the \`rdme\` cli on 2022-01-01T00:00:00.000Z -# You can view our full documentation here: https://docs.readme.com/docs/rdme -name: ReadMe GitHub Action šŸ¦‰ - -on: - push: - branches: - # This workflow will run every time you push code to the following branch: \`docs-test-branch\` - # Check out GitHub's docs for more info on configuring this: - # https://docs.github.com/actions/using-workflows/events-that-trigger-workflows - - docs-test-branch - -jobs: - rdme-docs: - runs-on: ubuntu-latest - steps: - - name: Check out repo šŸ“š - uses: actions/checkout@v4 - - - name: Run \`docs\` command šŸš€ - uses: readmeio/rdme@v7 - with: - rdme: docs ./__tests__/__fixtures__/docs/new-docs --key=\${{ secrets.README_API_KEY }} --version=1.0.1 -" -`; diff --git a/__tests__/commands/docs/__snapshots__/multiple.test.ts.snap b/__tests__/commands/docs/__snapshots__/multiple.test.ts.snap deleted file mode 100644 index e6de4e4bc..000000000 --- a/__tests__/commands/docs/__snapshots__/multiple.test.ts.snap +++ /dev/null @@ -1,3 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`rdme docs (multiple) > should return an error message when it encounters a cycle 1`] = `[Error: Cyclic dependency, node was:{"content":"\\n# Parent Body\\n","data":{"title":"Parent","parentDocSlug":"grandparent"},"filePath":"__tests__/__fixtures__/docs/multiple-docs-cycle/parent.md","hash":"0fc832371f8e240047bfc14bc8be9e37d50c8bb8","slug":"parent"}]`; diff --git a/__tests__/commands/docs/index.test.ts b/__tests__/commands/docs/index.test.ts deleted file mode 100644 index f71d9d12c..000000000 --- a/__tests__/commands/docs/index.test.ts +++ /dev/null @@ -1,729 +0,0 @@ -/* eslint-disable no-console */ - -import fs from 'node:fs'; -import path from 'node:path'; - -import chalk from 'chalk'; -import frontMatter from 'gray-matter'; -import nock from 'nock'; -import prompts from 'prompts'; -import { describe, beforeAll, afterAll, beforeEach, afterEach, it, expect, vi, type MockInstance } from 'vitest'; - -import Command from '../../../src/commands/docs/index.js'; -import { APIv1Error } from '../../../src/lib/apiError.js'; -import { getAPIv1Mock, getAPIv1MockWithVersionHeader } from '../../helpers/get-api-mock.js'; -import { after, before } from '../../helpers/get-gha-setup.js'; -import hashFileContents from '../../helpers/hash-file-contents.js'; -import { runCommandAndReturnResult, runCommandWithHooks } from '../../helpers/oclif.js'; -import { after as afterGHAEnv, before as beforeGHAEnv } from '../../helpers/setup-gha-env.js'; - -const fixturesBaseDir = '__fixtures__/docs'; -const fullFixturesDir = `${__dirname}./../../${fixturesBaseDir}`; - -const key = 'API_KEY'; -const version = '1.0.0'; -const category = 'CATEGORY_ID'; - -describe('rdme docs', () => { - let run: (args?: string[]) => Promise; - - beforeAll(() => { - nock.disableNetConnect(); - run = runCommandAndReturnResult(Command); - }); - - afterAll(() => nock.cleanAll()); - - it('should error if no path provided', () => { - return expect(run(['--key', key, '--version', '1.0.0'])).rejects.toThrow('Missing 1 required arg:\npath'); - }); - - it('should error if the argument is not a folder', async () => { - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - await expect(run(['--key', key, '--version', '1.0.0', 'not-a-folder'])).rejects.toStrictEqual( - new Error("Oops! We couldn't locate a file or directory at the path you provided."), - ); - - versionMock.done(); - }); - - it('should error if the folder contains no markdown files', async () => { - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - await expect(run(['--key', key, '--version', '1.0.0', '.github/workflows'])).rejects.toStrictEqual( - new Error( - "The directory you provided (.github/workflows) doesn't contain any of the following required files: .markdown, .md.", - ), - ); - - versionMock.done(); - }); - - describe('existing docs', () => { - let simpleDoc; - let anotherDoc; - - beforeEach(() => { - let fileContents = fs.readFileSync(path.join(fullFixturesDir, '/existing-docs/simple-doc.md')); - simpleDoc = { - slug: 'simple-doc', - doc: frontMatter(fileContents), - hash: hashFileContents(fileContents), - }; - - fileContents = fs.readFileSync(path.join(fullFixturesDir, '/existing-docs/subdir/another-doc.md')); - anotherDoc = { - slug: 'another-doc', - doc: frontMatter(fileContents), - hash: hashFileContents(fileContents), - }; - }); - - it('should fetch doc and merge with what is returned', () => { - expect.assertions(1); - - const getMocks = getAPIv1MockWithVersionHeader(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 updateMocks = getAPIv1MockWithVersionHeader(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, - }) - .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 = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - return run([`./__tests__/${fixturesBaseDir}/existing-docs`, '--key', key, '--version', 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(); - updateMocks.done(); - versionMock.done(); - }, - ); - }); - - it('should return doc update info for dry run', () => { - expect.assertions(1); - - const getMocks = getAPIv1MockWithVersionHeader(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 versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - return run(['--dryRun', `./__tests__/${fixturesBaseDir}/existing-docs`, '--key', key, '--version', 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( - [ - `šŸŽ­ dry run! This will update 'simple-doc' with contents from __tests__/${fixturesBaseDir}/existing-docs/simple-doc.md with the following metadata: ${JSON.stringify( - simpleDoc.doc.data, - )}`, - `šŸŽ­ dry run! This will update 'another-doc' with contents from __tests__/${fixturesBaseDir}/existing-docs/subdir/another-doc.md with the following metadata: ${JSON.stringify( - anotherDoc.doc.data, - )}`, - ].join('\n'), - ); - - getMocks.done(); - versionMock.done(); - }, - ); - }); - - it('should not send requests for docs that have not changed', () => { - expect.assertions(1); - - const getMocks = getAPIv1MockWithVersionHeader(version) - .get('/api/v1/docs/simple-doc') - .basicAuth({ user: key }) - .reply(200, { category, slug: simpleDoc.slug, lastUpdatedHash: simpleDoc.hash }) - .get('/api/v1/docs/another-doc') - .basicAuth({ user: key }) - .reply(200, { category, slug: anotherDoc.slug, lastUpdatedHash: anotherDoc.hash }); - - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - return run([`./__tests__/${fixturesBaseDir}/existing-docs`, '--key', key, '--version', version]).then( - skippedDocs => { - expect(skippedDocs).toBe( - [ - '`simple-doc` was not updated because there were no changes.', - '`another-doc` was not updated because there were no changes.', - ].join('\n'), - ); - - getMocks.done(); - versionMock.done(); - }, - ); - }); - - it('should adjust "no changes" message if in dry run', () => { - expect.assertions(1); - - const getMocks = getAPIv1MockWithVersionHeader(version) - .get('/api/v1/docs/simple-doc') - .basicAuth({ user: key }) - .reply(200, { category, slug: simpleDoc.slug, lastUpdatedHash: simpleDoc.hash }) - .get('/api/v1/docs/another-doc') - .basicAuth({ user: key }) - .reply(200, { category, slug: anotherDoc.slug, lastUpdatedHash: anotherDoc.hash }); - - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - return run(['--dryRun', `./__tests__/${fixturesBaseDir}/existing-docs`, '--key', key, '--version', version]).then( - skippedDocs => { - expect(skippedDocs).toBe( - [ - 'šŸŽ­ dry run! `simple-doc` will not be updated because there were no changes.', - 'šŸŽ­ dry run! `another-doc` will not be updated because there were no changes.', - ].join('\n'), - ); - - getMocks.done(); - versionMock.done(); - }, - ); - }); - }); - - describe('new docs', () => { - it('should create new doc', 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 = getAPIv1MockWithVersionHeader(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 = getAPIv1MockWithVersionHeader(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 = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - await expect(run([`./__tests__/${fixturesBaseDir}/new-docs`, '--key', key, '--version', 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 return creation info for dry run', async () => { - const slug = 'new-doc'; - const doc = frontMatter(fs.readFileSync(path.join(fullFixturesDir, `/new-docs/${slug}.md`))); - - const getMock = getAPIv1MockWithVersionHeader(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 versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - await expect( - run(['--dryRun', `./__tests__/${fixturesBaseDir}/new-docs`, '--key', key, '--version', version]), - ).resolves.toBe( - `šŸŽ­ dry run! This will create 'new-doc' with contents from __tests__/${fixturesBaseDir}/new-docs/new-doc.md with the following metadata: ${JSON.stringify( - doc.data, - )}`, - ); - - getMock.done(); - versionMock.done(); - }); - - it('should fail if any docs are invalid', async () => { - const folder = 'failure-docs'; - const slug = 'new-doc'; - - const errorObject = { - error: 'DOC_INVALID', - message: "We couldn't save this doc (Path `category` is required.).", - }; - - const doc = frontMatter(fs.readFileSync(path.join(fullFixturesDir, `/${folder}/${slug}.md`))); - - const hash = hashFileContents(fs.readFileSync(path.join(fullFixturesDir, `/${folder}/${slug}.md`))); - - const getMocks = getAPIv1MockWithVersionHeader(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 postMocks = getAPIv1MockWithVersionHeader(version) - .post('/api/v1/docs', { slug, body: doc.content, ...doc.data, lastUpdatedHash: hash }) - .basicAuth({ user: key }) - .reply(400, errorObject); - - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - const fullDirectory = `__tests__/${fixturesBaseDir}/${folder}`; - - const formattedErrorObject = { - ...errorObject, - message: `Error uploading ${chalk.underline(`${fullDirectory}/${slug}.md`)}:\n\n${errorObject.message}`, - }; - - await expect(run([`./${fullDirectory}`, '--key', key, '--version', version])).rejects.toStrictEqual( - new APIv1Error(formattedErrorObject), - ); - - getMocks.done(); - postMocks.done(); - versionMock.done(); - }); - }); - - describe('slug metadata', () => { - it('should use provided slug', async () => { - const slug = 'new-doc-slug'; - const id = '1234'; - const doc = frontMatter(fs.readFileSync(path.join(fullFixturesDir, `/slug-docs/${slug}.md`))); - const hash = hashFileContents(fs.readFileSync(path.join(fullFixturesDir, `/slug-docs/${slug}.md`))); - - const getMock = getAPIv1Mock() - .get(`/api/v1/docs/${doc.data.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 = getAPIv1Mock() - .post('/api/v1/docs', { slug, body: doc.content, ...doc.data, lastUpdatedHash: hash }) - .basicAuth({ user: key }) - .reply(201, { slug: doc.data.slug, _id: id, body: doc.content, ...doc.data, lastUpdatedHash: hash }); - - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - await expect(run([`./__tests__/${fixturesBaseDir}/slug-docs`, '--key', key, '--version', version])).resolves.toBe( - `šŸŒ± successfully created 'marc-actually-wrote-a-test' (ID: 1234) with contents from __tests__/${fixturesBaseDir}/slug-docs/new-doc-slug.md`, - ); - - getMock.done(); - postMock.done(); - versionMock.done(); - }); - }); - - describe('GHA onboarding E2E tests', () => { - let consoleInfoSpy: MockInstance; - let yamlOutput; - - const getCommandOutput = () => { - return [consoleInfoSpy.mock.calls.join('\n\n')].filter(Boolean).join('\n\n'); - }; - - beforeEach(() => { - consoleInfoSpy = vi.spyOn(console, 'info').mockImplementation(() => {}); - - before((fileName, data) => { - yamlOutput = data; - }); - }); - - afterEach(() => { - after(); - - consoleInfoSpy.mockRestore(); - }); - - it('should create GHA workflow with version passed in via prompt', async () => { - expect.assertions(6); - - const altVersion = '1.0.1'; - 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 versionsMock = getAPIv1Mock() - .get('/api/v1/version') - .basicAuth({ user: key }) - .reply(200, [{ version }, { version: altVersion }]); - - const getMock = getAPIv1MockWithVersionHeader(altVersion) - .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 = getAPIv1MockWithVersionHeader(altVersion) - .post('/api/v1/docs', { slug, body: doc.content, ...doc.data, lastUpdatedHash: hash }) - .basicAuth({ user: key }) - .reply(201, { _id: id, slug, body: doc.content, ...doc.data, lastUpdatedHash: hash }); - - const fileName = 'docs-test-file'; - prompts.inject([altVersion, true, 'docs-test-branch', fileName]); - - await expect(run([`./__tests__/${fixturesBaseDir}/new-docs`, '--key', key])).resolves.toMatchSnapshot(); - - expect(yamlOutput).toMatchSnapshot(); - expect(fs.writeFileSync).toHaveBeenCalledWith(`.github/workflows/${fileName}.yml`, expect.any(String)); - expect(console.info).toHaveBeenCalledTimes(2); - const output = getCommandOutput(); - expect(output).toMatch("Looks like you're running this command in a GitHub Repository!"); - expect(output).toMatch(`successfully created '${slug}' (ID: ${id}) with contents from`); - - versionsMock.done(); - getMock.done(); - postMock.done(); - }); - - it('should create GHA workflow with version passed in via opt', async () => { - expect.assertions(3); - - const slug = 'new-doc'; - 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 = getAPIv1MockWithVersionHeader(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 = getAPIv1MockWithVersionHeader(version) - .post('/api/v1/docs', { slug, body: doc.content, ...doc.data, lastUpdatedHash: hash }) - .basicAuth({ user: key }) - .reply(201, { slug, body: doc.content, ...doc.data, lastUpdatedHash: hash }); - - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - const fileName = 'docs-test-file'; - prompts.inject([true, 'docs-test-branch', fileName]); - - await expect( - run([`./__tests__/${fixturesBaseDir}/new-docs`, '--key', key, '--version', version]), - ).resolves.toMatchSnapshot(); - - expect(yamlOutput).toMatchSnapshot(); - expect(fs.writeFileSync).toHaveBeenCalledWith(`.github/workflows/${fileName}.yml`, expect.any(String)); - - getMock.done(); - postMock.done(); - versionMock.done(); - }); - - it('should create GHA workflow with version passed as opt (github flag enabled)', async () => { - expect.assertions(3); - - const slug = 'new-doc'; - 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 = getAPIv1MockWithVersionHeader(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 = getAPIv1MockWithVersionHeader(version) - .post('/api/v1/docs', { slug, body: doc.content, ...doc.data, lastUpdatedHash: hash }) - .basicAuth({ user: key }) - .reply(201, { slug, body: doc.content, ...doc.data, lastUpdatedHash: hash }); - - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - const fileName = 'docs-test-file-github-flag'; - prompts.inject(['docs-test-branch-github-flag', fileName]); - - await expect( - run([`./__tests__/${fixturesBaseDir}/new-docs`, '--github', '--key', key, '--version', version]), - ).resolves.toMatchSnapshot(); - - expect(yamlOutput).toMatchSnapshot(); - expect(fs.writeFileSync).toHaveBeenCalledWith(`.github/workflows/${fileName}.yml`, expect.any(String)); - - getMock.done(); - postMock.done(); - versionMock.done(); - }); - - it('should reject if user says no to creating GHA workflow', async () => { - const slug = 'new-doc'; - 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 = getAPIv1MockWithVersionHeader(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 = getAPIv1MockWithVersionHeader(version) - .post('/api/v1/docs', { slug, body: doc.content, ...doc.data, lastUpdatedHash: hash }) - .basicAuth({ user: key }) - .reply(201, { slug, body: doc.content, ...doc.data, lastUpdatedHash: hash }); - - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - prompts.inject([false]); - - await expect( - run([`./__tests__/${fixturesBaseDir}/new-docs`, '--key', key, '--version', version]), - ).rejects.toStrictEqual( - new Error( - 'GitHub Actions workflow creation cancelled. If you ever change your mind, you can run this command again with the `--github` flag.', - ), - ); - - getMock.done(); - postMock.done(); - versionMock.done(); - }); - }); - - describe('command execution in GitHub Actions runner', () => { - beforeEach(() => { - beforeGHAEnv(); - }); - - afterEach(afterGHAEnv); - - 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 = getAPIv1MockWithVersionHeader(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 = getAPIv1Mock({ - '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 = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - await expect(run([`./__tests__/${fixturesBaseDir}/new-docs`, '--key', key, '--version', 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 = getAPIv1MockWithVersionHeader(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 = getAPIv1Mock({ - '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 = getAPIv1Mock({ - '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 = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - return run([`__tests__/${fixturesBaseDir}/existing-docs`, '--key', key, '--version', 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', () => { - it('should error if no path provided', async () => { - return expect( - (await runCommandWithHooks(['guides', '--key', key, '--version', '1.0.0'])).error.message, - ).toContain('Missing 1 required arg:\npath'); - }); - }); -}); diff --git a/__tests__/commands/docs/multiple.test.ts b/__tests__/commands/docs/multiple.test.ts deleted file mode 100644 index 40c0a29de..000000000 --- a/__tests__/commands/docs/multiple.test.ts +++ /dev/null @@ -1,180 +0,0 @@ -import fs from 'node:fs'; -import path from 'node:path'; - -import frontMatter from 'gray-matter'; -import nock from 'nock'; -import { describe, beforeAll, afterAll, it, expect } from 'vitest'; - -import Command from '../../../src/commands/docs/index.js'; -import { getAPIv1Mock, getAPIv1MockWithVersionHeader } from '../../helpers/get-api-mock.js'; -import hashFileContents from '../../helpers/hash-file-contents.js'; -import { runCommandAndReturnResult } from '../../helpers/oclif.js'; - -const fixturesBaseDir = '__fixtures__/docs'; -const fullFixturesDir = `${__dirname}./../../${fixturesBaseDir}`; - -const key = 'API_KEY'; -const version = '1.0.0'; - -describe('rdme docs (multiple)', () => { - let run: (args?: string[]) => Promise; - - beforeAll(() => { - nock.disableNetConnect(); - run = runCommandAndReturnResult(Command); - }); - - afterAll(() => nock.cleanAll()); - - it('should upload parent docs first', async () => { - const dir = 'multiple-docs'; - const slugs = ['grandparent', 'parent', 'child', 'friend']; - let id = 1234; - - const mocks = slugs.flatMap(slug => { - const doc = frontMatter(fs.readFileSync(path.join(fullFixturesDir, `/${dir}/${slug}.md`))); - const hash = hashFileContents(fs.readFileSync(path.join(fullFixturesDir, `/${dir}/${slug}.md`))); - - return [ - getAPIv1MockWithVersionHeader(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".', - }), - getAPIv1MockWithVersionHeader(version) - .post('/api/v1/docs', { slug, body: doc.content, ...doc.data, lastUpdatedHash: hash }) - .basicAuth({ user: key }) - // eslint-disable-next-line no-plusplus - .reply(201, { slug, _id: id++, body: doc.content, ...doc.data, lastUpdatedHash: hash }), - ]; - }); - - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - const promise = run([`./__tests__/${fixturesBaseDir}/${dir}`, '--key', key, '--version', version]); - - await expect(promise).resolves.toStrictEqual( - [ - `šŸŒ± successfully created 'friend' (ID: 1237) with contents from __tests__/${fixturesBaseDir}/${dir}/friend.md`, - `šŸŒ± successfully created 'grandparent' (ID: 1234) with contents from __tests__/${fixturesBaseDir}/${dir}/grandparent.md`, - `šŸŒ± successfully created 'parent' (ID: 1235) with contents from __tests__/${fixturesBaseDir}/${dir}/parent.md`, - `šŸŒ± successfully created 'child' (ID: 1236) with contents from __tests__/${fixturesBaseDir}/${dir}/child.md`, - ].join('\n'), - ); - - mocks.forEach(mock => mock.done()); - versionMock.done(); - }); - - it('should upload docs with parent doc ids first', async () => { - const dir = 'docs-with-parent-ids'; - const slugs = ['child', 'friend', 'with-parent-doc', 'parent']; - let id = 1234; - - const mocks = slugs.flatMap(slug => { - const doc = frontMatter(fs.readFileSync(path.join(fullFixturesDir, `/${dir}/${slug}.md`))); - const hash = hashFileContents(fs.readFileSync(path.join(fullFixturesDir, `/${dir}/${slug}.md`))); - - return [ - getAPIv1MockWithVersionHeader(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".', - }), - getAPIv1MockWithVersionHeader(version) - .post('/api/v1/docs', { slug, body: doc.content, ...doc.data, lastUpdatedHash: hash }) - .basicAuth({ user: key }) - // eslint-disable-next-line no-plusplus - .reply(201, { slug, _id: id++, body: doc.content, ...doc.data, lastUpdatedHash: hash }), - ]; - }); - - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - const promise = run([`./__tests__/${fixturesBaseDir}/${dir}`, '--key', key, '--version', version]); - - await expect(promise).resolves.toStrictEqual( - [ - `šŸŒ± successfully created 'with-parent-doc' (ID: 1236) with contents from __tests__/${fixturesBaseDir}/${dir}/with-parent-doc.md`, - `šŸŒ± successfully created 'friend' (ID: 1235) with contents from __tests__/${fixturesBaseDir}/${dir}/friend.md`, - `šŸŒ± successfully created 'parent' (ID: 1237) with contents from __tests__/${fixturesBaseDir}/${dir}/parent.md`, - `šŸŒ± successfully created 'child' (ID: 1234) with contents from __tests__/${fixturesBaseDir}/${dir}/child.md`, - ].join('\n'), - ); - - mocks.forEach(mock => mock.done()); - versionMock.done(); - }); - - it('should upload child docs without the parent', async () => { - const dir = 'multiple-docs-no-parents'; - const slugs = ['child', 'friend']; - let id = 1234; - - const mocks = slugs.flatMap(slug => { - const doc = frontMatter(fs.readFileSync(path.join(fullFixturesDir, `/${dir}/${slug}.md`))); - const hash = hashFileContents(fs.readFileSync(path.join(fullFixturesDir, `/${dir}/${slug}.md`))); - - return [ - getAPIv1MockWithVersionHeader(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".', - }), - getAPIv1MockWithVersionHeader(version) - .post('/api/v1/docs', { slug, body: doc.content, ...doc.data, lastUpdatedHash: hash }) - .basicAuth({ user: key }) - // eslint-disable-next-line no-plusplus - .reply(201, { slug, _id: id++, body: doc.content, ...doc.data, lastUpdatedHash: hash }), - ]; - }); - - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - const promise = run([`./__tests__/${fixturesBaseDir}/${dir}`, '--key', key, '--version', version]); - - await expect(promise).resolves.toStrictEqual( - [ - `šŸŒ± successfully created 'child' (ID: 1234) with contents from __tests__/${fixturesBaseDir}/${dir}/child.md`, - `šŸŒ± successfully created 'friend' (ID: 1235) with contents from __tests__/${fixturesBaseDir}/${dir}/friend.md`, - ].join('\n'), - ); - - mocks.forEach(mock => mock.done()); - versionMock.done(); - }); - - it('should return an error message when it encounters a cycle', async () => { - const dir = 'multiple-docs-cycle'; - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - const promise = run([`./__tests__/${fixturesBaseDir}/${dir}`, '--key', key, '--version', version]); - - await expect(promise).rejects.toMatchSnapshot(); - versionMock.done(); - }); -}); diff --git a/__tests__/commands/docs/prune.test.ts b/__tests__/commands/docs/prune.test.ts deleted file mode 100644 index 162e5cb7e..000000000 --- a/__tests__/commands/docs/prune.test.ts +++ /dev/null @@ -1,172 +0,0 @@ -import nock from 'nock'; -import prompts from 'prompts'; -import { describe, beforeAll, afterAll, it, expect } from 'vitest'; - -import Command from '../../../src/commands/docs/prune.js'; -import { getAPIv1Mock, getAPIv1MockWithVersionHeader } from '../../helpers/get-api-mock.js'; -import { runCommandAndReturnResult, runCommandWithHooks } from '../../helpers/oclif.js'; - -const fixturesBaseDir = '__fixtures__/docs'; - -const key = 'API_KEY'; -const version = '1.0.0'; - -describe('rdme docs prune', () => { - const folder = `./__tests__/${fixturesBaseDir}/delete-docs`; - let run: (args?: string[]) => Promise; - - beforeAll(() => { - nock.disableNetConnect(); - run = runCommandAndReturnResult(Command); - }); - - afterAll(() => nock.cleanAll()); - - it('should error if no folder provided', () => { - return expect(run(['--key', key, '--version', version])).rejects.rejects.toThrow('Missing 1 required arg:\nfolder'); - }); - - it('should error if the argument is not a folder', async () => { - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - await expect(run(['--key', key, '--version', version, 'not-a-folder'])).rejects.toStrictEqual( - new Error("ENOENT: no such file or directory, scandir 'not-a-folder'"), - ); - - versionMock.done(); - }); - - it('should do nothing if the user aborted', async () => { - prompts.inject([false]); - - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - await expect(run([folder, '--key', key, '--version', version])).rejects.toStrictEqual( - new Error('Aborting, no changes were made.'), - ); - - versionMock.done(); - }); - - it('should not ask for user confirmation if `confirm` is set to true', async () => { - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - const apiMocks = getAPIv1MockWithVersionHeader(version) - .get('/api/v1/categories?perPage=20&page=1') - .basicAuth({ user: key }) - .reply(200, [{ slug: 'category1', type: 'guide' }], { 'x-total-count': '1' }) - .get('/api/v1/categories/category1/docs') - .basicAuth({ user: key }) - .reply(200, [{ slug: 'this-doc-should-be-missing-in-folder' }, { slug: 'some-doc' }]) - .delete('/api/v1/docs/this-doc-should-be-missing-in-folder') - .basicAuth({ user: key }) - .reply(204, ''); - - await expect(run([folder, '--key', key, '--version', version, '--confirm'])).resolves.toBe( - 'šŸ—‘ļø successfully deleted `this-doc-should-be-missing-in-folder`.', - ); - - apiMocks.done(); - versionMock.done(); - }); - - it('should delete doc if file is missing', async () => { - prompts.inject([true]); - - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - const apiMocks = getAPIv1MockWithVersionHeader(version) - .get('/api/v1/categories?perPage=20&page=1') - .basicAuth({ user: key }) - .reply(200, [{ slug: 'category1', type: 'guide' }], { 'x-total-count': '1' }) - .get('/api/v1/categories/category1/docs') - .basicAuth({ user: key }) - .reply(200, [{ slug: 'this-doc-should-be-missing-in-folder' }, { slug: 'some-doc' }]) - .delete('/api/v1/docs/this-doc-should-be-missing-in-folder') - .basicAuth({ user: key }) - .reply(204, ''); - - await expect(run([folder, '--key', key, '--version', version])).resolves.toBe( - 'šŸ—‘ļø successfully deleted `this-doc-should-be-missing-in-folder`.', - ); - - apiMocks.done(); - versionMock.done(); - }); - - it('should delete doc and its child if they are missing', async () => { - prompts.inject([true]); - - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - const apiMocks = getAPIv1MockWithVersionHeader(version) - .get('/api/v1/categories?perPage=20&page=1') - .basicAuth({ user: key }) - .reply(200, [{ slug: 'category1', type: 'guide' }], { 'x-total-count': '1' }) - .get('/api/v1/categories/category1/docs') - .basicAuth({ user: key }) - .reply(200, [ - { slug: 'this-doc-should-be-missing-in-folder', children: [{ slug: 'this-child-is-also-missing' }] }, - { slug: 'some-doc' }, - ]) - .delete('/api/v1/docs/this-doc-should-be-missing-in-folder') - .basicAuth({ user: key }) - .reply(204, '') - .delete('/api/v1/docs/this-child-is-also-missing') - .basicAuth({ user: key }) - .reply(204, ''); - - await expect(run([folder, '--key', key, '--version', version])).resolves.toBe( - 'šŸ—‘ļø successfully deleted `this-child-is-also-missing`.\nšŸ—‘ļø successfully deleted `this-doc-should-be-missing-in-folder`.', - ); - - apiMocks.done(); - versionMock.done(); - }); - - it('should return doc delete info for dry run', async () => { - prompts.inject([true]); - - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - const apiMocks = getAPIv1MockWithVersionHeader(version) - .get('/api/v1/categories?perPage=20&page=1') - .basicAuth({ user: key }) - .reply(200, [{ slug: 'category1', type: 'guide' }], { 'x-total-count': '1' }) - .get('/api/v1/categories/category1/docs') - .basicAuth({ user: key }) - .reply(200, [{ slug: 'this-doc-should-be-missing-in-folder' }]); - - await expect(run([folder, '--key', key, '--version', version, '--dryRun'])).resolves.toBe( - 'šŸŽ­ dry run! This will delete `this-doc-should-be-missing-in-folder`.', - ); - - apiMocks.done(); - versionMock.done(); - }); - - describe('rdme guides prune', () => { - it('should error if no folder provided', async () => { - return expect( - (await runCommandWithHooks(['guides', 'prune', '--key', key, '--version', version])).error.message, - ).toContain('Missing 1 required arg:\nfolder'); - }); - }); -}); diff --git a/__tests__/commands/docs/single.test.ts b/__tests__/commands/docs/single.test.ts deleted file mode 100644 index 007bd28d2..000000000 --- a/__tests__/commands/docs/single.test.ts +++ /dev/null @@ -1,443 +0,0 @@ -import fs from 'node:fs'; -import path from 'node:path'; - -import chalk from 'chalk'; -import frontMatter from 'gray-matter'; -import nock from 'nock'; -import { describe, beforeAll, afterAll, beforeEach, afterEach, it, expect } from 'vitest'; - -import Command from '../../../src/commands/docs/index.js'; -import { APIv1Error } from '../../../src/lib/apiError.js'; -import { getAPIv1Mock, getAPIv1MockWithVersionHeader } from '../../helpers/get-api-mock.js'; -import hashFileContents from '../../helpers/hash-file-contents.js'; -import { runCommandAndReturnResult } from '../../helpers/oclif.js'; -import { after as afterGHAEnv, before as beforeGHAEnv } from '../../helpers/setup-gha-env.js'; - -const fixturesBaseDir = '__fixtures__/docs'; -const fullFixturesDir = `${__dirname}./../../${fixturesBaseDir}`; - -const key = 'API_KEY'; -const version = '1.0.0'; -const category = 'CATEGORY_ID'; - -describe('rdme docs (single)', () => { - let run: (args?: string[]) => Promise; - - beforeAll(() => { - nock.disableNetConnect(); - run = runCommandAndReturnResult(Command); - }); - - afterAll(() => nock.cleanAll()); - - it('should error if no file path provided', () => { - return expect(run(['--key', key, '--version', version])).rejects.toThrow('Missing 1 required arg:\npath'); - }); - - it('should error if the argument is not a Markdown file', async () => { - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - await expect(run(['--key', key, '--version', version, 'not-a-markdown-file'])).rejects.toStrictEqual( - new Error("Oops! We couldn't locate a file or directory at the path you provided."), - ); - - versionMock.done(); - }); - - it('should support .markdown files but error if file path cannot be found', async () => { - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - await expect(run(['--key', key, '--version', version, 'non-existent-file.markdown'])).rejects.toStrictEqual( - new Error("Oops! We couldn't locate a file or directory at the path you provided."), - ); - versionMock.done(); - }); - - describe('new docs', () => { - it('should create new doc', 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 = getAPIv1MockWithVersionHeader(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 = getAPIv1MockWithVersionHeader(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 = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - await expect( - run([`./__tests__/${fixturesBaseDir}/new-docs/new-doc.md`, '--key', key, '--version', 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 return creation info for dry run', async () => { - const slug = 'new-doc'; - const doc = frontMatter(fs.readFileSync(path.join(fullFixturesDir, `/new-docs/${slug}.md`))); - - const getMock = getAPIv1MockWithVersionHeader(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 versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - await expect( - run(['--dryRun', `./__tests__/${fixturesBaseDir}/new-docs/new-doc.md`, '--key', key, '--version', version]), - ).resolves.toBe( - `šŸŽ­ dry run! This will create 'new-doc' with contents from ./__tests__/${fixturesBaseDir}/new-docs/new-doc.md with the following metadata: ${JSON.stringify( - doc.data, - )}`, - ); - - getMock.done(); - versionMock.done(); - }); - - it('should skip doc if it does not contain any front matter attributes', async () => { - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - const filePath = `./__tests__/${fixturesBaseDir}/failure-docs/doc-sans-attributes.md`; - - await expect(run(['--key', key, '--version', version, filePath])).resolves.toBe( - `ā­ļø no front matter attributes found for ${filePath}, skipping`, - ); - - versionMock.done(); - }); - - it('should fail if some other error when retrieving page slug', async () => { - const slug = 'new-doc'; - - const errorObject = { - error: 'INTERNAL_ERROR', - message: 'Unknown error (yikes)', - suggestion: '...a suggestion to resolve the issue...', - help: 'If you need help, email support@readme.io and mention log "fake-metrics-uuid".', - }; - - const getMock = getAPIv1MockWithVersionHeader(version) - .get(`/api/v1/docs/${slug}`) - .basicAuth({ user: key }) - .reply(500, errorObject); - - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - const filePath = `./__tests__/${fixturesBaseDir}/failure-docs/${slug}.md`; - - const formattedErrorObject = { - ...errorObject, - message: `Error uploading ${chalk.underline(`${filePath}`)}:\n\n${errorObject.message}`, - }; - - await expect(run([filePath, '--key', key, '--version', version])).rejects.toStrictEqual( - new APIv1Error(formattedErrorObject), - ); - - getMock.done(); - versionMock.done(); - }); - }); - - describe('slug metadata', () => { - it('should use provided slug', async () => { - const slug = 'new-doc-slug'; - const id = '1234'; - const doc = frontMatter(fs.readFileSync(path.join(fullFixturesDir, `/slug-docs/${slug}.md`))); - const hash = hashFileContents(fs.readFileSync(path.join(fullFixturesDir, `/slug-docs/${slug}.md`))); - - const getMock = getAPIv1Mock() - .get(`/api/v1/docs/${doc.data.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 = getAPIv1Mock() - .post('/api/v1/docs', { slug, body: doc.content, ...doc.data, lastUpdatedHash: hash }) - .basicAuth({ user: key }) - .reply(201, { slug: doc.data.slug, _id: id, body: doc.content, ...doc.data, lastUpdatedHash: hash }); - - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - await expect( - run([`./__tests__/${fixturesBaseDir}/slug-docs/new-doc-slug.md`, '--key', key, '--version', version]), - ).resolves.toBe( - `šŸŒ± successfully created 'marc-actually-wrote-a-test' (ID: 1234) with contents from ./__tests__/${fixturesBaseDir}/slug-docs/new-doc-slug.md`, - ); - - getMock.done(); - postMock.done(); - versionMock.done(); - }); - }); - - describe('existing docs', () => { - let simpleDoc; - - beforeEach(() => { - const fileContents = fs.readFileSync(path.join(fullFixturesDir, '/existing-docs/simple-doc.md')); - simpleDoc = { - slug: 'simple-doc', - doc: frontMatter(fileContents), - hash: hashFileContents(fileContents), - }; - }); - - it('should fetch doc and merge with what is returned', async () => { - const getMock = getAPIv1MockWithVersionHeader(version) - .get('/api/v1/docs/simple-doc') - .basicAuth({ user: key }) - .reply(200, { category, slug: simpleDoc.slug, lastUpdatedHash: 'anOldHash' }); - - const updateMock = getAPIv1MockWithVersionHeader(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 = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - await expect( - run([`./__tests__/${fixturesBaseDir}/existing-docs/simple-doc.md`, '--key', key, '--version', version]), - ).resolves.toBe( - `āœļø successfully updated 'simple-doc' with contents from ./__tests__/${fixturesBaseDir}/existing-docs/simple-doc.md`, - ); - - getMock.done(); - updateMock.done(); - versionMock.done(); - }); - - it('should return doc update info for dry run', async () => { - const getMock = getAPIv1MockWithVersionHeader(version) - .get('/api/v1/docs/simple-doc') - .basicAuth({ user: key }) - .reply(200, { category, slug: simpleDoc.slug, lastUpdatedHash: 'anOldHash' }); - - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - await expect( - run([ - '--dryRun', - `./__tests__/${fixturesBaseDir}/existing-docs/simple-doc.md`, - '--key', - key, - '--version', - version, - ]), - ).resolves.toBe( - [ - `šŸŽ­ dry run! This will update 'simple-doc' with contents from ./__tests__/${fixturesBaseDir}/existing-docs/simple-doc.md with the following metadata: ${JSON.stringify( - simpleDoc.doc.data, - )}`, - ].join('\n'), - ); - - getMock.done(); - versionMock.done(); - }); - - it('should not send requests for docs that have not changed', async () => { - const getMock = getAPIv1MockWithVersionHeader(version) - .get('/api/v1/docs/simple-doc') - .basicAuth({ user: key }) - .reply(200, { category, slug: simpleDoc.slug, lastUpdatedHash: simpleDoc.hash }); - - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - await expect( - run([`./__tests__/${fixturesBaseDir}/existing-docs/simple-doc.md`, '--key', key, '--version', version]), - ).resolves.toBe('`simple-doc` was not updated because there were no changes.'); - - getMock.done(); - versionMock.done(); - }); - - it('should adjust "no changes" message if in dry run', async () => { - const getMock = getAPIv1MockWithVersionHeader(version) - .get('/api/v1/docs/simple-doc') - .basicAuth({ user: key }) - .reply(200, { category, slug: simpleDoc.slug, lastUpdatedHash: simpleDoc.hash }); - - const versionMock = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - await expect( - run([ - '--dryRun', - `./__tests__/${fixturesBaseDir}/existing-docs/simple-doc.md`, - '--key', - key, - '--version', - version, - ]), - ).resolves.toBe('šŸŽ­ dry run! `simple-doc` will not be updated because there were no changes.'); - - getMock.done(); - versionMock.done(); - }); - }); - - describe('command execution in GitHub Actions runner', () => { - beforeEach(() => { - beforeGHAEnv(); - }); - - afterEach(afterGHAEnv); - - 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 = getAPIv1MockWithVersionHeader(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 = getAPIv1Mock({ - '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 = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - await expect( - run([`./__tests__/${fixturesBaseDir}/new-docs/new-doc.md`, '--key', key, '--version', 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', async () => { - 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 = getAPIv1MockWithVersionHeader(version) - .get('/api/v1/docs/simple-doc') - .basicAuth({ user: key }) - .reply(200, { category, slug: simpleDoc.slug, lastUpdatedHash: 'anOldHash' }); - - const updateMock = getAPIv1Mock({ - '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 = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - await expect( - run([`__tests__/${fixturesBaseDir}/existing-docs/simple-doc.md`, '--key', key, '--version', version]), - ).resolves.toBe( - `āœļø successfully updated 'simple-doc' with contents from __tests__/${fixturesBaseDir}/existing-docs/simple-doc.md`, - ); - - getMock.done(); - updateMock.done(); - versionMock.done(); - }); - }); -}); diff --git a/__tests__/commands/open.test.ts b/__tests__/commands/open.test.ts deleted file mode 100644 index 3ab9829f0..000000000 --- a/__tests__/commands/open.test.ts +++ /dev/null @@ -1,75 +0,0 @@ -import type { Version } from '../../src/commands/versions/index.js'; - -import chalk from 'chalk'; -import { describe, afterEach, beforeAll, it, expect } from 'vitest'; - -import pkg from '../../package.json' with { type: 'json' }; -import Command from '../../src/commands/open.js'; -import configStore from '../../src/lib/configstore.js'; -import { getAPIv1Mock } from '../helpers/get-api-mock.js'; -import { runCommandAndReturnResult } from '../helpers/oclif.js'; - -const mockArg = ['--mock']; - -describe('rdme open', () => { - let run: (args?: string[]) => Promise; - - beforeAll(() => { - run = runCommandAndReturnResult(Command); - }); - - afterEach(() => { - configStore.clear(); - }); - - it('should error if no project provided', () => { - configStore.delete('project'); - - return expect(run(mockArg)).rejects.toStrictEqual(new Error(`Please login using \`${pkg.name} login\`.`)); - }); - - it('should open the project', () => { - configStore.set('project', 'subdomain'); - - const projectUrl = 'https://subdomain.readme.io'; - - return expect(run(mockArg)).resolves.toBe(`Opening ${chalk.green(projectUrl)} in your browser...`); - }); - - describe('open --dash', () => { - it('should open the dash', async () => { - configStore.set('project', 'subdomain'); - configStore.set('apiKey', '12345'); - - const version = '1.0'; - const key = '12345'; - const versionPayload: Version = { - createdAt: '2019-06-17T22:39:56.462Z', - is_deprecated: false, - is_hidden: false, - is_beta: false, - is_stable: true, - codename: '', - version, - }; - - const mockRequest = getAPIv1Mock() - .get('/api/v1/version') - .basicAuth({ user: key }) - .reply(200, [versionPayload, { version: '1.0.1' }]); - - const dashUrl = 'https://dash.readme.com/project/subdomain/v1.0/overview'; - - await expect(run(mockArg.concat('--dash'))).resolves.toBe(`Opening ${chalk.green(dashUrl)} in your browser...`); - mockRequest.done(); - }); - - it('should require user to be logged in', () => { - configStore.set('project', 'subdomain'); - - return expect(run(mockArg.concat('--dash'))).rejects.toStrictEqual( - new Error(`Please login using \`${pkg.name} login\`.`), - ); - }); - }); -}); diff --git a/__tests__/commands/versions/create.test.ts b/__tests__/commands/versions/create.test.ts deleted file mode 100644 index 014bad9ff..000000000 --- a/__tests__/commands/versions/create.test.ts +++ /dev/null @@ -1,176 +0,0 @@ -import nock from 'nock'; -import prompts from 'prompts'; -import { describe, beforeAll, afterEach, it, expect } from 'vitest'; - -import Command from '../../../src/commands/versions/create.js'; -import { APIv1Error } from '../../../src/lib/apiError.js'; -import { getAPIv1Mock } from '../../helpers/get-api-mock.js'; -import { runCommandAndReturnResult } from '../../helpers/oclif.js'; - -const key = 'API_KEY'; -const version = '1.0.0'; - -describe('rdme versions create', () => { - let run: (args?: string[]) => Promise; - - beforeAll(() => { - nock.disableNetConnect(); - run = runCommandAndReturnResult(Command); - }); - - afterEach(() => nock.cleanAll()); - - it('should error if no version provided', () => { - return expect(run(['--key', key])).rejects.toThrow('Missing 1 required arg:\nversion'); - }); - - it('should error if invalid version provided', () => { - return expect(run(['--key', key, 'test'])).rejects.toStrictEqual( - new Error('Please specify a semantic version. See `rdme help versions create` for help.'), - ); - }); - - it('should create a specific version', async () => { - prompts.inject([version, false, true, true, false]); - const newVersion = '1.0.1'; - - const mockRequest = getAPIv1Mock() - .get('/api/v1/version') - .basicAuth({ user: key }) - .reply(200, [{ version }, { version: '1.1.0' }]) - .post('/api/v1/version', { - version: newVersion, - is_stable: false, - is_beta: true, - from: '1.0.0', - is_hidden: true, - is_deprecated: false, - }) - .basicAuth({ user: key }) - .reply(201, { version: newVersion }); - - await expect(run(['--key', key, newVersion])).resolves.toBe(`Version ${newVersion} created successfully.`); - mockRequest.done(); - }); - - it('should create a specific version with options', async () => { - const newVersion = '1.0.1'; - - const mockRequest = getAPIv1Mock() - .post('/api/v1/version', { - version: newVersion, - codename: 'test', - from: '1.0.0', - is_beta: false, - is_deprecated: false, - is_hidden: false, - is_stable: false, - }) - .basicAuth({ user: key }) - .reply(201, { version: newVersion }); - - await expect( - run([ - '--key', - key, - newVersion, - '--fork', - version, - '--beta', - 'false', - '--deprecated', - 'false', - '--main', - 'false', - '--codename', - 'test', - '--hidden', - 'false', - ]), - ).resolves.toBe(`Version ${newVersion} created successfully.`); - - mockRequest.done(); - }); - - it('should create successfully a main version', async () => { - const newVersion = '1.0.1'; - - const mockRequest = getAPIv1Mock() - .post('/api/v1/version', { - version: newVersion, - from: '1.0.0', - is_beta: false, - is_stable: true, - }) - .basicAuth({ user: key }) - .reply(201, { version: newVersion }); - - await expect( - run([ - '--key', - key, - newVersion, - '--fork', - version, - '--beta', - 'false', - '--main', - 'true', - '--hidden', - 'true', - '--deprecated', - 'true', - ]), - ).resolves.toBe(`Version ${newVersion} created successfully.`); - - mockRequest.done(); - }); - - it('should catch any post request errors', async () => { - const errorResponse = { - error: 'VERSION_EMPTY', - message: 'You need to include an x-readme-version header', - suggestion: '...a suggestion to resolve the issue...', - help: 'If you need help, email support@readme.io and mention log "fake-metrics-uuid".', - }; - - const mockRequest = getAPIv1Mock().post('/api/v1/version').basicAuth({ user: key }).reply(400, errorResponse); - - await expect(run(['--key', key, version, '--fork', '0.0.5'])).rejects.toStrictEqual(new APIv1Error(errorResponse)); - mockRequest.done(); - }); - - describe('bad flag values', () => { - it('should throw if non-boolean `beta` flag is passed', () => { - const newVersion = '1.0.1'; - - return expect(run(['--key', key, newVersion, '--fork', version, '--beta', 'test'])).rejects.toThrow( - 'Expected --beta=test to be one of: true, false', - ); - }); - - it('should throw if non-boolean `deprecated` flag is passed', () => { - const newVersion = '1.0.1'; - - return expect(run(['--key', key, newVersion, '--fork', version, '--deprecated', 'test'])).rejects.toThrow( - 'Expected --deprecated=test to be one of: true, false', - ); - }); - - it('should throw if non-boolean `hidden` flag is passed', () => { - const newVersion = '1.0.1'; - - return expect(run(['--key', key, newVersion, '--fork', version, '--hidden', 'test'])).rejects.toThrow( - 'Expected --hidden=test to be one of: true, false', - ); - }); - - it('should throw if non-boolean `main` flag is passed', () => { - const newVersion = '1.0.1'; - - return expect(run(['--key', key, newVersion, '--fork', version, '--main', 'test'])).rejects.toThrow( - 'Expected --main=test to be one of: true, false', - ); - }); - }); -}); diff --git a/__tests__/commands/versions/delete.test.ts b/__tests__/commands/versions/delete.test.ts deleted file mode 100644 index a82b11efe..000000000 --- a/__tests__/commands/versions/delete.test.ts +++ /dev/null @@ -1,55 +0,0 @@ -import nock from 'nock'; -import { describe, beforeAll, afterEach, it, expect } from 'vitest'; - -import Command from '../../../src/commands/versions/delete.js'; -import { APIv1Error } from '../../../src/lib/apiError.js'; -import { getAPIv1Mock } from '../../helpers/get-api-mock.js'; -import { runCommandAndReturnResult } from '../../helpers/oclif.js'; - -const key = 'API_KEY'; -const version = '1.0.0'; - -describe('rdme versions delete', () => { - let run: (args?: string[]) => Promise; - - beforeAll(() => { - nock.disableNetConnect(); - run = runCommandAndReturnResult(Command); - }); - - afterEach(() => nock.cleanAll()); - - it('should delete a specific version', async () => { - const mockRequest = getAPIv1Mock() - .delete(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { removed: true }) - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - await expect(run(['--key', key, version])).resolves.toBe('Version 1.0.0 deleted successfully.'); - mockRequest.done(); - }); - - it('should catch any request errors', async () => { - const errorResponse = { - error: 'VERSION_NOTFOUND', - message: - "The version you specified ({version}) doesn't match any of the existing versions ({versions_list}) in ReadMe.", - suggestion: '...a suggestion to resolve the issue...', - help: 'If you need help, email support@readme.io and mention log "fake-metrics-uuid".', - }; - - const mockRequest = getAPIv1Mock() - .delete(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(404, errorResponse) - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }); - - await expect(run(['--key', key, version])).rejects.toStrictEqual(new APIv1Error(errorResponse)); - mockRequest.done(); - }); -}); diff --git a/__tests__/commands/versions/index.test.ts b/__tests__/commands/versions/index.test.ts deleted file mode 100644 index 7ba6650d7..000000000 --- a/__tests__/commands/versions/index.test.ts +++ /dev/null @@ -1,65 +0,0 @@ -import type { Version } from '../../../src/commands/versions/index.js'; - -import nock from 'nock'; -import { describe, beforeAll, afterEach, it, expect } from 'vitest'; - -import Command from '../../../src/commands/versions/index.js'; -import { getAPIv1Mock } from '../../helpers/get-api-mock.js'; -import { runCommandAndReturnResult } from '../../helpers/oclif.js'; - -const key = 'API_KEY'; -const version = '1.0.0'; -const version2 = '2.0.0'; - -const versionPayload: Version = { - createdAt: '2019-06-17T22:39:56.462Z', - is_deprecated: false, - is_hidden: false, - is_beta: false, - is_stable: true, - codename: '', - version, -}; - -const version2Payload: Version = { - createdAt: '2019-06-17T22:39:56.462Z', - is_deprecated: false, - is_hidden: false, - is_beta: false, - is_stable: true, - codename: '', - version: version2, -}; - -describe('rdme versions', () => { - let run: (args?: string[]) => Promise; - - beforeAll(() => { - nock.disableNetConnect(); - run = runCommandAndReturnResult(Command); - }); - - afterEach(() => nock.cleanAll()); - - it('should make a request to get a list of existing versions', async () => { - const mockRequest = getAPIv1Mock() - .get('/api/v1/version') - .basicAuth({ user: key }) - .reply(200, [versionPayload, version2Payload]); - - const output = await run(['--key', key]); - expect(output).toStrictEqual(JSON.stringify([versionPayload, version2Payload], null, 2)); - mockRequest.done(); - }); - - it('should get a specific version object if version flag provided', async () => { - const mockRequest = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, versionPayload); - - const output = await run(['--key', key, '--version', version]); - expect(output).toStrictEqual(JSON.stringify(versionPayload, null, 2)); - mockRequest.done(); - }); -}); diff --git a/__tests__/commands/versions/update.test.ts b/__tests__/commands/versions/update.test.ts deleted file mode 100644 index 66734d9ab..000000000 --- a/__tests__/commands/versions/update.test.ts +++ /dev/null @@ -1,388 +0,0 @@ -import nock from 'nock'; -import prompts from 'prompts'; -import { describe, beforeAll, afterEach, it, expect } from 'vitest'; - -import Command from '../../../src/commands/versions/update.js'; -import { APIv1Error } from '../../../src/lib/apiError.js'; -import { getAPIv1Mock } from '../../helpers/get-api-mock.js'; -import { runCommandAndReturnResult } from '../../helpers/oclif.js'; - -const key = 'API_KEY'; -const version = '1.0.0'; - -describe('rdme versions update', () => { - let run: (args?: string[]) => Promise; - - beforeAll(() => { - nock.disableNetConnect(); - run = runCommandAndReturnResult(Command); - }); - - afterEach(() => nock.cleanAll()); - - it('should update a specific version object using prompts', async () => { - const versionToChange = '1.1.0'; - prompts.inject([versionToChange, undefined, false, true, false, false]); - - const updatedVersionObject = { - version: versionToChange, - is_stable: false, - is_beta: true, - is_deprecated: false, - is_hidden: false, - }; - - const mockRequest = getAPIv1Mock() - .get('/api/v1/version') - .basicAuth({ user: key }) - .reply(200, [{ version }, { version: versionToChange }]) - .get(`/api/v1/version/${versionToChange}`) - .basicAuth({ user: key }) - .reply(200, { version: versionToChange }) - .put(`/api/v1/version/${versionToChange}`, updatedVersionObject) - .basicAuth({ user: key }) - .reply(201, updatedVersionObject); - - await expect(run(['--key', key])).resolves.toBe(`Version ${versionToChange} updated successfully.`); - mockRequest.done(); - }); - - it('should rename a specific version object using prompts', async () => { - const versionToChange = '1.1.0'; - const renamedVersion = '1.1.0-update'; - prompts.inject([versionToChange, renamedVersion, false, true, false, false]); - - const updatedVersionObject = { - version: renamedVersion, - is_stable: false, - is_beta: true, - is_deprecated: false, - is_hidden: false, - }; - - const mockRequest = getAPIv1Mock() - .get('/api/v1/version') - .basicAuth({ user: key }) - .reply(200, [{ version }, { version: versionToChange }]) - .get(`/api/v1/version/${versionToChange}`) - .basicAuth({ user: key }) - .reply(200, { version: versionToChange }) - .put(`/api/v1/version/${versionToChange}`, updatedVersionObject) - .basicAuth({ user: key }) - .reply(201, updatedVersionObject); - - await expect(run(['--key', key])).resolves.toBe(`Version ${versionToChange} updated successfully.`); - mockRequest.done(); - }); - - it('should use subset of prompts when updating stable version', async () => { - const versionToChange = '1.1.0'; - prompts.inject([versionToChange, undefined, true]); - - const updatedVersionObject = { - version: versionToChange, - is_beta: true, - }; - - const mockRequest = getAPIv1Mock() - .get('/api/v1/version') - .basicAuth({ user: key }) - .reply(200, [{ version }, { version: versionToChange, is_stable: true }]) - .get(`/api/v1/version/${versionToChange}`) - .basicAuth({ user: key }) - .reply(200, { version: versionToChange, is_stable: true }) - .put(`/api/v1/version/${versionToChange}`, updatedVersionObject) - .basicAuth({ user: key }) - .reply(201, updatedVersionObject); - - await expect(run(['--key', key])).resolves.toBe(`Version ${versionToChange} updated successfully.`); - mockRequest.done(); - }); - - it('should update a specific version object using flags', async () => { - const versionToChange = '1.1.0'; - const renamedVersion = '1.1.0-update'; - - const updatedVersionObject = { - codename: 'updated-test', - version: renamedVersion, - is_beta: true, - is_deprecated: true, - is_hidden: false, - is_stable: false, - }; - - const mockRequest = getAPIv1Mock() - .get(`/api/v1/version/${versionToChange}`) - .basicAuth({ user: key }) - .reply(200, { version: versionToChange }) - .get(`/api/v1/version/${versionToChange}`) - .basicAuth({ user: key }) - .reply(200, { version: versionToChange }) - .put(`/api/v1/version/${versionToChange}`, updatedVersionObject) - .basicAuth({ user: key }) - .reply(201, updatedVersionObject); - - await expect( - run([ - '--key', - key, - versionToChange, - '--newVersion', - renamedVersion, - '--deprecated', - 'true', - '--beta', - 'true', - '--main', - 'false', - '--codename', - 'updated-test', - '--hidden', - 'false', - ]), - ).resolves.toBe(`Version ${versionToChange} updated successfully.`); - mockRequest.done(); - }); - - it("should update a specific version object using flags that contain the string 'false'", async () => { - const versionToChange = '1.1.0'; - const renamedVersion = '1.1.0-update'; - - const updatedVersionObject = { - codename: 'updated-test', - version: renamedVersion, - is_beta: false, - is_deprecated: false, - is_hidden: true, - is_stable: false, - }; - - const mockRequest = getAPIv1Mock() - .get(`/api/v1/version/${versionToChange}`) - .basicAuth({ user: key }) - .reply(200, { version: versionToChange }) - .get(`/api/v1/version/${versionToChange}`) - .basicAuth({ user: key }) - .reply(200, { version: versionToChange }) - .put(`/api/v1/version/${versionToChange}`, updatedVersionObject) - .basicAuth({ user: key }) - .reply(201, updatedVersionObject); - - await expect( - run([ - '--key', - key, - versionToChange, - '--newVersion', - renamedVersion, - '--beta', - 'false', - '--deprecated', - 'false', - '--main', - 'false', - '--codename', - 'updated-test', - '--hidden', - 'true', - ]), - ).resolves.toBe(`Version ${versionToChange} updated successfully.`); - mockRequest.done(); - }); - - it("should update a specific version object using flags that contain the string 'false' and a prompt", async () => { - const versionToChange = '1.1.0'; - const renamedVersion = '1.1.0-update'; - // prompt for beta flag - prompts.inject([false]); - - const updatedVersionObject = { - codename: 'updated-test', - version: renamedVersion, - is_beta: false, - is_hidden: false, - is_stable: false, - }; - - const mockRequest = getAPIv1Mock() - .get(`/api/v1/version/${versionToChange}`) - .basicAuth({ user: key }) - .reply(200, { version: versionToChange }) - .get(`/api/v1/version/${versionToChange}`) - .basicAuth({ user: key }) - .reply(200, { version: versionToChange }) - .put(`/api/v1/version/${versionToChange}`, updatedVersionObject) - .basicAuth({ user: key }) - .reply(201, updatedVersionObject); - - await expect( - run([ - '--key', - key, - versionToChange, - '--newVersion', - renamedVersion, - '--main', - 'false', - '--codename', - 'updated-test', - '--hidden', - 'false', - ]), - ).resolves.toBe(`Version ${versionToChange} updated successfully.`); - mockRequest.done(); - }); - - it('should update a specific version object even if user bypasses prompt for new version name', async () => { - const versionToChange = '1.1.0'; - // simulating user entering nothing for the prompt to enter a new version name - prompts.inject(['']); - - const updatedVersionObject = { - codename: 'updated-test', - is_beta: false, - is_hidden: false, - is_stable: false, - version: versionToChange, - }; - - const mockRequest = getAPIv1Mock() - .get(`/api/v1/version/${versionToChange}`) - .basicAuth({ user: key }) - .reply(200, { version: versionToChange }) - .get(`/api/v1/version/${versionToChange}`) - .basicAuth({ user: key }) - .reply(200, { version: versionToChange }) - .put(`/api/v1/version/${versionToChange}`, updatedVersionObject) - .basicAuth({ user: key }) - .reply(201, updatedVersionObject); - - await expect( - run([ - '--key', - key, - versionToChange, - '--beta', - 'false', - '--main', - 'false', - '--codename', - 'updated-test', - '--hidden', - 'false', - ]), - ).resolves.toBe(`Version ${versionToChange} updated successfully.`); - mockRequest.done(); - }); - - it('should update a version to be the main one', async () => { - const versionToChange = '1.1.0'; - const renamedVersion = '1.1.0-update'; - - const updatedVersionObject = { - version: renamedVersion, - is_beta: false, - is_stable: true, - }; - - const mockRequest = getAPIv1Mock() - .get(`/api/v1/version/${versionToChange}`) - .basicAuth({ user: key }) - .reply(200, { version: versionToChange }) - .get(`/api/v1/version/${versionToChange}`) - .basicAuth({ user: key }) - .reply(200, { version: versionToChange }) - .put(`/api/v1/version/${versionToChange}`, updatedVersionObject) - .basicAuth({ user: key }) - .reply(201, updatedVersionObject); - - await expect( - run([ - '--key', - key, - versionToChange, - '--newVersion', - renamedVersion, - '--deprecated', - 'true', - '--beta', - 'false', - '--main', - 'true', - '--hidden', - 'true', - ]), - ).resolves.toBe(`Version ${versionToChange} updated successfully.`); - mockRequest.done(); - }); - - it('should catch any put request errors', async () => { - const renamedVersion = '1.0.0-update'; - - const updatedVersionObject = { - version: renamedVersion, - is_beta: true, - is_deprecated: true, - is_hidden: false, - is_stable: false, - }; - - prompts.inject([renamedVersion, false, true, false, true]); - - const errorResponse = { - error: 'VERSION_DUPLICATE', - message: 'The version already exists.', - suggestion: '...a suggestion to resolve the issue...', - help: 'If you need help, email support@readme.io and mention log "fake-metrics-uuid".', - }; - - const mockRequest = getAPIv1Mock() - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }) - .get(`/api/v1/version/${version}`) - .basicAuth({ user: key }) - .reply(200, { version }) - .put(`/api/v1/version/${version}`, updatedVersionObject) - .basicAuth({ user: key }) - .reply(400, errorResponse); - - await expect(run(['--key', key, version])).rejects.toStrictEqual(new APIv1Error(errorResponse)); - mockRequest.done(); - }); - - describe('bad flag values', () => { - it('should throw if non-boolean `beta` flag is passed', () => { - const versionToChange = '1.1.0'; - - return expect(run(['--key', key, versionToChange, '--beta', 'hi'])).rejects.toThrow( - 'Expected --beta=hi to be one of: true, false', - ); - }); - - it('should throw if non-boolean `deprecated` flag is passed', () => { - const versionToChange = '1.1.0'; - - return expect(run(['--key', key, versionToChange, '--deprecated', 'hi'])).rejects.toThrow( - 'Expected --deprecated=hi to be one of: true, false', - ); - }); - - it('should throw if non-boolean `hidden` flag is passed', () => { - const versionToChange = '1.1.0'; - - return expect(run(['--key', key, versionToChange, '--hidden', 'hi'])).rejects.toThrow( - 'Expected --hidden=hi to be one of: true, false', - ); - }); - - it('should throw if non-boolean `main` flag is passed', () => { - const versionToChange = '1.1.0'; - - return expect(run(['--key', key, versionToChange, '--main', 'hi'])).rejects.toThrow( - 'Expected --main=hi to be one of: true, false', - ); - }); - }); -}); diff --git a/__tests__/lib/__snapshots__/createGHA.test.ts.snap b/__tests__/lib/__snapshots__/createGHA.test.ts.snap index fce4a5120..79d9e2e84 100644 --- a/__tests__/lib/__snapshots__/createGHA.test.ts.snap +++ b/__tests__/lib/__snapshots__/createGHA.test.ts.snap @@ -164,334 +164,6 @@ jobs: " `; -exports[`#createGHA > command inputs > 'custompages' ' (single)' > should run GHA creation workflow and generate valid workflow file 1`] = ` -" -Your GitHub Actions workflow file has been created! āœØ - -Almost done! Just a couple more steps: -1. Push your newly created file (.github/workflows/rdme-custompages.yml) to GitHub šŸš€ -2. Create a GitHub secret called README_API_KEY and populate the value with your ReadMe API key (ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢I_KEY) šŸ”‘ - -šŸ” Check out GitHub's docs for more info on creating encrypted secrets (https://docs.github.com/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) - -šŸ¦‰ If you have any more questions, feel free to drop us a line! support@readme.io -" -`; - -exports[`#createGHA > command inputs > 'custompages' ' (single)' > should run GHA creation workflow and generate valid workflow file 2`] = ` -"# This GitHub Actions workflow was auto-generated by the \`rdme\` cli on 2022-01-01T00:00:00.000Z -# You can view our full documentation here: https://docs.readme.com/docs/rdme -name: ReadMe GitHub Action šŸ¦‰ - -on: - push: - branches: - # This workflow will run every time you push code to the following branch: \`some-branch\` - # Check out GitHub's docs for more info on configuring this: - # https://docs.github.com/actions/using-workflows/events-that-trigger-workflows - - some-branch - -jobs: - rdme-custompages: - runs-on: ubuntu-latest - steps: - - name: Check out repo šŸ“š - uses: actions/checkout@v4 - - - name: Run \`custompages\` command šŸš€ - uses: readmeio/rdme@v7 - with: - rdme: custompages ./custompages/rdme.md --key=\${{ secrets.README_API_KEY }} -" -`; - -exports[`#createGHA > command inputs > 'custompages' ' (single)' > should run GHA creation workflow with \`--github\` flag and messy file name and generate valid workflow file 1`] = ` -" -Your GitHub Actions workflow file has been created! āœØ - -Almost done! Just a couple more steps: -1. Push your newly created file (.github/workflows/rdme-custompages-with-github-flag.yml) to GitHub šŸš€ -2. Create a GitHub secret called README_API_KEY and populate the value with your ReadMe API key (ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢I_KEY) šŸ”‘ - -šŸ” Check out GitHub's docs for more info on creating encrypted secrets (https://docs.github.com/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) - -šŸ¦‰ If you have any more questions, feel free to drop us a line! support@readme.io -" -`; - -exports[`#createGHA > command inputs > 'custompages' ' (single)' > should run GHA creation workflow with \`--github\` flag and messy file name and generate valid workflow file 2`] = ` -"# This GitHub Actions workflow was auto-generated by the \`rdme\` cli on 2022-01-01T00:00:00.000Z -# You can view our full documentation here: https://docs.readme.com/docs/rdme -name: ReadMe GitHub Action šŸ¦‰ - -on: - push: - branches: - # This workflow will run every time you push code to the following branch: \`another-branch\` - # Check out GitHub's docs for more info on configuring this: - # https://docs.github.com/actions/using-workflows/events-that-trigger-workflows - - another-branch - -jobs: - rdme-custompages: - runs-on: ubuntu-latest - steps: - - name: Check out repo šŸ“š - uses: actions/checkout@v4 - - - name: Run \`custompages\` command šŸš€ - uses: readmeio/rdme@v7 - with: - rdme: custompages ./custompages/rdme.md --key=\${{ secrets.README_API_KEY }} -" -`; - -exports[`#createGHA > command inputs > 'custompages' '' > should run GHA creation workflow and generate valid workflow file 1`] = ` -" -Your GitHub Actions workflow file has been created! āœØ - -Almost done! Just a couple more steps: -1. Push your newly created file (.github/workflows/rdme-custompages.yml) to GitHub šŸš€ -2. Create a GitHub secret called README_API_KEY and populate the value with your ReadMe API key (ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢I_KEY) šŸ”‘ - -šŸ” Check out GitHub's docs for more info on creating encrypted secrets (https://docs.github.com/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) - -šŸ¦‰ If you have any more questions, feel free to drop us a line! support@readme.io -" -`; - -exports[`#createGHA > command inputs > 'custompages' '' > should run GHA creation workflow and generate valid workflow file 2`] = ` -"# This GitHub Actions workflow was auto-generated by the \`rdme\` cli on 2022-01-01T00:00:00.000Z -# You can view our full documentation here: https://docs.readme.com/docs/rdme -name: ReadMe GitHub Action šŸ¦‰ - -on: - push: - branches: - # This workflow will run every time you push code to the following branch: \`some-branch\` - # Check out GitHub's docs for more info on configuring this: - # https://docs.github.com/actions/using-workflows/events-that-trigger-workflows - - some-branch - -jobs: - rdme-custompages: - runs-on: ubuntu-latest - steps: - - name: Check out repo šŸ“š - uses: actions/checkout@v4 - - - name: Run \`custompages\` command šŸš€ - uses: readmeio/rdme@v7 - with: - rdme: custompages ./custompages --key=\${{ secrets.README_API_KEY }} -" -`; - -exports[`#createGHA > command inputs > 'custompages' '' > should run GHA creation workflow with \`--github\` flag and messy file name and generate valid workflow file 1`] = ` -" -Your GitHub Actions workflow file has been created! āœØ - -Almost done! Just a couple more steps: -1. Push your newly created file (.github/workflows/rdme-custompages-with-github-flag.yml) to GitHub šŸš€ -2. Create a GitHub secret called README_API_KEY and populate the value with your ReadMe API key (ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢I_KEY) šŸ”‘ - -šŸ” Check out GitHub's docs for more info on creating encrypted secrets (https://docs.github.com/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) - -šŸ¦‰ If you have any more questions, feel free to drop us a line! support@readme.io -" -`; - -exports[`#createGHA > command inputs > 'custompages' '' > should run GHA creation workflow with \`--github\` flag and messy file name and generate valid workflow file 2`] = ` -"# This GitHub Actions workflow was auto-generated by the \`rdme\` cli on 2022-01-01T00:00:00.000Z -# You can view our full documentation here: https://docs.readme.com/docs/rdme -name: ReadMe GitHub Action šŸ¦‰ - -on: - push: - branches: - # This workflow will run every time you push code to the following branch: \`another-branch\` - # Check out GitHub's docs for more info on configuring this: - # https://docs.github.com/actions/using-workflows/events-that-trigger-workflows - - another-branch - -jobs: - rdme-custompages: - runs-on: ubuntu-latest - steps: - - name: Check out repo šŸ“š - uses: actions/checkout@v4 - - - name: Run \`custompages\` command šŸš€ - uses: readmeio/rdme@v7 - with: - rdme: custompages ./custompages --key=\${{ secrets.README_API_KEY }} -" -`; - -exports[`#createGHA > command inputs > 'docs' ' (single)' > should run GHA creation workflow and generate valid workflow file 1`] = ` -" -Your GitHub Actions workflow file has been created! āœØ - -Almost done! Just a couple more steps: -1. Push your newly created file (.github/workflows/rdme-docs.yml) to GitHub šŸš€ -2. Create a GitHub secret called README_API_KEY and populate the value with your ReadMe API key (ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢I_KEY) šŸ”‘ - -šŸ” Check out GitHub's docs for more info on creating encrypted secrets (https://docs.github.com/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) - -šŸ¦‰ If you have any more questions, feel free to drop us a line! support@readme.io -" -`; - -exports[`#createGHA > command inputs > 'docs' ' (single)' > should run GHA creation workflow and generate valid workflow file 2`] = ` -"# This GitHub Actions workflow was auto-generated by the \`rdme\` cli on 2022-01-01T00:00:00.000Z -# You can view our full documentation here: https://docs.readme.com/docs/rdme -name: ReadMe GitHub Action šŸ¦‰ - -on: - push: - branches: - # This workflow will run every time you push code to the following branch: \`some-branch\` - # Check out GitHub's docs for more info on configuring this: - # https://docs.github.com/actions/using-workflows/events-that-trigger-workflows - - some-branch - -jobs: - rdme-docs: - runs-on: ubuntu-latest - steps: - - name: Check out repo šŸ“š - uses: actions/checkout@v4 - - - name: Run \`docs\` command šŸš€ - uses: readmeio/rdme@v7 - with: - rdme: docs ./docs/rdme.md --key=\${{ secrets.README_API_KEY }} --version=1.0.0 -" -`; - -exports[`#createGHA > command inputs > 'docs' ' (single)' > should run GHA creation workflow with \`--github\` flag and messy file name and generate valid workflow file 1`] = ` -" -Your GitHub Actions workflow file has been created! āœØ - -Almost done! Just a couple more steps: -1. Push your newly created file (.github/workflows/rdme-docs-with-github-flag.yml) to GitHub šŸš€ -2. Create a GitHub secret called README_API_KEY and populate the value with your ReadMe API key (ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢I_KEY) šŸ”‘ - -šŸ” Check out GitHub's docs for more info on creating encrypted secrets (https://docs.github.com/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) - -šŸ¦‰ If you have any more questions, feel free to drop us a line! support@readme.io -" -`; - -exports[`#createGHA > command inputs > 'docs' ' (single)' > should run GHA creation workflow with \`--github\` flag and messy file name and generate valid workflow file 2`] = ` -"# This GitHub Actions workflow was auto-generated by the \`rdme\` cli on 2022-01-01T00:00:00.000Z -# You can view our full documentation here: https://docs.readme.com/docs/rdme -name: ReadMe GitHub Action šŸ¦‰ - -on: - push: - branches: - # This workflow will run every time you push code to the following branch: \`another-branch\` - # Check out GitHub's docs for more info on configuring this: - # https://docs.github.com/actions/using-workflows/events-that-trigger-workflows - - another-branch - -jobs: - rdme-docs: - runs-on: ubuntu-latest - steps: - - name: Check out repo šŸ“š - uses: actions/checkout@v4 - - - name: Run \`docs\` command šŸš€ - uses: readmeio/rdme@v7 - with: - rdme: docs ./docs/rdme.md --key=\${{ secrets.README_API_KEY }} --version=1.0.0 -" -`; - -exports[`#createGHA > command inputs > 'docs' '' > should run GHA creation workflow and generate valid workflow file 1`] = ` -" -Your GitHub Actions workflow file has been created! āœØ - -Almost done! Just a couple more steps: -1. Push your newly created file (.github/workflows/rdme-docs.yml) to GitHub šŸš€ -2. Create a GitHub secret called README_API_KEY and populate the value with your ReadMe API key (ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢I_KEY) šŸ”‘ - -šŸ” Check out GitHub's docs for more info on creating encrypted secrets (https://docs.github.com/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) - -šŸ¦‰ If you have any more questions, feel free to drop us a line! support@readme.io -" -`; - -exports[`#createGHA > command inputs > 'docs' '' > should run GHA creation workflow and generate valid workflow file 2`] = ` -"# This GitHub Actions workflow was auto-generated by the \`rdme\` cli on 2022-01-01T00:00:00.000Z -# You can view our full documentation here: https://docs.readme.com/docs/rdme -name: ReadMe GitHub Action šŸ¦‰ - -on: - push: - branches: - # This workflow will run every time you push code to the following branch: \`some-branch\` - # Check out GitHub's docs for more info on configuring this: - # https://docs.github.com/actions/using-workflows/events-that-trigger-workflows - - some-branch - -jobs: - rdme-docs: - runs-on: ubuntu-latest - steps: - - name: Check out repo šŸ“š - uses: actions/checkout@v4 - - - name: Run \`docs\` command šŸš€ - uses: readmeio/rdme@v7 - with: - rdme: docs ./docs --key=\${{ secrets.README_API_KEY }} --version=1.0.0 -" -`; - -exports[`#createGHA > command inputs > 'docs' '' > should run GHA creation workflow with \`--github\` flag and messy file name and generate valid workflow file 1`] = ` -" -Your GitHub Actions workflow file has been created! āœØ - -Almost done! Just a couple more steps: -1. Push your newly created file (.github/workflows/rdme-docs-with-github-flag.yml) to GitHub šŸš€ -2. Create a GitHub secret called README_API_KEY and populate the value with your ReadMe API key (ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢ā€¢I_KEY) šŸ”‘ - -šŸ” Check out GitHub's docs for more info on creating encrypted secrets (https://docs.github.com/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) - -šŸ¦‰ If you have any more questions, feel free to drop us a line! support@readme.io -" -`; - -exports[`#createGHA > command inputs > 'docs' '' > should run GHA creation workflow with \`--github\` flag and messy file name and generate valid workflow file 2`] = ` -"# This GitHub Actions workflow was auto-generated by the \`rdme\` cli on 2022-01-01T00:00:00.000Z -# You can view our full documentation here: https://docs.readme.com/docs/rdme -name: ReadMe GitHub Action šŸ¦‰ - -on: - push: - branches: - # This workflow will run every time you push code to the following branch: \`another-branch\` - # Check out GitHub's docs for more info on configuring this: - # https://docs.github.com/actions/using-workflows/events-that-trigger-workflows - - another-branch - -jobs: - rdme-docs: - runs-on: ubuntu-latest - steps: - - name: Check out repo šŸ“š - uses: actions/checkout@v4 - - - name: Run \`docs\` command šŸš€ - uses: readmeio/rdme@v7 - with: - rdme: docs ./docs --key=\${{ secrets.README_API_KEY }} --version=1.0.0 -" -`; - exports[`#createGHA > command inputs > 'openapi' '' > should run GHA creation workflow and generate valid workflow file 1`] = ` " Your GitHub Actions workflow file has been created! āœØ diff --git a/__tests__/lib/createGHA.test.ts b/__tests__/lib/createGHA.test.ts index 943bb90f9..99f14053a 100644 --- a/__tests__/lib/createGHA.test.ts +++ b/__tests__/lib/createGHA.test.ts @@ -59,13 +59,6 @@ describe('#createGHA', () => { // hence we're using this command ID here { cmd: 'openapi:validate', opts: { spec: 'petstore.json' }, label: '' }, { cmd: 'openapi', opts: { key, spec: 'petstore.json', id: 'spec_id' }, label: '' }, - { cmd: 'docs', opts: { key, path: './docs', version: '1.0.0' }, label: '' }, - { - cmd: 'docs', - - label: ' (single)', - opts: { key, path: './docs/rdme.md', version: '1.0.0' }, - }, { cmd: 'changelogs', opts: { key, path: './changelogs' }, label: '' }, { cmd: 'changelogs', @@ -73,12 +66,6 @@ describe('#createGHA', () => { label: ' (single)', opts: { key, path: './changelogs/rdme.md' }, }, - { cmd: 'custompages', opts: { key, path: './custompages' }, label: '' }, - { - cmd: 'custompages', - label: ' (single)', - opts: { key, path: './custompages/rdme.md' }, - }, ])('$cmd $label', ({ cmd, opts }) => { let CurrentCommand: Command.Class; diff --git a/__tests__/lib/prompts.test.ts b/__tests__/lib/prompts.test.ts index d1dba0a90..94b8287a6 100644 --- a/__tests__/lib/prompts.test.ts +++ b/__tests__/lib/prompts.test.ts @@ -4,17 +4,6 @@ import { describe, it, expect } from 'vitest'; import * as promptHandler from '../../src/lib/prompts.js'; import promptTerminal from '../../src/lib/promptWrapper.js'; -const versionlist = [ - { - version: '1', - is_stable: true, - }, - { - version: '2', - is_stable: false, - }, -]; - const specList = [ { _id: 'spec1', @@ -78,26 +67,4 @@ describe('prompt test bed', () => { expect(answer).toStrictEqual({ option: 'spec1' }); }); }); - - describe('versionPrompt()', () => { - it('should allow user to choose a fork if flag is not passed (creating version)', async () => { - prompts.inject(['1', true, true]); - - const answer = await promptTerminal(promptHandler.versionPrompt(versionlist)); - expect(answer).toStrictEqual({ from: '1', is_stable: true, is_beta: true }); - }); - - it('should skip fork prompt if value passed (updating version)', async () => { - prompts.inject(['1.2.1', false, true, true, false]); - - const answer = await promptTerminal(promptHandler.versionPrompt(versionlist, { is_stable: false })); - expect(answer).toStrictEqual({ - newVersion: '1.2.1', - is_stable: false, - is_beta: true, - is_hidden: true, - is_deprecated: false, - }); - }); - }); }); diff --git a/documentation/commands/categories.md b/documentation/commands/categories.md deleted file mode 100644 index 237c23592..000000000 --- a/documentation/commands/categories.md +++ /dev/null @@ -1,92 +0,0 @@ -`rdme categories` -================= - -List or create categories in your ReadMe developer hub. - -* [`rdme categories`](#rdme-categories) -* [`rdme categories create TITLE`](#rdme-categories-create-title) - -## `rdme categories` - -Get all categories in your ReadMe project. - -``` -USAGE - $ rdme categories --key [--version ] - -FLAGS - --key= (required) An API key for your ReadMe project. Note that API authentication is required despite - being omitted from the example usage. See our docs for more information: - https://github.com/readmeio/rdme/tree/v9#authentication - --version= ReadMe project version - -DESCRIPTION - Get all categories in your ReadMe project. - -EXAMPLES - Get all categories associated to your project version: - - $ rdme categories --version={project-version} - -FLAG DESCRIPTIONS - --key= - - An API key for your ReadMe project. Note that API authentication is required despite being omitted from the example - usage. See our docs for more information: https://github.com/readmeio/rdme/tree/v9#authentication - - ReadMe project API key - - --version= ReadMe project version - - If running command in a CI environment and this option is not passed, the main project version will be used. See our - docs for more information: https://docs.readme.com/main/docs/versions -``` - -## `rdme categories create TITLE` - -Create a category with the specified title and guide in your ReadMe project. - -``` -USAGE - $ rdme categories create TITLE --categoryType guide|reference --key [--preventDuplicates] [--version ] - -ARGUMENTS - TITLE Title of the category - -FLAGS - --categoryType=