import { Decimal } from 'decimal.js'; import { describe, expect, it } from 'vitest'; import { Attribution } from '../../src/domain/attribution.js'; const make = (overrides: Partial[0]> = {}) => new Attribution({ id: 1, moduleId: 10, personneId: 5, heuresAttribuees: new Decimal(20), ...overrides, }); describe('Attribution — constructeur', () => { it('cree une attribution valide', () => { const a = make(); expect(a.statut).toBe('planifie'); expect(a.heuresRealisees.toNumber()).toBe(0); }); it('throw si heuresAttribuees <= 0', () => { expect(() => make({ heuresAttribuees: new Decimal(0) })).toThrow(); expect(() => make({ heuresAttribuees: new Decimal(-5) })).toThrow(); }); it('throw si heuresRealisees < 0', () => { expect(() => make({ heuresRealisees: new Decimal(-1) })).toThrow(); }); it('throw si dateFin < dateDebut', () => { expect(() => make({ dateDebut: new Date('2026-02-01'), dateFin: new Date('2026-01-01') }), ).toThrow(); }); }); describe('Attribution — transitions de statut', () => { it('demarrer: planifie -> en_cours', () => { const a = make(); a.demarrer(); expect(a.statut).toBe('en_cours'); }); it('demarrer invalide depuis realise', () => { const a = make({ statut: 'realise' }); expect(() => a.demarrer()).toThrow(); }); it('cloturer: en_cours -> realise', () => { const a = make({ statut: 'en_cours' }); a.cloturer(); expect(a.statut).toBe('realise'); }); it('cloturer: planifie -> realise (skip en_cours autorise)', () => { const a = make(); a.cloturer(); expect(a.statut).toBe('realise'); }); it('cloturer invalide depuis annule', () => { const a = make({ statut: 'annule' }); expect(() => a.cloturer()).toThrow(); }); it('annuler depuis planifie OK', () => { const a = make(); a.annuler('client desistement'); expect(a.statut).toBe('annule'); }); it('annuler invalide depuis realise', () => { const a = make({ statut: 'realise' }); expect(() => a.annuler('motif')).toThrow(); }); }); describe('Attribution — saisirHeuresRealisees', () => { it('cas nominal', () => { const a = make(); a.saisirHeuresRealisees(new Decimal(15)); expect(a.heuresRealisees.toNumber()).toBe(15); }); it('throw si heures < 0', () => { const a = make(); expect(() => a.saisirHeuresRealisees(new Decimal(-1))).toThrow(); }); it('throw si attribution annulee', () => { const a = make({ statut: 'annule' }); expect(() => a.saisirHeuresRealisees(new Decimal(5))).toThrow(); }); it('throw si attribution realisee', () => { const a = make({ statut: 'realise' }); expect(() => a.saisirHeuresRealisees(new Decimal(5))).toThrow(); }); }); describe('Attribution — isActive', () => { it('planifie et en_cours sont actifs', () => { expect(make().isActive()).toBe(true); expect(make({ statut: 'en_cours' }).isActive()).toBe(true); }); it('realise et annule ne sont pas actifs', () => { expect(make({ statut: 'realise' }).isActive()).toBe(false); expect(make({ statut: 'annule' }).isActive()).toBe(false); }); });