fix(phase2): restore agent streams and persist extension installations
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
// @vitest-environment happy-dom
|
||||
import { afterEach, beforeEach, expect, it, vi } from 'vitest'
|
||||
import { createPinia, setActivePinia, disposePinia } from 'pinia'
|
||||
import { useAgentStore } from './agent'
|
||||
const mock = vi.hoisted(() => ({ stream: vi.fn(), get: vi.fn(), cancel: vi.fn() }))
|
||||
vi.mock('@/services/agentService', () => ({ streamAgentEvents: mock.stream, getAgentRun: mock.get, cancelAgentRun: mock.cancel }))
|
||||
let pinia: ReturnType<typeof createPinia>
|
||||
beforeEach(() => { vi.useFakeTimers(); vi.clearAllMocks(); pinia = createPinia(); setActivePinia(pinia); mock.stream.mockReturnValue({ cancel: vi.fn() }); mock.get.mockImplementation(async id => ({ run_id: id, status: 'running' })) })
|
||||
afterEach(() => { disposePinia(pinia); vi.useRealTimers() })
|
||||
const handler = () => mock.stream.mock.calls.at(-1)![1]
|
||||
const event = (sequence: number, name = 'RunStarted') => ({ run_id: 'r', sequence, event: name, data: {}, timestamp: 'now' })
|
||||
it.each(['error', 'eof'])('retains cancellation and resumes after sequence on %s', async kind => {
|
||||
const store = useAgentStore(); await store.loadRun('r')
|
||||
handler().onEvent(event(5))
|
||||
kind === 'error' ? handler().onError(new Error('offline')) : handler().onDone()
|
||||
expect(store.isRunning).toBe(true)
|
||||
await vi.advanceTimersByTimeAsync(1000)
|
||||
expect(mock.stream.mock.calls.at(-1)![2]).toBe(5)
|
||||
handler().onEvent(event(5)); handler().onEvent(event(6, 'RunCompleted')); handler().onDone()
|
||||
expect(store.events).toHaveLength(2)
|
||||
expect(store.isRunning).toBe(false)
|
||||
await vi.advanceTimersByTimeAsync(40000)
|
||||
expect(mock.stream).toHaveBeenCalledTimes(2)
|
||||
})
|
||||
it('invalidates old streams and pending retry when changing run or cancelling', async () => {
|
||||
const store = useAgentStore(); await store.loadRun('r')
|
||||
const old = handler(); old.onError(new Error('offline'))
|
||||
await store.loadRun('s'); old.onEvent(event(8))
|
||||
expect(store.events).toHaveLength(0)
|
||||
handler().onError(new Error('offline')); await store.cancelRun('s')
|
||||
await vi.advanceTimersByTimeAsync(40000)
|
||||
expect(mock.stream).toHaveBeenCalledTimes(2)
|
||||
})
|
||||
it('bounds retry attempts and supports explicit retry without losing events', async () => {
|
||||
const store = useAgentStore(); await store.loadRun('r')
|
||||
handler().onEvent(event(1))
|
||||
for (let attempt = 0; attempt < 6; attempt++) { handler().onError(new Error('offline')); await vi.advanceTimersByTimeAsync(16000) }
|
||||
expect(mock.stream).toHaveBeenCalledTimes(6)
|
||||
expect(store.connectionState).toBe('disconnected')
|
||||
expect(store.isRunning).toBe(true)
|
||||
store.reconnect()
|
||||
expect(mock.stream.mock.calls.at(-1)![2]).toBe(1)
|
||||
})
|
||||
Reference in New Issue
Block a user