peregrine/web/src/stores/settings/system.test.ts
pyr0ball 5afb752be6 fix(settings): system tab review fixes
- guard confirmByok() against byok-ack POST failure (leave modal open on error)
- fix drag reorder to use ID-based index lookup (not filtered-list index)
- guard cancelByok() against empty snapshot
- add LlmConfigPayload Pydantic model for PUT endpoint
- add test for confirmByok() failure path
2026-03-22 12:01:55 -07:00

73 lines
3.3 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from 'vitest'
import { setActivePinia, createPinia } from 'pinia'
import { useSystemStore } from './system'
vi.mock('../../composables/useApi', () => ({ useApiFetch: vi.fn() }))
import { useApiFetch } from '../../composables/useApi'
const mockFetch = vi.mocked(useApiFetch)
describe('useSystemStore — BYOK gate', () => {
beforeEach(() => { setActivePinia(createPinia()); vi.clearAllMocks() })
it('save() proceeds without modal when no cloud backends enabled', async () => {
mockFetch.mockResolvedValue({ data: { ok: true }, error: null })
const store = useSystemStore()
store.backends = [{ id: 'ollama', enabled: true, priority: 1 }]
store.byokAcknowledged = []
await store.trySave()
expect(store.byokPending).toHaveLength(0)
expect(mockFetch).toHaveBeenCalledWith('/api/settings/system/llm', expect.anything())
})
it('save() sets byokPending when new cloud backend enabled', async () => {
const store = useSystemStore()
store.backends = [{ id: 'anthropic', enabled: true, priority: 1 }]
store.byokAcknowledged = []
await store.trySave()
expect(store.byokPending).toContain('anthropic')
expect(mockFetch).not.toHaveBeenCalledWith('/api/settings/system/llm', expect.anything())
})
it('save() skips modal for already-acknowledged backends', async () => {
mockFetch.mockResolvedValue({ data: { ok: true }, error: null })
const store = useSystemStore()
store.backends = [{ id: 'anthropic', enabled: true, priority: 1 }]
store.byokAcknowledged = ['anthropic']
await store.trySave()
expect(store.byokPending).toHaveLength(0)
})
it('confirmByok() saves acknowledgment then commits LLM config', async () => {
mockFetch.mockResolvedValue({ data: { ok: true }, error: null })
const store = useSystemStore()
store.byokPending = ['anthropic']
store.backends = [{ id: 'anthropic', enabled: true, priority: 1 }]
await store.confirmByok()
expect(mockFetch).toHaveBeenCalledWith('/api/settings/system/llm/byok-ack', expect.anything())
expect(mockFetch).toHaveBeenCalledWith('/api/settings/system/llm', expect.anything())
})
it('confirmByok() sets saveError and leaves modal open when ack POST fails', async () => {
mockFetch.mockResolvedValue({ data: null, error: 'Network error' })
const store = useSystemStore()
store.byokPending = ['anthropic']
store.backends = [{ id: 'anthropic', enabled: true, priority: 1 }]
await store.confirmByok()
expect(store.saveError).toBeTruthy()
expect(store.byokPending).toContain('anthropic') // modal stays open
expect(mockFetch).not.toHaveBeenCalledWith('/api/settings/system/llm', expect.anything())
})
it('cancelByok() clears pending and restores backends to pre-save state', async () => {
mockFetch.mockResolvedValue({ data: { ok: true }, error: null })
const store = useSystemStore()
const original = [{ id: 'ollama', enabled: true, priority: 1 }]
store.backends = [...original]
await store.trySave() // captures snapshot, commits (no cloud backends)
store.backends = [{ id: 'anthropic', enabled: true, priority: 1 }]
store.byokPending = ['anthropic']
store.cancelByok()
expect(store.byokPending).toHaveLength(0)
expect(store.backends).toEqual(original)
})
})