diff --git a/packages/core-app-api/src/routing/collectors.stable.test.tsx b/packages/core-app-api/src/routing/collectors.stable.test.tsx index 1c5bc8c639..b37faae54c 100644 --- a/packages/core-app-api/src/routing/collectors.stable.test.tsx +++ b/packages/core-app-api/src/routing/collectors.stable.test.tsx @@ -15,13 +15,9 @@ */ import React, { PropsWithChildren } from 'react'; -import { routingV1Collector } from './collectors'; +import { routingV2Collector } from './collectors'; -import { - traverseElementTree, - childDiscoverer, - routeElementDiscoverer, -} from '../extensions/traversal'; +import { traverseElementTree, childDiscoverer } from '../extensions/traversal'; import { createRoutableExtension, createRouteRef, @@ -32,6 +28,11 @@ import { } from '@backstage/core-plugin-api'; import { MemoryRouter, Routes, Route } from 'react-router-dom'; +jest.mock('react-router', () => jest.requireActual('react-router-stable')); +jest.mock('react-router-dom', () => + jest.requireActual('react-router-dom-stable'), +); + const MockComponent = ({ children }: PropsWithChildren<{ path?: string }>) => ( <>{children} ); @@ -109,7 +110,7 @@ function routeObj( routeRefs: new Set(refs), children: [ { - path: '/*', + path: '*', caseSensitive: false, element: 'match-all', routeRefs: new Set(), @@ -126,33 +127,33 @@ describe('discovery', () => {
,
,
- + } />
, ]; const root = ( - + }>
- + }>
Some text here shouldn't be a problem
{null}
- + } />
- + {false} {list} {true} {0}
- +
- } /> + } />
@@ -160,17 +161,17 @@ describe('discovery', () => { const { routing } = traverseElementTree({ root, - discoverers: [childDiscoverer, routeElementDiscoverer], + discoverers: [childDiscoverer], collectors: { - routing: routingV1Collector, + routing: routingV2Collector, }, }); expect(sortedEntries(routing.paths)).toEqual([ - [ref1, '/foo'], - [ref2, '/bar/:id'], - [ref3, '/baz'], - [ref4, '/divsoup'], - [ref5, '/blop'], + [ref1, 'foo'], + [ref2, 'bar/:id'], + [ref3, 'baz'], + [ref4, 'divsoup'], + [ref5, 'blop'], ]); expect(sortedEntries(routing.parents)).toEqual([ [ref1, undefined], @@ -181,14 +182,22 @@ describe('discovery', () => { ]); expect(routing.objects).toEqual([ routeObj( - '/foo', + 'foo', [ref1], [ - routeObj('/bar/:id', [ref2], [routeObj('/baz', [ref3])]), - routeObj('/blop', [ref5]), + routeObj( + 'bar/:id', + [ref2], + [routeObj('baz', [ref3], undefined, undefined, plugin)], + undefined, + plugin, + ), + routeObj('blop', [ref5], undefined, undefined, plugin), ], + undefined, + plugin, ), - routeObj('/divsoup', [ref4], undefined, undefined, plugin), + routeObj('divsoup', [ref4], undefined, undefined, plugin), ]); }); @@ -216,9 +225,9 @@ describe('discovery', () => { const { routing } = traverseElementTree({ root, - discoverers: [childDiscoverer, routeElementDiscoverer], + discoverers: [childDiscoverer], collectors: { - routing: routingV1Collector, + routing: routingV2Collector, }, }); expect(sortedEntries(routing.paths)).toEqual([ @@ -261,9 +270,9 @@ describe('discovery', () => { const { routing } = traverseElementTree({ root, - discoverers: [childDiscoverer, routeElementDiscoverer], + discoverers: [childDiscoverer], collectors: { - routing: routingV1Collector, + routing: routingV2Collector, }, }); expect(sortedEntries(routing.paths)).toEqual([ @@ -310,9 +319,9 @@ describe('discovery', () => { const { routing } = traverseElementTree({ root, - discoverers: [childDiscoverer, routeElementDiscoverer], + discoverers: [childDiscoverer], collectors: { - routing: routingV1Collector, + routing: routingV2Collector, }, }); expect(sortedEntries(routing.paths)).toEqual([ @@ -363,9 +372,9 @@ describe('discovery', () => { expect(() => { traverseElementTree({ root, - discoverers: [childDiscoverer, routeElementDiscoverer], + discoverers: [childDiscoverer], collectors: { - routing: routingV1Collector, + routing: routingV2Collector, }, }); }).toThrow('Mounted routable extension must have a path'); diff --git a/packages/core-app-api/src/routing/collectors.tsx b/packages/core-app-api/src/routing/collectors.tsx index 895be6afa2..95fa3694f1 100644 --- a/packages/core-app-api/src/routing/collectors.tsx +++ b/packages/core-app-api/src/routing/collectors.tsx @@ -35,6 +35,13 @@ export const MATCH_ALL_ROUTE: BackstageRouteObject = { routeRefs: new Set(), }; +function stringifyNode(node: ReactNode): string { + if (!isValidElement(node)) { + return String(node); + } + return (node.type as { displayName?: string })?.displayName ?? String(node); +} + interface RoutingV2CollectorContext { routeRef?: RouteRef; gatherPath?: string; @@ -162,7 +169,11 @@ export const routingV2Collector = createCollector( if (mountPoint) { if (!ctx?.gatherPath) { - throw new Error('Routable extension must be assigned a path'); + throw new Error( + `Routable extension ${stringifyNode( + node, + )} with mount point ${mountPoint} must be assigned a path`, + ); } ctx?.obj?.routeRefs.add(mountPoint);