feat(v2): add themeConfig validation to algolia theme (#3133)

* Algolia theme option validation

* validateThemeConfig

* remove useless runtime check
This commit is contained in:
Sébastien Lorber 2020-07-27 18:12:56 +02:00 committed by GitHub
parent 2159c4fcfb
commit a1db6f7d75
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 134 additions and 13 deletions

View file

@ -9,6 +9,7 @@
"license": "MIT",
"dependencies": {
"@docsearch/react": "^1.0.0-alpha.24",
"@hapi/joi": "^17.1.1",
"algoliasearch": "^4.0.0",
"algoliasearch-helper": "^3.1.1",
"clsx": "^1.1.1",

View file

@ -0,0 +1,91 @@
/**
* 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.
*/
const {validateThemeConfig, DEFAULT_CONFIG} = require('../validateThemeConfig');
function testValidateThemeConfig(themeConfig) {
function validate(schema, cfg) {
const {value, error} = schema.validate(cfg, {
convert: false,
});
if (error) {
throw error;
}
return value;
}
return validateThemeConfig({themeConfig, validate});
}
describe('validateThemeConfig', () => {
test('minimal config', () => {
const algolia = {
indexName: 'index',
apiKey: 'apiKey',
};
expect(testValidateThemeConfig({algolia})).toEqual({
algolia: {
...DEFAULT_CONFIG,
...algolia,
},
});
});
test('unknown attributes', () => {
const algolia = {
indexName: 'index',
apiKey: 'apiKey',
unknownKey: 'unknownKey',
};
expect(testValidateThemeConfig({algolia})).toEqual({
algolia: {
...DEFAULT_CONFIG,
...algolia,
},
});
});
test('undefined config', () => {
const algolia = undefined;
expect(() =>
testValidateThemeConfig({algolia}),
).toThrowErrorMatchingInlineSnapshot(
`"\\"themeConfig.algolia\\" is required"`,
);
});
test('undefined config 2', () => {
expect(() =>
testValidateThemeConfig({}),
).toThrowErrorMatchingInlineSnapshot(
`"\\"themeConfig.algolia\\" is required"`,
);
});
test('empty config', () => {
const algolia = {};
expect(() =>
testValidateThemeConfig({algolia}),
).toThrowErrorMatchingInlineSnapshot(`"\\"algolia.apiKey\\" is required"`);
});
test('missing indexName config', () => {
const algolia = {apiKey: 'apiKey'};
expect(() =>
testValidateThemeConfig({algolia}),
).toThrowErrorMatchingInlineSnapshot(
`"\\"algolia.indexName\\" is required"`,
);
});
test('missing apiKey config', () => {
const algolia = {indexName: 'indexName'};
expect(() =>
testValidateThemeConfig({algolia}),
).toThrowErrorMatchingInlineSnapshot(`"\\"algolia.apiKey\\" is required"`);
});
});

View file

@ -10,10 +10,11 @@ const fs = require('fs');
const eta = require('eta');
const {normalizeUrl} = require('@docusaurus/utils');
const openSearchTemplate = require('./templates/opensearch');
const {validateThemeConfig} = require('./validateThemeConfig');
const OPEN_SEARCH_FILENAME = 'opensearch.xml';
module.exports = function (context) {
function theme(context) {
const {
baseUrl,
siteConfig: {title, url, favicon},
@ -70,4 +71,8 @@ module.exports = function (context) {
};
},
};
};
}
module.exports = theme;
theme.validateThemeConfig = validateThemeConfig;

View file

@ -128,17 +128,7 @@ function DocSearch(props) {
}
function SearchBar() {
const {siteConfig = {}} = useDocusaurusContext();
if (!siteConfig.themeConfig.algolia) {
// eslint-disable-next-line no-console
console.warn(`DocSearch requires an \`algolia\` field in your \`themeConfig\`.
See: https://v2.docusaurus.io/docs/search/#using-algolia-docsearch`);
return null;
}
const {siteConfig} = useDocusaurusContext();
return <DocSearch {...siteConfig.themeConfig.algolia} />;
}

View file

@ -0,0 +1,34 @@
/**
* 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.
*/
const Joi = require('@hapi/joi');
const DEFAULT_CONFIG = {
// By default, all Docusaurus sites are using the same AppId
// This has been designed on purpose with Algolia.
appId: 'BH4D9OD16A',
};
exports.DEFAULT_CONFIG = DEFAULT_CONFIG;
const Schema = Joi.object({
algolia: Joi.object({
appId: Joi.string().default(DEFAULT_CONFIG.appId),
apiKey: Joi.string().required(),
indexName: Joi.string().required(),
})
.label('themeConfig.algolia')
.required()
.unknown(), // DocSearch 3 is still alpha: don't validate the rest for now
});
exports.Schema = Schema;
exports.validateThemeConfig = function validateThemeConfig({
validate,
themeConfig,
}) {
return validate(Schema, themeConfig);
};