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);