From aeb9fb254ee7b0c88a9caa0b760fef1ee2f03f69 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 17 Dec 2020 13:49:21 +0100 Subject: [PATCH] core-api: add route validation to app + test Co-authored-by: blam --- packages/core-api/src/app/App.test.tsx | 60 +++++++++++++++++++++++++- packages/core-api/src/app/App.tsx | 4 +- 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/packages/core-api/src/app/App.test.tsx b/packages/core-api/src/app/App.test.tsx index 431ffa5959..7ab4928abf 100644 --- a/packages/core-api/src/app/App.test.tsx +++ b/packages/core-api/src/app/App.test.tsx @@ -14,9 +14,9 @@ * limitations under the License. */ -import { renderWithEffects } from '@backstage/test-utils'; +import { renderWithEffects, withLogCollector } from '@backstage/test-utils'; import { lightTheme } from '@backstage/theme'; -import { screen } from '@testing-library/react'; +import { render, screen } from '@testing-library/react'; import React from 'react'; import { BrowserRouter, Routes } from 'react-router-dom'; import { createRoutableExtension } from '../extensions'; @@ -125,4 +125,60 @@ describe('Integration Test', () => { expect(screen.getByText('Our Route Is: /foo/bar')).toBeInTheDocument(); }); + + it('should throw some error when the route has duplicate params', () => { + const components = { + NotFoundErrorPage: () => null, + BootErrorPage: () => null, + Progress: () => null, + Router: BrowserRouter, + }; + + const app = new PrivateAppImpl({ + apis: [], + defaultApis: [], + themes: [ + { + id: 'light', + title: 'Light Theme', + variant: 'light', + theme: lightTheme, + }, + ], + icons: defaultSystemIcons, + plugins: [], + components, + bindRoutes: ({ bind }) => { + bind(plugin1.externalRoutes, { foo: plugin2RouteRef }); + }, + }); + + const Provider = app.getProvider(); + const Router = app.getRouter(); + const { error: errorLogs } = withLogCollector(() => { + expect(() => + render( + + + + + + + + + , + ), + ).toThrow( + 'Parameter :thing is duplicated in path /test/:thing/some/:thing', + ); + }); + expect(errorLogs).toEqual([ + expect.stringContaining( + 'Parameter :thing is duplicated in path /test/:thing/some/:thing', + ), + expect.stringContaining( + 'The above error occurred in the component', + ), + ]); + }); }); diff --git a/packages/core-api/src/app/App.tsx b/packages/core-api/src/app/App.tsx index 4a23c26bba..08393f3e9e 100644 --- a/packages/core-api/src/app/App.tsx +++ b/packages/core-api/src/app/App.tsx @@ -56,7 +56,7 @@ import { routeParentCollector, routePathCollector, } from '../routing/collectors'; -import { RoutingProvider } from '../routing/hooks'; +import { RoutingProvider, validateRoutes } from '../routing/hooks'; import { ExternalRouteRef } from '../routing/RouteRef'; import { AppContextProvider } from './AppContext'; import { AppIdentity } from './AppIdentity'; @@ -253,6 +253,8 @@ export class PrivateAppImpl implements BackstageApp { }, }); + validateRoutes(routePaths, routeParents); + const loadedConfig = useConfigLoader( this.configLoader, this.components,