"""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) == [] def test_relation_field_without_a_chosen_target_does_not_crash_the_whole_request(client, game): """Régression : "Relation vers un autre objet" est TOUJOURS une option du sélecteur de type (db/constants.py), même quand il n'existe encore AUCUN autre objet à pointer (ex. le tout premier objet créé dans un jeu) — le sélecteur "Objet lié" est alors vide, et create_definition() faisait int("") sans filet, plantant TOUTE la requête (500) avant même d'atteindre son commit() : l'objet n'était donc PAS créé du tout, pas seulement son champ "Relation" — vécu comme "le panneau recharge la page sans créer d'objet" alors que des champs avaient bien été renseignés. Le champ "Relation" invalide doit être ignoré (comme une ligne sans nom), pas faire échouer tout le reste.""" resp = client.post(f"/game/{game}/objects/new", data={ "object_name": "Personnage", "field_name[]": ["nom", "arme"], "field_type[]": ["texte", "relation"], "field_relation[]": ["", ""], "field_required[]": ["0", "0"], "field_min[]": ["", ""], "field_max[]": ["", ""], }, follow_redirects=False) assert resp.status_code == 302 definitions = db.list_definitions(game) assert len(definitions) == 1 fields = db.get_definition(game, definitions[0]["id"])["fields"] assert [f["name"] for f in fields] == ["nom"] def test_add_relation_field_without_a_chosen_target_is_ignored_not_a_crash(client, game): """Même garde, côté "+ Ajouter un champ" du panneau d'un objet déjà créé (object_field_add.py / add_field_to_definition.py).""" resp = client.post(f"/game/{game}/objects/new", data={ "object_name": "Personnage", "field_name[]": ["nom"], "field_type[]": ["texte"], "field_relation[]": [""], "field_required[]": ["0"], "field_min[]": [""], "field_max[]": [""], }, follow_redirects=False) def_id = int(resp.headers["Location"].rstrip("/").split("/")[-1]) resp = client.post(f"/game/{game}/objects/{def_id}/fields/add", data={ "field_name": "arme", "field_type": "relation", "field_relation": "", }, follow_redirects=False) assert resp.status_code == 302 fields = db.get_definition(game, def_id)["fields"] assert [f["name"] for f in fields] == ["nom"]