Intègre un chat IA capable de manipuler la scène via les mêmes fonctions que l'éditeur manuel (objets, variables, déclencheurs, images générées), avec conversations multiples par écran façon Claude. Corrige au passage le rafraîchissement pjax hors-ordre, l'onglet IA/déclencheurs vide après sélection d'un objet, la comparaison de booléens dans les conditions, et le blocage du glisser-déposer hors du cadre caméra après un redimensionnement de fond par l'IA. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
122 lines
5.4 KiB
Python
122 lines
5.4 KiB
Python
"""Onglet "Variables" de l'éditeur de scène (templates/scene_edit.html) —
|
|
CRUD classique (formulaires POST/redirect, voir l'onglet "Événements"
|
|
pour le même patron) sur les fonctions déjà existantes de db/global_vars/
|
|
(list/create/update/delete). Le nom est la clé stable lue par
|
|
static/js/play/conditions.js::readVariableValue — jamais modifiable après
|
|
création (voir db/global_vars/update_global_variable.py)."""
|
|
import re
|
|
|
|
import db
|
|
|
|
|
|
def _create_screen(client, slug, name="Accueil"):
|
|
resp = client.post(f"/game/{slug}/screens/new", data={"name": name}, follow_redirects=False)
|
|
return int(re.search(r"/screens/(\d+)/edit", resp.headers["Location"]).group(1))
|
|
|
|
|
|
def test_create_global_var_route_persists_and_redirects_to_the_variables_tab(client, game):
|
|
screen_id = _create_screen(client, game)
|
|
resp = client.post(
|
|
f"/game/{game}/variables/new",
|
|
data={"name": "score_total", "type": "nombre_entier", "default_value": "0", "screen_id": screen_id},
|
|
follow_redirects=False,
|
|
)
|
|
assert resp.status_code == 302
|
|
assert resp.headers["Location"].endswith(f"/game/{game}/screens/{screen_id}/edit?tab=variables")
|
|
variables = db.list_global_variables(game)
|
|
assert [v["name"] for v in variables] == ["score_total"]
|
|
assert variables[0]["type"] == "nombre_entier"
|
|
assert variables[0]["value"] == "0"
|
|
|
|
|
|
def test_create_global_var_is_idempotent_by_name(client, game):
|
|
screen_id = _create_screen(client, game)
|
|
client.post(f"/game/{game}/variables/new", data={"name": "score_total", "screen_id": screen_id})
|
|
client.post(f"/game/{game}/variables/new", data={"name": "score_total", "screen_id": screen_id})
|
|
assert len(db.list_global_variables(game)) == 1
|
|
|
|
|
|
def test_global_var_edit_route_updates_type_and_value(client, game):
|
|
screen_id = _create_screen(client, game)
|
|
client.post(f"/game/{game}/variables/new", data={"name": "score_total", "type": "nombre_entier", "default_value": "0", "screen_id": screen_id})
|
|
var_id = db.list_global_variables(game)[0]["id"]
|
|
|
|
resp = client.post(
|
|
f"/game/{game}/variables/{var_id}/edit",
|
|
data={"type": "texte", "value": "beaucoup", "screen_id": screen_id},
|
|
follow_redirects=False,
|
|
)
|
|
assert resp.status_code == 302
|
|
assert resp.headers["Location"].endswith(f"/game/{game}/screens/{screen_id}/edit?tab=variables")
|
|
variable = db.list_global_variables(game)[0]
|
|
assert variable["type"] == "texte"
|
|
assert variable["value"] == "beaucoup"
|
|
assert variable["name"] == "score_total" # le nom ne change jamais
|
|
|
|
|
|
def test_global_var_delete_route_removes_it(client, game):
|
|
screen_id = _create_screen(client, game)
|
|
client.post(f"/game/{game}/variables/new", data={"name": "score_total", "screen_id": screen_id})
|
|
var_id = db.list_global_variables(game)[0]["id"]
|
|
|
|
resp = client.post(f"/game/{game}/variables/{var_id}/delete", data={"screen_id": screen_id}, follow_redirects=False)
|
|
assert resp.status_code == 302
|
|
assert resp.headers["Location"].endswith(f"/game/{game}/screens/{screen_id}/edit?tab=variables")
|
|
assert db.list_global_variables(game) == []
|
|
|
|
|
|
def test_variables_tab_lists_existing_variables_in_the_scene_edit_page(client, game):
|
|
screen_id = _create_screen(client, game)
|
|
client.post(f"/game/{game}/variables/new", data={"name": "score_total", "type": "nombre_entier", "default_value": "5", "screen_id": screen_id})
|
|
|
|
html = client.get(f"/game/{game}/screens/{screen_id}/edit").get_data(as_text=True)
|
|
assert "score_total" in html
|
|
assert 'data-tab="variables"' in html
|
|
|
|
|
|
# ---------- Réponse AJAX (voir static/js/scenes/global-variables.js) —
|
|
# demande explicite : plus de rechargement de page pour créer/modifier/
|
|
# supprimer une variable. ----------
|
|
|
|
def test_create_global_var_ajax_returns_the_row_html_without_redirecting(client, game):
|
|
screen_id = _create_screen(client, game)
|
|
resp = client.post(
|
|
f"/game/{game}/variables/new",
|
|
data={"name": "score_total", "type": "nombre_entier", "default_value": "0", "screen_id": screen_id},
|
|
headers={"X-Requested-With": "fetch"},
|
|
)
|
|
assert resp.status_code == 200
|
|
body = resp.get_json()
|
|
assert body["ok"] is True
|
|
assert "score_total" in body["row_html"]
|
|
assert 'data-var-row="' in body["row_html"]
|
|
|
|
|
|
def test_global_var_edit_ajax_returns_ok_without_redirecting(client, game):
|
|
screen_id = _create_screen(client, game)
|
|
client.post(f"/game/{game}/variables/new", data={"name": "score_total", "type": "nombre_entier", "default_value": "0", "screen_id": screen_id})
|
|
var_id = db.list_global_variables(game)[0]["id"]
|
|
|
|
resp = client.post(
|
|
f"/game/{game}/variables/{var_id}/edit",
|
|
data={"type": "texte", "value": "beaucoup"},
|
|
headers={"X-Requested-With": "fetch"},
|
|
)
|
|
assert resp.status_code == 200
|
|
assert resp.get_json() == {"ok": True}
|
|
assert db.list_global_variables(game)[0]["value"] == "beaucoup"
|
|
|
|
|
|
def test_global_var_delete_ajax_returns_ok_without_redirecting(client, game):
|
|
screen_id = _create_screen(client, game)
|
|
client.post(f"/game/{game}/variables/new", data={"name": "score_total", "screen_id": screen_id})
|
|
var_id = db.list_global_variables(game)[0]["id"]
|
|
|
|
resp = client.post(
|
|
f"/game/{game}/variables/{var_id}/delete",
|
|
headers={"X-Requested-With": "fetch"},
|
|
)
|
|
assert resp.status_code == 200
|
|
assert resp.get_json() == {"ok": True}
|
|
assert db.list_global_variables(game) == []
|