"""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 from typing import Any from flask.testing import FlaskClient import db from tests.conftest import not_none def _create_screen(client: FlaskClient, slug: str, name: str = "Accueil") -> Any: resp = client.post(f"/game/{slug}/screens/new", data={"name": name}, follow_redirects=False) return int(not_none(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: FlaskClient, game: str) -> None: 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: FlaskClient, game: str) -> None: 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: FlaskClient, game: str) -> None: 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: FlaskClient, game: str) -> None: 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: FlaskClient, game: str) -> None: 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: FlaskClient, game: str) -> None: 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: FlaskClient, game: str) -> None: 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: FlaskClient, game: str) -> None: 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) == []