// 发送后的运行态投影:把刚启动的 run 合进列表,并用事件上的服务端时间。 import { describe, expect, it } from 'vitest' import type { Run } from '../src/contracts' import { activeRun, eventTime, mergeStartedRun } from '../src/store' function run(id: string, status: Run['status'], over: Partial = {}): Run { return { id, conversationId: 'c', projectId: 'p', kind: 'conversation', status, createdAt: '2026-10-03T00:00:00Z', ...over, } } describe('mergeStartedRun', () => { it('adds a pending run so the composer treats the conversation as active', () => { const merged = mergeStartedRun([], run('r1', 'pending')) expect(activeRun(merged)?.id).toBe('r1') }) it('keeps an existing record when the same id arrives again', () => { const settled = run('r1', 'completed', { phase: 'done' }) const merged = mergeStartedRun([settled], run('r1', 'pending')) expect(merged).toHaveLength(1) expect(merged[0].status).toBe('completed') expect(activeRun(merged)).toBeUndefined() }) }) describe('eventTime', () => { it('parses the server timestamp', () => { expect(eventTime({ ts: '2026-10-03T14:50:25.073Z' }, 0)).toBe(Date.parse('2026-10-03T14:50:25.073Z')) }) it('falls back when the timestamp is missing or unparseable', () => { expect(eventTime({}, 42)).toBe(42) expect(eventTime({ ts: 'not-a-time' }, 42)).toBe(42) }) })