22541 compose mapped breadcrumb groups in factory and add null fallback guard
This commit is contained in:
+21
-58
@@ -17,13 +17,7 @@ import {
|
||||
buildBreadcrumbRendererMaps,
|
||||
resolveMappedRouteRenderer as resolveMappedRouteRendererByMaps
|
||||
} from "../lib/routing/breadcrumbRouteMaps";
|
||||
import {
|
||||
createSimpleRouteRenderers,
|
||||
createSimpleLinkTextPairRenderers,
|
||||
createSimpleMyPortalRouteRenderers,
|
||||
createCaseDetailRouteRenderers,
|
||||
createDetailAndAccountRouteRenderers
|
||||
} from "../lib/routing/breadcrumbRendererFactories";
|
||||
import { createMappedRouteRendererGroups } from "../lib/routing/breadcrumbRendererFactories";
|
||||
|
||||
const Breadcrumbs = (props) => {
|
||||
const {
|
||||
@@ -196,37 +190,6 @@ const Breadcrumbs = (props) => {
|
||||
</>
|
||||
);
|
||||
|
||||
const simpleRouteRenderersByPath = createSimpleRouteRenderers({
|
||||
t,
|
||||
renderTextCrumb,
|
||||
renderMyPortalSectionCrumbs
|
||||
});
|
||||
|
||||
const simpleLinkTextPairRenderersByPath = createSimpleLinkTextPairRenderers(
|
||||
{
|
||||
t,
|
||||
router,
|
||||
isWelsh,
|
||||
renderLinkCrumb,
|
||||
renderTextCrumb
|
||||
}
|
||||
);
|
||||
|
||||
const simpleMyPortalRouteRenderersByPath =
|
||||
createSimpleMyPortalRouteRenderers({
|
||||
t,
|
||||
router,
|
||||
isWelsh,
|
||||
myPortalHref,
|
||||
currentViewState,
|
||||
getViewAllLabel,
|
||||
renderAnchorCrumb,
|
||||
renderLinkCrumb,
|
||||
renderTextCrumb,
|
||||
renderMyPortalCrumb,
|
||||
renderMyPortalSectionCrumbs
|
||||
});
|
||||
|
||||
const resolveMappedRouteRenderer = (path) => {
|
||||
return resolveMappedRouteRendererByMaps(path, mappedRouteRendererMaps);
|
||||
};
|
||||
@@ -241,39 +204,39 @@ const Breadcrumbs = (props) => {
|
||||
query: router.query,
|
||||
hasSession: Boolean(session),
|
||||
getViewAllLabel,
|
||||
advancedLabel: () => t("common:breadcrumb-advanced-search-results"),
|
||||
addressLabel: () => t("common:breadcrumb-address-search-results"),
|
||||
defaultLabel: () => t("common:breadcrumb-search-results")
|
||||
advancedLabel: t("common:breadcrumb-advanced-search-results"),
|
||||
addressLabel: t("common:breadcrumb-address-search-results"),
|
||||
defaultLabel: t("common:breadcrumb-search-results")
|
||||
});
|
||||
|
||||
const caseDetailRouteRenderersByPath = createCaseDetailRouteRenderers({
|
||||
const {
|
||||
simpleRouteRenderersByPath,
|
||||
simpleLinkTextPairRenderersByPath,
|
||||
simpleMyPortalRouteRenderersByPath,
|
||||
caseDetailRouteRenderersByPath,
|
||||
detailAndAccountRouteRenderersByPath
|
||||
} = createMappedRouteRendererGroups({
|
||||
t,
|
||||
router,
|
||||
isWelsh,
|
||||
myPortalHref,
|
||||
cyMyPortalHref,
|
||||
currentViewState,
|
||||
getViewAllLabel,
|
||||
caseResultsHref,
|
||||
breadcrumbLabel,
|
||||
fallbackSearchTitle,
|
||||
currentReference,
|
||||
caseReferenceDisplay,
|
||||
getViewAllLabel,
|
||||
renderAnchorCrumb,
|
||||
renderLinkCrumb,
|
||||
renderTextCrumb,
|
||||
renderCaseReferenceCrumb,
|
||||
renderMyPortalCrumb
|
||||
renderMyPortalCrumb,
|
||||
renderMyPortalSectionCrumbs,
|
||||
renderDnsCaseReferenceCrumbs
|
||||
});
|
||||
|
||||
const detailAndAccountRouteRenderersByPath =
|
||||
createDetailAndAccountRouteRenderers({
|
||||
t,
|
||||
router,
|
||||
isWelsh,
|
||||
cyMyPortalHref,
|
||||
currentReference,
|
||||
caseReferenceDisplay,
|
||||
renderMyPortalCrumb,
|
||||
renderLinkCrumb,
|
||||
renderCaseReferenceCrumb,
|
||||
renderDnsCaseReferenceCrumbs
|
||||
});
|
||||
|
||||
const mappedRouteRendererMaps = buildBreadcrumbRendererMaps({
|
||||
simpleRouteRenderersByPath,
|
||||
simpleLinkTextPairRenderersByPath,
|
||||
|
||||
@@ -312,3 +312,92 @@ export const createDetailAndAccountRouteRenderers = ({
|
||||
</>
|
||||
)
|
||||
});
|
||||
|
||||
export const createMappedRouteRendererGroups = ({
|
||||
t,
|
||||
router,
|
||||
isWelsh,
|
||||
myPortalHref,
|
||||
cyMyPortalHref,
|
||||
currentViewState,
|
||||
getViewAllLabel,
|
||||
caseResultsHref,
|
||||
breadcrumbLabel,
|
||||
fallbackSearchTitle,
|
||||
currentReference,
|
||||
caseReferenceDisplay,
|
||||
renderAnchorCrumb,
|
||||
renderLinkCrumb,
|
||||
renderTextCrumb,
|
||||
renderCaseReferenceCrumb,
|
||||
renderMyPortalCrumb,
|
||||
renderMyPortalSectionCrumbs,
|
||||
renderDnsCaseReferenceCrumbs
|
||||
}) => {
|
||||
const simpleRouteRenderersByPath = createSimpleRouteRenderers({
|
||||
t,
|
||||
renderTextCrumb,
|
||||
renderMyPortalSectionCrumbs
|
||||
});
|
||||
|
||||
const simpleLinkTextPairRenderersByPath = createSimpleLinkTextPairRenderers(
|
||||
{
|
||||
t,
|
||||
router,
|
||||
isWelsh,
|
||||
renderLinkCrumb,
|
||||
renderTextCrumb
|
||||
}
|
||||
);
|
||||
|
||||
const simpleMyPortalRouteRenderersByPath =
|
||||
createSimpleMyPortalRouteRenderers({
|
||||
t,
|
||||
router,
|
||||
isWelsh,
|
||||
myPortalHref,
|
||||
currentViewState,
|
||||
getViewAllLabel,
|
||||
renderAnchorCrumb,
|
||||
renderLinkCrumb,
|
||||
renderTextCrumb,
|
||||
renderMyPortalCrumb,
|
||||
renderMyPortalSectionCrumbs
|
||||
});
|
||||
|
||||
const caseDetailRouteRenderersByPath = createCaseDetailRouteRenderers({
|
||||
t,
|
||||
router,
|
||||
isWelsh,
|
||||
caseResultsHref,
|
||||
breadcrumbLabel,
|
||||
fallbackSearchTitle,
|
||||
caseReferenceDisplay,
|
||||
getViewAllLabel,
|
||||
renderLinkCrumb,
|
||||
renderCaseReferenceCrumb,
|
||||
renderMyPortalCrumb
|
||||
});
|
||||
|
||||
const detailAndAccountRouteRenderersByPath =
|
||||
createDetailAndAccountRouteRenderers({
|
||||
t,
|
||||
router,
|
||||
isWelsh,
|
||||
cyMyPortalHref,
|
||||
currentReference,
|
||||
caseReferenceDisplay,
|
||||
renderMyPortalCrumb,
|
||||
renderLinkCrumb,
|
||||
renderCaseReferenceCrumb,
|
||||
renderDnsCaseReferenceCrumbs
|
||||
});
|
||||
|
||||
return {
|
||||
simpleRouteRenderersByPath,
|
||||
simpleLinkTextPairRenderersByPath,
|
||||
simpleMyPortalRouteRenderersByPath,
|
||||
caseDetailRouteRenderersByPath,
|
||||
detailAndAccountRouteRenderersByPath
|
||||
};
|
||||
};
|
||||
|
||||
@@ -532,6 +532,39 @@ Follow-ups:
|
||||
- Next slice option A (larger): move per-path map object declarations out of `components/breadcrumbs.js` into module-level pure factories (still injected with `t/router/currentView`) to further shrink component body.
|
||||
- Next slice option B (smaller): add one focused parity test asserting mapped resolver fallback returns `null` in component rendering path for non-mapped routes (ensures no accidental render noise).
|
||||
|
||||
### CL-22541-R: breadcrumbs mapped-group factory composition + unmapped-route null parity guard
|
||||
|
||||
date: 2026-04-09
|
||||
author: Cline
|
||||
scope: `lib/routing/breadcrumbRendererFactories.js`, `components/breadcrumbs.js`, `tests/phase22/breadcrumbs-route-map-structure.test.cjs`
|
||||
type: change
|
||||
rationale: Execute both approved next slices in one commit by centralizing deterministic mapped route-group composition into a factory-level helper and adding explicit structure guard coverage for null fallback behavior on unmapped routes.
|
||||
impact: Refactor-only structural consolidation and test hardening; no intended route/auth/session/API/EN-CY/a11y behavior change.
|
||||
status: completed
|
||||
|
||||
Summary:
|
||||
|
||||
- Added `createMappedRouteRendererGroups(...)` in `lib/routing/breadcrumbRendererFactories.js` to compose and return all deterministic mapped renderer groups in one place:
|
||||
- `simpleRouteRenderersByPath`
|
||||
- `simpleLinkTextPairRenderersByPath`
|
||||
- `simpleMyPortalRouteRenderersByPath`
|
||||
- `caseDetailRouteRenderersByPath`
|
||||
- `detailAndAccountRouteRenderersByPath`
|
||||
- Updated `components/breadcrumbs.js` to consume `createMappedRouteRendererGroups(...)` and remove local per-group factory composition boilerplate while preserving existing map precedence and resolver flow.
|
||||
- Expanded `tests/phase22/breadcrumbs-route-map-structure.test.cjs` to assert:
|
||||
- grouped renderer maps are composed via `createMappedRouteRendererGroups(...)`
|
||||
- mapped rendering path explicitly preserves null fallback (`routeRenderer ? routeRenderer() : null`)
|
||||
|
||||
Validation:
|
||||
|
||||
- `npx eslint lib/routing/breadcrumbRendererFactories.js components/breadcrumbs.js tests/phase22/breadcrumbs-route-map-structure.test.cjs tests/phase22/breadcrumb-route-maps-helper.test.cjs tests/phase22/index.test.cjs` -> pass.
|
||||
- `node tests/phase22/index.test.cjs` -> pass (combined suite; breadcrumbs-route-map 4/4).
|
||||
|
||||
Follow-ups:
|
||||
|
||||
- Next slice option A (larger): extract remaining deterministic inline branches (`/myportal/case`, `/case/id/[incident]` if kept deterministic after constraints review) only if they remain callback/state free.
|
||||
- Next slice option B (smaller): add one focused assertion in helper-level tests that empty grouped map entries are tolerated without affecting precedence resolution.
|
||||
|
||||
### CL-00X: 22500 `components/elements/index.js` Phase 1 helper extraction
|
||||
|
||||
date: 2026-04-07
|
||||
|
||||
@@ -155,73 +155,17 @@ test("breadcrumbs/component composes mapped routes via imported factories and sh
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
/createSimpleRouteRenderers/.test(source),
|
||||
/createMappedRouteRendererGroups/.test(source),
|
||||
true,
|
||||
"Expected breadcrumbs to reference createSimpleRouteRenderers"
|
||||
"Expected breadcrumbs to reference createMappedRouteRendererGroups"
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
/createSimpleLinkTextPairRenderers/.test(source),
|
||||
true,
|
||||
"Expected breadcrumbs to reference createSimpleLinkTextPairRenderers"
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
/createSimpleMyPortalRouteRenderers/.test(source),
|
||||
true,
|
||||
"Expected breadcrumbs to reference createSimpleMyPortalRouteRenderers"
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
/createCaseDetailRouteRenderers/.test(source),
|
||||
true,
|
||||
"Expected breadcrumbs to reference createCaseDetailRouteRenderers"
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
/createDetailAndAccountRouteRenderers/.test(source),
|
||||
true,
|
||||
"Expected breadcrumbs to reference createDetailAndAccountRouteRenderers"
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
/const\s+simpleRouteRenderersByPath\s*=\s*createSimpleRouteRenderers\s*\(/.test(
|
||||
/const\s+\{[\s\S]*simpleRouteRenderersByPath[\s\S]*detailAndAccountRouteRenderersByPath[\s\S]*\}\s*=\s*createMappedRouteRendererGroups\s*\(/.test(
|
||||
source
|
||||
),
|
||||
true,
|
||||
"Expected breadcrumbs to build simple route renderers from factory"
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
/const\s+simpleLinkTextPairRenderersByPath\s*=\s*createSimpleLinkTextPairRenderers\s*\(/.test(
|
||||
source
|
||||
),
|
||||
true,
|
||||
"Expected breadcrumbs to build link-text pair renderers from factory"
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
/const\s+simpleMyPortalRouteRenderersByPath\s*=\s*createSimpleMyPortalRouteRenderers\s*\(/.test(
|
||||
source
|
||||
),
|
||||
true,
|
||||
"Expected breadcrumbs to build my-portal route renderers from factory"
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
/const\s+caseDetailRouteRenderersByPath\s*=\s*createCaseDetailRouteRenderers\s*\(/.test(
|
||||
source
|
||||
),
|
||||
true,
|
||||
"Expected breadcrumbs to build case detail route renderers from factory"
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
/const\s+detailAndAccountRouteRenderersByPath\s*=\s*createDetailAndAccountRouteRenderers\s*\(/.test(
|
||||
source
|
||||
),
|
||||
true,
|
||||
"Expected breadcrumbs to build detail and account route renderers from factory"
|
||||
"Expected breadcrumbs to compose grouped renderer maps via createMappedRouteRendererGroups"
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
@@ -256,6 +200,12 @@ test("breadcrumbs/component composes mapped routes via imported factories and sh
|
||||
"Expected reusable renderMappedRoute helper to exist"
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
source.includes("return routeRenderer ? routeRenderer() : null;"),
|
||||
true,
|
||||
"Expected mapped renderer flow to return null for unmapped routes"
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
source.includes("{renderMappedRoute(pathname)}"),
|
||||
true,
|
||||
|
||||
Reference in New Issue
Block a user