Dev #1
@@ -30,6 +30,36 @@ def list_elements(slug, screen_id, enforce_visibility=False):
|
||||
d["style"] = json.loads(d["style"] or "{}")
|
||||
d["attributes"] = json.loads(d["attributes"] or "{}")
|
||||
result.append(d)
|
||||
|
||||
# Descendant d'un exemplaire d'élément de jeu (element_type_id réglé sur
|
||||
# un ancêtre) : un ancien enfant copié en base par l'ex-instantiate_
|
||||
# template_tree (mécanisme retiré, voir add_element.py) — son contenu
|
||||
# vient désormais TOUJOURS en direct de l'écran-modèle au moment du
|
||||
# rendu (voir render_element_html.py/_render_element_type_children),
|
||||
# jamais de ces lignes, qui peuvent encore traîner en base pour un
|
||||
# exemplaire posé avant ce changement. Exclu ici pour ne plus jamais
|
||||
# apparaître sélectionnable dans l'arborescence de l'éditeur — sinon
|
||||
# ses réglages, plus jamais synchronisés avec le modèle, donnaient
|
||||
# l'impression trompeuse que "les propriétés ne sont pas prises en
|
||||
# compte" (une taille de texte modifiée dans le modèle ne se reflétant
|
||||
# jamais sur cette ligne fantôme, toujours sélectionnable à l'écran).
|
||||
by_id = {d["id"]: d for d in result}
|
||||
|
||||
def _has_linked_ancestor(d):
|
||||
seen = set()
|
||||
parent_id = d.get("parent_id")
|
||||
while parent_id and parent_id not in seen:
|
||||
seen.add(parent_id)
|
||||
parent = by_id.get(parent_id)
|
||||
if not parent:
|
||||
return False
|
||||
if parent.get("element_type_id"):
|
||||
return True
|
||||
parent_id = parent.get("parent_id")
|
||||
return False
|
||||
|
||||
result = [d for d in result if not _has_linked_ancestor(d)]
|
||||
|
||||
children_map = {}
|
||||
for d in result:
|
||||
if d.get("parent_id"):
|
||||
|
||||
@@ -56,6 +56,47 @@ def test_editing_the_template_updates_the_play_page_too(client, game):
|
||||
assert "Contenu mis à jour" in html
|
||||
|
||||
|
||||
def test_leftover_orphaned_children_no_longer_appear_in_the_editor(client, game):
|
||||
"""Régression : un exemplaire posé AVANT ce mécanisme (ou tout ancien
|
||||
enfant copié en base par l'ex-instantiate_template_tree, retiré)
|
||||
laisse d'éventuelles lignes orphelines en base sous l'exemplaire — leur
|
||||
contenu n'est plus jamais rendu (voir render_element_html.py), mais
|
||||
elles restaient sélectionnables dans l'arborescence de l'éditeur, avec
|
||||
leurs propres réglages jamais synchronisés avec le modèle : une taille
|
||||
de texte modifiée dans le modèle ne s'y reflétait jamais, donnant
|
||||
l'impression trompeuse que "les propriétés ne sont pas prises en
|
||||
compte"."""
|
||||
import json
|
||||
|
||||
import db
|
||||
|
||||
et, _titre_id = _create_card_element_type(client, game)
|
||||
screen_id = _create_screen(client, game)
|
||||
resp = client.post(
|
||||
f"/game/{game}/screens/{screen_id}/elements/add",
|
||||
data={"widget": "__catalogue__", "element_type_id": str(et["id"])},
|
||||
follow_redirects=False,
|
||||
)
|
||||
instance_id = int(re.search(r"selected=(\d+)", resp.headers["Location"]).group(1))
|
||||
|
||||
conn = db.connect(game)
|
||||
conn.execute(
|
||||
"""INSERT INTO _screen_elements (screen_id, parent_id, widget, content, attributes, x, y, width, height, z_index, style)
|
||||
VALUES (?, ?, 'titre', 'Ancien contenu figé', '{}', 10, 10, 50, 20, 1, ?)""",
|
||||
(screen_id, instance_id, json.dumps({"font-size": "21px"})),
|
||||
)
|
||||
orphan_id = conn.execute("SELECT last_insert_rowid() AS id").fetchone()["id"]
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
html = client.get(f"/game/{game}/screens/{screen_id}/edit").data.decode()
|
||||
assert f'id="elt-{orphan_id}"' not in html
|
||||
assert "Ancien contenu figé" not in html
|
||||
|
||||
html_selected = client.get(f"/game/{game}/screens/{screen_id}/edit?selected={orphan_id}").data.decode()
|
||||
assert 'value="21' not in html_selected
|
||||
|
||||
|
||||
def test_instance_position_on_screen_is_independent_per_instance(client, game):
|
||||
"""Non-régression : la position/taille sur l'écran reste propre à
|
||||
chaque exemplaire (seul le CONTENU intérieur est désormais partagé)."""
|
||||
|
||||
Reference in New Issue
Block a user