From fce073f658a1d122e8f2f661ee999319a7b7ba66 Mon Sep 17 00:00:00 2001 From: Aramis Sennyey Date: Fri, 4 Nov 2022 15:06:43 -0400 Subject: [PATCH] Update AppManager and test case to handle parsing backend.baseUrl as relative. Signed-off-by: Aramis Sennyey --- packages/app-defaults/src/defaults/apis.ts | 14 +-- .../core-app-api/src/app/AppManager.test.tsx | 90 +++++++++++++++++++ packages/core-app-api/src/app/AppManager.tsx | 29 +++++- 3 files changed, 121 insertions(+), 12 deletions(-) diff --git a/packages/app-defaults/src/defaults/apis.ts b/packages/app-defaults/src/defaults/apis.ts index c53ce63ada..7ff8ce16bc 100644 --- a/packages/app-defaults/src/defaults/apis.ts +++ b/packages/app-defaults/src/defaults/apis.ts @@ -65,17 +65,9 @@ export const apis = [ api: discoveryApiRef, deps: { configApi: configApiRef }, factory: ({ configApi }) => { - let baseUrl; - try { - // Try parsing the url relative to the current document origin, if it fails the URL is misformed. - baseUrl = new URL( - configApi.getString('backend.baseUrl'), - document.location.origin, - ).href.replace(/\/$/, ''); - } catch (err) { - baseUrl = configApi.getString('backend.baseUrl'); - } - return UrlPatternDiscovery.compile(`${baseUrl}/api/{{ pluginId }}`); + return UrlPatternDiscovery.compile( + `${configApi.getString('backend.baseUrl')}/api/{{ pluginId }}`, + ); }, }), createApiFactory({ diff --git a/packages/core-app-api/src/app/AppManager.test.tsx b/packages/core-app-api/src/app/AppManager.test.tsx index c70b43581a..33b7ad5b9a 100644 --- a/packages/core-app-api/src/app/AppManager.test.tsx +++ b/packages/core-app-api/src/app/AppManager.test.tsx @@ -34,6 +34,7 @@ import { createSubRouteRef, createRoutableExtension, analyticsApiRef, + useApiHolder, } from '@backstage/core-plugin-api'; import { AppManager } from './AppManager'; import { AppComponents, AppIcons } from './types'; @@ -569,4 +570,93 @@ describe('Integration Test', () => { ), ]); }); + + it('should add the fully qualified origin when the backend.baseUrl is relative', async () => { + const app = new AppManager({ + apis: [], + defaultApis: [], + themes: [ + { + id: 'light', + title: 'Light Theme', + variant: 'light', + Provider: ({ children }) => <>{children}, + }, + ], + icons, + plugins: [], + components, + configLoader: async () => [ + { + context: 'test', + data: { + backend: { + baseUrl: '/', + }, + }, + }, + ], + }); + + const Provider = app.getProvider(); + const ConfigDisplay = () => { + const apiHolder = useApiHolder(); + const config = apiHolder.get(configApiRef); + return {config?.getString('backend.baseUrl')}; + }; + + const dom = await renderWithEffects( + + + , + ); + + // Verify that the backend.baseUrl is set correctly by the AppManager. + expect(dom.getByText(document.location.origin)).toBeTruthy(); + }); + + it('should NOT change the origin when the backend.baseUrl is absolute', async () => { + const backendUrl = 'http://localhost:7007'; + const app = new AppManager({ + apis: [], + defaultApis: [], + themes: [ + { + id: 'light', + title: 'Light Theme', + variant: 'light', + Provider: ({ children }) => <>{children}, + }, + ], + icons, + plugins: [], + components, + configLoader: async () => [ + { + context: 'test', + data: { + backend: { + baseUrl: backendUrl, + }, + }, + }, + ], + }); + + const Provider = app.getProvider(); + const ConfigDisplay = () => { + const apiHolder = useApiHolder(); + const config = apiHolder.get(configApiRef); + return {config?.getString('backend.baseUrl')}; + }; + + const dom = await renderWithEffects( + + + , + ); + + // Verify that the backend.baseUrl is set correctly by the AppManager. + expect(dom.getByText(backendUrl)).toBeTruthy(); + }); }); diff --git a/packages/core-app-api/src/app/AppManager.tsx b/packages/core-app-api/src/app/AppManager.tsx index bbd27f84ce..cd571c7799 100644 --- a/packages/core-app-api/src/app/AppManager.tsx +++ b/packages/core-app-api/src/app/AppManager.tsx @@ -154,7 +154,34 @@ function useConfigLoader( }; } - const configReader = ConfigReader.fromConfigs(config.value ?? []); + let configReader = ConfigReader.fromConfigs(config.value ?? []); + + const getFullBackendUrl = () => { + // Backend.baseUrl should always be defined. + let url; + try { + url = new URL( + configReader.getString('backend.baseUrl'), + document.location.origin, + ).href.replace(/\/$/, ''); + } catch (err) { + // Backend.baseUrl was not a valid URL. This should be caught during the build process. + } + return url; + }; + + const relativeBackendConfig = { + data: { + backend: { + baseUrl: getFullBackendUrl(), + }, + }, + context: 'relative-override', + }; + + configReader = ConfigReader.fromConfigs( + config.value ? [...config.value, relativeBackendConfig] : [], + ); return { api: configReader }; }