docusaurus/packages/docusaurus-plugin-content-docs/src/client/__tests__/docsClientUtils.test.ts
2024-07-25 12:34:34 +02:00

536 lines
15 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 _ from 'lodash';
import {fromPartial} from '@total-typescript/shoehorn';
import {
getActivePlugin,
getLatestVersion,
getActiveDocContext,
getActiveVersion,
getDocVersionSuggestions,
} from '../docsClientUtils';
import type {
GlobalPluginData,
GlobalVersion,
ActivePlugin,
GlobalDoc,
} from '../index';
function globalVersion(partial: Partial<GlobalVersion>): GlobalVersion {
return fromPartial<GlobalVersion>(partial);
}
function globalDoc(partial: Partial<GlobalDoc>): GlobalDoc {
return fromPartial<GlobalDoc>(partial);
}
describe('docsClientUtils', () => {
it('getActivePlugin', () => {
const data: {[key: string]: GlobalPluginData} = {
pluginIosId: {
path: '/ios',
versions: [],
breadcrumbs: true,
},
pluginAndroidId: {
path: '/android',
versions: [],
breadcrumbs: true,
},
};
expect(getActivePlugin(data, '/')).toBeUndefined();
expect(getActivePlugin(data, '/xyz')).toBeUndefined();
expect(() =>
getActivePlugin(data, '/', {failfast: true}),
).toThrowErrorMatchingInlineSnapshot(
`"Can't find active docs plugin for "/" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: /ios, /android"`,
);
expect(() =>
getActivePlugin(data, '/xyz', {failfast: true}),
).toThrowErrorMatchingInlineSnapshot(
`"Can't find active docs plugin for "/xyz" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: /ios, /android"`,
);
const activePluginIos: ActivePlugin = {
pluginId: 'pluginIosId',
pluginData: data.pluginIosId!,
};
expect(getActivePlugin(data, '/ios')).toEqual(activePluginIos);
expect(getActivePlugin(data, '/ios/')).toEqual(activePluginIos);
expect(getActivePlugin(data, '/ios/abc/def')).toEqual(activePluginIos);
const activePluginAndroid: ActivePlugin = {
pluginId: 'pluginAndroidId',
pluginData: data.pluginAndroidId!,
};
expect(getActivePlugin(data, '/android')).toEqual(activePluginAndroid);
expect(getActivePlugin(data, '/android/')).toEqual(activePluginAndroid);
expect(getActivePlugin(data, '/android/ijk')).toEqual(activePluginAndroid);
// https://github.com/facebook/docusaurus/issues/6434
const onePluginAtRoot: {[key: string]: GlobalPluginData} = {
pluginIosId: {
path: '/',
versions: [],
breadcrumbs: true,
},
pluginAndroidId: {
path: '/android',
versions: [],
breadcrumbs: true,
},
};
expect(getActivePlugin(onePluginAtRoot, '/android/foo')!.pluginId).toBe(
'pluginAndroidId',
);
const onePluginAtRootReversed: {[key: string]: GlobalPluginData} = {
pluginAndroidId: {
path: '/android',
versions: [],
breadcrumbs: true,
},
pluginIosId: {
path: '/',
versions: [],
breadcrumbs: true,
},
};
expect(
getActivePlugin(onePluginAtRootReversed, '/android/foo')!.pluginId,
).toBe('pluginAndroidId');
});
it('getLatestVersion', () => {
const versions: GlobalVersion[] = [
globalVersion({
isLast: false,
}),
globalVersion({
isLast: true,
}),
globalVersion({
isLast: false,
}),
];
expect(
getLatestVersion(
fromPartial({
versions,
}),
),
).toEqual(versions[1]);
});
describe('getActiveVersion', () => {
function testActiveVersion(versions: GlobalVersion[], path: string) {
return getActiveVersion(fromPartial({versions}), path);
}
it('getActiveVersion for regular docs versions', () => {
const versions: GlobalVersion[] = [
globalVersion({
name: 'next',
path: '/docs/next',
}),
globalVersion({
name: 'version2',
path: '/docs',
}),
globalVersion({
name: 'version1',
path: '/docs/version1',
}),
];
expect(testActiveVersion(versions, '/someUnknownPath')).toBeUndefined();
expect(testActiveVersion(versions, '/docs/next')?.name).toBe('next');
expect(testActiveVersion(versions, '/docs/next/')?.name).toBe('next');
expect(testActiveVersion(versions, '/docs/next/someDoc')?.name).toBe(
'next',
);
expect(testActiveVersion(versions, '/docs')?.name).toBe('version2');
expect(testActiveVersion(versions, '/docs/')?.name).toBe('version2');
expect(testActiveVersion(versions, '/docs/someDoc')?.name).toBe(
'version2',
);
expect(testActiveVersion(versions, '/docs/version1')?.name).toBe(
'version1',
);
expect(testActiveVersion(versions, '/docs/version1/')?.name).toBe(
'version1',
);
expect(testActiveVersion(versions, '/docs/version1/someDoc')?.name).toBe(
'version1',
);
});
it('getActiveVersion is not sensitive to version order', () => {
const v1 = globalVersion({
name: 'version1',
path: '/docs',
});
const v2 = globalVersion({
name: 'version2',
path: '/docs/v2',
});
expect(testActiveVersion([v1, v2], '/docs')?.name).toBe('version1');
expect(testActiveVersion([v2, v1], '/docs')?.name).toBe('version1');
expect(testActiveVersion([v1, v2], '/docs/myDoc')?.name).toBe('version1');
expect(testActiveVersion([v2, v1], '/docs/myDoc')?.name).toBe('version1');
expect(testActiveVersion([v1, v2], '/docs/v2')?.name).toBe('version2');
expect(testActiveVersion([v2, v1], '/docs/v2')?.name).toBe('version2');
expect(testActiveVersion([v1, v2], '/docs/v2/myDoc')?.name).toBe(
'version2',
);
expect(testActiveVersion([v2, v1], '/docs/v2/myDoc')?.name).toBe(
'version2',
);
});
it('getActiveVersion is not sensitive to isLast attribute', () => {
const v1 = globalVersion({
name: 'version1',
path: '/docs',
isLast: false,
});
const v2 = globalVersion({
name: 'version2',
path: '/docs/v2',
isLast: false,
});
expect(testActiveVersion([v1, v2], '/docs')?.name).toBe('version1');
expect(testActiveVersion([v1, v2], '/docs/v2')?.name).toBe('version2');
expect(
testActiveVersion([{...v1, isLast: true}, v2], '/docs')?.name,
).toBe('version1');
expect(
testActiveVersion([{...v1, isLast: true}, v2], '/docs/v2')?.name,
).toBe('version2');
expect(
testActiveVersion([v1, {...v2, isLast: true}], '/docs')?.name,
).toBe('version1');
expect(
testActiveVersion([v1, {...v2, isLast: true}], '/docs/v2')?.name,
).toBe('version2');
});
it('getActiveVersion matches first version when same paths', () => {
const v1 = globalVersion({
name: 'version1',
path: '/docs',
});
const v2 = globalVersion({
name: 'version2',
path: '/docs',
});
expect(testActiveVersion([v1, v2], '/docs')?.name).toBe('version1');
expect(testActiveVersion([v2, v1], '/docs')?.name).toBe('version2');
expect(testActiveVersion([v1, v2], '/docs/myDoc')?.name).toBe('version1');
expect(testActiveVersion([v2, v1], '/docs/myDoc')?.name).toBe('version2');
});
it('getActiveVersion without trailing slash', () => {
const versions = [
globalVersion({
name: 'current',
path: '/docs',
}),
globalVersion({
name: 'version2',
path: '/docs/version2',
}),
globalVersion({
name: 'version1',
path: '/docs/version1',
}),
];
expect(testActiveVersion(versions, '/docs')?.name).toBe('current');
});
it('getActiveVersion with trailing slash', () => {
const versions = [
globalVersion({
name: 'current',
path: '/docs/',
}),
globalVersion({
name: 'version2',
path: '/docs/version2/',
}),
globalVersion({
name: 'version1',
path: '/docs/version1/',
}),
];
expect(testActiveVersion(versions, '/docs')?.name).toBe('current');
});
it('getActiveVersion - docs only without trailing slash', () => {
const versions = [
globalVersion({
name: 'current',
path: '/',
}),
globalVersion({
name: 'version2',
path: '/version2',
}),
globalVersion({
name: 'version1',
path: '/version1',
}),
];
expect(testActiveVersion(versions, '/')?.name).toBe('current');
});
it('getActiveVersion - docs only with trailing slash', () => {
const versions = [
globalVersion({
name: 'current',
path: '/',
}),
globalVersion({
name: 'version2',
path: '/version2/',
}),
globalVersion({
name: 'version1',
path: '/version1/',
}),
];
expect(testActiveVersion(versions, '/')?.name).toBe('current');
});
});
it('getActiveDocContext', () => {
const versionNext: GlobalVersion = globalVersion({
name: 'next',
path: '/docs/next',
docs: [
globalDoc({
id: 'doc1',
path: '/docs/next/',
}),
globalDoc({
id: 'doc2',
path: '/docs/next/doc2',
}),
],
});
const version2: GlobalVersion = globalVersion({
name: 'version2',
path: '/docs',
docs: [
globalDoc({
id: 'doc1',
path: '/docs/',
}),
globalDoc({
id: 'doc2',
path: '/docs/doc2',
}),
],
});
const version1: GlobalVersion = globalVersion({
name: 'version1',
path: '/docs/version1',
docs: [
globalDoc({
id: 'doc1',
path: '/docs/version1/',
}),
],
});
// Shuffle, because order shouldn't matter
const versions: GlobalVersion[] = _.shuffle([
versionNext,
version2,
version1,
]);
const data: GlobalPluginData = {
path: 'docs',
versions,
breadcrumbs: true,
};
expect(getActiveDocContext(data, '/doesNotExist')).toEqual({
activeVersion: undefined,
activeDoc: undefined,
alternateDocVersions: {},
});
expect(getActiveDocContext(data, '/docs/next/doesNotExist')).toEqual({
activeVersion: versionNext,
activeDoc: undefined,
alternateDocVersions: {},
});
expect(getActiveDocContext(data, '/docs/next')).toEqual({
activeVersion: versionNext,
activeDoc: versionNext.docs[0],
alternateDocVersions: {
next: versionNext.docs[0],
version2: version2.docs[0],
version1: version1.docs[0],
},
});
expect(getActiveDocContext(data, '/docs/next/doc2')).toEqual({
activeVersion: versionNext,
activeDoc: versionNext.docs[1],
alternateDocVersions: {
next: versionNext.docs[1],
version2: version2.docs[1],
version1: undefined,
},
});
expect(getActiveDocContext(data, '/docs/')).toEqual({
activeVersion: version2,
activeDoc: version2.docs[0],
alternateDocVersions: {
next: versionNext.docs[0],
version2: version2.docs[0],
version1: version1.docs[0],
},
});
expect(getActiveDocContext(data, '/docs/doc2')).toEqual({
activeVersion: version2,
activeDoc: version2.docs[1],
alternateDocVersions: {
next: versionNext.docs[1],
version2: version2.docs[1],
version1: undefined,
},
});
expect(getActiveDocContext(data, '/docs/version1')).toEqual({
activeVersion: version1,
activeDoc: version1.docs[0],
alternateDocVersions: {
next: versionNext.docs[0],
version2: version2.docs[0],
version1: version1.docs[0],
},
});
expect(getActiveDocContext(data, '/docs/version1/doc2')).toEqual({
activeVersion: version1,
activeDoc: undefined,
alternateDocVersions: {},
});
});
it('getDocVersionSuggestions', () => {
const versionNext: GlobalVersion = globalVersion({
name: 'next',
path: '/docs/next',
docs: [
globalDoc({
id: 'doc1',
path: '/docs/next/',
}),
globalDoc({
id: 'doc2',
path: '/docs/next/doc2',
}),
],
});
const version2: GlobalVersion = globalVersion({
name: 'version2',
path: '/docs',
isLast: true,
docs: [
globalDoc({
id: 'doc1',
path: '/docs/',
}),
globalDoc({
id: 'doc2',
path: '/docs/doc2',
}),
],
});
const version1: GlobalVersion = globalVersion({
name: 'version1',
path: '/docs/version1',
docs: [
globalDoc({
id: 'doc1',
path: '/docs/version1/',
}),
],
});
// Shuffle, because order shouldn't matter
const versions: GlobalVersion[] = _.shuffle([
versionNext,
version2,
version1,
]);
const data: GlobalPluginData = {
path: 'docs',
versions,
breadcrumbs: true,
};
expect(getDocVersionSuggestions(data, '/doesNotExist')).toEqual({
latestDocSuggestion: undefined,
latestVersionSuggestion: version2,
});
expect(getDocVersionSuggestions(data, '/docs/next')).toEqual({
latestDocSuggestion: version2.docs[0],
latestVersionSuggestion: version2,
});
expect(getDocVersionSuggestions(data, '/docs/next/doc2')).toEqual({
latestDocSuggestion: version2.docs[1],
latestVersionSuggestion: version2,
});
expect(getDocVersionSuggestions(data, '/docs/')).toEqual({
latestDocSuggestion: version2.docs[0],
latestVersionSuggestion: version2,
});
expect(getDocVersionSuggestions(data, '/docs/doc2')).toEqual({
latestDocSuggestion: version2.docs[1],
latestVersionSuggestion: version2,
});
expect(getDocVersionSuggestions(data, '/docs/version1/')).toEqual({
latestDocSuggestion: version2.docs[0],
latestVersionSuggestion: version2,
});
expect(getDocVersionSuggestions(data, '/docs/version1/doc2')).toEqual({
latestDocSuggestion: undefined, // Because /docs/version1/doc2 does not exist
latestVersionSuggestion: version2,
});
});
});