diff --git a/packages/core-api/src/routing/hooks.test.tsx b/packages/core-api/src/routing/hooks.test.tsx index c08891c8cc..65c7858954 100644 --- a/packages/core-api/src/routing/hooks.test.tsx +++ b/packages/core-api/src/routing/hooks.test.tsx @@ -27,6 +27,7 @@ import { createPlugin } from '../plugin'; import { routeCollector, routeParentCollector } from './collectors'; import { useRouteRef, RoutingProvider } from './hooks'; import { createRouteRef } from './RouteRef'; +import { RouteRef } from './types'; const mockConfig = () => ({ path: '/unused', title: 'Unused' }); const MockComponent = ({ children }: PropsWithChildren<{}>) => <>{children}; @@ -36,11 +37,19 @@ const plugin = createPlugin({ id: 'my-plugin' }); const ref1 = createRouteRef(mockConfig()); const ref2 = createRouteRef(mockConfig()); const ref3 = createRouteRef(mockConfig()); +const ref4 = createRouteRef(mockConfig()); -const MockRouteSource = () => { - const routeFunc = useRouteRef(ref2); - expect(routeFunc?.()).toBe('/foo/bar'); - return null; +const MockRouteSource = (props: { + name: string; + routeRef: RouteRef; + params?: Record; +}) => { + const routeFunc = useRouteRef(props.routeRef); + return ( +
+ Path at {props.name}: {routeFunc?.(props.params)} +
+ ); }; const Extension1 = plugin.provide( @@ -52,18 +61,21 @@ const Extension2 = plugin.provide( const Extension3 = plugin.provide( createRoutableExtension({ component: MockComponent, mountPoint: ref3 }), ); +const Extension4 = plugin.provide( + createRoutableExtension({ component: MockRouteSource, mountPoint: ref4 }), +); describe('discovery', () => { - it('should handle all react router Route patterns', () => { + it('should handle simple routeRef path creation for routeRefs used in other parts of the app', () => { const root = ( - + - + ); @@ -76,12 +88,57 @@ describe('discovery', () => { }, }); - render( + const rendered = render( {root} , ); - expect.assertions(2); + expect(rendered.getByText('Path at inside: /foo/bar')).toBeInTheDocument(); + expect(rendered.getByText('Path at outside: /foo/bar')).toBeInTheDocument(); + }); + + it('should handle routeRefs with parameters', () => { + const root = ( + + + + + + + + + ); + + const { routes, routeParents } = traverseElementTree({ + root, + discoverers: [childDiscoverer, routeElementDiscoverer], + collectors: { + routes: routeCollector, + routeParents: routeParentCollector, + }, + }); + + const rendered = render( + + {root} + , + ); + + expect( + rendered.getByText('Path at inside: /foo/bar/bleb'), + ).toBeInTheDocument(); + expect( + rendered.getByText('Path at outside: /foo/bar/blob'), + ).toBeInTheDocument(); }); }); diff --git a/packages/core-api/src/routing/hooks.tsx b/packages/core-api/src/routing/hooks.tsx index 8a2aa72c92..739d74247c 100644 --- a/packages/core-api/src/routing/hooks.tsx +++ b/packages/core-api/src/routing/hooks.tsx @@ -16,8 +16,9 @@ import React, { createContext, ReactNode, useContext } from 'react'; import { RouteRef } from './types'; +import { generatePath } from 'react-router-dom'; -export type RouteFunc = () => string; +export type RouteFunc = (params?: Record) => string; class RouteResolver { constructor( @@ -38,8 +39,8 @@ class RouteResolver { currentRouteRef = this.routeParents.get(currentRouteRef); } - return () => { - return fullPath; + return (params?: Record) => { + return generatePath(fullPath, params); }; } }