# Plan de tests de recette - LOT 1

## A. Tests locaux livrés

Exécuter :

```bash
php tests/run.php
```

Référence finale 1.0.5-lot1 : 10/10 tests réussis.

Référence maintenance 1.0.6-lot1 préalable au LOT 2 : 11/11 tests réussis, avec ajout du contrôle `orphan_file_scanner`.

## B. Migration

1. Exécuter la migration sur une base vide.
2. Réexécuter `php scripts/migrate.php` : aucune migration supplémentaire ne doit être appliquée.
3. Modifier temporairement le checksum d'une copie du fichier SQL : le runner doit refuser la divergence.
4. Exécuter `php scripts/verify_installation.php`.

## C. Authentification et sécurité

1. Connexion valide, access token de 15 minutes et refresh token.
2. Rotation du refresh token ; l'ancien token ne doit plus fonctionner.
3. Révocation utilisateur ; les refresh tokens doivent être révoqués.
4. Huit échecs de connexion dans la fenêtre configurée ; réponse 429.
5. Invitation à usage unique ; second usage refusé.
6. Reset mot de passe à usage unique ; sessions existantes révoquées.
7. Test sans HTTPS en configuration de production ; requête refusée.

## D. Isolation des organisations

1. Créer deux organisations A et B et deux utilisateurs.
2. Créer un événement et une photo dans A.
3. Tenter de lire l'événement, le snapshot, l'audit et le fichier depuis B.
4. Toutes les tentatives doivent répondre 403 ou 404 sans révéler les métadonnées de A.

## E. Révisions et idempotence

1. Créer un événement avec une clé d'idempotence.
2. Rejouer le même appel avec la même clé et le même corps : même réponse, aucun doublon.
3. Rejouer avec un corps différent : 409 `IDEMPOTENCY_CONFLICT`.
4. Créer la révision 1 avec `base_revision=0`.
5. Rejouer un snapshot identique avec `base_revision=1` : pas de nouvelle révision.
6. Publier une révision.
7. Envoyer une écriture avec une ancienne base : 409 `REVISION_CONFLICT`.
8. Vérifier les checksums et le manifest des objets.

## F. Liste noire SAS

Tenter un snapshot contenant successivement :

- `event_runs` ;
- `incidents` ;
- `remote_tracking_positions` ;
- `runner_location_requests` ;
- `weather_alert_items` ;
- `route_cache` ;
- `device_token` ;
- `photo_blob`.

Chaque snapshot doit être refusé sans écriture partielle.

## G. Photos

1. Upload JPEG et PNG valides.
2. Refus BMP, WEBP, SVG, fichier PHP renommé, double extension dangereuse, image supérieure à 10 Mo et dimensions excessives.
3. Remplacement d'une photo : nouvelle version courante, ancienne version en corbeille.
4. Restauration de l'ancienne version : inversion transactionnelle des états.
5. Téléchargement sur un second compte autorisé : hash identique.
6. Exécuter `photo_integrity.php` et contrôler `file_integrity_audit`.
7. Simuler une date de purge dépassée sur recette et vérifier la suppression du binaire.

## H. Stockage privé et fichiers orphelins

1. Exécuter `php scripts/scan_orphan_files.php --json`.
2. Vérifier séparément les fichiers sans référence SQL, les fichiers marqués purgés encore présents et les références actives sans fichier.
3. Déplacer les orphelins en quarantaine avec `php scripts/scan_orphan_files.php --quarantine --json`.
4. Ne supprimer définitivement un fichier qu'après contrôle du manifeste de quarantaine.

## I. Sauvegarde et restauration

1. Créer un événement, une révision et une photo.
2. Exécuter `php scripts/backup.php`.
3. Restaurer le dump et les fichiers dans un environnement distinct.
4. Vérifier le manifest, les hashes et le téléchargement de la photo.
5. Vérifier que la base restaurée ne contient aucune table Tracking/LIVE.

## J. Critère de sortie

Le LOT 1 ne peut être déclaré validé qu'après conservation des preuves suivantes :

- sorties des scripts ;
- réponses API anonymisées ;
- captures de l'isolation inter-organisation ;
- résultat de restauration ;
- journal des anomalies et décisions ;
- confirmation qu'aucune régression n'a été introduite dans les services historiques.
