From 47b462362a37fc8637dd112f69617191a1e790fa Mon Sep 17 00:00:00 2001 From: Lukas May Date: Sat, 31 Jan 2026 19:28:22 +0100 Subject: [PATCH] test(11-08): add E2E tests for breakdown mode and full workflow Add architect workflow E2E tests: - Breakdown mode: spawn architect, complete with phases - Phase persistence: create and retrieve phases from breakdown output - Full workflow: discuss -> breakdown -> phase persistence --- src/test/e2e/architect-workflow.test.ts | 98 +++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/src/test/e2e/architect-workflow.test.ts b/src/test/e2e/architect-workflow.test.ts index 943a8b3..e548602 100644 --- a/src/test/e2e/architect-workflow.test.ts +++ b/src/test/e2e/architect-workflow.test.ts @@ -99,4 +99,102 @@ describe('Architect Workflow E2E', () => { expect(finalAgent?.status).toBe('idle'); }); }); + + describe('breakdown mode', () => { + it('should spawn architect in breakdown mode and create phases', async () => { + vi.useFakeTimers(); + + const initiative = await harness.createInitiative('Auth System'); + + // Set up breakdown completion + harness.setArchitectBreakdownComplete('auth-breakdown', [ + { number: 1, name: 'Database Setup', description: 'User table and auth schema', dependencies: [] }, + { number: 2, name: 'JWT Implementation', description: 'Token generation and validation', dependencies: [1] }, + { number: 3, name: 'Protected Routes', description: 'Middleware and route guards', dependencies: [2] }, + ]); + + const agent = await harness.caller.spawnArchitectBreakdown({ + name: 'auth-breakdown', + initiativeId: initiative.id, + }); + + expect(agent.mode).toBe('breakdown'); + + await harness.advanceTimers(); + + // Verify stopped with breakdown_complete + const events = harness.getEmittedEvents('agent:stopped') as AgentStoppedEvent[]; + expect(events).toHaveLength(1); + expect(events[0].payload.reason).toBe('breakdown_complete'); + }); + + it('should persist phases from breakdown output', async () => { + const initiative = await harness.createInitiative('Auth System'); + + const phasesData = [ + { number: 1, name: 'Foundation', description: 'Core setup' }, + { number: 2, name: 'Features', description: 'Main features' }, + ]; + + // Persist phases (simulating what would happen after breakdown) + const created = await harness.createPhasesFromBreakdown(initiative.id, phasesData); + + expect(created).toHaveLength(2); + expect(created[0].number).toBe(1); + expect(created[1].number).toBe(2); + + // Verify retrieval + const phases = await harness.getPhases(initiative.id); + expect(phases).toHaveLength(2); + expect(phases[0].name).toBe('Foundation'); + expect(phases[1].name).toBe('Features'); + }); + }); + + describe('full workflow', () => { + it('should complete discuss -> breakdown -> phases workflow', async () => { + vi.useFakeTimers(); + + // 1. Create initiative + const initiative = await harness.createInitiative('Full Workflow Test'); + + // 2. Discuss phase + harness.setArchitectDiscussComplete('discuss-agent', [ + { topic: 'Scope', decision: 'MVP only', reason: 'Time constraint' }, + ], 'Scope defined'); + + await harness.caller.spawnArchitectDiscuss({ + name: 'discuss-agent', + initiativeId: initiative.id, + }); + await harness.advanceTimers(); + + // 3. Breakdown phase + harness.setArchitectBreakdownComplete('breakdown-agent', [ + { number: 1, name: 'Core', description: 'Core functionality', dependencies: [] }, + { number: 2, name: 'Polish', description: 'UI and UX', dependencies: [1] }, + ]); + + await harness.caller.spawnArchitectBreakdown({ + name: 'breakdown-agent', + initiativeId: initiative.id, + contextSummary: 'MVP scope defined', + }); + await harness.advanceTimers(); + + // 4. Persist phases + await harness.createPhasesFromBreakdown(initiative.id, [ + { number: 1, name: 'Core', description: 'Core functionality' }, + { number: 2, name: 'Polish', description: 'UI and UX' }, + ]); + + // 5. Verify final state + const phases = await harness.getPhases(initiative.id); + expect(phases).toHaveLength(2); + + // Both agents should be idle + const agents = await harness.caller.listAgents(); + expect(agents.filter(a => a.status === 'idle')).toHaveLength(2); + }); + }); });