mirror of
https://github.com/datahub-project/datahub.git
synced 2025-11-01 19:25:56 +00:00
feat(ui): add summary page feature flag to local storage and make it generic (#14807)
Co-authored-by: Chris Collins <chriscollins3456@gmail.com>
This commit is contained in:
parent
7768abc6eb
commit
d268d14ee2
@ -64,11 +64,4 @@ describe('useShowAssetSummaryPage', () => {
|
||||
const { result } = renderHook(() => useShowAssetSummaryPage());
|
||||
expect(result.current).toBe(false);
|
||||
});
|
||||
|
||||
it('should return false when appConfig is undefined', () => {
|
||||
mockedUseAppConfig.mockReturnValue(undefined as any);
|
||||
|
||||
const { result } = renderHook(() => useShowAssetSummaryPage());
|
||||
expect(result.current).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,9 +1,6 @@
|
||||
import { useAppConfig } from '@app/useAppConfig';
|
||||
import { useFeatureFlag } from '@app/sharedV2/hooks/useFeatureFlag';
|
||||
|
||||
export function useShowAssetSummaryPage() {
|
||||
const appConfig = useAppConfig();
|
||||
if (appConfig?.loaded) {
|
||||
return appConfig.config.featureFlags.assetSummaryPageV1;
|
||||
}
|
||||
return false;
|
||||
const assetSummaryPageV1 = useFeatureFlag('assetSummaryPageV1');
|
||||
return assetSummaryPageV1;
|
||||
}
|
||||
|
||||
@ -0,0 +1,122 @@
|
||||
import { renderHook } from '@testing-library/react-hooks';
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { loadFeatureFlagFromLocalStorage, useFeatureFlag } from '@app/sharedV2/hooks/useFeatureFlag';
|
||||
import { useAppConfig } from '@app/useAppConfig';
|
||||
|
||||
// Mocks
|
||||
const localStorageMock = (() => {
|
||||
let store: Record<string, string> = {};
|
||||
return {
|
||||
getItem: (key: string) => store[key] ?? null,
|
||||
setItem: (key: string, value: string) => {
|
||||
store[key] = value;
|
||||
},
|
||||
clear: () => {
|
||||
store = {};
|
||||
},
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(window, 'localStorage', { value: localStorageMock });
|
||||
|
||||
vi.mock('@app/useAppConfig', () => ({
|
||||
useAppConfig: vi.fn(),
|
||||
}));
|
||||
|
||||
describe('useFeatureFlag', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
localStorage.clear();
|
||||
});
|
||||
|
||||
it('should return flag value from appConfig and set localStorage when config loaded', () => {
|
||||
(useAppConfig as any).mockReturnValue({
|
||||
loaded: true,
|
||||
config: { featureFlags: { myFlag: true } },
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useFeatureFlag('myFlag'));
|
||||
|
||||
expect(result.current).toBe(true);
|
||||
expect(localStorage.getItem('myFlag')).toBe('true');
|
||||
});
|
||||
|
||||
it('should not set localStorage if value is unchanged', () => {
|
||||
localStorage.setItem('myFlag', 'true');
|
||||
|
||||
(useAppConfig as any).mockReturnValue({
|
||||
loaded: true,
|
||||
config: { featureFlags: { myFlag: true } },
|
||||
});
|
||||
|
||||
const setItemSpy = vi.spyOn(localStorage, 'setItem');
|
||||
|
||||
renderHook(() => useFeatureFlag('myFlag'));
|
||||
|
||||
expect(setItemSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should return value from localStorage if config not loaded', () => {
|
||||
localStorage.setItem('myFlag', 'true');
|
||||
|
||||
(useAppConfig as any).mockReturnValue({
|
||||
loaded: false,
|
||||
config: { featureFlags: { myFlag: false } },
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useFeatureFlag('myFlag'));
|
||||
|
||||
expect(result.current).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false if localStorage has no value and config not loaded', () => {
|
||||
(useAppConfig as any).mockReturnValue({
|
||||
loaded: false,
|
||||
config: { featureFlags: {} },
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useFeatureFlag('myFlag'));
|
||||
|
||||
expect(result.current).toBe(false);
|
||||
});
|
||||
|
||||
it('should return false if feature flag is undefined in loaded config', () => {
|
||||
(useAppConfig as any).mockReturnValue({
|
||||
loaded: true,
|
||||
config: { featureFlags: {} },
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useFeatureFlag('myFlag'));
|
||||
expect(result.current).toBe(undefined);
|
||||
});
|
||||
|
||||
it('should store false value in localStorage if feature flag is false and config loaded', () => {
|
||||
(useAppConfig as any).mockReturnValue({
|
||||
loaded: true,
|
||||
config: { featureFlags: { myFlag: false } },
|
||||
});
|
||||
|
||||
renderHook(() => useFeatureFlag('myFlag'));
|
||||
expect(localStorage.getItem('myFlag')).toBe('false');
|
||||
});
|
||||
});
|
||||
|
||||
describe('loadFeatureFlagFromLocalStorage', () => {
|
||||
beforeEach(() => {
|
||||
localStorage.clear();
|
||||
});
|
||||
|
||||
it('should return true if localStorage value is true', () => {
|
||||
localStorage.setItem('someFlag', 'true');
|
||||
expect(loadFeatureFlagFromLocalStorage('someFlag')).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false if localStorage value is false', () => {
|
||||
localStorage.setItem('someFlag', 'false');
|
||||
expect(loadFeatureFlagFromLocalStorage('someFlag')).toBe(false);
|
||||
});
|
||||
|
||||
it('should return false if localStorage has no key', () => {
|
||||
expect(loadFeatureFlagFromLocalStorage('someFlag')).toBe(false);
|
||||
});
|
||||
});
|
||||
31
datahub-web-react/src/app/sharedV2/hooks/useFeatureFlag.ts
Normal file
31
datahub-web-react/src/app/sharedV2/hooks/useFeatureFlag.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import { useAppConfig } from '@app/useAppConfig';
|
||||
|
||||
export function useFeatureFlag(featureFlagKey: string) {
|
||||
const appConfig = useAppConfig();
|
||||
|
||||
const featureFlagValue = appConfig?.config?.featureFlags?.[featureFlagKey];
|
||||
|
||||
if (appConfig.loaded) {
|
||||
setFeatureFlagInLocalStorage(featureFlagKey, featureFlagValue);
|
||||
return featureFlagValue;
|
||||
}
|
||||
|
||||
return loadFeatureFlagFromLocalStorage(featureFlagKey);
|
||||
}
|
||||
|
||||
function setFeatureFlagInLocalStorage(flagKey: string, value: boolean) {
|
||||
const rawValue = localStorage.getItem(flagKey);
|
||||
const storedValue = rawValue === null ? undefined : rawValue === 'true';
|
||||
|
||||
if (rawValue === null || storedValue !== value) {
|
||||
saveFeatureFlagToLocalStorage(flagKey, value);
|
||||
}
|
||||
}
|
||||
|
||||
export function loadFeatureFlagFromLocalStorage(flagKey: string): boolean {
|
||||
return localStorage.getItem(flagKey) === 'true';
|
||||
}
|
||||
|
||||
function saveFeatureFlagToLocalStorage(flagKey: string, value: boolean) {
|
||||
localStorage.setItem(flagKey, String(value));
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user