From 6cf4fdbe72484aa8c8dd69c69db8f222ce3551db Mon Sep 17 00:00:00 2001 From: william Date: Thu, 27 Aug 2026 19:03:29 +0200 Subject: [PATCH] =?UTF-8?q?Corrige=20la=20cr=C3=A9ation=20d'objet=20sans?= =?UTF-8?q?=20champ=20:=20le=20panneau=20rechargeait=20la=20page=20sans=20?= =?UTF-8?q?rien=20cr=C3=A9er?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug rapporté : le panneau "+ Nouvel objet" du tableau de bord "recharge la page sans créer d'objet". Cause : object_new exigeait "name AND fields" pour créer quoi que ce soit — or le formulaire du panneau permet de taper le nom et de cliquer directement "Créer l'objet" SANS avoir cliqué au préalable "+ Ajouter un champ" (les champs se posent typiquement APRÈS, depuis le panneau "Modifier un objet", workflow déjà supporté). Sans champ soumis, la condition échouait, la route redirigeait silencieusement vers le tableau de bord SANS créer l'objet ET sans le moindre message d'erreur — vécu comme "un rechargement qui ne fait rien". create_definition(fields=[]) fonctionne déjà très bien (crée juste une table avec id/created_at, sans colonne "métier") : retiré l'exigence d'au moins un champ, ne reste que "name" non vide. Nouveau test (tests/test_object_new_without_fields.py), confirmé en échec sur l'ancien code (git stash) puis au vert avec le correctif. 131 tests au vert au total. Co-Authored-By: Claude Sonnet 5 --- routes/objects/object_new.py | 9 ++++++++- tests/test_object_new_without_fields.py | 27 +++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 tests/test_object_new_without_fields.py diff --git a/routes/objects/object_new.py b/routes/objects/object_new.py index 2c23524a..98c0bbc0 100644 --- a/routes/objects/object_new.py +++ b/routes/objects/object_new.py @@ -15,8 +15,15 @@ def object_new(slug): externe obsolète) redirige simplement vers le tableau de bord.""" if request.method == "POST": name = request.form.get("object_name", "").strip() + # Aucun champ requis à la création : create_definition(fields=[]) + # crée simplement une table sans colonne "métier" (juste id/ + # created_at), et le panneau "Modifier un objet" (onglet Champs, + # bouton "+ Ajouter") permet d'en poser ensuite — exiger au moins + # un champ ici faisait échouer silencieusement la création (aucun + # message d'erreur, juste un retour au tableau de bord) dès qu'on + # tapait le nom sans avoir encore cliqué "+ Ajouter un champ". fields = _parse_field_rows(request.form) - if name and fields: + if name: definition_id = db.create_definition(slug, name, fields) return redirect(url_for("object_view", slug=slug, definition_id=definition_id)) diff --git a/tests/test_object_new_without_fields.py b/tests/test_object_new_without_fields.py new file mode 100644 index 00000000..944447a9 --- /dev/null +++ b/tests/test_object_new_without_fields.py @@ -0,0 +1,27 @@ +"""Régression : le panneau "+ Nouvel objet" du tableau de bord (game_dashboard.html) +soumet le formulaire dès qu'on tape un nom et clique "Créer l'objet", +SANS avoir forcément cliqué "+ Ajouter un champ" au moins une fois avant +(les champs se posent typiquement APRÈS, depuis le panneau "Modifier un +objet"). routes/objects/object_new.py exigeait pourtant au moins un champ +pour créer quoi que ce soit ("if name and fields"), sans le moindre +message d'erreur en cas d'échec — juste un aller-retour silencieux vers le +tableau de bord, vécu comme "le panneau recharge la page sans créer +d'objet".""" +import db + + +def test_object_created_with_a_name_but_no_field(client, game): + resp = client.post(f"/game/{game}/objects/new", data={"object_name": "Compteur"}, follow_redirects=False) + assert resp.status_code == 302 + assert "/objects/" in resp.headers["Location"] + + definitions = db.list_definitions(game) + assert len(definitions) == 1 + assert definitions[0]["name"] == "Compteur" + assert db.get_definition(game, definitions[0]["id"])["fields"] == [] + + +def test_object_not_created_without_a_name(client, game): + resp = client.post(f"/game/{game}/objects/new", data={"object_name": " "}, follow_redirects=False) + assert resp.status_code == 302 + assert db.list_definitions(game) == []