-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add unit tests on makeBreadcrumbsSegments
- Loading branch information
1 parent
a9bed0b
commit 7bd9679
Showing
4 changed files
with
244 additions
and
82 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
import { BreadcrumbProps } from "@codegouvfr/react-dsfr/Breadcrumb"; | ||
import { flatten, keys } from "ramda"; | ||
import { | ||
Breadcrumbs, | ||
BreadcrumbsItem, | ||
} from "src/app/contents/breadcrumbs/breadcrumbs"; | ||
|
||
export const makeBreadcrumbsSegments = | ||
<K>( | ||
breadcrumbsSet: Breadcrumbs<K extends string ? K : never>, | ||
rootAncestor: BreadcrumbProps["segments"][0], | ||
) => | ||
({ | ||
currentRouteKey, | ||
}: { | ||
currentRouteKey: K; | ||
}): BreadcrumbProps["segments"] => { | ||
const currentRouteAncestor = keys(breadcrumbsSet).find((key) => { | ||
const currentRouteInBreadcrumbs = breadcrumbsSet[key]; | ||
if (!currentRouteInBreadcrumbs) return false; | ||
return ( | ||
currentRouteInBreadcrumbs.route.name === currentRouteKey || | ||
isRouteInChildren(currentRouteKey, currentRouteInBreadcrumbs) | ||
); | ||
}); | ||
return [ | ||
rootAncestor, | ||
...(currentRouteAncestor && breadcrumbsSet[currentRouteAncestor] | ||
? formatToBreadcrumbsSegments( | ||
breadcrumbsSet[currentRouteAncestor], | ||
currentRouteKey, | ||
) | ||
: []), | ||
]; | ||
}; | ||
|
||
const isRouteInChildren = <T>( | ||
currentRouteKey: T, | ||
breadcrumbsItem: BreadcrumbsItem, | ||
): boolean => { | ||
const children = breadcrumbsItem.children; | ||
if (!children) return false; | ||
return keys(children).some((key) => { | ||
const child = children[key]; | ||
if (!child) return false; | ||
if (child.route.name === currentRouteKey) return true; | ||
if (child.children) { | ||
return isRouteInChildren(currentRouteKey, child); | ||
} | ||
}); | ||
}; | ||
|
||
const formatToBreadcrumbsSegments = <T>( | ||
ancestor: BreadcrumbsItem, | ||
currentRouteKey: T, | ||
): BreadcrumbProps["segments"] => { | ||
const { label, route, children } = ancestor; | ||
const ancestorSegment = { label, linkProps: route.link }; | ||
if (!children || ancestor.route.name === currentRouteKey) | ||
return [ancestorSegment]; | ||
const childSegments = flatten( | ||
keys(children).map((key) => { | ||
const child = children[key]; | ||
|
||
if (!child) return; | ||
|
||
const { route, label, children: childChildren } = child; | ||
const { name: routeName, link: linkProps } = route; | ||
|
||
if ( | ||
isRouteInChildren(currentRouteKey, child) && | ||
routeName !== currentRouteKey && | ||
childChildren | ||
) { | ||
return formatToBreadcrumbsSegments(child, currentRouteKey); | ||
} | ||
if (routeName !== currentRouteKey) return; | ||
|
||
return { | ||
label, | ||
linkProps, | ||
}; | ||
}), | ||
).filter((child) => child !== undefined); | ||
return [ancestorSegment, ...childSegments]; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
import { BreadcrumbProps } from "@codegouvfr/react-dsfr/Breadcrumb"; | ||
import { Route } from "type-route"; | ||
import { makeBreadcrumbsSegments } from "./breadcrumbs"; | ||
|
||
const makeFakeRoute = (name: string): Route<any> => ({ | ||
name, | ||
link: { | ||
href: `/${name}`, | ||
onClick: () => {}, | ||
}, | ||
action: null, | ||
params: {}, | ||
href: `/${name}`, | ||
push: () => {}, | ||
replace: () => {}, | ||
}); | ||
|
||
describe("makeBreadcrumbsSegments", () => { | ||
it("should returns segments for a route at level 1", () => { | ||
const segments = getTestBreadcrumbs({ | ||
currentRouteKey: "homeCandidates", | ||
}); | ||
expect(segments).toEqual([ | ||
{ | ||
label: "Accueil", | ||
linkProps: { | ||
href: "/", | ||
onClick: expect.any(Function), | ||
}, | ||
}, | ||
{ | ||
label: "Candidats", | ||
linkProps: { | ||
href: "/homeCandidates", | ||
onClick: expect.any(Function), | ||
}, | ||
}, | ||
]); | ||
}); | ||
it("should returns segments for a route at a deep level", () => { | ||
const segments = getTestBreadcrumbs({ | ||
currentRouteKey: "searchDiagoriente", | ||
}); | ||
expect(segments).toEqual([ | ||
{ | ||
label: "Accueil", | ||
linkProps: { | ||
href: "/", | ||
onClick: expect.any(Function), | ||
}, | ||
}, | ||
{ | ||
label: "Candidats", | ||
linkProps: { | ||
href: "/homeCandidates", | ||
onClick: expect.any(Function), | ||
}, | ||
}, | ||
{ | ||
label: "Recherche", | ||
linkProps: { | ||
href: "/search", | ||
onClick: expect.any(Function), | ||
}, | ||
}, | ||
{ | ||
label: "Recherche (langage naturel)", | ||
linkProps: { | ||
href: "/searchDiagoriente", | ||
onClick: expect.any(Function), | ||
}, | ||
}, | ||
]); | ||
}); | ||
|
||
it("should returns segments for a route without its siblings", () => { | ||
const segments = getTestBreadcrumbs({ | ||
currentRouteKey: "beneficiaryDashboard", | ||
}); | ||
expect(segments).toEqual([ | ||
{ | ||
label: "Accueil", | ||
linkProps: { | ||
href: "/", | ||
onClick: expect.any(Function), | ||
}, | ||
}, | ||
{ | ||
label: "Candidats", | ||
linkProps: { | ||
href: "/homeCandidates", | ||
onClick: expect.any(Function), | ||
}, | ||
}, | ||
{ | ||
label: "Tableau de bord", | ||
linkProps: { | ||
href: "/beneficiaryDashboard", | ||
onClick: expect.any(Function), | ||
}, | ||
}, | ||
]); | ||
}); | ||
}); | ||
|
||
const testBreadcrumbsSet = { | ||
homeCandidates: { | ||
label: "Candidats", | ||
route: makeFakeRoute("homeCandidates"), | ||
children: { | ||
search: { | ||
label: "Recherche", | ||
route: makeFakeRoute("search"), | ||
children: { | ||
searchDiagoriente: { | ||
label: "Recherche (langage naturel)", | ||
route: makeFakeRoute("searchDiagoriente"), | ||
}, | ||
}, | ||
}, | ||
|
||
beneficiaryDashboard: { | ||
label: "Tableau de bord", | ||
route: makeFakeRoute("beneficiaryDashboard"), | ||
}, | ||
}, | ||
}, | ||
}; | ||
|
||
const testRootAncestor: BreadcrumbProps["segments"][0] = { | ||
label: "Accueil", | ||
linkProps: { | ||
href: "/", | ||
onClick: () => {}, | ||
}, | ||
}; | ||
|
||
const getTestBreadcrumbs = makeBreadcrumbsSegments( | ||
testBreadcrumbsSet, | ||
testRootAncestor, | ||
); |