f5ca841d92
Sostituisce il prototipo del cliente (salvava anche con "No" al consenso sanitario, perche' controllava solo che il campo non fosse vuoto). Qui il consenso si verifica PRIMA di scrivere qualunque dato: se non e' affermativo non si apre nessuna sessione, e la risposta lo dice. Il rifiuto si registra comunque fra le note di profilo, con esito e versione del questionario: va dimostrato tanto quanto un assenso. - src/lib/longevity/vista.ts: campiDelQuestionario (dal registro, non da una lista nel codice) e salvaDalForm (consenso prima di tutto, poi delega a salvaCompilazione). - src/pages/api/longevity/questionario.ts: il client_code arriva SEMPRE da codicePerUtente sulla sessione, mai dal corpo della richiesta. - src/lib/longevity/db.ts: getLongevityDb/getIdentityDb, connessioni singole per processo (come getDb() del sito), cosi' l'endpoint non apre una nuova connessione a ogni richiesta. - src/components/longevity/Questionario.tsx + pages/longevity/questionario.astro: isola React a quattro blocchi (le tre aree di domande + note/consenso), la pagina non interroga mai il database da sola.
88 lines
3.4 KiB
TypeScript
88 lines
3.4 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { readFileSync } from 'node:fs';
|
|
import { join } from 'node:path';
|
|
import { createLongevityDb } from '../../src/lib/longevity/db';
|
|
import { seedRegistro } from '../../src/lib/longevity/registro';
|
|
import { campiDelQuestionario, salvaDalForm } from '../../src/lib/longevity/vista';
|
|
|
|
function dbPronto() {
|
|
const db = createLongevityDb(':memory:');
|
|
seedRegistro(db);
|
|
db.prepare(`INSERT INTO soggetti (client_code, sesso) VALUES ('ISL-0001','F')`).run();
|
|
return db;
|
|
}
|
|
|
|
describe('i campi del questionario vengono dal registro', () => {
|
|
it('costruisce i campi leggendo il registro, non una lista nel codice', () => {
|
|
const db = dbPronto();
|
|
const campi = campiDelQuestionario(db, '2026-08-22');
|
|
expect(campi.length).toBe(20);
|
|
const alcol = campi.find((c) => c.id === 'q_alcol_life')!;
|
|
expect(alcol.etichetta).toMatch(/alcoliche/i);
|
|
expect(alcol.max).toBe(30);
|
|
});
|
|
|
|
it('una domanda disattivata sparisce dal modulo senza toccare il codice', () => {
|
|
const db = dbPronto();
|
|
db.prepare(`UPDATE registro_test SET attivo_a = '2026-01-01' WHERE test_id = 'q_sigarette'`).run();
|
|
const campi = campiDelQuestionario(db, '2026-08-22');
|
|
expect(campi.map((c) => c.id)).not.toContain('q_sigarette');
|
|
expect(campi.length).toBe(19);
|
|
});
|
|
});
|
|
|
|
describe('il salvataggio, e il consenso', () => {
|
|
const risposte = { q_riposato: 8, q_ore_sonno: 7.5 };
|
|
|
|
it('salva una compilazione quando il consenso e dato', () => {
|
|
const db = dbPronto();
|
|
const esito = salvaDalForm(db, {
|
|
client_code: 'ISL-0001', data: '2026-08-22', eta: 35,
|
|
risposte, consensoSanitario: 'Si', liberi: {},
|
|
});
|
|
expect(esito.ok).toBe(true);
|
|
const n = db.prepare(`SELECT COUNT(*) n FROM sessioni`).get() as { n: number };
|
|
expect(n.n).toBe(1);
|
|
});
|
|
|
|
it('NON salva se il consenso e rifiutato: "No" non e un consenso', () => {
|
|
const db = dbPronto();
|
|
const esito = salvaDalForm(db, {
|
|
client_code: 'ISL-0001', data: '2026-08-22', eta: 35,
|
|
risposte, consensoSanitario: 'No', liberi: {},
|
|
});
|
|
expect(esito.ok).toBe(false);
|
|
const n = db.prepare(`SELECT COUNT(*) n FROM sessioni`).get() as { n: number };
|
|
expect(n.n).toBe(0); // niente sessione, niente misure
|
|
});
|
|
|
|
it('NON salva se il consenso manca del tutto', () => {
|
|
const db = dbPronto();
|
|
const esito = salvaDalForm(db, {
|
|
client_code: 'ISL-0001', data: '2026-08-22', eta: 35,
|
|
risposte, consensoSanitario: '', liberi: {},
|
|
});
|
|
expect(esito.ok).toBe(false);
|
|
});
|
|
|
|
it('registra il consenso anche quando e rifiutato: il rifiuto va dimostrato', () => {
|
|
const db = dbPronto();
|
|
salvaDalForm(db, {
|
|
client_code: 'ISL-0001', data: '2026-08-22', eta: 35,
|
|
risposte, consensoSanitario: 'No', liberi: {},
|
|
});
|
|
const note = db.prepare(
|
|
`SELECT campo_id, testo FROM profilo_note WHERE campo_id LIKE 'consenso%'`
|
|
).all() as { campo_id: string; testo: string }[];
|
|
expect(note.length).toBeGreaterThan(0);
|
|
expect(note[0].testo).toMatch(/No/);
|
|
});
|
|
|
|
it('il codice cliente NON puo arrivare da chi chiama la pagina', () => {
|
|
const src = readFileSync(join(process.cwd(), 'src/pages/api/longevity/questionario.ts'), 'utf8');
|
|
// il codice si prende dalla sessione dell'utente, mai dal corpo della richiesta
|
|
expect(src).toMatch(/codicePerUtente/);
|
|
expect(src).not.toMatch(/body\.client_code|body\.clientId|corpo\.client_code/);
|
|
});
|
|
});
|