import { strict as assert } from 'node:assert'; import test from 'node:test'; import type { AgentDecomposeResponse } from '@ftb/shared'; import { createAiDecomposeSessionStore, getAiDecomposeButtonMode, type AiDecomposeCompletedPayload, } from './ai-decompose-session'; const response: AgentDecomposeResponse = { ok: true, result: { report: { matched: [], reqOnly: [], noteOnly: [], ambiguous: [] }, devTaskDrafts: [], testCaseDrafts: [], }, meta: { model: 'test-model', inputTokens: 10, outputTokens: 5, durationMs: 1200 }, }; const payload: AiDecomposeCompletedPayload = { result: response, dedupeSummary: { removedDevTaskCount: 0, removedTestCaseCount: 0 }, }; test('keeps generated result after request finishes outside the button component', async () => { const store = createAiDecomposeSessionStore(); let resolveRequest!: (value: AiDecomposeCompletedPayload) => void; const request = new Promise((resolve) => { resolveRequest = resolve; }); const running = store.start('plan-1', 'dev_tasks', () => request); assert.equal(store.get('plan-1', 'dev_tasks').status, 'generating'); assert.equal(getAiDecomposeButtonMode(store.get('plan-1', 'dev_tasks')), 'generating'); resolveRequest(payload); await running; const completed = store.get('plan-1', 'dev_tasks'); assert.equal(completed.status, 'completed'); assert.deepEqual(completed.payload, payload); assert.equal(getAiDecomposeButtonMode(completed), 'view_result'); }); test('keeps completed result until user adopts or rejects it', async () => { const store = createAiDecomposeSessionStore(); await store.start('plan-1', 'test_cases', async () => payload); assert.equal(getAiDecomposeButtonMode(store.get('plan-1', 'test_cases')), 'view_result'); store.markReviewed('plan-1', 'test_cases'); assert.equal(store.get('plan-1', 'test_cases').status, 'idle'); assert.equal(getAiDecomposeButtonMode(store.get('plan-1', 'test_cases')), 'generate'); }); test('reuses in-flight request for the same plan and target', async () => { const store = createAiDecomposeSessionStore(); let callCount = 0; const run = async () => { callCount += 1; return payload; }; const first = store.start('plan-1', 'dev_tasks', run); const second = store.start('plan-1', 'dev_tasks', run); assert.equal(first, second); await Promise.all([first, second]); assert.equal(callCount, 1); });