feat: finishing up some other use cases and re-writing some logic with some more tests
Signed-off-by: blam <ben@blam.sh>
This commit is contained in:
@@ -114,7 +114,7 @@ const routes = (
|
||||
path="/tech-radar"
|
||||
element={<TechRadarPage width={1500} height={800} />}
|
||||
/>
|
||||
<FeatureFlagged flag="show-graphiql-page">
|
||||
<FeatureFlagged with="show-graphiql-page">
|
||||
<Route path="/graphiql" element={<GraphiQLPage />} />
|
||||
</FeatureFlagged>
|
||||
<Route path="/lighthouse" element={<LighthousePage />} />
|
||||
|
||||
@@ -283,7 +283,7 @@ const serviceEntityPage = (
|
||||
{overviewContent}
|
||||
</EntityLayout.Route>
|
||||
|
||||
<FeatureFlagged flag="show-graphiql-page">
|
||||
<FeatureFlagged with="show-graphiql-page">
|
||||
<EntityLayout.Route path="/ci-cd" title="CI/CD">
|
||||
{cicdContent}
|
||||
</EntityLayout.Route>
|
||||
@@ -306,7 +306,7 @@ const serviceEntityPage = (
|
||||
|
||||
<EntityLayout.Route path="/dependencies" title="Dependencies">
|
||||
<Grid container spacing={3} alignItems="stretch">
|
||||
<FeatureFlagged flag="show-graphiql-page">
|
||||
<FeatureFlagged with="show-graphiql-page">
|
||||
<Grid item md={6}>
|
||||
<EntityDependsOnComponentsCard variant="gridItem" />
|
||||
</Grid>
|
||||
|
||||
@@ -177,8 +177,8 @@ export const featureFlagCollector = createCollector(
|
||||
() => new Set<string>(),
|
||||
(acc, node) => {
|
||||
if (node.type === FeatureFlagged) {
|
||||
const { flag } = node.props as FeatureFlaggedProps;
|
||||
acc.add(flag);
|
||||
const props = node.props as FeatureFlaggedProps;
|
||||
acc.add('with' in props ? props.with : props.without);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
@@ -37,8 +37,11 @@ attachComponentData(InnerComponent, INNER_COMPONENT_KEY, {
|
||||
});
|
||||
const MockComponent = (_props: { children: ReactNode }) => null;
|
||||
|
||||
const FeatureFlagComponent = (_props: { children: ReactNode; flag: string }) =>
|
||||
null;
|
||||
const FeatureFlagComponent = (_props: {
|
||||
children: ReactNode;
|
||||
with?: string;
|
||||
without?: string;
|
||||
}) => null;
|
||||
attachComponentData(FeatureFlagComponent, 'core.featureFlagged', true);
|
||||
const mockFeatureFlagsApi = new LocalStorageFeatureFlags();
|
||||
const Wrapper = ({ children }: { children?: React.ReactNode }) => (
|
||||
@@ -151,73 +154,155 @@ describe('useElementFilter', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should not discover deeper than the feature gate if the feature flag is disabled', () => {
|
||||
jest.spyOn(mockFeatureFlagsApi, 'isActive').mockImplementation(() => false);
|
||||
const tree = (
|
||||
<MockComponent>
|
||||
<FeatureFlagComponent flag="testing-flag">
|
||||
<WrappingComponent key="first">
|
||||
describe('FeatureFlags', () => {
|
||||
describe('with', () => {
|
||||
it('should not discover deeper than the feature gate if the feature flag is disabled', () => {
|
||||
jest
|
||||
.spyOn(mockFeatureFlagsApi, 'isActive')
|
||||
.mockImplementation(() => false);
|
||||
const tree = (
|
||||
<MockComponent>
|
||||
<FeatureFlagComponent with="testing-flag">
|
||||
<WrappingComponent key="first">
|
||||
<InnerComponent />
|
||||
</WrappingComponent>
|
||||
</FeatureFlagComponent>
|
||||
<MockComponent>
|
||||
<WrappingComponent key="second">
|
||||
<InnerComponent />
|
||||
</WrappingComponent>
|
||||
</MockComponent>
|
||||
<InnerComponent />
|
||||
</WrappingComponent>
|
||||
</FeatureFlagComponent>
|
||||
<MockComponent>
|
||||
<WrappingComponent key="second">
|
||||
</MockComponent>
|
||||
);
|
||||
|
||||
const { result } = renderHook(
|
||||
props =>
|
||||
useElementFilter(props.tree, elements =>
|
||||
elements
|
||||
.selectByComponentData({ key: WRAPPING_COMPONENT_KEY })
|
||||
.getElements(),
|
||||
),
|
||||
{
|
||||
initialProps: { tree },
|
||||
wrapper: Wrapper,
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current.length).toBe(1);
|
||||
expect(result.current[0].key).toContain('second');
|
||||
});
|
||||
|
||||
it('should discover components behind a feature flag if the flag is enabled', () => {
|
||||
jest
|
||||
.spyOn(mockFeatureFlagsApi, 'isActive')
|
||||
.mockImplementation(() => true);
|
||||
const tree = (
|
||||
<MockComponent>
|
||||
<FeatureFlagComponent with="testing-flag">
|
||||
<WrappingComponent key="first">
|
||||
<InnerComponent />
|
||||
</WrappingComponent>
|
||||
</FeatureFlagComponent>
|
||||
<MockComponent>
|
||||
<WrappingComponent key="second">
|
||||
<InnerComponent />
|
||||
</WrappingComponent>
|
||||
</MockComponent>
|
||||
<InnerComponent />
|
||||
</WrappingComponent>
|
||||
</MockComponent>
|
||||
<InnerComponent />
|
||||
</MockComponent>
|
||||
);
|
||||
</MockComponent>
|
||||
);
|
||||
|
||||
const { result } = renderHook(
|
||||
props =>
|
||||
useElementFilter(props.tree, elements =>
|
||||
elements
|
||||
.selectByComponentData({ key: WRAPPING_COMPONENT_KEY })
|
||||
.getElements(),
|
||||
),
|
||||
{
|
||||
initialProps: { tree },
|
||||
wrapper: Wrapper,
|
||||
},
|
||||
);
|
||||
const { result } = renderHook(
|
||||
props =>
|
||||
useElementFilter(props.tree, elements =>
|
||||
elements
|
||||
.selectByComponentData({ key: WRAPPING_COMPONENT_KEY })
|
||||
.getElements(),
|
||||
),
|
||||
{
|
||||
initialProps: { tree },
|
||||
wrapper: Wrapper,
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current.length).toBe(1);
|
||||
expect(result.current[0].key).toContain('second');
|
||||
});
|
||||
expect(result.current.length).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
it('should discover components behind a feature flag if the flag is enabled', () => {
|
||||
jest.spyOn(mockFeatureFlagsApi, 'isActive').mockImplementation(() => true);
|
||||
const tree = (
|
||||
<MockComponent>
|
||||
<FeatureFlagComponent flag="testing-flag">
|
||||
<WrappingComponent key="first">
|
||||
describe('without', () => {
|
||||
it('should discover deeper than the feature gate if the feature flag is disabled', () => {
|
||||
jest
|
||||
.spyOn(mockFeatureFlagsApi, 'isActive')
|
||||
.mockImplementation(() => false);
|
||||
const tree = (
|
||||
<MockComponent>
|
||||
<FeatureFlagComponent without="testing-flag">
|
||||
<WrappingComponent key="first">
|
||||
<InnerComponent />
|
||||
</WrappingComponent>
|
||||
</FeatureFlagComponent>
|
||||
<MockComponent>
|
||||
<WrappingComponent key="second">
|
||||
<InnerComponent />
|
||||
</WrappingComponent>
|
||||
</MockComponent>
|
||||
<InnerComponent />
|
||||
</WrappingComponent>
|
||||
</FeatureFlagComponent>
|
||||
<MockComponent>
|
||||
<WrappingComponent key="second">
|
||||
</MockComponent>
|
||||
);
|
||||
|
||||
const { result } = renderHook(
|
||||
props =>
|
||||
useElementFilter(props.tree, elements =>
|
||||
elements
|
||||
.selectByComponentData({ key: WRAPPING_COMPONENT_KEY })
|
||||
.getElements(),
|
||||
),
|
||||
{
|
||||
initialProps: { tree },
|
||||
wrapper: Wrapper,
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current.length).toBe(2);
|
||||
});
|
||||
|
||||
it('should not discover components behind a feature flag if the flag is enabled', () => {
|
||||
jest
|
||||
.spyOn(mockFeatureFlagsApi, 'isActive')
|
||||
.mockImplementation(() => true);
|
||||
const tree = (
|
||||
<MockComponent>
|
||||
<FeatureFlagComponent without="testing-flag">
|
||||
<WrappingComponent key="first">
|
||||
<InnerComponent />
|
||||
</WrappingComponent>
|
||||
</FeatureFlagComponent>
|
||||
<MockComponent>
|
||||
<WrappingComponent key="second">
|
||||
<InnerComponent />
|
||||
</WrappingComponent>
|
||||
</MockComponent>
|
||||
<InnerComponent />
|
||||
</WrappingComponent>
|
||||
</MockComponent>
|
||||
<InnerComponent />
|
||||
</MockComponent>
|
||||
);
|
||||
</MockComponent>
|
||||
);
|
||||
|
||||
const { result } = renderHook(
|
||||
props =>
|
||||
useElementFilter(props.tree, elements =>
|
||||
elements
|
||||
.selectByComponentData({ key: WRAPPING_COMPONENT_KEY })
|
||||
.getElements(),
|
||||
),
|
||||
{
|
||||
initialProps: { tree },
|
||||
wrapper: Wrapper,
|
||||
},
|
||||
);
|
||||
const { result } = renderHook(
|
||||
props =>
|
||||
useElementFilter(props.tree, elements =>
|
||||
elements
|
||||
.selectByComponentData({ key: WRAPPING_COMPONENT_KEY })
|
||||
.getElements(),
|
||||
),
|
||||
{
|
||||
initialProps: { tree },
|
||||
wrapper: Wrapper,
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current.length).toBe(2);
|
||||
expect(result.current.length).toBe(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should reject when strict mode is enabled with the correct string', () => {
|
||||
@@ -252,7 +337,7 @@ describe('useElementFilter', () => {
|
||||
<>
|
||||
<MockComponent>
|
||||
<>
|
||||
<FeatureFlagComponent flag="testing-flag">
|
||||
<FeatureFlagComponent with="testing-flag">
|
||||
<WrappingComponent key="first">
|
||||
<InnerComponent />
|
||||
</WrappingComponent>
|
||||
|
||||
@@ -45,8 +45,12 @@ function selectChildren(
|
||||
}
|
||||
|
||||
if (getComponentData(node, 'core.featureFlagged')) {
|
||||
const { flag } = node.props as { flag: string };
|
||||
if (featureFlagsApi.isActive(flag)) {
|
||||
const props = node.props as { with: string } | { without: string };
|
||||
const isEnabled =
|
||||
'with' in props
|
||||
? featureFlagsApi.isActive(props.with)
|
||||
: !featureFlagsApi.isActive(props.without);
|
||||
if (isEnabled) {
|
||||
return selectChildren(
|
||||
node.props.children,
|
||||
featureFlagsApi,
|
||||
|
||||
@@ -40,6 +40,7 @@ describe('index', () => {
|
||||
useApi: expect.any(Function),
|
||||
useApiHolder: expect.any(Function),
|
||||
useApp: expect.any(Function),
|
||||
useElementFilter: expect.any(Function),
|
||||
useRouteRef: expect.any(Function),
|
||||
useRouteRefParams: expect.any(Function),
|
||||
withApis: expect.any(Function),
|
||||
|
||||
Reference in New Issue
Block a user