diff --git a/packages/docusaurus-plugin-content-showcase/src/__tests__/__fixtures__/tags.yml b/packages/docusaurus-plugin-content-showcase/src/__tests__/__fixtures__/tags.yml new file mode 100644 index 0000000000..8b22ab180c --- /dev/null +++ b/packages/docusaurus-plugin-content-showcase/src/__tests__/__fixtures__/tags.yml @@ -0,0 +1,12 @@ +favorite: + label: "Favorite" + description: + message: "Our favorite Docusaurus sites that you must absolutely check out!" + id: "showcase.tag.favorite.description" + color: "#e9669e" +opensource: + label: "Open-Source" + description: + message: "Open-Source Docusaurus sites can be useful for inspiration!" + id: "showcase.tag.opensource.description" + color: "#39ca30" diff --git a/packages/docusaurus-plugin-content-showcase/src/__tests__/tags.test.ts b/packages/docusaurus-plugin-content-showcase/src/__tests__/tags.test.ts new file mode 100644 index 0000000000..1f9fa3b3aa --- /dev/null +++ b/packages/docusaurus-plugin-content-showcase/src/__tests__/tags.test.ts @@ -0,0 +1,55 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {getTagsList} from '../tags'; + +const tags = { + favorite: { + label: 'Favorite', + description: { + message: + 'Our favorite Docusaurus sites that you must absolutely check out!', + id: 'showcase.tag.favorite.description', + }, + color: '#e9669e', + }, + opensource: { + label: 'Open-Source', + description: { + message: 'Open-Source Docusaurus sites can be useful for inspiration!', + id: 'showcase.tag.opensource.description', + }, + // todo throw an error with `getTagsList tagSchema` + color: '#39c', + }, +}; + +describe('showcase tags', () => { + it('get tag list', async () => { + const tagList = await getTagsList({ + configTags: tags, + configPath: '', + }); + expect(tagList).toEqual(Object.keys(tags)); + }); + + it('get tag list from file', async () => { + const tagList = await getTagsList({ + configTags: './__fixtures__/tags.yml', + configPath: __dirname, + }); + expect(tagList).toEqual(Object.keys(tags)); + }); + + it('error get tag list', async () => { + const tagList = await getTagsList({ + configTags: tags, + configPath: '', + }); + expect(tagList).toEqual(Object.keys(tags)); + }); +}); diff --git a/packages/docusaurus-plugin-content-showcase/src/__tests__/validation.test.ts b/packages/docusaurus-plugin-content-showcase/src/__tests__/validation.test.ts index cf93a2c565..65bf07950e 100644 --- a/packages/docusaurus-plugin-content-showcase/src/__tests__/validation.test.ts +++ b/packages/docusaurus-plugin-content-showcase/src/__tests__/validation.test.ts @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. */ +import {fromPartial} from '@total-typescript/shoehorn'; import {createShowcaseItemSchema, validateShowcaseItem} from '../validation'; import {getTagsList} from '../tags'; import type {ShowcaseItem} from '@docusaurus/plugin-content-showcase'; @@ -68,7 +69,7 @@ describe('showcase item schema', () => { ); }); it('reject invalid item', async () => { - const item = {}; + const item: ShowcaseItem = fromPartial({}); const showcaseItemSchema = await prepareSchema(); expect(() => validateShowcaseItem({item, showcaseItemSchema}), @@ -77,7 +78,8 @@ describe('showcase item schema', () => { ); }); it('reject invalid item value', async () => { - const item = {title: 42}; + // @ts-expect-error: title should be a string + const item: ShowcaseItem = fromPartial({title: 42}); const showcaseItemSchema = await prepareSchema(); expect(() => diff --git a/packages/docusaurus-plugin-content-showcase/src/options.ts b/packages/docusaurus-plugin-content-showcase/src/options.ts index 5c60814b74..f7c08f71b7 100644 --- a/packages/docusaurus-plugin-content-showcase/src/options.ts +++ b/packages/docusaurus-plugin-content-showcase/src/options.ts @@ -28,6 +28,7 @@ const PluginOptionSchema = Joi.object({ exclude: Joi.array().items(Joi.string()).default(DEFAULT_OPTIONS.exclude), id: Joi.string().default(DEFAULT_OPTIONS.id), tags: Joi.alternatives() + // todo ozaki understand this .try(Joi.string().default(DEFAULT_OPTIONS.tags), tagSchema) .default(DEFAULT_OPTIONS.tags), }); diff --git a/packages/docusaurus-plugin-content-showcase/src/tags.ts b/packages/docusaurus-plugin-content-showcase/src/tags.ts index 97bf80f50e..db8925e883 100644 --- a/packages/docusaurus-plugin-content-showcase/src/tags.ts +++ b/packages/docusaurus-plugin-content-showcase/src/tags.ts @@ -20,9 +20,12 @@ export const tagSchema = Joi.object().pattern( id: Joi.string().required(), }).required(), color: Joi.string() - // todo doesn't seems to work ??? - .regex(/^#[\dA-Fa-f]{6}$/) - .required(), + .pattern(/^#[\dA-Fa-f]{6}$/) + .required() + .messages({ + 'string.pattern.base': + 'Color must be a hexadecimal color string (e.g., #RRGGBB #rrggbb)', + }), }), ); @@ -34,7 +37,8 @@ export async function getTagsList({ configPath: string; }): Promise { if (typeof configTags === 'object') { - return Object.keys(configTags); + const tags = tagSchema.validate(configTags); + return Object.keys(tags.value); } const tagsPath = path.resolve(configPath, configTags); @@ -47,7 +51,7 @@ export async function getTagsList({ if (tags.error) { throw new Error( `There was an error extracting tags: ${tags.error.message}`, - {cause: tags.error}, + {cause: tags}, ); }