"""Unit tests for the docker plugin's presentation layer (no DB). CI never renders these templates through the running app (the unit-lane app is created with testing=True, which skips plugin loading), so a Jinja syntax error would otherwise ship green. These tests parse every docker template and smoke the routes module so a broken tag or import is caught in the unit lane. """ import pathlib import jinja2 from plugins.docker import routes as r _TEMPLATES = pathlib.Path(r.__file__).parent / "templates" / "docker" def test_all_docker_templates_parse(): env = jinja2.Environment() files = sorted(_TEMPLATES.glob("*.html")) assert files, "no docker templates found" for f in files: # Raises TemplateSyntaxError on an unbalanced/typo'd tag. env.parse(f.read_text()) def test_routes_module_exposes_new_views(): # Import-smoke + confirms the #942 view functions are defined. for name in ("container_detail", "container_history", "swarm", "disk", "index", "rows"): assert callable(getattr(r, name)), name assert r.docker_bp.name == "docker" def test_disk_prune_view_defined(): # M78 admin-gated prune action. assert callable(r.disk_prune) def test_container_log_views_defined(): # M79 per-container log viewer + its HTMX-polled line fragment. assert callable(r.container_logs) assert callable(r.container_logs_lines) def test_uptime_is_the_shared_duration_or_none(): from datetime import datetime, timedelta, timezone now = datetime.now(timezone.utc) assert r._uptime(None) is None assert r._uptime(now + timedelta(minutes=5)) is None # clock skew: not "-5m" assert r._uptime(now - timedelta(days=3, hours=4, seconds=30)) == "3d 4h"