import { describe, it, expect, vi } from 'vitest'; import { CommandBus } from '@application/handlers/CommandBus'; import { EventBus } from '@domain/events/EventBus'; import type { AppState, StateRepository } from '@domain/ports/StateRepository'; import { createCreateEnclosHandler } from '@application/commands/CreateEnclos'; import { createDeleteEnclosHandler } from '@application/commands/DeleteEnclos'; import { createAddDragodindeHandler } from '@application/commands/AddDragodinde'; import { createRemoveDragodindeHandler } from '@application/commands/RemoveDragodinde'; import { MAX_ENCLOS, MAX_DD } from '@domain/entities/Enclos'; 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(); cmdBus.register('create-enclos', createCreateEnclosHandler(state, repo)); cmdBus.register('delete-enclos', createDeleteEnclosHandler(state, repo, events)); cmdBus.register('add-dragodinde', createAddDragodindeHandler(state, repo)); cmdBus.register('remove-dragodinde', createRemoveDragodindeHandler(state, repo)); return { state, cmdBus, events }; } describe('Enclos Management', () => { it('create up to MAX_ENCLOS', () => { const { state, cmdBus } = setup(); for (let i = 0; i < MAX_ENCLOS + 2; i++) { cmdBus.execute({ type: 'create-enclos' }); } expect(state.enclos).toHaveLength(MAX_ENCLOS); }); it('delete switches to dashboard when last enclos removed', () => { const { state, cmdBus } = setup(); cmdBus.execute({ type: 'create-enclos' }); const id = state.enclos[0]!.id; state.activeId = id; cmdBus.execute({ type: 'delete-enclos', enclosId: id }); expect(state.enclos).toHaveLength(0); expect(state.activeId).toBe('dashboard'); }); it('add DDs up to MAX_DD per enclos', () => { const { state, cmdBus } = setup(); cmdBus.execute({ type: 'create-enclos' }); const encId = state.enclos[0]!.id; // Already has 1 DD from creation for (let i = 0; i < MAX_DD; i++) { cmdBus.execute({ type: 'add-dragodinde', enclosId: encId }); } expect(state.enclos[0]!.dragodindes.length).toBeLessThanOrEqual(MAX_DD); }); it('remove DD from enclos', () => { const { state, cmdBus } = setup(); cmdBus.execute({ type: 'create-enclos' }); const encId = state.enclos[0]!.id; const ddId = state.enclos[0]!.dragodindes[0]!.id; cmdBus.execute({ type: 'remove-dragodinde', enclosId: encId, ddId }); expect(state.enclos[0]!.dragodindes).toHaveLength(0); }); });