import { describe, it, expect } from 'vitest' import { deriveJobsFromSource, CRON_BY_PERIOD } from '../derive.js' // The « aucun runtime scheduled[day] » closer: a scheduled UC derives the // job triple (service method + Hangfire registration + POST trigger) instead // of shipping emission entities nothing ever writes (26 AC on one runtime). const UC = `### UC-FLOTTE-PARAM-ALERTES-003 — Notifier les échéances à venir - **Exécution** : scheduled[day], priorité high. - Le système parcourt les échéances dont la fenêtre d'anticipation est ouverte et enregistre chaque envoi dans AlertEmission (idempotence BR-009). ### UC-FLOTTE-PARAM-ALERTES-004 — Relancer les relevés manquants - **Exécution** : scheduled (week). - Le système relance les conducteurs sans relevé du mois. ### UC-FLOTTE-PARAM-ALERTES-005 — Consulter le journal - **Exécution** : manual. ` describe('derive-job-specs', () => { const warnings: string[] = [] const jobs = deriveJobsFromSource(UC, 'flotte', 'PARAMETRAGE', new Set(['AlertEmission', 'AlertRule']), warnings) it('derives one job per scheduled UC — manual UCs never schedule', () => { expect(jobs).toHaveLength(2) expect(jobs.map(j => j.ucCode)).toEqual(['UC-FLOTTE-PARAM-ALERTES-003', 'UC-FLOTTE-PARAM-ALERTES-004']) }) it('the bracket AND parenthesis period forms both resolve, cron mapped off-peak', () => { expect(jobs[0].period).toBe('day') expect(jobs[0].cron).toBe(CRON_BY_PERIOD.day) expect(jobs[1].period).toBe('week') expect(jobs[1].cron).toBe('0 3 * * 1') }) it('jobId / slug / methodName derive stably from the title', () => { expect(jobs[0].jobId).toBe('flotte-parametrage-notifier-les-echeances-a') expect(jobs[0].methodName).toBe('RunNotifierLesEcheancesAAsync') expect(jobs[0].slug).toBe('notifier-les-echeances-a') }) it('the emission entity resolves from the UC text × entité.md; missing → ba.gap warning', () => { expect(jobs[0].emissionEntity).toBe('AlertEmission') expect(jobs[1].emissionEntity).toBeNull() expect(warnings.some(w => w.includes('UC-FLOTTE-PARAM-ALERTES-004') && w.includes('ba.gap'))).toBe(true) }) }) describe('derive-job-specs — scheduled without a resolvable period', () => { it('warns instead of guessing a cadence', () => { const warnings: string[] = [] const jobs = deriveJobsFromSource('### UC-X-001 — Purger\n\n- Exécution : scheduled, cadence à définir.\n', 'x', 'MOD', new Set(), warnings) expect(jobs).toHaveLength(0) expect(warnings[0]).toContain('no period resolves') }) })