PD-85 — Scénarios de tests contractuels
1. Références
- Spécification :
PD-85-specification.md - Epic :
EPIC-XX (incohérence détectée avec référence PD-185 en annexe de la spec)
2. Matrice de couverture
| ID Invariant | ID Critère | ID Test | Couverture | Commentaire |
| INV-02 | CA-01 | TC-NOM-01, TC-INV-02 | Oui | Vérifie FiveSectionsComplete pour chaque preuve exportée |
| INV-03 | CA-07 | TC-NOM-02, TC-INV-03 | Oui | Rejet partiel si ReKey actif |
| INV-09 | CA-01 | TC-NOM-01, TC-INV-09 | Oui | Aucun secret dans payload export |
| INV-11 | CA-01 | TC-NOM-01, TC-INV-11 | Oui | envelopeSeal valide sur preuves conservées |
| INV-12 | CA-01 | TC-NOM-01, TC-INV-12 | Oui | Matériel offline présent pour chaque preuve valide |
| INV-85-01 | CA-11 | TC-INV-8501 | Oui | Absence d’opération de déchiffrement côté backend |
| INV-85-02 | CA-01 | TC-NOM-01, TC-INV-8502 | Oui | exportId UUID v4 unique |
| INV-85-03 | CA-08 | TC-NOM-05, TC-INV-8503 | Oui | Recalcul SHA3-256 canonicalisé conforme |
| INV-85-04 | CA-10 | TC-NOM-06, TC-NOM-07, TC-INV-8504 | Oui | URL valide avant expiration, invalide après, TTL <= 30 min |
| INV-85-05 | CA-12 | TC-INV-8505 | Partiel | Succès 200 testable; politique 4xx/422 ambiguë |
| INV-85-06 | CA-01 | TC-INV-8506 | Oui | Aucune mutation des ProofEnvelope source |
| INV-85-07 | CA-05 | TC-ERR-04, TC-INV-8507 | Oui | Blocage strict > 1 GB |
| INV-85-08-transitions | — | TC-INV-8508 | Oui | États terminaux sans transition sortante runtime |
| INV-85-09-envelope-encryption | — | TC-INV-8509 | Oui | Secrets temporaires chiffrés au repos uniquement |
| — | CA-02 | TC-ERR-01, TC-ERR-06 | Oui | Payload absent/vide/format invalide => 400 |
| — | CA-03 | TC-ERR-02 | Oui | Plan FREE => 403 |
| — | CA-04 | TC-ERR-03 | Partiel | Cas mixte inexistant/non possédé non spécifié |
| — | CA-06 | TC-ERR-05 | Oui | Tous invalides => 422 exhaustif |
| — | CA-07 | TC-NOM-02 | Oui | Export partiel conservant valides |
| — | CA-09 | TC-NOM-04 | Oui | Tri chronologique non décroissant |
| — | CA-13 | TC-NOM-03 | Oui | Évidences mineur/représentant selon applicabilité |
| — | CA-14 | TC-NOM-04 | Oui | exportedBy.userId + role valides |
3. Scénarios de test – Flux nominaux
TEST-ID: TC-NOM-01
Référence spec: CA-01, INV-02, INV-09, INV-11, INV-12, INV-85-02, INV-85-06
GIVEN
- Utilisateur authentifié Premium
- 5 proofIds possédés, valides RFC (FiveSectionsComplete, envelopeSeal valide, offline material présent, sans ReKey actif)
- Taille totale chiffrée <= 1 GB
WHEN
- POST /exports/complaint-file avec les 5 proofIds
THEN
- HTTP 200
- exportId présent, format UUID v4
- manifest, chronology, signedUrls, guideUrl, readmeVerification présents et non vides
- proofCount = 5 et rejectedProofs = []
AND
- Aucune preuve source n’est modifiée (checksum/metadata identiques avant/après)
TEST-ID: TC-NOM-02
Référence spec: CA-07, INV-03
GIVEN
- Utilisateur Premium
- 10 proofIds possédés dont 2 invalides (ex: ReKey actif / section RFC manquante)
WHEN
- POST /exports/complaint-file
THEN
- HTTP 200
- proofCount = 8
- rejectedProofs contient exactement 2 entrées, chacune avec motif explicite
AND
- Les 8 preuves valides figurent dans manifest/proofs et pas les 2 rejetées
TEST-ID: TC-NOM-03
Référence spec: CA-13
GIVEN
- Utilisateur authentifié avec rôle LEGAL_GUARDIAN
- Dossier mineur avec données applicables disponibles (Mandate, Dual Validation, ReKey Lifecycle)
WHEN
- POST /exports/complaint-file avec preuves valides
THEN
- HTTP 200
- exportedBy.role = LEGAL_GUARDIAN
- Evidences additionnelles applicables présentes dans le payload export
AND
- Aucune évidence non applicable n’est ajoutée
TEST-ID: TC-NOM-04
Référence spec: CA-09, CA-14
GIVEN
- Réponse 200 d’un export valide
WHEN
- Contrôle du contenu chronology.events et manifest.exportedBy
THEN
- chronology.events[*].timestamp en ordre non décroissant (RFC3339 UTC strict)
- exportedBy.userId est UUID v4 valide
- exportedBy.role ∈ {USER, LEGAL_GUARDIAN}
AND
- proofCount = longueur réelle de manifest.proofs
TEST-ID: TC-NOM-05
Référence spec: CA-08, INV-85-03
GIVEN
- Réponse 200 contenant manifest.integrityHash
WHEN
- Recalcul SHA3-256 sur manifest canonicalisé (champ integrityHash exclu)
THEN
- Hash recalculé == manifest.integrityHash
AND
- integrityHash respecte regex ^[0-9a-f]{64}$
TEST-ID: TC-NOM-06
Référence spec: CA-10, INV-85-04
GIVEN
- Réponse 200 avec signedUrls et expiresAt
WHEN
- Accès à chaque signed URL avant expiresAt
THEN
- Accès autorisé (objet récupérable)
AND
- Schéma URL = https, TTL annoncé <= 30 minutes
TEST-ID: TC-NOM-07
Référence spec: CA-10, INV-85-04
GIVEN
- Réponse 200 avec signedUrls
WHEN
- Attente jusqu’après expiresAt puis tentative d’accès
THEN
- Accès refusé (URL expirée)
AND
- Aucun renouvellement implicite de lien n’est retourné
4. Scénarios de test – Cas d’erreur
TEST-ID: TC-ERR-01
Référence spec: CA-02 (proofIds absent/vide)
GIVEN
- Utilisateur authentifié
WHEN
- POST /exports/complaint-file sans proofIds puis avec proofIds=[]
THEN
- HTTP 400 dans les deux cas
- Message de validation explicite
AND
- Aucun exportId créé, aucune URL signée émise
TEST-ID: TC-ERR-02
Référence spec: CA-03
GIVEN
- Utilisateur authentifié plan FREE
WHEN
- POST /exports/complaint-file avec payload valide
THEN
- HTTP 403
- Motif explicite de blocage Premium/capability
AND
- Aucun artefact export généré
TEST-ID: TC-ERR-03
Référence spec: CA-04
GIVEN
- Utilisateur authentifié
WHEN
- POST avec un proofId non possédé (et séparément un proofId inexistant)
THEN
- HTTP 404
- Erreur corrélée à l’identifiant concerné
AND
- Aucun export partiel implicite n’est produit en mode erreur 404
TEST-ID: TC-ERR-04
Référence spec: CA-05, INV-85-07
GIVEN
- Utilisateur Premium
- Sélection de preuves dont taille chiffrée estimée > 1 GB
WHEN
- POST /exports/complaint-file
THEN
- HTTP 413
- Réponse contient taille estimée et limite = 1 GB
AND
- Aucune signed URL n’est émise
TEST-ID: TC-ERR-05
Référence spec: CA-06
GIVEN
- Utilisateur Premium
- 3 proofs, toutes invalides (invariants violés)
WHEN
- POST /exports/complaint-file
THEN
- HTTP 422
- rejectedProofs exhaustif: 3 entrées, motifs explicites
AND
- Aucun proof valide dans manifest (ou manifest absent selon contrat d’erreur)
TEST-ID: TC-ERR-06
Référence spec: CA-02 (payload invalide format UUID)
GIVEN
- Utilisateur authentifié
WHEN
- POST avec proofIds contenant UUID non v4 / format invalide
THEN
- HTTP 400
- Message explicite de format invalide
AND
- Aucun traitement d’export effectif
5. Tests d’invariants (non négociables)
| Invariant | Test(s) dédiés | Observable | Commentaire |
| INV-02 | TC-INV-02 | Toute preuve exportée satisfait FiveSectionsComplete | Rejet sinon |
| INV-03 | TC-INV-03 | Aucune preuve exportée avec ReKey actif | Rejet partiel/total selon cas |
| INV-09 | TC-INV-09 | Absence de secrets dans manifest/chronology/readme | Scan déterministe de patterns sensibles |
| INV-11 | TC-INV-11 | envelopeSeal valide pour chaque preuve exportée | Vérification cryptographique |
| INV-12 | TC-INV-12 | Matériel de vérification offline présent et cohérent | Vérifiable sans backend |
| INV-85-01 | TC-INV-8501 | Aucune trace d’appel de déchiffrement côté serveur | Logs techniques/audit |
| INV-85-02 | TC-INV-8502 | exportId UUID v4 unique à chaque requête distincte | Non collision sur série de tests |
| INV-85-03 | TC-INV-8503 | Recalcul hash manifest (JCS) strictement identique | Exclusion du champ integrityHash |
| INV-85-04 | TC-INV-8504 | expiresAt-now borné [1..30] min et refus post-expiration | Borne contractuelle respectée |
| INV-85-05 | TC-INV-8505 | Événement audit WORM immuable présent | Vérifie append-only / non altérable |
| INV-85-06 | TC-INV-8506 | Aucune mutation des ProofEnvelope source | Hash/metadata avant-après inchangés |
| INV-85-07 | TC-INV-8507 | Rejet strict au-delà de 1 GB | 413 + taille/limite |
| INV-85-08-transitions | TC-INV-8508 | État terminal unique, sans transition sortante observée | Cohérence machine à états |
| INV-85-09-envelope-encryption | TC-INV-8509 | Artefacts crypto temporaires chiffrés au repos uniquement | Aucun secret en clair en base |
6. Tests de non-régression
| Test ID | Objet | Observable | Commentaire |
| TC-NR-01 | Stabilité du contrat de réponse 200 | Schéma JSON inchangé (champs obligatoires présents) | Détecte rupture API |
| TC-NR-02 | Stabilité des codes d’erreur | 400/403/404/413/422 inchangés selon même jeu de données | Détecte régression de mapping |
| TC-NR-03 | Déterminisme proofCount | proofCount == proofs.length sur exports répétés | Contrôle cohérence interne |
| TC-NR-04 | Intégrité hash inter-exécutions | integrityHash reproductible à données identiques | Détecte changement de canonicalisation |
| TC-NR-05 | Non-régression sécurité URL signées | Fenêtre TTL respectée à chaque release | Détecte extension non conforme |
| TC-NR-06 | Non-régression WORM audit | Présence entrée audit sur succès export | Conformité traçabilité minimale |
7. Tests négatifs et adversariaux
| Test ID | Entrée invalide / abus | Résultat attendu | Observable |
| TC-NEG-01 | proofIds avec doublons | Soit déduplication explicite soit rejet 400 (comportement contractuel à figer) | Réponse déterministe documentée |
| TC-NEG-02 | Mélange proofIds valides + format invalide | 400 (payload invalide prioritaire) | Aucun export produit |
| TC-NEG-03 | signedUrls[].url non-HTTPS injecté (test de robustesse fournisseur URL) | Rejet interne / 500 non conforme bloquant | Contrat HTTPS strict |
| TC-NEG-04 | Horodatage non UTC (+02:00) dans données internes | Rejet preuve ou erreur interne conforme aux règles date | UTC Z strict |
| TC-NEG-05 | Tentative de lecture URL après expiration répétée | Refus systématique | Pas de réactivation implicite |
| TC-NEG-06 | Recherche de secrets en clair (DEK, ReKey, fragments) en stockage temporaire | Aucun secret en clair détecté | Conformité INV-85-09 |
8. Observabilité requise pour les tests
- État système : snapshots avant/après des métadonnées
ProofEnvelope (immutabilité), états ReKey, ownership. - Réponse API : code HTTP, payload JSON complet, temps serveur, horodatages normalisés UTC.
- Journal d’audit : entrée WORM corrélée (
exportId, userId, résultat, timestamp, terminal state). - Événement signé / horodaté : champs
sealedAt, envelopeSeal, cohérence de signature/horodatage. - Export probatoire :
manifest.json, chronology.json, README_VERIFICATION.txt, guideUrl, signedUrls. - Télémétrie sécurité : traces d’absence d’opération de déchiffrement backend et contrôle chiffrement au repos.
9. Règles non testables
| Règle | Raison | Impact |
Valeur par défaut signedUrlTtl | Défaut non spécifié (seule borne max <=30 min est donnée) | Majeur |
| Politique d’audit pour 4xx/422 (CA-12) | Spec indique “à confirmer” | Majeur |
| Cas mixte 404 (inexistant + non possédé) | Priorité/agrégation d’erreur non définie | Majeur |
| Contexte de perf P95 (50/100 preuves) | Environnement de mesure absent | Mineur (hors périmètre contractuel actuel) |
Enum normative documentType | Valeurs non figées | Mineur |
Format contractuel proofEnvelopeRef | Non défini (UUID/URN/autre) | Mineur |
10. Verdict QA
- ⚠️ Testable partiellement (avec réserves listées)
Motif : la couverture fonctionnelle/invariants est testable de manière déterministe, mais plusieurs points contractuels bloquent une validation exhaustive sans ambiguïté (TTL par défaut, politique audit erreurs, règle 404 mixte).