handbook_engine / tests /test_templates.py
internationalscholarsprogram's picture
fix: ISP handbook styling overhaul - margins, typography, emphasis, benefits, CSS cascade
ec94fc1
"""Tests for the Jinja2 template rendering pipeline."""
from __future__ import annotations
import pytest
from pathlib import Path
from app.services.utils import h, handbook_anchor
from app.services.renderers import sort_toc
# ── Templates exist ──
def test_templates_directory_exists():
templates_dir = Path(__file__).resolve().parent.parent / "app" / "templates"
assert templates_dir.is_dir(), f"Templates directory not found: {templates_dir}"
def test_main_template_exists():
template_path = Path(__file__).resolve().parent.parent / "app" / "templates" / "handbook.html"
assert template_path.is_file(), f"Main template not found: {template_path}"
def test_partials_exist():
partials_dir = Path(__file__).resolve().parent.parent / "app" / "templates" / "partials"
assert partials_dir.is_dir()
required_partials = ["cover.html", "toc.html", "university.html", "section.html"]
for name in required_partials:
p = partials_dir / name
assert p.is_file(), f"Partial template not found: {p}"
# ── Print CSS exists ──
def test_print_css_exists():
css_path = Path(__file__).resolve().parent.parent / "app" / "static" / "css" / "print.css"
assert css_path.is_file(), f"Print CSS not found: {css_path}"
def test_print_css_has_page_rules():
css_path = Path(__file__).resolve().parent.parent / "app" / "static" / "css" / "print.css"
css = css_path.read_text(encoding="utf-8")
assert "@page" in css
assert "size: A4" in css
assert "page-break" in css
def test_print_css_has_core_classes():
css_path = Path(__file__).resolve().parent.parent / "app" / "static" / "css" / "print.css"
css = css_path.read_text(encoding="utf-8")
expected_classes = [
".h2", ".h3", ".p", ".tbl", ".programs",
".cover-page", ".toc-page", ".uni-name",
".benefits-bar", ".career-list",
]
for cls in expected_classes:
assert cls in css, f"Expected class {cls} missing from print.css"
# ── Jinja2 environment ──
def test_jinja2_env_loads():
from app.services.html_builder import _get_jinja_env
env = _get_jinja_env()
template = env.get_template("handbook.html")
assert template is not None
def test_jinja2_renders_minimal_context():
"""Test that the main template renders with minimal data (no sections)."""
from app.services.html_builder import _get_jinja_env
from markupsafe import Markup
env = _get_jinja_env()
template = env.get_template("handbook.html")
html = template.render(
font_css=Markup("/* no fonts */"),
base_url="file:///tmp",
extra_css="",
cover_image="",
toc_image="",
toc_items=[],
toc_items_sorted=[],
toc_title="Table of Contents",
toc_sort_order=None,
general_sections=[],
summary_block=None,
universities=[],
bottom_pages=[],
debug=False,
stats={},
)
assert "<!doctype html>" in html.lower() or "<!DOCTYPE html>" in html
assert "<body>" in html
assert "</body>" in html
assert "ISP Handbook" in html
def test_jinja2_renders_with_cover():
"""Test cover image inclusion in template."""
from app.services.html_builder import _get_jinja_env
from markupsafe import Markup
env = _get_jinja_env()
template = env.get_template("handbook.html")
html = template.render(
font_css=Markup(""),
base_url="file:///tmp",
extra_css="",
cover_image="file:///tmp/cover.jpg",
toc_image="",
toc_items=[],
toc_items_sorted=[],
toc_title="Table of Contents",
toc_sort_order=None,
general_sections=[],
summary_block=None,
universities=[],
bottom_pages=[],
debug=False,
stats={},
)
assert "cover-page" in html
assert "cover.jpg" in html
def test_jinja2_renders_toc():
"""Test TOC rendering in template."""
from app.services.html_builder import _get_jinja_env
from markupsafe import Markup
env = _get_jinja_env()
template = env.get_template("handbook.html")
toc_items_sorted = [
{"title": "Overview", "display_title": "OVERVIEW", "target": "#overview",
"level": 0, "bold": True, "upper": True, "page": "3"},
{"title": "Drew University", "display_title": "Drew University", "target": "#uni-drew",
"level": 1, "bold": False, "upper": False, "page": ""},
]
html = template.render(
font_css=Markup(""),
base_url="file:///tmp",
extra_css="",
cover_image="",
toc_image="",
toc_items=toc_items_sorted, # non-empty triggers TOC
toc_items_sorted=toc_items_sorted,
toc_title="Table of Contents",
toc_sort_order=1,
general_sections=[],
summary_block=None,
universities=[],
bottom_pages=[],
debug=False,
stats={},
)
assert "toc-page" in html
assert "OVERVIEW" in html
assert "Drew University" in html
assert "toc-table" in html
def test_jinja2_renders_sections():
"""Test global section rendering."""
from app.services.html_builder import _get_jinja_env
from markupsafe import Markup
env = _get_jinja_env()
template = env.get_template("handbook.html")
sections = [{
"anchor": "g-overview-1",
"data": {"section_key": "overview", "section_title": "Overview", "sort_order": 1},
"page_break": True,
"sec_class": "sec-overview",
"rendered_html": Markup('<h2 class="h2">OVERVIEW</h2><p class="p">Welcome to the handbook.</p>'),
}]
html = template.render(
font_css=Markup(""),
base_url="file:///tmp",
extra_css="",
cover_image="",
toc_image="",
toc_items=[],
toc_items_sorted=[],
toc_title="Table of Contents",
toc_sort_order=None,
general_sections=sections,
summary_block=None,
universities=[],
bottom_pages=[],
debug=False,
stats={},
)
assert "sec-overview" in html
assert "OVERVIEW" in html
assert "Welcome to the handbook." in html
assert "page-break" in html
# ── PDF renderer module ──
def test_pdf_renderer_module_imports():
"""Test that the PDF renderer module can be imported."""
from app.services.pdf_renderer import render_pdf_from_html, shutdown_browser
assert callable(render_pdf_from_html)
assert callable(shutdown_browser)