import { describe, it, expect, vi } from 'vitest'; import { CommandBus } from '@application/handlers/CommandBus'; import { QueryBus } from '@application/handlers/QueryBus'; import { EventBus } from '@domain/events/EventBus'; import type { AppState, StateRepository } from '@domain/ports/StateRepository'; import { createRegisterAccouplementHandler } from '@application/commands/RegisterAccouplement'; import { createGetDashboardHandler } from '@application/queries/GetDashboard'; import { createGetBreedingOptionsHandler } from '@application/queries/GetBreedingOptions'; import { BreedingService } from '@domain/services/BreedingService'; function setup() { const repo: StateRepository = { load: vi.fn(async () => null), save: vi.fn() }; const events = new EventBus(); const state: AppState = { enclos: [], activeId: 'dashboard', nextEnclosId: 1, alarmSound: 'arpege', notifsEnabled: true, ntfyTopic: '', archivedStats: [], inventaire: {}, workflows: [], accouplements: [], }; const cmdBus = new CommandBus(); const qBus = new QueryBus(); cmdBus.register('register-accouplement', createRegisterAccouplementHandler(state, repo, events)); qBus.register('get-dashboard', createGetDashboardHandler(state)); qBus.register('get-breeding-options', createGetBreedingOptionsHandler()); return { state, cmdBus, qBus }; } describe('Breeding Workflow', () => { it('select parents → deduce baby → register → dashboard reflects', () => { const { cmdBus, qBus } = setup(); const svc = new BreedingService(); // 1. Get compatible partners for Rousse const options = qBus.execute({ type: 'get-breeding-options', race: 'Rousse' }); expect(options.partners.some((p: any) => p.partner === 'Dorée')).toBe(true); // 2. Deduce baby const baby = svc.deduceBaby('Rousse', 'Dorée'); expect(baby).toBe('Dorée et Rousse'); // 3. Register accouplement cmdBus.execute({ type: 'register-accouplement', parentA: 'Rousse', parentB: 'Dorée', baby: 'Dorée et Rousse', couples: 10, babiesObtained: 7, }); // 4. Dashboard shows updated stats const dash = qBus.execute({ type: 'get-dashboard' }); expect(dash.totalCouples).toBe(10); expect(dash.totalBabies).toBe(7); expect(dash.successRate).toBe(70); expect(dash.raceBreakdown['Dorée et Rousse']).toBe(7); }); it('multiple accouplements accumulate', () => { const { cmdBus, qBus } = setup(); cmdBus.execute({ type: 'register-accouplement', parentA: 'Rousse', parentB: 'Dorée', baby: 'Dorée et Rousse', couples: 5, babiesObtained: 3, }); cmdBus.execute({ type: 'register-accouplement', parentA: 'Amande', parentB: 'Dorée', baby: 'Amande et Dorée', couples: 8, babiesObtained: 5, }); const dash = qBus.execute({ type: 'get-dashboard' }); expect(dash.totalCouples).toBe(13); expect(dash.totalBabies).toBe(8); }); });