mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-10 15:47:23 +02:00
767 lines
18 KiB
TypeScript
767 lines
18 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 {
|
|
createSidebarsUtils,
|
|
collectSidebarDocItems,
|
|
collectSidebarCategories,
|
|
collectSidebarLinks,
|
|
transformSidebarItems,
|
|
collectSidebarsDocIds,
|
|
toDocNavigationLink,
|
|
toNavigationLink,
|
|
} from '../utils';
|
|
import type {Sidebar, Sidebars} from '../types';
|
|
import type {
|
|
DocMetadataBase,
|
|
PropNavigationLink,
|
|
} from '@docusaurus/plugin-content-docs';
|
|
|
|
describe('createSidebarsUtils', () => {
|
|
const sidebar1: Sidebar = [
|
|
{
|
|
type: 'category',
|
|
collapsed: false,
|
|
collapsible: true,
|
|
label: 'S1 Category',
|
|
items: [
|
|
{
|
|
type: 'category',
|
|
collapsed: false,
|
|
collapsible: true,
|
|
label: 'S1 Subcategory',
|
|
items: [{type: 'doc', id: 'doc1'}],
|
|
},
|
|
{type: 'doc', id: 'doc2'},
|
|
],
|
|
},
|
|
];
|
|
|
|
const sidebar2: Sidebar = [
|
|
{
|
|
type: 'category',
|
|
collapsed: false,
|
|
collapsible: true,
|
|
label: 'S2 Category',
|
|
items: [
|
|
{type: 'doc', id: 'doc3', label: 'Doc 3'},
|
|
{type: 'doc', id: 'doc4'},
|
|
],
|
|
},
|
|
];
|
|
|
|
const sidebar3: Sidebar = [
|
|
{
|
|
type: 'category',
|
|
collapsed: false,
|
|
collapsible: true,
|
|
label: 'S3 Category',
|
|
link: {
|
|
type: 'doc',
|
|
id: 'doc5',
|
|
},
|
|
items: [
|
|
{
|
|
type: 'category',
|
|
collapsed: false,
|
|
collapsible: true,
|
|
label: 'S3 SubCategory',
|
|
link: {
|
|
type: 'generated-index',
|
|
slug: '/s3-subcategory-index-slug',
|
|
permalink: '/s3-subcategory-index-permalink',
|
|
},
|
|
items: [
|
|
{
|
|
type: 'category',
|
|
collapsed: false,
|
|
collapsible: true,
|
|
label: 'S3 SubSubCategory',
|
|
link: {
|
|
type: 'generated-index',
|
|
slug: '/s3-subsubcategory-slug',
|
|
permalink: '/s3-subsubcategory-index-permalink',
|
|
},
|
|
items: [
|
|
{type: 'doc', id: 'doc6'},
|
|
{type: 'doc', id: 'doc7'},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
];
|
|
|
|
const sidebar4: Sidebar = [
|
|
{
|
|
type: 'category',
|
|
items: [
|
|
{type: 'link', href: 'https://facebook.com'},
|
|
{type: 'link', href: 'https://reactjs.org'},
|
|
{type: 'link', href: 'https://docusaurus.io'},
|
|
],
|
|
},
|
|
{
|
|
type: 'category',
|
|
collapsed: false,
|
|
collapsible: true,
|
|
label: 'S4 Category',
|
|
link: {
|
|
type: 'generated-index',
|
|
slug: '/s4-category-slug',
|
|
permalink: '/s4-category-slug',
|
|
},
|
|
items: [
|
|
{type: 'doc', id: 'doc8'},
|
|
{type: 'doc', id: 'doc9'},
|
|
],
|
|
},
|
|
];
|
|
|
|
const sidebars: Sidebars = {sidebar1, sidebar2, sidebar3, sidebar4};
|
|
|
|
const {
|
|
getFirstDocIdOfFirstSidebar,
|
|
getSidebarNameByDocId,
|
|
getDocNavigation,
|
|
getCategoryGeneratedIndexNavigation,
|
|
getCategoryGeneratedIndexList,
|
|
getFirstLink,
|
|
} = createSidebarsUtils(sidebars);
|
|
|
|
it('getFirstDocIdOfFirstSidebar', async () => {
|
|
expect(getFirstDocIdOfFirstSidebar()).toBe('doc1');
|
|
});
|
|
|
|
it('getSidebarNameByDocId', async () => {
|
|
expect(getSidebarNameByDocId('doc1')).toBe('sidebar1');
|
|
expect(getSidebarNameByDocId('doc2')).toBe('sidebar1');
|
|
expect(getSidebarNameByDocId('doc3')).toBe('sidebar2');
|
|
expect(getSidebarNameByDocId('doc4')).toBe('sidebar2');
|
|
expect(getSidebarNameByDocId('doc5')).toBe('sidebar3');
|
|
expect(getSidebarNameByDocId('doc6')).toBe('sidebar3');
|
|
expect(getSidebarNameByDocId('doc7')).toBe('sidebar3');
|
|
expect(getSidebarNameByDocId('unknown_id')).toBeUndefined();
|
|
});
|
|
|
|
it('getDocNavigation', async () => {
|
|
expect(getDocNavigation('doc1', 'doc1', undefined)).toEqual({
|
|
sidebarName: 'sidebar1',
|
|
previous: undefined,
|
|
next: {
|
|
type: 'doc',
|
|
id: 'doc2',
|
|
},
|
|
});
|
|
expect(getDocNavigation('doc2', 'doc2', undefined)).toEqual({
|
|
sidebarName: 'sidebar1',
|
|
previous: {
|
|
type: 'doc',
|
|
id: 'doc1',
|
|
},
|
|
next: undefined,
|
|
});
|
|
|
|
expect(getDocNavigation('doc3', 'doc3', undefined)).toEqual({
|
|
sidebarName: 'sidebar2',
|
|
previous: undefined,
|
|
next: {
|
|
type: 'doc',
|
|
id: 'doc4',
|
|
},
|
|
});
|
|
expect(getDocNavigation('doc4', 'doc4', undefined)).toEqual({
|
|
sidebarName: 'sidebar2',
|
|
previous: {
|
|
type: 'doc',
|
|
id: 'doc3',
|
|
label: 'Doc 3',
|
|
},
|
|
next: undefined,
|
|
});
|
|
|
|
expect(getDocNavigation('doc5', 'doc5', undefined)).toMatchObject({
|
|
sidebarName: 'sidebar3',
|
|
previous: undefined,
|
|
next: {
|
|
type: 'category',
|
|
label: 'S3 SubCategory',
|
|
},
|
|
});
|
|
expect(getDocNavigation('doc6', 'doc6', undefined)).toMatchObject({
|
|
sidebarName: 'sidebar3',
|
|
previous: {
|
|
type: 'category',
|
|
label: 'S3 SubSubCategory',
|
|
},
|
|
next: {
|
|
type: 'doc',
|
|
id: 'doc7',
|
|
},
|
|
});
|
|
expect(getDocNavigation('doc7', 'doc7', undefined)).toEqual({
|
|
sidebarName: 'sidebar3',
|
|
previous: {
|
|
type: 'doc',
|
|
id: 'doc6',
|
|
},
|
|
next: undefined,
|
|
});
|
|
expect(getDocNavigation('doc3', 'doc3', null)).toEqual({
|
|
sidebarName: undefined,
|
|
previous: undefined,
|
|
next: undefined,
|
|
});
|
|
expect(() =>
|
|
getDocNavigation('doc3', 'doc3', 'foo'),
|
|
).toThrowErrorMatchingInlineSnapshot(
|
|
`"Doc with ID doc3 wants to display sidebar foo but a sidebar with this name doesn't exist"`,
|
|
);
|
|
expect(getDocNavigation('doc3', 'doc3', 'sidebar1')).toEqual({
|
|
sidebarName: 'sidebar1',
|
|
previous: undefined,
|
|
next: undefined,
|
|
});
|
|
});
|
|
|
|
it('getCategoryGeneratedIndexNavigation', async () => {
|
|
expect(
|
|
getCategoryGeneratedIndexNavigation('/s3-subcategory-index-permalink'),
|
|
).toMatchObject({
|
|
sidebarName: 'sidebar3',
|
|
previous: {
|
|
type: 'category',
|
|
label: 'S3 Category',
|
|
},
|
|
next: {
|
|
type: 'category',
|
|
label: 'S3 SubSubCategory',
|
|
},
|
|
});
|
|
|
|
expect(
|
|
getCategoryGeneratedIndexNavigation('/s3-subsubcategory-index-permalink'),
|
|
).toMatchObject({
|
|
sidebarName: 'sidebar3',
|
|
previous: {
|
|
type: 'category',
|
|
label: 'S3 SubCategory',
|
|
},
|
|
next: {
|
|
type: 'doc',
|
|
id: 'doc6',
|
|
},
|
|
});
|
|
});
|
|
|
|
it('getCategoryGeneratedIndexList', async () => {
|
|
expect(getCategoryGeneratedIndexList()).toMatchObject([
|
|
{
|
|
type: 'category',
|
|
label: 'S3 SubCategory',
|
|
},
|
|
{
|
|
type: 'category',
|
|
label: 'S3 SubSubCategory',
|
|
},
|
|
{
|
|
type: 'category',
|
|
label: 'S4 Category',
|
|
},
|
|
]);
|
|
});
|
|
|
|
it('getFirstLink', () => {
|
|
expect(getFirstLink('sidebar1')).toEqual({
|
|
id: 'doc1',
|
|
type: 'doc',
|
|
label: 'doc1',
|
|
});
|
|
expect(getFirstLink('sidebar2')).toEqual({
|
|
id: 'doc3',
|
|
type: 'doc',
|
|
label: 'Doc 3',
|
|
});
|
|
expect(getFirstLink('sidebar3')).toEqual({
|
|
id: 'doc5',
|
|
type: 'doc',
|
|
label: 'S3 Category',
|
|
});
|
|
expect(getFirstLink('sidebar4')).toEqual({
|
|
type: 'generated-index',
|
|
permalink: '/s4-category-slug',
|
|
label: 'S4 Category',
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('collectSidebarDocItems', () => {
|
|
it('can collect docs', async () => {
|
|
const sidebar: Sidebar = [
|
|
{
|
|
type: 'category',
|
|
collapsed: false,
|
|
collapsible: true,
|
|
label: 'Category1',
|
|
items: [
|
|
{
|
|
type: 'category',
|
|
collapsed: false,
|
|
collapsible: true,
|
|
label: 'Subcategory 1',
|
|
items: [{type: 'doc', id: 'doc1'}],
|
|
},
|
|
{
|
|
type: 'category',
|
|
collapsed: false,
|
|
collapsible: true,
|
|
label: 'Subcategory 2',
|
|
items: [
|
|
{type: 'doc', id: 'doc2'},
|
|
{
|
|
type: 'category',
|
|
collapsed: false,
|
|
collapsible: true,
|
|
label: 'Sub sub category 1',
|
|
items: [{type: 'doc', id: 'doc3'}],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
type: 'category',
|
|
collapsed: false,
|
|
collapsible: true,
|
|
label: 'Category2',
|
|
items: [
|
|
{type: 'doc', id: 'doc4'},
|
|
{type: 'doc', id: 'doc5'},
|
|
],
|
|
},
|
|
];
|
|
|
|
expect(collectSidebarDocItems(sidebar).map((doc) => doc.id)).toEqual([
|
|
'doc1',
|
|
'doc2',
|
|
'doc3',
|
|
'doc4',
|
|
'doc5',
|
|
]);
|
|
});
|
|
});
|
|
|
|
describe('collectSidebarCategories', () => {
|
|
it('can collect categories', async () => {
|
|
const sidebar: Sidebar = [
|
|
{
|
|
type: 'category',
|
|
collapsed: false,
|
|
collapsible: true,
|
|
label: 'Category1',
|
|
items: [
|
|
{
|
|
type: 'category',
|
|
collapsed: false,
|
|
collapsible: true,
|
|
label: 'Subcategory 1',
|
|
items: [{type: 'doc', id: 'doc1'}],
|
|
},
|
|
{
|
|
type: 'category',
|
|
collapsed: false,
|
|
collapsible: true,
|
|
label: 'Subcategory 2',
|
|
items: [
|
|
{type: 'doc', id: 'doc2'},
|
|
{
|
|
type: 'category',
|
|
collapsed: false,
|
|
collapsible: true,
|
|
label: 'Sub sub category 1',
|
|
items: [{type: 'doc', id: 'doc3'}],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
type: 'category',
|
|
collapsed: false,
|
|
collapsible: true,
|
|
label: 'Category2',
|
|
items: [
|
|
{type: 'doc', id: 'doc4'},
|
|
{type: 'doc', id: 'doc5'},
|
|
],
|
|
},
|
|
];
|
|
|
|
expect(
|
|
collectSidebarCategories(sidebar).map((category) => category.label),
|
|
).toEqual([
|
|
'Category1',
|
|
'Subcategory 1',
|
|
'Subcategory 2',
|
|
'Sub sub category 1',
|
|
'Category2',
|
|
]);
|
|
});
|
|
});
|
|
|
|
describe('collectSidebarLinks', () => {
|
|
it('can collect links', async () => {
|
|
const sidebar: Sidebar = [
|
|
{
|
|
type: 'category',
|
|
collapsed: false,
|
|
collapsible: true,
|
|
label: 'Category1',
|
|
items: [
|
|
{
|
|
type: 'link',
|
|
href: 'https://google.com',
|
|
label: 'Google',
|
|
},
|
|
{
|
|
type: 'category',
|
|
collapsed: false,
|
|
collapsible: true,
|
|
label: 'Subcategory 2',
|
|
items: [
|
|
{
|
|
type: 'link',
|
|
href: 'https://facebook.com',
|
|
label: 'Facebook',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
];
|
|
|
|
expect(collectSidebarLinks(sidebar).map((link) => link.href)).toEqual([
|
|
'https://google.com',
|
|
'https://facebook.com',
|
|
]);
|
|
});
|
|
});
|
|
|
|
describe('collectSidebarsDocIds', () => {
|
|
it('can collect sidebars doc items', async () => {
|
|
const sidebar1: Sidebar = [
|
|
{
|
|
type: 'category',
|
|
collapsed: false,
|
|
collapsible: true,
|
|
label: 'Category1',
|
|
items: [
|
|
{
|
|
type: 'category',
|
|
collapsed: false,
|
|
collapsible: true,
|
|
label: 'Subcategory 1',
|
|
items: [{type: 'doc', id: 'doc1'}],
|
|
},
|
|
{type: 'doc', id: 'doc2'},
|
|
],
|
|
},
|
|
];
|
|
|
|
const sidebar2: Sidebar = [
|
|
{
|
|
type: 'category',
|
|
collapsed: false,
|
|
collapsible: true,
|
|
label: 'Category2',
|
|
items: [
|
|
{type: 'doc', id: 'doc3'},
|
|
{type: 'doc', id: 'doc4'},
|
|
],
|
|
},
|
|
];
|
|
|
|
const sidebar3: Sidebar = [
|
|
{type: 'doc', id: 'doc5'},
|
|
{type: 'doc', id: 'doc6'},
|
|
];
|
|
expect(collectSidebarsDocIds({sidebar1, sidebar2, sidebar3})).toEqual({
|
|
sidebar1: ['doc1', 'doc2'],
|
|
sidebar2: ['doc3', 'doc4'],
|
|
sidebar3: ['doc5', 'doc6'],
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('transformSidebarItems', () => {
|
|
it('can transform sidebar items', async () => {
|
|
const sidebar: Sidebar = [
|
|
{
|
|
type: 'category',
|
|
collapsed: false,
|
|
collapsible: true,
|
|
label: 'Category1',
|
|
items: [
|
|
{
|
|
type: 'category',
|
|
collapsed: false,
|
|
collapsible: true,
|
|
label: 'Subcategory 1',
|
|
items: [{type: 'doc', id: 'doc1'}],
|
|
customProps: {fakeProp: false},
|
|
},
|
|
{
|
|
type: 'category',
|
|
collapsed: false,
|
|
collapsible: true,
|
|
label: 'Subcategory 2',
|
|
items: [
|
|
{type: 'doc', id: 'doc2'},
|
|
{
|
|
type: 'category',
|
|
collapsed: false,
|
|
collapsible: true,
|
|
label: 'Sub sub category 1',
|
|
items: [
|
|
{type: 'doc', id: 'doc3', customProps: {lorem: 'ipsum'}},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
type: 'category',
|
|
collapsed: false,
|
|
collapsible: true,
|
|
label: 'Category2',
|
|
items: [
|
|
{type: 'doc', id: 'doc4'},
|
|
{type: 'doc', id: 'doc5'},
|
|
],
|
|
},
|
|
];
|
|
|
|
expect(
|
|
transformSidebarItems(sidebar, (item) => {
|
|
if (item.type === 'category') {
|
|
return {...item, label: `MODIFIED LABEL: ${item.label}`};
|
|
}
|
|
return item;
|
|
}),
|
|
).toEqual([
|
|
{
|
|
type: 'category',
|
|
collapsed: false,
|
|
collapsible: true,
|
|
label: 'MODIFIED LABEL: Category1',
|
|
items: [
|
|
{
|
|
type: 'category',
|
|
collapsed: false,
|
|
collapsible: true,
|
|
label: 'MODIFIED LABEL: Subcategory 1',
|
|
items: [{type: 'doc', id: 'doc1'}],
|
|
customProps: {fakeProp: false},
|
|
},
|
|
{
|
|
type: 'category',
|
|
collapsed: false,
|
|
collapsible: true,
|
|
label: 'MODIFIED LABEL: Subcategory 2',
|
|
items: [
|
|
{type: 'doc', id: 'doc2'},
|
|
{
|
|
type: 'category',
|
|
collapsed: false,
|
|
collapsible: true,
|
|
label: 'MODIFIED LABEL: Sub sub category 1',
|
|
items: [
|
|
{type: 'doc', id: 'doc3', customProps: {lorem: 'ipsum'}},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
type: 'category',
|
|
collapsed: false,
|
|
collapsible: true,
|
|
label: 'MODIFIED LABEL: Category2',
|
|
items: [
|
|
{type: 'doc', id: 'doc4'},
|
|
{type: 'doc', id: 'doc5'},
|
|
],
|
|
},
|
|
]);
|
|
});
|
|
});
|
|
|
|
describe('toDocNavigationLink', () => {
|
|
type TestDoc = Pick<DocMetadataBase, 'permalink' | 'title' | 'frontMatter'>;
|
|
function testDoc(data: TestDoc) {
|
|
return data as DocMetadataBase;
|
|
}
|
|
|
|
it('with no front matter', () => {
|
|
expect(
|
|
toDocNavigationLink(
|
|
testDoc({
|
|
title: 'Doc Title',
|
|
permalink: '/docPermalink',
|
|
frontMatter: {},
|
|
}),
|
|
),
|
|
).toEqual({
|
|
title: 'Doc Title',
|
|
permalink: '/docPermalink',
|
|
} as PropNavigationLink);
|
|
});
|
|
|
|
it('with pagination_label front matter', () => {
|
|
expect(
|
|
toDocNavigationLink(
|
|
testDoc({
|
|
title: 'Doc Title',
|
|
permalink: '/docPermalink',
|
|
frontMatter: {
|
|
pagination_label: 'pagination_label',
|
|
},
|
|
}),
|
|
),
|
|
).toEqual({
|
|
title: 'pagination_label',
|
|
permalink: '/docPermalink',
|
|
} as PropNavigationLink);
|
|
});
|
|
|
|
it('with sidebar_label front matter', () => {
|
|
expect(
|
|
toDocNavigationLink(
|
|
testDoc({
|
|
title: 'Doc Title',
|
|
permalink: '/docPermalink',
|
|
frontMatter: {
|
|
sidebar_label: 'sidebar_label',
|
|
},
|
|
}),
|
|
),
|
|
).toEqual({
|
|
title: 'sidebar_label',
|
|
permalink: '/docPermalink',
|
|
} as PropNavigationLink);
|
|
});
|
|
|
|
it('with pagination_label + sidebar_label front matter', () => {
|
|
expect(
|
|
toDocNavigationLink(
|
|
testDoc({
|
|
title: 'Doc Title',
|
|
permalink: '/docPermalink',
|
|
frontMatter: {
|
|
pagination_label: 'pagination_label',
|
|
sidebar_label: 'sidebar_label',
|
|
},
|
|
}),
|
|
),
|
|
).toEqual({
|
|
title: 'pagination_label',
|
|
permalink: '/docPermalink',
|
|
} as PropNavigationLink);
|
|
});
|
|
});
|
|
|
|
describe('toNavigationLink', () => {
|
|
type TestDoc = Pick<DocMetadataBase, 'permalink' | 'title'>;
|
|
function testDoc(data: TestDoc) {
|
|
return {...data, frontMatter: {}} as DocMetadataBase;
|
|
}
|
|
|
|
const docsById: {[docId: string]: DocMetadataBase} = {
|
|
doc1: testDoc({
|
|
title: 'Doc 1',
|
|
permalink: '/doc1',
|
|
}),
|
|
doc2: testDoc({
|
|
title: 'Doc 1',
|
|
permalink: '/doc1',
|
|
}),
|
|
};
|
|
|
|
it('with doc items', () => {
|
|
expect(toNavigationLink({type: 'doc', id: 'doc1'}, docsById)).toEqual(
|
|
toDocNavigationLink(docsById.doc1),
|
|
);
|
|
expect(toNavigationLink({type: 'doc', id: 'doc2'}, docsById)).toEqual(
|
|
toDocNavigationLink(docsById.doc2),
|
|
);
|
|
expect(() =>
|
|
toNavigationLink({type: 'doc', id: 'doc3'}, docsById),
|
|
).toThrowErrorMatchingInlineSnapshot(
|
|
`"Can't create navigation link: no doc found with id=doc3"`,
|
|
);
|
|
});
|
|
|
|
it('with category item and doc link', () => {
|
|
expect(
|
|
toNavigationLink(
|
|
{
|
|
type: 'category',
|
|
label: 'Category',
|
|
items: [],
|
|
link: {
|
|
type: 'doc',
|
|
id: 'doc1',
|
|
},
|
|
collapsed: true,
|
|
collapsible: true,
|
|
},
|
|
docsById,
|
|
),
|
|
).toEqual(toDocNavigationLink(docsById.doc1));
|
|
expect(() =>
|
|
toNavigationLink(
|
|
{
|
|
type: 'category',
|
|
label: 'Category',
|
|
items: [],
|
|
link: {
|
|
type: 'doc',
|
|
id: 'doc3',
|
|
},
|
|
collapsed: true,
|
|
collapsible: true,
|
|
},
|
|
docsById,
|
|
),
|
|
).toThrowErrorMatchingInlineSnapshot(
|
|
`"Can't create navigation link: no doc found with id=doc3"`,
|
|
);
|
|
});
|
|
|
|
it('with category item and generated-index link', () => {
|
|
expect(
|
|
toNavigationLink(
|
|
{
|
|
type: 'category',
|
|
label: 'Category',
|
|
items: [],
|
|
link: {
|
|
type: 'generated-index',
|
|
slug: 'slug',
|
|
permalink: 'generated-index-permalink',
|
|
},
|
|
collapsed: true,
|
|
collapsible: true,
|
|
},
|
|
docsById,
|
|
),
|
|
).toEqual({title: 'Category', permalink: 'generated-index-permalink'});
|
|
});
|
|
});
|