Verifica i permessi per ruolo contro il database Supabase locale.
Le policy RLS scritte su auth.uid() e il trigger di DD-016 non erano coperti da nessun test: schema-profili prova solo l'utente anonimo, e sul database di .env non si può scrivere perché è quello di produzione. Il nuovo test/integration/permessi.test.ts crea utenti veri sullo stack locale (npx supabase start) e interroga il database come loro: un giocatore vede e modifica solo il proprio profilo, non ne cancella, non cambia numero e ruolo mentre reclama uno slot, non prende lo slot di un altro, non si assegna il ruolo admin e non vede i ruoli altrui. Un controllo positivo sull'admin evita il falso verde di un database completamente chiuso. Prende URL e chiavi da `supabase status` invece che da .env e si ferma se l'URL non è locale: un .env puntato alla produzione non deve poter trasformare un test in una scrittura sul database vero. Senza stack locale si salta con il motivo, quindi la suite resta verde su una macchina senza Docker. Ogni test ripristina in un finally lo stato che tocca, così si rilancia senza db reset. test/README.md documenta il flusso Docker e corregge la convenzione: non è più «nessun test scrive sul database» ma «sul database di .env non scrive nessuno». Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+46
-7
@@ -20,18 +20,57 @@ non può inquinare gli altri.
|
||||
| Cartella | Cosa verifica | Serve rete? |
|
||||
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- |
|
||||
| `unit/` | Logica di dominio pura: badge, serie, palloni, pagelle, MVP, cacche, scout, obiettivi, notifiche, parsing CSI, dati della rosa. Più le funzioni pure isolabili nei moduli con hook/rete (validazione upload, guardie push, JWT VAPID, cattura errori, avatar) | No |
|
||||
| `integration/` | Le route `/api/public/*` sul server di sviluppo: risposte, cache, validazione degli input. Più schema e permessi del Profilo Giocatore (`schema-profili`) contro il database configurato | Sì |
|
||||
| `integration/` | Le route `/api/public/*` sul server di sviluppo: risposte, cache, validazione degli input. Più schema e permessi del Profilo Giocatore (`schema-profili`) contro il database configurato, e i permessi per ruolo (`permessi`) sul database locale | Sì |
|
||||
| `e2e/` | Percorsi completi sull'app servita: schermate, dati CSI fino alla pagina, file PWA, 404 | Sì |
|
||||
| `helpers/` | Avvio del server di test e mini-harness condiviso | — |
|
||||
|
||||
## Database locale in Docker
|
||||
|
||||
Alcune cose non si possono verificare senza scrivere: le policy RLS scritte su
|
||||
`auth.uid()`, i trigger, i vincoli. Contro il progetto cloud quelle scritture non
|
||||
si fanno, quindi servono un database usa e getta e utenti veri.
|
||||
|
||||
```bash
|
||||
npx supabase start # avvia lo stack in Docker (migration applicate + seed.sql)
|
||||
npx supabase status # URL e chiavi locali; Studio su http://127.0.0.1:54323
|
||||
npx supabase db reset # ricrea il database da zero se i dati si sporcano
|
||||
npx supabase stop # spegne tutto
|
||||
|
||||
bun test/integration/permessi.test.ts # i test che richiedono lo stack locale
|
||||
```
|
||||
|
||||
Il primo `start` scarica le immagini (qualche minuto), i successivi partono in
|
||||
una decina di secondi. Le mail finiscono in Mailpit (http://127.0.0.1:54324),
|
||||
non escono dalla macchina.
|
||||
|
||||
I test che scrivono **non leggono `.env`**: prendono URL e chiavi da
|
||||
`supabase status` e si fermano se l'URL non è `127.0.0.1`. È una cintura di
|
||||
sicurezza, non una comodità: così un `.env` puntato alla produzione non può
|
||||
trasformare un test in una scrittura sul database vero.
|
||||
|
||||
Ognuno ripristina lo stato che tocca (utenti creati, slot della rosa, colonne
|
||||
modificate) in un `finally`, così la suite si può rilanciare all'infinito senza
|
||||
un `db reset` in mezzo.
|
||||
|
||||
Due cose scoperte scrivendo questi test, utili a chi ne aggiunge:
|
||||
|
||||
- la **service key non è un amministratore**: per il trigger
|
||||
`enforce_giocatori_squadra_update` (DD-016) `auth.uid()` è NULL, quindi ogni
|
||||
UPDATE su `giocatori_squadra` fatto con la service key viene rifiutato. Per
|
||||
collegare uno slot a un account serve il JWT di un utente con ruolo `admin`;
|
||||
- su un UPDATE o un DELETE che non tocca nessuna riga PostgREST risponde 2xx.
|
||||
Il codice di stato non basta: serve `Prefer: return=representation` e contare
|
||||
le righe, oppure rileggere il dato.
|
||||
|
||||
## Convenzioni
|
||||
|
||||
- **Nessun test scrive sul database.** Integration ed e2e fanno solo letture e
|
||||
verifiche di validazione: si possono lanciare anche contro l'ambiente reale.
|
||||
L'unica eccezione apparente è `schema-profili`, che _tenta_ scritture da utente
|
||||
anonimo proprio per dimostrare che la RLS le respinge, e poi rilegge la riga per
|
||||
verificare che non sia cambiata: su un UPDATE a zero righe PostgREST risponde 2xx,
|
||||
quindi lo stato conta più del codice di risposta.
|
||||
- **Sul database configurato in `.env` nessun test scrive.** Integration ed e2e
|
||||
fanno solo letture e verifiche di validazione: si possono lanciare anche contro
|
||||
l'ambiente reale. L'unica eccezione apparente è `schema-profili`, che _tenta_
|
||||
scritture da utente anonimo proprio per dimostrare che la RLS le respinge, e poi
|
||||
rilegge la riga per verificare che non sia cambiata: su un UPDATE a zero righe
|
||||
PostgREST risponde 2xx, quindi lo stato conta più del codice di risposta.
|
||||
I test che scrivono davvero girano solo sul database locale (vedi sopra).
|
||||
- I test legati alla migration M2 si **saltano da soli** dove quella migration non è
|
||||
ancora applicata, indicandolo nel motivo. Per vederli tutti verdi serve un
|
||||
database che la contenga: `npx supabase start` ne crea uno in locale.
|
||||
|
||||
Reference in New Issue
Block a user