mirror of
https://github.com/facebook/docusaurus.git
synced 2025-12-25 17:22:50 +00:00
fix(docs): breadcrumb APIs only return category/docs items, ignoring links (#11616)
Some checks failed
Argos CI / take-screenshots (push) Waiting to run
Build Hash Router / Build Hash Router (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
Continuous Releases / Continuous Releases (push) Waiting to run
E2E Tests / E2E — Yarn v1 (20) (push) Waiting to run
E2E Tests / E2E — Yarn v1 (20.0) (push) Waiting to run
E2E Tests / E2E — Yarn v1 (22) (push) Waiting to run
E2E Tests / E2E — Yarn v1 (24) (push) Waiting to run
E2E Tests / E2E — Yarn v1 (25.1) (push) Waiting to run
E2E Tests / E2E — Yarn v1 Windows (push) Waiting to run
E2E Tests / E2E — Yarn Berry (node-modules, -s) (push) Waiting to run
E2E Tests / E2E — Yarn Berry (node-modules, -st) (push) Waiting to run
E2E Tests / E2E — Yarn Berry (pnp, -s) (push) Waiting to run
E2E Tests / E2E — Yarn Berry (pnp, -st) (push) Waiting to run
E2E Tests / E2E — npm (push) Waiting to run
E2E Tests / E2E — pnpm (push) Waiting to run
Canary Release / Publish Canary (push) Has been cancelled
Some checks failed
Argos CI / take-screenshots (push) Waiting to run
Build Hash Router / Build Hash Router (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
Continuous Releases / Continuous Releases (push) Waiting to run
E2E Tests / E2E — Yarn v1 (20) (push) Waiting to run
E2E Tests / E2E — Yarn v1 (20.0) (push) Waiting to run
E2E Tests / E2E — Yarn v1 (22) (push) Waiting to run
E2E Tests / E2E — Yarn v1 (24) (push) Waiting to run
E2E Tests / E2E — Yarn v1 (25.1) (push) Waiting to run
E2E Tests / E2E — Yarn v1 Windows (push) Waiting to run
E2E Tests / E2E — Yarn Berry (node-modules, -s) (push) Waiting to run
E2E Tests / E2E — Yarn Berry (node-modules, -st) (push) Waiting to run
E2E Tests / E2E — Yarn Berry (pnp, -s) (push) Waiting to run
E2E Tests / E2E — Yarn Berry (pnp, -st) (push) Waiting to run
E2E Tests / E2E — npm (push) Waiting to run
E2E Tests / E2E — pnpm (push) Waiting to run
Canary Release / Publish Canary (push) Has been cancelled
Co-authored-by: sebastien <lorber.sebastien@gmail.com>
This commit is contained in:
parent
47a98a1d6e
commit
7f5d6122d2
|
|
@ -568,13 +568,28 @@ describe('useSidebarBreadcrumbs', () => {
|
|||
|
||||
it('returns first level link', () => {
|
||||
const pathname = '/somePathName';
|
||||
const sidebar = [testCategory(), testLink({href: pathname})];
|
||||
const sidebar = [testCategory(), testLink({href: pathname, docId: 'doc1'})];
|
||||
|
||||
expect(createUseSidebarBreadcrumbsMock(sidebar)(pathname)).toEqual([
|
||||
sidebar[1],
|
||||
]);
|
||||
});
|
||||
|
||||
it('returns doc links only', () => {
|
||||
const pathname = '/somePathName';
|
||||
|
||||
// A link that is not a doc link should not appear in the breadcrumbs
|
||||
// See https://github.com/facebook/docusaurus/pull/11616
|
||||
const nonDocLink = testLink({href: pathname});
|
||||
const docLink = testLink({href: pathname, docId: 'doc1'});
|
||||
|
||||
const sidebar = [testCategory(), nonDocLink, docLink];
|
||||
|
||||
expect(createUseSidebarBreadcrumbsMock(sidebar)(pathname)).toEqual([
|
||||
docLink,
|
||||
]);
|
||||
});
|
||||
|
||||
it('returns nested category', () => {
|
||||
const pathname = '/somePathName';
|
||||
|
||||
|
|
@ -613,7 +628,7 @@ describe('useSidebarBreadcrumbs', () => {
|
|||
it('returns nested link', () => {
|
||||
const pathname = '/somePathName';
|
||||
|
||||
const link = testLink({href: pathname});
|
||||
const link = testLink({href: pathname, docId: 'docNested'});
|
||||
|
||||
const categoryLevel3 = testCategory({
|
||||
items: [testLink(), link, testLink()],
|
||||
|
|
@ -657,6 +672,35 @@ describe('useSidebarBreadcrumbs', () => {
|
|||
createUseSidebarBreadcrumbsMock(undefined, false)('/foo'),
|
||||
).toBeNull();
|
||||
});
|
||||
|
||||
// Regression test for https://github.com/facebook/docusaurus/issues/11612
|
||||
it('returns the category that owns the URL, not a category with a link pointing to it', () => {
|
||||
const categoryA: PropSidebarItemCategory = testCategory({
|
||||
label: 'Category A',
|
||||
href: '/category-a',
|
||||
items: [
|
||||
testLink({href: '/category-a/doc1', label: 'Doc 1'}),
|
||||
testLink({href: '/category-a/doc2', label: 'Doc 2'}),
|
||||
// This link points to Category B's generated-index
|
||||
testLink({href: '/category-b', label: 'Go to Category B'}),
|
||||
],
|
||||
});
|
||||
|
||||
const categoryB: PropSidebarItemCategory = testCategory({
|
||||
label: 'Category B',
|
||||
href: '/category-b',
|
||||
items: [
|
||||
testLink({href: '/category-b/item1', label: 'Item 1'}),
|
||||
testLink({href: '/category-b/item2', label: 'Item 2'}),
|
||||
],
|
||||
});
|
||||
|
||||
const sidebar: PropSidebar = [categoryA, categoryB];
|
||||
|
||||
expect(createUseSidebarBreadcrumbsMock(sidebar)('/category-b')).toEqual([
|
||||
categoryB,
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('useCurrentSidebarCategory', () => {
|
||||
|
|
@ -708,12 +752,16 @@ describe('useCurrentSidebarCategory', () => {
|
|||
expect(mockUseCurrentSidebarCategory('/cat2')).toEqual(category2);
|
||||
});
|
||||
|
||||
it('works for category link item', () => {
|
||||
const link = testLink({href: '/my/link/path'});
|
||||
it('works for category doc link item', () => {
|
||||
const pathname = '/my/link/path';
|
||||
const nonDocLink = testLink({href: pathname});
|
||||
const docLink = testLink({href: pathname, docId: 'doc1'});
|
||||
|
||||
const category: PropSidebarItemCategory = testCategory({
|
||||
href: '/cat1',
|
||||
items: [testLink(), testLink(), link, testCategory()],
|
||||
items: [testLink(), testLink(), nonDocLink, docLink, testCategory()],
|
||||
});
|
||||
|
||||
const sidebar: PropSidebar = [
|
||||
testLink(),
|
||||
testLink(),
|
||||
|
|
@ -724,18 +772,28 @@ describe('useCurrentSidebarCategory', () => {
|
|||
const mockUseCurrentSidebarCategory =
|
||||
createUseCurrentSidebarCategoryMock(sidebar);
|
||||
|
||||
expect(mockUseCurrentSidebarCategory('/my/link/path')).toEqual(category);
|
||||
expect(mockUseCurrentSidebarCategory(pathname)).toEqual(category);
|
||||
});
|
||||
|
||||
it('works for nested category link item', () => {
|
||||
const link = testLink({href: '/my/link/path'});
|
||||
const pathname = '/my/link/path';
|
||||
const nonDocLink = testLink({href: pathname});
|
||||
const docLink = testLink({href: pathname, docId: 'doc1'});
|
||||
|
||||
const category2: PropSidebarItemCategory = testCategory({
|
||||
href: '/cat2',
|
||||
items: [testLink(), testLink(), link, testCategory()],
|
||||
items: [
|
||||
testLink(),
|
||||
testLink(),
|
||||
testCategory({items: [nonDocLink]}),
|
||||
nonDocLink,
|
||||
docLink,
|
||||
testCategory(),
|
||||
],
|
||||
});
|
||||
const category1: PropSidebarItemCategory = testCategory({
|
||||
href: '/cat1',
|
||||
items: [testLink(), testLink(), category2, testCategory()],
|
||||
items: [testLink(), nonDocLink, testLink(), category2, testCategory()],
|
||||
});
|
||||
const sidebar: PropSidebar = [
|
||||
testLink(),
|
||||
|
|
@ -780,6 +838,38 @@ describe('useCurrentSidebarCategory', () => {
|
|||
`"Unexpected: cant find current sidebar in context"`,
|
||||
);
|
||||
});
|
||||
|
||||
// Regression test for https://github.com/facebook/docusaurus/issues/11612
|
||||
it('returns the category that owns the URL, not a category with a link pointing to it', () => {
|
||||
const categoryA: PropSidebarItemCategory = testCategory({
|
||||
label: 'Category A',
|
||||
href: '/category-a',
|
||||
items: [
|
||||
testLink({href: '/category-a/doc1', label: 'Doc 1'}),
|
||||
testLink({href: '/category-a/doc2', label: 'Doc 2'}),
|
||||
// This link points to Category B's generated-index
|
||||
testLink({href: '/category-b', label: 'Go to Category B'}),
|
||||
],
|
||||
});
|
||||
|
||||
const categoryB: PropSidebarItemCategory = testCategory({
|
||||
label: 'Category B',
|
||||
href: '/category-b',
|
||||
items: [
|
||||
testLink({href: '/category-b/item1', label: 'Item 1'}),
|
||||
testLink({href: '/category-b/item2', label: 'Item 2'}),
|
||||
],
|
||||
});
|
||||
|
||||
const sidebar: PropSidebar = [categoryA, categoryB];
|
||||
|
||||
const mockUseCurrentSidebarCategory =
|
||||
createUseCurrentSidebarCategoryMock(sidebar);
|
||||
|
||||
// When visiting /category-b, we should get Category B (the owner),
|
||||
// not Category A (which just has a link to it)
|
||||
expect(mockUseCurrentSidebarCategory('/category-b')).toEqual(categoryB);
|
||||
});
|
||||
});
|
||||
|
||||
describe('useCurrentSidebarSiblings', () => {
|
||||
|
|
@ -805,10 +895,10 @@ describe('useCurrentSidebarSiblings', () => {
|
|||
testCategory(),
|
||||
];
|
||||
|
||||
const mockUseCurrentSidebarCategory =
|
||||
const mockUseCurrentSidebarSiblings =
|
||||
createUseCurrentSidebarSiblingsMock(sidebar);
|
||||
|
||||
expect(mockUseCurrentSidebarCategory('/cat')).toEqual(category.items);
|
||||
expect(mockUseCurrentSidebarSiblings('/cat')).toEqual(category.items);
|
||||
});
|
||||
|
||||
it('works for sidebar root', () => {
|
||||
|
|
@ -823,10 +913,10 @@ describe('useCurrentSidebarSiblings', () => {
|
|||
testCategory(),
|
||||
];
|
||||
|
||||
const mockUseCurrentSidebarCategory =
|
||||
const mockUseCurrentSidebarSiblings =
|
||||
createUseCurrentSidebarSiblingsMock(sidebar);
|
||||
|
||||
expect(mockUseCurrentSidebarCategory('/rootLink')).toEqual(sidebar);
|
||||
expect(mockUseCurrentSidebarSiblings('/rootLink')).toEqual(sidebar);
|
||||
});
|
||||
|
||||
it('works for nested sidebar category', () => {
|
||||
|
|
@ -852,10 +942,13 @@ describe('useCurrentSidebarSiblings', () => {
|
|||
});
|
||||
|
||||
it('works for category link item', () => {
|
||||
const link = testLink({href: '/my/link/path'});
|
||||
const pathname = '/my/link/path';
|
||||
const nonDocLink = testLink({href: pathname});
|
||||
const docLink = testLink({href: pathname, docId: 'doc1'});
|
||||
|
||||
const category: PropSidebarItemCategory = testCategory({
|
||||
href: '/cat1',
|
||||
items: [testLink(), testLink(), link, testCategory()],
|
||||
items: [testLink(), testLink(), nonDocLink, docLink, testCategory()],
|
||||
});
|
||||
const sidebar: PropSidebar = [
|
||||
testLink(),
|
||||
|
|
@ -864,23 +957,24 @@ describe('useCurrentSidebarSiblings', () => {
|
|||
testCategory(),
|
||||
];
|
||||
|
||||
const mockUseCurrentSidebarCategory =
|
||||
const mockUseCurrentSidebarSiblings =
|
||||
createUseCurrentSidebarSiblingsMock(sidebar);
|
||||
|
||||
expect(mockUseCurrentSidebarCategory('/my/link/path')).toEqual(
|
||||
category.items,
|
||||
);
|
||||
expect(mockUseCurrentSidebarSiblings(pathname)).toEqual(category.items);
|
||||
});
|
||||
|
||||
it('works for nested category link item', () => {
|
||||
const link = testLink({href: '/my/link/path'});
|
||||
const pathname = '/my/link/path';
|
||||
const nonDocLink = testLink({href: pathname});
|
||||
const docLink = testLink({href: pathname, docId: 'doc1'});
|
||||
|
||||
const category2: PropSidebarItemCategory = testCategory({
|
||||
href: '/cat2',
|
||||
items: [testLink(), testLink(), link, testCategory()],
|
||||
items: [testLink(), testLink(), nonDocLink, testCategory()],
|
||||
});
|
||||
const category1: PropSidebarItemCategory = testCategory({
|
||||
href: '/cat1',
|
||||
items: [testLink(), testLink(), category2, testCategory()],
|
||||
items: [testLink(), testLink(), category2, docLink, testCategory()],
|
||||
});
|
||||
const sidebar: PropSidebar = [
|
||||
testLink(),
|
||||
|
|
@ -889,18 +983,16 @@ describe('useCurrentSidebarSiblings', () => {
|
|||
testCategory(),
|
||||
];
|
||||
|
||||
const mockUseCurrentSidebarCategory =
|
||||
const mockUseCurrentSidebarSiblings =
|
||||
createUseCurrentSidebarSiblingsMock(sidebar);
|
||||
|
||||
expect(mockUseCurrentSidebarCategory('/my/link/path')).toEqual(
|
||||
category2.items,
|
||||
);
|
||||
expect(mockUseCurrentSidebarSiblings(pathname)).toEqual(category1.items);
|
||||
});
|
||||
|
||||
it('throws when sidebar is missing', () => {
|
||||
const mockUseCurrentSidebarCategory = createUseCurrentSidebarSiblingsMock();
|
||||
const mockUseCurrentSidebarSiblings = createUseCurrentSidebarSiblingsMock();
|
||||
expect(() =>
|
||||
mockUseCurrentSidebarCategory('/cat'),
|
||||
mockUseCurrentSidebarSiblings('/cat'),
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
`"Unexpected: cant find current sidebar in context"`,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -234,15 +234,22 @@ function getSidebarBreadcrumbs({
|
|||
}): PropSidebarBreadcrumbsItem[] {
|
||||
const breadcrumbs: PropSidebarBreadcrumbsItem[] = [];
|
||||
|
||||
function extract(items: PropSidebarItem[]) {
|
||||
function extract(items: PropSidebarItem[]): boolean {
|
||||
for (const item of items) {
|
||||
if (
|
||||
(item.type === 'category' &&
|
||||
(isSamePath(item.href, pathname) || extract(item.items))) ||
|
||||
(item.type === 'link' && isSamePath(item.href, pathname))
|
||||
// Extract category item
|
||||
if (item.type === 'category') {
|
||||
if (isSamePath(item.href, pathname) || extract(item.items)) {
|
||||
breadcrumbs.unshift(item);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Extract doc item
|
||||
else if (
|
||||
item.type === 'link' &&
|
||||
item.docId &&
|
||||
isSamePath(item.href, pathname)
|
||||
) {
|
||||
const filtered = onlyCategories && item.type !== 'category';
|
||||
if (!filtered) {
|
||||
if (!onlyCategories) {
|
||||
breadcrumbs.unshift(item);
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
Loading…
Reference in New Issue