ARCH-005, premiere moitie. matches.py et team_matches.py lisaient une
quarantaine de champs sur request.form a la main et les croyaient tous.
Ce que ca produisait n etait pas bruyant :
- edit_match attrapait une heure invalide et faisait start_time = None,
puis annoncait que le match etait mis a jour. Le match perdait son
heure et le calendrier l affichait a minuit ;
- match_type etait accepte tel quel. Une valeur inconnue creait un match
auquel aucun joueur n etait rattache, sans un mot ;
- une fin avant le debut etait enregistree telle quelle ;
- title est NOT NULL dans le modele et n etait pas verifie dans la route,
donc un titre vide etait un 500 ;
- 'a,b' dans la selection de joueurs arrivait sur int() sans garde.
app/forms.py rassemble les deux fonctions de frontiere, qui vivaient dans
users/_shared.py parce que c est la qu elles avaient d abord servi. Elles
y restent re-exportees, donc aucun des trente appels n a bouge.
Le mixin des schemas lit desormais un champ vide comme un champ absent.
C est ce qui rendait ces formulaires invalidables : un formulaire HTML
envoie tout ce qu il affiche, donc une date optionnelle non remplie
arrive comme '' et non comme rien. Seuls les champs declares optionnels
sont concernes ; un champ requis laisse vide doit toujours echouer.
Deux duplications absorbees au passage, toutes deux nommees par l audit :
la boucle de creation des participants, ecrite deux fois et deja divergee
— la copie de edit_match gardait ses identifiants en chaines et appelait
int() une ligne plus loin — et le contexte de re-affichage du formulaire,
dont les versions courtes faisaient mourir un refus dans tojson sur un
Undefined : un message de validation devenait un 500.
Limite connue et consignee : le formulaire revient rempli avec les
valeurs enregistrees, pas avec la saisie refusee. Reafficher la
soumission demande de toucher aux gabarits, c est un autre changement.
19 tests neufs sur ces routes, qui n en avaient aucun. 447 au total.