diff --git a/packages/core-app-api/package.json b/packages/core-app-api/package.json index 1c15f7d6f5..9a10514ab7 100644 --- a/packages/core-app-api/package.json +++ b/packages/core-app-api/package.json @@ -37,6 +37,7 @@ "@backstage/types": "workspace:^", "@backstage/version-bridge": "workspace:^", "@types/prop-types": "^15.7.3", + "canvas": "^2.10.2", "prop-types": "^15.7.2", "react-use": "^17.2.4", "zen-observable": "^0.9.0", diff --git a/packages/core-app-api/src/app/AppManager.test.tsx b/packages/core-app-api/src/app/AppManager.test.tsx index c70b43581a..b03fedd89a 100644 --- a/packages/core-app-api/src/app/AppManager.test.tsx +++ b/packages/core-app-api/src/app/AppManager.test.tsx @@ -34,9 +34,11 @@ import { createSubRouteRef, createRoutableExtension, analyticsApiRef, + useApi, } from '@backstage/core-plugin-api'; import { AppManager } from './AppManager'; import { AppComponents, AppIcons } from './types'; +import { FeatureFlagged } from '../routing/FeatureFlagged'; describe('Integration Test', () => { const noOpAnalyticsApi = createApiFactory( @@ -415,6 +417,82 @@ describe('Integration Test', () => { }); }); + it('should prevent duplicate feature flags from being rendered', async () => { + const p1 = createPlugin({ + id: 'p1', + featureFlags: [{ name: 'show-p1-feature' }], + }); + const p2 = createPlugin({ + id: 'p2', + featureFlags: [{ name: 'show-p2-feature' }], + }); + + const storageFlags = new LocalStorageFeatureFlags(); + jest.spyOn(storageFlags, 'registerFlag'); + + const apis = [ + noOpAnalyticsApi, + createApiFactory({ + api: featureFlagsApiRef, + deps: { configApi: configApiRef }, + factory() { + return storageFlags; + }, + }), + ]; + + const app = new AppManager({ + apis, + defaultApis: [], + themes: [ + { + id: 'light', + title: 'Light Theme', + variant: 'light', + Provider: ({ children }) => <>{children}>, + }, + ], + icons, + plugins: [p1, p2], + components, + configLoader: async () => [], + bindRoutes: ({ bind }) => { + bind(plugin1.externalRoutes, { + extRouteRef1: plugin1RouteRef, + extRouteRef2: plugin2RouteRef, + }); + }, + }); + + const Provider = app.getProvider(); + const Router = app.getRouter(); + + function FeatureFlags() { + const featureFlags = useApi(featureFlagsApiRef); + return ( +