docusaurus/packages/docusaurus/src/server/__tests__/configValidation.test.ts
Joshua Chen aa5a2d4c04
test: enable a few jest eslint rules (#6900)
* test: enable a few jest eslint rules

* more
2022-03-12 08:43:09 +08:00

295 lines
7.5 KiB
TypeScript

/**
* 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 {
ConfigSchema,
DEFAULT_CONFIG,
validateConfig,
} from '../configValidation';
import type {DocusaurusConfig} from '@docusaurus/types';
const baseConfig: DocusaurusConfig = {
baseUrl: '/',
title: 'my site',
url: 'https://mysite.com',
};
const normalizeConfig = (config) => validateConfig({...baseConfig, ...config});
describe('normalizeConfig', () => {
it('normalizes empty config', () => {
const value = normalizeConfig({});
expect(value).toEqual({
...DEFAULT_CONFIG,
...baseConfig,
});
});
it('accepts correctly defined config options', () => {
const userConfig = {
...DEFAULT_CONFIG,
...baseConfig,
tagline: 'my awesome site',
organizationName: 'facebook',
projectName: 'docusaurus',
githubHost: 'github.com',
customFields: {
myCustomField: '42',
},
scripts: [
{
src: `/analytics.js`,
async: true,
defer: true,
'data-domain': 'xyz', // See https://github.com/facebook/docusaurus/issues/3378
},
],
stylesheets: [
{
href: '/katex/katex.min.css',
type: 'text/css',
crossorigin: 'anonymous',
},
],
};
const normalizedConfig = normalizeConfig(userConfig);
expect(normalizedConfig).toEqual(userConfig);
});
it('accepts custom field in config', () => {
const value = normalizeConfig({
customFields: {
author: 'anshul',
},
});
expect(value).toEqual({
...DEFAULT_CONFIG,
...baseConfig,
customFields: {
author: 'anshul',
},
});
});
it('throws error for unknown field', () => {
expect(() => {
normalizeConfig({
invalid: true,
});
}).toThrowErrorMatchingSnapshot();
});
it('throws error for baseUrl without trailing `/`', () => {
expect(() => {
normalizeConfig({
baseUrl: 'noslash',
});
}).toThrowErrorMatchingSnapshot();
});
it.each([
['should throw error if plugins is not array', {}],
[
"should throw error if plugins is not a string and it's not an array #1",
[123],
],
[
'should throw error if plugins is not an array of [string, object][] #1',
[['example/path', 'wrong parameter here']],
],
[
'should throw error if plugins is not an array of [string, object][] #2',
[[{}, 'example/path']],
],
[
'should throw error if plugins is not an array of [string, object][] #3',
[[{}, {}]],
],
])(`%s for the input of: %p`, (_message, plugins) => {
expect(() => {
normalizeConfig({
plugins,
});
}).toThrowErrorMatchingSnapshot();
});
it.each([
['should throw error if themes is not array', {}],
[
"should throw error if themes is not a string and it's not an array #1",
[123],
],
[
'should throw error if themes is not an array of [string, object][] #1',
[['example/path', 'wrong parameter here']],
],
[
'should throw error if themes is not an array of [string, object][] #2',
[[{}, 'example/path']],
],
[
'should throw error if themes is not an array of [string, object][] #3',
[[{}, {}]],
],
])(`%s for the input of: %p`, (_message, themes) => {
expect(() => {
normalizeConfig({
themes,
});
}).toThrowErrorMatchingSnapshot();
});
it.each([
['should accept [string] for plugins', ['plain/string']],
[
'should accept string[] for plugins',
['plain/string', 'another/plain/string/path'],
],
[
'should accept [string, object] for plugins',
[['plain/string', {it: 'should work'}]],
],
[
'should accept [string, object][] for plugins',
[
['plain/string', {it: 'should work'}],
['this/should/work', {too: 'yes'}],
],
],
[
'should accept ([string, object]|string)[] for plugins',
[
'plain/string',
['plain', {it: 'should work'}],
['this/should/work', {too: 'yes'}],
],
],
[
'should accept function for plugin',
[function plugin(_context, _options) {}],
],
[
'should accept [function, object] for plugin',
[[(_context, _options) => {}, {it: 'should work'}]],
],
])(`%s for the input of: %p`, (_message, plugins) => {
expect(() => {
normalizeConfig({
plugins,
});
}).not.toThrowError();
});
it.each([
['should accept [string] for themes', ['plain/string']],
[
'should accept string[] for themes',
['plain/string', 'another/plain/string/path'],
],
[
'should accept [string, object] for themes',
[['plain/string', {it: 'should work'}]],
],
[
'should accept [string, object][] for themes',
[
['plain/string', {it: 'should work'}],
['this/should/work', {too: 'yes'}],
],
],
[
'should accept ([string, object]|string)[] for themes',
[
'plain/string',
['plain', {it: 'should work'}],
['this/should/work', {too: 'yes'}],
],
],
[
'should accept function for theme',
[function theme(_context, _options) {}],
],
[
'should accept [function, object] for theme',
[[function theme(_context, _options) {}, {it: 'should work'}]],
],
])(`%s for the input of: %p`, (_message, themes) => {
expect(() => {
normalizeConfig({
themes,
});
}).not.toThrowError();
});
it('throws error if themes is not array', () => {
expect(() => {
normalizeConfig({
themes: {},
});
}).toThrowErrorMatchingSnapshot();
});
it('throws error if presets is not array', () => {
expect(() => {
normalizeConfig({
presets: {},
});
}).toThrowErrorMatchingSnapshot();
});
it("throws error if scripts doesn't have src", () => {
expect(() => {
normalizeConfig({
scripts: ['https://some.com', {}],
});
}).toThrowErrorMatchingSnapshot();
});
it("throws error if css doesn't have href", () => {
expect(() => {
normalizeConfig({
stylesheets: ['https://somescript.com', {type: 'text/css'}],
});
}).toThrowErrorMatchingSnapshot();
});
it('throws error for required fields', () => {
expect(
() =>
validateConfig({
invalidField: true,
presets: {},
stylesheets: {},
themes: {},
scripts: {},
} as unknown as DocusaurusConfig), // to fields not in the type
).toThrowErrorMatchingSnapshot();
});
});
describe('config warnings', () => {
function getWarning(config: unknown) {
return ConfigSchema.validate(config).warning;
}
it('baseConfig has no warning', () => {
const warning = getWarning(baseConfig);
expect(warning).toBeUndefined();
});
it('site url has warning when using subpath', () => {
const warning = getWarning({
...baseConfig,
url: 'https://mysite.com/someSubpath',
});
expect(warning).toBeDefined();
expect(warning?.details.length).toEqual(1);
expect(warning?.details[0].message).toMatchInlineSnapshot(
`"Docusaurus config validation warning. Field \\"url\\": the url is not supposed to contain a sub-path like '/someSubpath', please use the baseUrl field for sub-paths"`,
);
});
});