// Il consenso veniva scritto DOPO che salvaCompilazione aveva già chiuso la propria // transazione: se il passo successivo falliva, restavano i dati sanitari SENZA il record // di consenso che li giustifica — l'esatto contrario dell'invariante ("o entra tutto nel // fascicolo, o non entra niente"). Questo file forza un fallimento nel calcolo dei // punteggi (mockando calcolaSessione) DOPO che la sessione e le misure sono già scritte, e // verifica che l'intera transazione — sessione, misure, punteggi, consenso — vada // indietro insieme. Il mock vive in un file a parte perché vi.mock è per-file: gli altri // test su calcolaSessione (referto.test.ts, salvataggio-e2e.test.ts) devono restare reali. import { describe, it, expect, vi } from 'vitest'; import { createLongevityDb } from '../../src/lib/longevity/db'; import { seedRegistro, seedPesi, MODEL_VERSION } from '../../src/lib/longevity/registro'; vi.mock('../../src/lib/longevity/motore', async (importOriginal) => { const reale = await importOriginal(); return { ...reale, calcolaSessione: () => { throw new Error('rottura simulata nel calcolo dei punteggi'); }, }; }); function dbPronto() { const db = createLongevityDb(':memory:'); seedRegistro(db); seedPesi(db, MODEL_VERSION); db.prepare(`INSERT INTO soggetti (client_code, sesso) VALUES ('ISL-0001','F')`).run(); return db; } describe('salvaDalForm — atomicità di dati, punteggi e consenso', () => { it('se il calcolo dei punteggi fallisce DOPO che sessione e misure sono state scritte, tutto torna indietro: niente sessione, niente misure, niente nota di consenso', async () => { const { salvaDalForm } = await import('../../src/lib/longevity/vista'); const db = dbPronto(); expect(() => salvaDalForm(db, { client_code: 'ISL-0001', data: '2026-08-22', eta: 35, risposte: { q_riposato: 8 }, consensoSanitario: 'Si', liberi: {}, }) ).toThrow(/rottura simulata/); const sessioni = db.prepare(`SELECT COUNT(*) n FROM sessioni`).get() as { n: number }; const misure = db.prepare(`SELECT COUNT(*) n FROM misure`).get() as { n: number }; const score = db.prepare(`SELECT COUNT(*) n FROM score`).get() as { n: number }; const consenso = db.prepare(`SELECT COUNT(*) n FROM profilo_note WHERE campo_id = 'consenso_sanitario'`) .get() as { n: number }; expect(sessioni.n).toBe(0); expect(misure.n).toBe(0); expect(score.n).toBe(0); expect(consenso.n).toBe(0); }); });