diff --git a/code/websites/pokedex.online/tests/unit/composables/useFeatureFlags.test.js b/code/websites/pokedex.online/tests/unit/composables/useFeatureFlags.test.js new file mode 100644 index 0000000..4793783 --- /dev/null +++ b/code/websites/pokedex.online/tests/unit/composables/useFeatureFlags.test.js @@ -0,0 +1,74 @@ +/** + * useFeatureFlags Composable Tests + * Verifies feature flag state management and permissions + */ + +import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { useFeatureFlags } from '../../../src/composables/useFeatureFlags.js'; + +describe('useFeatureFlags', () => { + beforeEach(() => { + localStorage.clear(); + }); + + afterEach(() => { + localStorage.clear(); + }); + + it('returns flag default values', () => { + const { isEnabled } = useFeatureFlags(); + + // ENABLE_CACHING defaults to true + expect(isEnabled.value('enable-caching')).toBe(true); + // DARK_MODE defaults to false + expect(isEnabled.value('dark-mode')).toBe(false); + }); + + it('returns false for unknown flag', () => { + const { isEnabled } = useFeatureFlags(); + expect(isEnabled.value('nonexistent-flag')).toBe(false); + }); + + it('returns false for flags requiring unavailable permissions', () => { + const { isEnabled } = useFeatureFlags(); + + // GAMEMASTER_DIFF_VIEWER requires permission + expect(isEnabled.value('gamemaster-diff-viewer')).toBe(false); + }); + + it('returns array of flags from getFlags', () => { + const { getFlags } = useFeatureFlags(); + + const flags = getFlags.value(); + + expect(Array.isArray(flags)).toBe(true); + expect(flags.length).toBeGreaterThan(0); + + // Check structure of returned flags + const darkMode = flags.find(f => f.name === 'dark-mode'); + expect(darkMode).toBeDefined(); + expect(darkMode).toHaveProperty('isEnabled'); + expect(darkMode).toHaveProperty('requiresPermission'); + }); + + it('setBackendFlags updates flag states', () => { + const { isEnabled, setBackendFlags } = useFeatureFlags(); + + expect(isEnabled.value('dark-mode')).toBe(false); + + setBackendFlags({ + 'dark-mode': true, + 'experimental-search': true + }); + + expect(isEnabled.value('dark-mode')).toBe(true); + expect(isEnabled.value('experimental-search')).toBe(true); + }); + + it('supports fetchFromBackend method', () => { + const { fetchFromBackend } = useFeatureFlags(); + + expect(fetchFromBackend).toBeDefined(); + expect(typeof fetchFromBackend).toBe('function'); + }); +});