peregrine/web/src/stores/appConfig.test.ts
pyr0ball 49e3265132 feat(web): merge Vue SPA from feature/vue-spa; add ClassicUIButton + useFeatureFlag
- Import web/ directory (Vue 3 + Vite + UnoCSS SPA) from feature/vue-spa branch
- Add web/src/components/ClassicUIButton.vue: switch-back to Streamlit via
  cookie (prgn_ui=streamlit) + ?prgn_switch=streamlit query param bridge
- Add web/src/composables/useFeatureFlag.ts: reads prgn_demo_tier cookie for
  demo toolbar visual consistency (not an authoritative gate, see issue #8)
- Update .gitignore: add .superpowers/, pytest-output.txt, docs/superpowers/
2026-03-22 18:46:11 -07:00

41 lines
1.2 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from 'vitest'
import { setActivePinia, createPinia } from 'pinia'
import { useAppConfigStore } from './appConfig'
vi.mock('../composables/useApi', () => ({
useApiFetch: vi.fn(),
}))
import { useApiFetch } from '../composables/useApi'
const mockFetch = vi.mocked(useApiFetch)
describe('useAppConfigStore', () => {
beforeEach(() => {
setActivePinia(createPinia())
vi.clearAllMocks()
})
it('defaults to safe values before load', () => {
const store = useAppConfigStore()
expect(store.isCloud).toBe(false)
expect(store.tier).toBe('free')
})
it('load() populates from API response', async () => {
mockFetch.mockResolvedValue({
data: { isCloud: true, isDevMode: false, tier: 'paid', contractedClient: false, inferenceProfile: 'cpu' },
error: null,
})
const store = useAppConfigStore()
await store.load()
expect(store.isCloud).toBe(true)
expect(store.tier).toBe('paid')
})
it('load() error leaves defaults intact', async () => {
mockFetch.mockResolvedValue({ data: null, error: { kind: 'network', message: 'fail' } })
const store = useAppConfigStore()
await store.load()
expect(store.isCloud).toBe(false)
})
})