From c92f5dedee4e0e80002f1176444c62cfe880e546 Mon Sep 17 00:00:00 2001 From: blam Date: Sat, 12 Jun 2021 17:35:08 +0200 Subject: [PATCH] feat: reworking the api in favour of `with` and `without` for wrapping component Signed-off-by: blam --- .../src/routing/FeatureFlagged.test.tsx | 102 ++++++++++++++++++ .../src/routing/FeatureFlagged.tsx | 20 +++- 2 files changed, 118 insertions(+), 4 deletions(-) create mode 100644 packages/core-app-api/src/routing/FeatureFlagged.test.tsx diff --git a/packages/core-app-api/src/routing/FeatureFlagged.test.tsx b/packages/core-app-api/src/routing/FeatureFlagged.test.tsx new file mode 100644 index 0000000000..e20af76ae1 --- /dev/null +++ b/packages/core-app-api/src/routing/FeatureFlagged.test.tsx @@ -0,0 +1,102 @@ +/* + * Copyright 2021 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { FeatureFlagged } from './FeatureFlagged'; +import { render } from '@testing-library/react'; +import { ApiProvider, ApiRegistry, LocalStorageFeatureFlags } from '../apis'; +import { featureFlagsApiRef } from '@backstage/core-plugin-api'; + +const mockFeatureFlagsApi = new LocalStorageFeatureFlags(); +const Wrapper = ({ children }: { children?: React.ReactNode }) => ( + + {children} + +); + +describe('FeatureFlagged', () => { + describe('with', () => { + it('should render contents when the feature flag is enabled', async () => { + jest + .spyOn(mockFeatureFlagsApi, 'isActive') + .mockImplementation(() => true); + + const { queryByText } = render( + +
+ +

BACKSTAGE!

+
+
+
, + ); + + expect(await queryByText('BACKSTAGE!')).toBeInTheDocument(); + }); + it('should not render contents when the feature flag is disabled', async () => { + jest + .spyOn(mockFeatureFlagsApi, 'isActive') + .mockImplementation(() => false); + + const { queryByText } = render( + +
+ +

BACKSTAGE!

+
+
+
, + ); + + expect(await queryByText('BACKSTAGE!')).not.toBeInTheDocument(); + }); + }); + describe('without', () => { + it('should not render contents when the feature flag is enabled', async () => { + jest + .spyOn(mockFeatureFlagsApi, 'isActive') + .mockImplementation(() => true); + + const { queryByText } = render( + +
+ +

BACKSTAGE!

+
+
+
, + ); + + expect(await queryByText('BACKSTAGE!')).not.toBeInTheDocument(); + }); + it('should render contents when the feature flag is disabled', async () => { + jest + .spyOn(mockFeatureFlagsApi, 'isActive') + .mockImplementation(() => false); + + const { queryByText } = render( + +
+ +

BACKSTAGE!

+
+
+
, + ); + + expect(await queryByText('BACKSTAGE!')).toBeInTheDocument(); + }); + }); +}); diff --git a/packages/core-app-api/src/routing/FeatureFlagged.tsx b/packages/core-app-api/src/routing/FeatureFlagged.tsx index 0adda78842..5b20d9aaac 100644 --- a/packages/core-app-api/src/routing/FeatureFlagged.tsx +++ b/packages/core-app-api/src/routing/FeatureFlagged.tsx @@ -20,14 +20,26 @@ import { attachComponentData, } from '@backstage/core-plugin-api'; -export type FeatureFlaggedProps = { - flag: string; +export type FeatureFlaggedWith = { + with: string; +}; + +export type FeatureFlaggedWithout = { + without: string; +}; + +export type FeatureFlaggedSelector = FeatureFlaggedWith | FeatureFlaggedWithout; +export type FeatureFlaggedProps = FeatureFlaggedSelector & { children: JSX.Element | null; }; -export const FeatureFlagged = ({ children, flag }: FeatureFlaggedProps) => { +export const FeatureFlagged = (props: FeatureFlaggedProps) => { + const { children } = props; const featureFlagApi = useApi(featureFlagsApiRef); - const isEnabled = featureFlagApi.isActive(flag); + const isEnabled = + 'with' in props + ? featureFlagApi.isActive(props.with) + : !featureFlagApi.isActive(props.without); return isEnabled ? children : null; };