longevity: revisione finale - codice cliente non riusabile, ruoli allineati, middleware verificato
- creaCliente: il codice si deduce dal massimo fra identity E longevity (non piu' solo identity), cosi' un client_code cancellato dall'anagrafica non torna mai disponibile e non si attribuiscono le misure di un vecchio cliente a uno nuovo. Compensazione se la scrittura su longevity fallisce dopo quella su identity. - ROLES unica fonte in auth.ts (Role e isRole derivati); users.astro e users/new.astro usano quella lista invece di array scritti a mano che dimenticavano cliente/trainer. - Commento falso su cosa protegge il middleware, riscritto: rimanda a isProtectedPath. - vitest.config.ts: alias per astro:middleware (stesso bersaglio della pipeline vite di Astro), cosi' src/middleware.ts e' finalmente importabile e testabile in isolamento - prima nessun test lo caricava davvero. - export.test.ts: asserzione posizionale per colonna, non piu' solo intestazioni scritte a mano; intercetta un riordino della SELECT che disallinea etichette e valori. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -46,4 +46,40 @@ describe('export per le statistiche', () => {
|
||||
expect(righe.length).toBe(3); // intestazione + 2 misure
|
||||
expect(righe[0]).toBe('client_code,sesso,eta,data,tipo_sessione,quest_version,test_id,valore,unita,fonte,fuori_range');
|
||||
});
|
||||
|
||||
it('ogni valore sta sotto l intestazione giusta, colonna per colonna (asserzione posizionale)', () => {
|
||||
// Non un indice scritto a mano: l'indice si cerca per NOME nell'intestazione prodotta.
|
||||
// Se un domani la SELECT in export.ts viene riordinata senza riallineare INTESTAZIONI,
|
||||
// il valore letto a quell'indice smette di corrispondere e l'asserzione fallisce -
|
||||
// invece di restare verde con l'età etichettata come sesso.
|
||||
const db = dbConDati();
|
||||
const { intestazioni, righe } = esportaMisure(db);
|
||||
const idx = (col: string) => {
|
||||
const i = intestazioni.indexOf(col);
|
||||
if (i < 0) throw new Error(`intestazione mancante: ${col}`);
|
||||
return i;
|
||||
};
|
||||
|
||||
const rigaSonno = righe.find((r) => r[idx('test_id')] === 'q_ore_sonno')!;
|
||||
expect(rigaSonno).toBeDefined();
|
||||
expect(rigaSonno[idx('client_code')]).toBe('ISL-0001');
|
||||
expect(rigaSonno[idx('sesso')]).toBe('F');
|
||||
expect(rigaSonno[idx('eta')]).toBe(35);
|
||||
expect(rigaSonno[idx('data')]).toBe('2026-08-21');
|
||||
expect(rigaSonno[idx('tipo_sessione')]).toBe('questionario');
|
||||
expect(rigaSonno[idx('quest_version')]).toBe('v1.0');
|
||||
expect(rigaSonno[idx('valore')]).toBe(7);
|
||||
// salvaCompilazione non passa 'unita' per le risposte del questionario: resta null.
|
||||
expect(rigaSonno[idx('unita')]).toBeNull();
|
||||
expect(rigaSonno[idx('fonte')]).toBe('questionario');
|
||||
expect(rigaSonno[idx('fuori_range')]).toBe(0);
|
||||
|
||||
const rigaRiposato = righe.find((r) => r[idx('test_id')] === 'q_riposato')!;
|
||||
expect(rigaRiposato).toBeDefined();
|
||||
expect(rigaRiposato[idx('client_code')]).toBe('ISL-0001');
|
||||
expect(rigaRiposato[idx('sesso')]).toBe('F');
|
||||
expect(rigaRiposato[idx('eta')]).toBe(35);
|
||||
expect(rigaRiposato[idx('valore')]).toBe(8);
|
||||
expect(rigaRiposato[idx('unita')]).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user