Files
Forge-Engine/tests/document/test_document_themes.py
T
williamandClaude Sonnet 5 1296edc2f8 Ajoute une largeur maximale optionnelle aux blocs de texte (titre/paragraphe)
Nouvel attribut max_width (vide par défaut = pleine largeur, inchangé)
sur les kinds titre/paragraphe, réglable depuis leur panneau
Propriétés. Le sous-titre de la page de garde du thème Sécurité
Incendie l'utilise (60ch) pour rester conforme à la maquette d'origine,
qui ne l'étirait pas sur toute la largeur de la page.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-24 10:39:18 +02:00

104 lines
4.5 KiB
Python

"""Catalogue de thèmes visuels (document_engine/themes/) — conversion du
contenu-seed en éléments "à plat" pour l'aperçu (seed_blocks_to_elements),
et respect par CHAQUE thème du catalogue des règles structurelles du
moteur (ex. un mini-jeu seul sur sa page, voir routes/document/
document_element_add.py) — vérifié ici statiquement sur les données du
catalogue, sans passer par une route HTTP."""
from typing import Any
import document_engine as doc_engine
def test_get_document_theme_entry_returns_none_for_an_unknown_id() -> None:
assert doc_engine.get_document_theme_entry("n-importe-quoi") is None
def test_get_document_theme_entry_returns_the_matching_entry() -> None:
entry = doc_engine.get_document_theme_entry("securite-incendie")
assert entry is not None
assert entry["id"] == "securite-incendie"
assert entry["name"] == "Sécurité Incendie"
assert len(entry["seed_pages"]) > 0
def test_securite_incendie_title_page_is_vertically_centered() -> None:
"""Retour utilisateur du 24/09/2026 : la page de garde doit être
centrée verticalement, comme une page de titre — les pages suivantes
restent alignées en haut (comportement par défaut)."""
entry = doc_engine.get_document_theme_entry("securite-incendie")
assert entry is not None
assert entry["seed_pages"][0]["vertical_align"] == "center"
assert entry["seed_pages"][1].get("vertical_align", "top") == "top"
def test_securite_incendie_intro_paragraph_has_a_max_width() -> None:
"""Retour utilisateur du 24/09/2026 : le sous-titre de la page de
garde doit rester aussi étroit que dans la maquette, pas étiré sur
toute la largeur de la page."""
entry = doc_engine.get_document_theme_entry("securite-incendie")
assert entry is not None
intro_paragraph = entry["seed_pages"][0]["blocks"][2]
assert intro_paragraph["kind"] == "paragraphe"
assert intro_paragraph["attributes"]["max_width"] == "60ch"
def test_seed_blocks_to_elements_assigns_unique_synthetic_ids() -> None:
blocks: list[dict[str, Any]] = [
{"kind": "titre", "attributes": {"content": "Titre"}},
{
"kind": "row",
"attributes": {"gap": 10},
"children": [
{"kind": "paragraphe", "attributes": {"content": "A"}},
{"kind": "paragraphe", "attributes": {"content": "B"}},
],
},
]
elements = doc_engine.seed_blocks_to_elements(blocks)
ids = [el["id"] for el in elements]
assert len(ids) == len(set(ids))
assert len(elements) == 4
row = next(el for el in elements if el["kind"] == "row")
children = [el for el in elements if el["parent_id"] == row["id"]]
assert len(children) == 2
def test_seed_blocks_to_elements_merges_onto_default_attributes() -> None:
elements = doc_engine.seed_blocks_to_elements([{"kind": "titre", "attributes": {"content": "Contenu seul"}}])
assert elements[0]["attributes"]["content"] == "Contenu seul"
assert elements[0]["attributes"]["style"] == "titre1"
def test_seed_blocks_to_elements_renders_without_error() -> None:
theme = doc_engine.get_document_theme_entry("securite-incendie")
assert theme is not None
elements = doc_engine.seed_blocks_to_elements(theme["seed_pages"][0]["blocks"])
html = doc_engine.render_document(elements)
assert "docText" in html
def test_every_theme_seed_page_has_a_valid_vertical_align() -> None:
for theme in doc_engine.DOCUMENT_THEMES:
for seed_page in theme["seed_pages"]:
align = seed_page.get("vertical_align", "top")
assert align in doc_engine.VERTICAL_ALIGNS, f"thème {theme['id']!r} : vertical_align invalide {align!r}"
def test_every_theme_seed_page_respects_the_minigame_exclusivity_rule() -> None:
"""Un mini-jeu doit toujours être SEUL sur sa page (règle appliquée
côté route pour un ajout manuel, voir routes/document/
document_element_add.py) — le contenu-seed d'un thème la respecte
dès sa conception puisque document_engine.replace_document_content
ne la revérifie pas elle-même (contenu fourni par le thème, pas par
l'utilisateur)."""
for theme in doc_engine.DOCUMENT_THEMES:
for seed_page in theme["seed_pages"]:
page_blocks = seed_page["blocks"]
minigame_blocks = [b for b in page_blocks if b["kind"] in doc_engine.MINIGAME_KINDS]
if minigame_blocks:
assert len(page_blocks) == 1, (
f"thème {theme['id']!r} : une page avec mini-jeu doit contenir uniquement ce mini-jeu"
)