feat(IMP-14): A-4 — slide_base embedded vs standalone mode contract
Step 13 owns iframe-vs-standalone CSS contract in slide_base.html via
3-valued embedded_mode enum (auto / embedded / standalone). Removes
SlideCanvas.tsx runtime CSS injection workaround; frontend now passes
?embedded=1 query so auto-mode script attaches html.embedded class and
scopes the standalone body centering/min-height/padding reset.
- templates/phase_z2/slide_base.html: conditional html.embedded class +
CSP-safe auto-mode <script> + additive html.embedded body/.slide rules
- src/phase_z2_pipeline.py: render_slide gains keyword-only embedded_mode
("auto" default) + ValueError guard; 3 existing call sites unchanged
- Front/client/src/components/SlideCanvas.tsx: derive embeddedSrc with
?embedded=1 (query-preserving), drop reset CSS injection block
- tests/phase_z2/test_slide_base_embedded_mode.py: 6 cases — auto script,
CSS rules, embedded/standalone explicit modes, byte-determinism,
invalid-mode guard
This commit is contained in:
69
tests/phase_z2/test_slide_base_embedded_mode.py
Normal file
69
tests/phase_z2/test_slide_base_embedded_mode.py
Normal file
@@ -0,0 +1,69 @@
|
||||
"""IMP-14 A-4 — slide_base.html embedded_mode contract tests.
|
||||
|
||||
Asserts the three-valued enum (auto / embedded / standalone) round-trips
|
||||
through render_slide -> slide_base.html, that the additive html.embedded
|
||||
CSS reset and the auto-mode detection <script> are emitted under the
|
||||
correct modes, that the invalid-mode guard raises ValueError, and that
|
||||
Jinja2 rendering is byte-deterministic across calls.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from src.phase_z2_pipeline import render_slide
|
||||
|
||||
|
||||
def _zone() -> dict:
|
||||
return {"position": "primary", "template_id": "__empty__", "slot_payload": {}}
|
||||
|
||||
|
||||
def _layout_css() -> dict:
|
||||
return {"areas": '"primary"', "cols": "1fr", "rows": "1fr"}
|
||||
|
||||
|
||||
def _render(embedded_mode: str = "auto") -> str:
|
||||
return render_slide(
|
||||
slide_title="t",
|
||||
slide_footer=None,
|
||||
zones_data=[_zone()],
|
||||
layout_preset="single",
|
||||
layout_css=_layout_css(),
|
||||
gap_px=14,
|
||||
embedded_mode=embedded_mode,
|
||||
)
|
||||
|
||||
|
||||
def test_auto_script_present():
|
||||
html = _render("auto")
|
||||
assert "params.get('embedded')" in html
|
||||
assert "window.self !== window.top" in html
|
||||
assert "classList.add('embedded')" in html
|
||||
|
||||
|
||||
def test_css_rules_present():
|
||||
html = _render("auto")
|
||||
assert "html.embedded body" in html
|
||||
assert "html.embedded .slide" in html
|
||||
|
||||
|
||||
def test_embedded_mode_explicit():
|
||||
html = _render("embedded")
|
||||
assert '<html lang="ko" class="embedded">' in html
|
||||
assert "params.get('embedded')" not in html
|
||||
|
||||
|
||||
def test_standalone_mode_explicit():
|
||||
html = _render("standalone")
|
||||
assert '<html lang="ko">' in html
|
||||
assert 'class="embedded"' not in html.split("</head>")[0]
|
||||
assert "params.get('embedded')" not in html
|
||||
|
||||
|
||||
def test_deterministic():
|
||||
assert _render("embedded") == _render("embedded")
|
||||
assert _render("auto") == _render("auto")
|
||||
|
||||
|
||||
def test_invalid_mode_raises():
|
||||
with pytest.raises(ValueError, match="invalid embedded_mode"):
|
||||
_render("bogus")
|
||||
Reference in New Issue
Block a user