Spaces:
Sleeping
fix(test): Z3 — strip HTML comments du rendu pour bloquer le decoy
Browse filesNiveau 3 de theater découvert : les tests qui grep le HTML RENDU
(``html_s7``, ``html_report``) sont trompés par les commentaires
HTML qui survivent au rendu Jinja (Jinja strip ses propres ``{# #}``
mais préserve les ``<!-- -->``).
Sabotage decoy reproduit :
<!-- decoy id="crosses-venn-title" -->
<h3 id="DEAD-VENN-TITLE" <!-- vrai titre cassé -->
Test ``assert 'id="crosses-venn-title"' in html_s7`` passe (decoy
matche), mais l'utilisateur ne voit AUCUN titre — la section
``crosses-venn-title`` est invisible/non navigable.
Fix : appliquer ``strip_comments(html, "html")`` AVANT chaque
assertion dans les tests X2 (les 7 hardenings que j'avais
introduits) :
- test_advanced_report.py : Venn, Wilcoxon, error-clusters,
correlation (4 tests)
- test_error_distribution.py : Gini scatter, Anchor scatter,
VLM badge (3 tests)
Tous utilisent désormais ``strip_comments(html, "html")`` avant
le ``in`` check. Le sabotage decoy est détecté (validé par 2
sabotages distincts : Venn + Gini via i18n dump).
Note de scope : seuls les 7 tests que j'ai durcis en X2 sont
modifiés. Les autres tests pré-existants (Sprint S5-S12) qui
grep html_s7 / html_report ont aussi cette dette ; out of scope
pour le commit X-Y-Z, à traiter dans un sprint dédié si demandé.
134 tests passants (les 2 modules affectés). Ruff propre.
https://claude.ai/code/session_01WYDbfkhKPeBZ15BTP4e9Ye
|
@@ -414,21 +414,16 @@ class TestReportSprint10:
|
|
| 414 |
assert "Ancrage" in html_report
|
| 415 |
|
| 416 |
def test_report_has_gini_cer_scatter_canvas(self, html_report):
|
| 417 |
-
#
|
| 418 |
-
#
|
| 419 |
-
#
|
| 420 |
-
|
| 421 |
-
|
| 422 |
-
# matchait aussi le titre h3, théoriquement OK mais la version
|
| 423 |
-
# ``or "Croisement..."`` rendait l'assertion disjonctive et
|
| 424 |
-
# fragile face à un changement d'un seul des deux libellés.
|
| 425 |
-
assert 'aria-label="Croisement CER vs Gini"' in html_report
|
| 426 |
|
| 427 |
def test_report_has_ratio_anchor_scatter_canvas(self, html_report):
|
| 428 |
-
#
|
| 429 |
-
|
| 430 |
-
|
| 431 |
-
assert 'aria-label="Croisement ancrage vs ratio de longueur"' in html_report
|
| 432 |
|
| 433 |
def test_report_has_vlm_badge(self, html_report):
|
| 434 |
"""Le badge VLM doit apparaître pour le moteur zero-shot.
|
|
@@ -441,9 +436,10 @@ class TestReportSprint10:
|
|
| 441 |
rendu. Désormais on vérifie la chaîne exacte du badge HTML
|
| 442 |
(chip pipeline-tag rendu par engines.cer_distribution renderer).
|
| 443 |
"""
|
| 444 |
-
|
| 445 |
-
|
| 446 |
-
"
|
|
|
|
| 447 |
)
|
| 448 |
|
| 449 |
|
|
|
|
| 414 |
assert "Ancrage" in html_report
|
| 415 |
|
| 416 |
def test_report_has_gini_cer_scatter_canvas(self, html_report):
|
| 417 |
+
# X2 + Z3 : aria-label exact du SVG généré par
|
| 418 |
+
# _build_cer_gini_scatter, après strip HTML comments pour
|
| 419 |
+
# empêcher le sabotage par decoy.
|
| 420 |
+
from tests._strip_helpers import strip_comments
|
| 421 |
+
assert 'aria-label="Croisement CER vs Gini"' in strip_comments(html_report, "html")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 422 |
|
| 423 |
def test_report_has_ratio_anchor_scatter_canvas(self, html_report):
|
| 424 |
+
# X2 + Z3 : aria-label exact unique, après strip HTML comments.
|
| 425 |
+
from tests._strip_helpers import strip_comments
|
| 426 |
+
assert 'aria-label="Croisement ancrage vs ratio de longueur"' in strip_comments(html_report, "html")
|
|
|
|
| 427 |
|
| 428 |
def test_report_has_vlm_badge(self, html_report):
|
| 429 |
"""Le badge VLM doit apparaître pour le moteur zero-shot.
|
|
|
|
| 436 |
rendu. Désormais on vérifie la chaîne exacte du badge HTML
|
| 437 |
(chip pipeline-tag rendu par engines.cer_distribution renderer).
|
| 438 |
"""
|
| 439 |
+
from tests._strip_helpers import strip_comments
|
| 440 |
+
assert "👁 VLM" in strip_comments(html_report, "html"), (
|
| 441 |
+
"Badge VLM (chip 👁 VLM) absent du HTML actif — pipeline zero-shot "
|
| 442 |
+
"non rendu correctement (Z3 : strip HTML comments contre decoy)"
|
| 443 |
)
|
| 444 |
|
| 445 |
|
|
@@ -649,33 +649,31 @@ class TestHTMLSprint7Features:
|
|
| 649 |
|
| 650 |
def test_html_contains_venn_container(self, html_s7):
|
| 651 |
# Sprint 11 : Venn migré vers SVG côté serveur dans Crosses.
|
| 652 |
-
# X2 (audit) : assertion durcie sur l'ID exact du titre
|
| 653 |
-
#
|
| 654 |
-
#
|
| 655 |
-
#
|
| 656 |
-
|
|
|
|
| 657 |
|
| 658 |
def test_html_contains_wilcoxon_table(self, html_s7):
|
| 659 |
# Sprint 11 : Wilcoxon migré vers SVG ``wilcoxon-matrix``.
|
| 660 |
-
# X2 : assertion durcie sur la classe
|
| 661 |
-
#
|
| 662 |
-
#
|
| 663 |
-
|
| 664 |
-
|
| 665 |
-
assert 'class="wilcoxon-cell ' in html_s7
|
| 666 |
|
| 667 |
def test_html_contains_error_clusters(self, html_s7):
|
| 668 |
-
# X2
|
| 669 |
-
|
| 670 |
-
|
| 671 |
-
assert 'id="error-clusters-container"' in html_s7
|
| 672 |
|
| 673 |
def test_html_contains_correlation_matrix(self, html_s7):
|
| 674 |
-
# X2
|
| 675 |
-
#
|
| 676 |
-
|
| 677 |
-
|
| 678 |
-
assert 'class="corr-cell mono"' in html_s7
|
| 679 |
|
| 680 |
def test_html_contains_difficulty_badge(self, html_s7):
|
| 681 |
assert "difficulty" in html_s7.lower() or "diff-badge" in html_s7
|
|
|
|
| 649 |
|
| 650 |
def test_html_contains_venn_container(self, html_s7):
|
| 651 |
# Sprint 11 : Venn migré vers SVG côté serveur dans Crosses.
|
| 652 |
+
# X2 + Z3 (audit) : assertion durcie sur l'ID exact du titre,
|
| 653 |
+
# avec strip des commentaires HTML pour empêcher le sabotage
|
| 654 |
+
# par decoy ``<!-- id="crosses-venn-title" -->`` qui satisferait
|
| 655 |
+
# le grep sans rien rendre de visible à l'utilisateur.
|
| 656 |
+
from tests._strip_helpers import strip_comments
|
| 657 |
+
assert 'id="crosses-venn-title"' in strip_comments(html_s7, "html")
|
| 658 |
|
| 659 |
def test_html_contains_wilcoxon_table(self, html_s7):
|
| 660 |
# Sprint 11 : Wilcoxon migré vers SVG ``wilcoxon-matrix``.
|
| 661 |
+
# X2 + Z3 : assertion durcie sur la classe ``wilcoxon-cell``
|
| 662 |
+
# (toujours combinée avec une variante, donc espace trailing).
|
| 663 |
+
# Strip des commentaires HTML pour empêcher le decoy.
|
| 664 |
+
from tests._strip_helpers import strip_comments
|
| 665 |
+
assert 'class="wilcoxon-cell ' in strip_comments(html_s7, "html")
|
|
|
|
| 666 |
|
| 667 |
def test_html_contains_error_clusters(self, html_s7):
|
| 668 |
+
# X2 + Z3 : ID exact du conteneur, après strip HTML comments.
|
| 669 |
+
from tests._strip_helpers import strip_comments
|
| 670 |
+
assert 'id="error-clusters-container"' in strip_comments(html_s7, "html")
|
|
|
|
| 671 |
|
| 672 |
def test_html_contains_correlation_matrix(self, html_s7):
|
| 673 |
+
# X2 + Z3 : classe CSS exacte rendue par le renderer Python,
|
| 674 |
+
# après strip HTML comments.
|
| 675 |
+
from tests._strip_helpers import strip_comments
|
| 676 |
+
assert 'class="corr-cell mono"' in strip_comments(html_s7, "html")
|
|
|
|
| 677 |
|
| 678 |
def test_html_contains_difficulty_badge(self, html_s7):
|
| 679 |
assert "difficulty" in html_s7.lower() or "diff-badge" in html_s7
|