diff --git a/packages/core-app-api/src/app/AppManager.test.tsx b/packages/core-app-api/src/app/AppManager.test.tsx index 33b7ad5b9a..b8aeb21818 100644 --- a/packages/core-app-api/src/app/AppManager.test.tsx +++ b/packages/core-app-api/src/app/AppManager.test.tsx @@ -571,92 +571,128 @@ 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: '/', - }, + describe('relative url resolvers', () => { + const checkConfigValue = async ( + data: object, + configString: string, + expectedValue: string, + ) => { + 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, + }, + ], + }); + + const Provider = app.getProvider(); + const ConfigDisplay = () => { + const apiHolder = useApiHolder(); + const config = apiHolder.get(configApiRef); + return {config?.getString(configString)}; + }; + + const dom = await renderWithEffects( + + + , + ); + + // Verify that the backend.baseUrl is set correctly by the AppManager. + expect(dom.getByText(expectedValue)).toBeTruthy(); + }; + [ + { + 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, - }, + paths: ['backend.baseUrl'], + }, + { + data: { + app: { + baseUrl: '/', }, }, - ], + paths: ['app.baseUrl'], + }, + { + data: { + backend: { + baseUrl: '/', + }, + app: { + baseUrl: '/', + }, + }, + paths: ['app.baseUrl', 'backend.baseUrl'], + }, + ].forEach(item => { + item.paths.forEach(path => { + it('should add the fully qualified origin when the relevant urls are relative', async () => { + await checkConfigValue(item.data, path, 'http://localhost'); + }); + }); + }); + [ + { + data: { + backend: { + baseUrl: 'https://google.com', + }, + }, + paths: ['backend.baseUrl'], + }, + { + data: { + app: { + baseUrl: 'https://bing.com', + }, + }, + paths: ['app.baseUrl'], + }, + { + data: { + backend: { + baseUrl: 'https://google.com', + }, + app: { + baseUrl: 'https://bing.com', + }, + }, + paths: ['app.baseUrl', 'backend.baseUrl'], + }, + ].forEach(item => { + item.paths.forEach(path => { + it('should NOT change the origin when the relevant urls are absolute', async () => { + await checkConfigValue( + item.data, + path, + path + .split('.') + .reduce( + (o, i) => o[i] as { [key: string]: object }, + item.data as { [key: string]: object }, + ) as unknown as string, + ); + }); + }); }); - - 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 176171e975..abf4d44318 100644 --- a/packages/core-app-api/src/app/AppManager.tsx +++ b/packages/core-app-api/src/app/AppManager.tsx @@ -156,33 +156,35 @@ function useConfigLoader( let configReader = ConfigReader.fromConfigs(config.value ?? []); - const getFullBackendUrl = () => { + const resolveRelativeUrl = (relativeUrl: string) => { // Backend.baseUrl should always be defined. let url; try { - url = new URL( - configReader.getString('backend.baseUrl'), - document.location.origin, - ).href.replace(/\/$/, ''); + url = new URL(relativeUrl, 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 = { + config.value?.push({ data: { + app: { + baseUrl: resolveRelativeUrl( + configReader.getOptionalString('app.baseUrl') || '/', + ), + }, backend: { - baseUrl: getFullBackendUrl(), + baseUrl: resolveRelativeUrl( + configReader.getOptionalString('backend.baseUrl') || '/', + ), }, }, - context: 'relative-override', - }; - - // Config reader may not have backend.baseUrl set. config.value may be undefined. - if (configReader.getOptionalString('backend.baseUrl')?.startsWith('/')) { - config.value?.push(relativeBackendConfig); - } + context: 'relative-resolver', + }); configReader = ConfigReader.fromConfigs(config.value ?? []);