22541 harden breadcrumb mapped route resolver against invalid entries

This commit is contained in:
2026-04-09 14:45:12 +01:00
parent 2a84056a76
commit 0cd78e6f46
3 changed files with 66 additions and 2 deletions
+8 -2
View File
@@ -1,5 +1,11 @@
const getMappedRendererByPath = (path, routeRendererMap) => const getMappedRendererByPath = (path, routeRendererMap) => {
routeRendererMap[path] || null; if (!routeRendererMap || typeof routeRendererMap !== "object") {
return null;
}
const routeRenderer = routeRendererMap[path];
return typeof routeRenderer === "function" ? routeRenderer : null;
};
const resolveMappedRouteRenderer = (path, routeRendererMaps = []) => { const resolveMappedRouteRenderer = (path, routeRendererMaps = []) => {
for (const routeRendererMap of routeRendererMaps) { for (const routeRendererMap of routeRendererMaps) {
+30
View File
@@ -638,6 +638,36 @@ Follow-ups:
- Next larger slice candidate: evaluate extraction viability for `/case` branch only if callback/`router.back()` behavior can remain explicit and parity-safe. - Next larger slice candidate: evaluate extraction viability for `/case` branch only if callback/`router.back()` behavior can remain explicit and parity-safe.
- Next smaller slice candidate: add helper-level test coverage for unexpected non-function map values and explicit skip behavior (defensive precedence guard). - Next smaller slice candidate: add helper-level test coverage for unexpected non-function map values and explicit skip behavior (defensive precedence guard).
### CL-22541-U: breadcrumbs smaller slice — defensive mapped-route resolver hardening
date: 2026-04-09
author: Cline
scope: `lib/routing/breadcrumbRouteMaps.js`, `tests/phase22/breadcrumb-route-maps-helper.test.cjs`
type: change
rationale: Execute the queued smaller slice by hardening mapped-route lookup against malformed map entries and non-function values while keeping precedence behavior unchanged.
impact: Refactor-hardening only; no intended breadcrumb route behavior change for valid mapped renderers.
status: completed
Summary:
- Updated `getMappedRendererByPath(...)` to safely handle invalid route-map entries:
- returns `null` when map is missing/non-object
- returns `null` when mapped value is not a function
- Preserved existing resolver precedence semantics for valid function renderers.
- Added focused helper test asserting resolver skips:
- invalid map entries (`null`/`undefined`)
- non-function mapped values
and still resolves the first later valid renderer.
Validation:
- `npx eslint lib/routing/breadcrumbRouteMaps.js tests/phase22/breadcrumb-route-maps-helper.test.cjs tests/phase22/index.test.cjs` -> pass.
- `node tests/phase22/index.test.cjs` -> pass (combined suite; breadcrumb-route-maps-helper 5/5).
Follow-ups:
- Next larger slice: extract remaining callback-bearing deterministic branches into mapped route groups with callback injection, then update structure guards accordingly.
### CL-00X: 22500 `components/elements/index.js` Phase 1 helper extraction ### CL-00X: 22500 `components/elements/index.js` Phase 1 helper extraction
date: 2026-04-07 date: 2026-04-07
@@ -191,6 +191,34 @@ test("resolveMappedRouteRenderer returns null for unmapped path", () => {
); );
}); });
test("resolveMappedRouteRenderer skips invalid map entries and non-function renderer values", () => {
const { buildBreadcrumbRendererMaps, resolveMappedRouteRenderer } =
loadHelpers();
const validRenderer = () => "valid";
const maps = buildBreadcrumbRendererMaps({
simpleRouteRenderersByPath: {
"/known": "not-a-function"
},
simpleLinkTextPairRenderersByPath: null,
simpleMyPortalRouteRenderersByPath: {
"/known": validRenderer
},
newAppealRouteRenderersByPath: undefined,
caseDetailRouteRenderersByPath: {},
detailAndAccountRouteRenderersByPath: {}
});
const result = resolveMappedRouteRenderer("/known", maps);
assert.strictEqual(
result,
validRenderer,
"Expected resolver to skip invalid/non-function entries and return first valid renderer"
);
});
const run = async () => { const run = async () => {
let passed = 0; let passed = 0;