import { act, renderHook } from '@testing-library/react'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; const LOCAL_KEY = 'goodgo:avm_v2'; function installMemoryStorage(): Storage { const store = new Map(); const storage: Storage = { get length() { return store.size; }, clear: () => store.clear(), getItem: (k) => (store.has(k) ? store.get(k)! : null), key: (i) => Array.from(store.keys())[i] ?? null, removeItem: (k) => { store.delete(k); }, setItem: (k, v) => { store.set(k, String(v)); }, }; vi.stubGlobal('localStorage', storage); Object.defineProperty(window, 'localStorage', { configurable: true, value: storage, }); return storage; } describe('useAvmV2Flag', () => { let storage: Storage; beforeEach(() => { vi.resetModules(); storage = installMemoryStorage(); window.history.replaceState({}, '', '/'); delete (process.env as Record)[ 'NEXT_PUBLIC_FEATURE_AVM_V2' ]; }); afterEach(() => { storage.clear(); vi.unstubAllGlobals(); }); it('returns false by default when env flag is not set', async () => { const { useAvmV2Flag } = await import('../use-avm-v2-flag'); const { result } = renderHook(() => useAvmV2Flag()); expect(result.current).toBe(false); }); it('returns true when NEXT_PUBLIC_FEATURE_AVM_V2 is "1"', async () => { process.env['NEXT_PUBLIC_FEATURE_AVM_V2'] = '1'; const { useAvmV2Flag } = await import('../use-avm-v2-flag'); const { result } = renderHook(() => useAvmV2Flag()); expect(result.current).toBe(true); }); it('returns true when NEXT_PUBLIC_FEATURE_AVM_V2 is "true"', async () => { process.env['NEXT_PUBLIC_FEATURE_AVM_V2'] = 'true'; const { useAvmV2Flag } = await import('../use-avm-v2-flag'); const { result } = renderHook(() => useAvmV2Flag()); expect(result.current).toBe(true); }); it('query param ?avm_v2=1 forces on and persists to localStorage', async () => { window.history.replaceState({}, '', '/?avm_v2=1'); const { useAvmV2Flag } = await import('../use-avm-v2-flag'); const { result } = renderHook(() => useAvmV2Flag()); await act(async () => { await Promise.resolve(); }); expect(result.current).toBe(true); expect(storage.getItem(LOCAL_KEY)).toBe('1'); }); it('query param ?avm_v2=0 forces off and persists to localStorage', async () => { process.env['NEXT_PUBLIC_FEATURE_AVM_V2'] = '1'; window.history.replaceState({}, '', '/?avm_v2=0'); const { useAvmV2Flag } = await import('../use-avm-v2-flag'); const { result } = renderHook(() => useAvmV2Flag()); await act(async () => { await Promise.resolve(); }); expect(result.current).toBe(false); expect(storage.getItem(LOCAL_KEY)).toBe('0'); }); it('respects localStorage override over env default', async () => { storage.setItem(LOCAL_KEY, '1'); const { useAvmV2Flag } = await import('../use-avm-v2-flag'); const { result } = renderHook(() => useAvmV2Flag()); await act(async () => { await Promise.resolve(); }); expect(result.current).toBe(true); }); });