"""HUD load-time: no market 404 poll, deferred overlays, WS backoff, nginx snippet.""" from __future__ import annotations from pathlib import Path ROOT = Path(__file__).resolve().parent.parent HTML = (ROOT / "app/static/index.html").read_text() def test_summarizer_dockerfile_copies_intel_modules(): df = (ROOT / "news/summerizer/Dockerfile").read_text() assert "intel.py" in df assert "nous_client.py" in df def test_news_panel_pins_daily_recap(): assert "kind=daily_recap" in HTML assert "DAILY RECAP" in HTML def test_nginx_ws_snippet_has_upgrade_headers(): conf = (ROOT / "deploy/osint-ws.nginx.conf").read_text() assert "proxy_http_version 1.1" in conf assert "Upgrade" in conf assert "Connection" in conf assert "/ws/" in conf def test_market_ticker_does_not_poll_unwired_endpoint(): assert "setInterval(probeMarket" not in HTML assert "initMarketTicker()" not in HTML or "probeMarket();" not in HTML.split("function initMarketTicker")[1][:400] def test_startup_defers_nonessential_overlays(): init = HTML.split("function initMap")[1].split("function readMapPrefs")[0] # Must not fire all four DB loads + live overlays in the same tick. assert "setTimeout" in init or "requestAnimationFrame" in init def test_ws_reconnect_uses_backoff(): assert "setTimeout(connectLiveWs, 4000)" not in HTML ws = HTML.split("function connectLiveWs")[1][:1200] assert "backoff" in ws.lower() or "wsRetry" in ws or "wsDelay" in ws def test_check_health_treats_degraded_status(): fn = HTML.split("async function checkHealth")[1].split("/* ═══════════════ NAV")[0] assert "degraded" in fn.lower() or "d.status" in fn def test_chokepoint_presets_in_toolbar(): assert 'id="chokepoint-btns"' in HTML assert 'id="chokepoint-select"' in HTML assert "loadChokepoints()" in HTML assert "/api/map/chokepoints" in HTML assert "function applyChokepoint" in HTML for name in ("Hormuz", "Bab el-Mandeb", "Suez", "Malacca", "Taiwan"): assert name in HTML def test_chokepoint_skips_aisstream_subscribe_outside_conus(): load = HTML.split("async function loadVessels")[1].split("async function toggleStorms")[0] assert "intersectsConus()" in load assert "api/vessels/subscribe" in load assert "src=${encodeURIComponent(vesselSrcPref)}" in load or "&src=" in load apply = HTML.split("function applyChokepoint")[1].split("function currentBBox")[0] assert "vesselapi" in apply assert "lp-vessels-on" in apply assert "lp-sentinel-on" in apply assert "map.setView" in apply assert "minlat,minlon,maxlat,maxlon" in HTML.split("function chokepointLeafletBounds")[1][:400] def test_news_ticker_polls_more_often_than_summarizer_cycle(): assert "NEWS_REFRESH_MS" in HTML # Summarizer is 15 min; ticker should refresh on a shorter cadence so # lesser-news fills show up without waiting for the next brief. line = [ln for ln in HTML.splitlines() if "NEWS_REFRESH_MS" in ln][0] assert "900000" not in line def test_phone_chokepoints_use_select_not_buttons(): mobile = HTML.split("@media (max-width: 820px)")[1].split("@media (prefers-reduced-motion")[0] assert "#chokepoint-select { display: block; }" in mobile assert ".chokepoint-btns { display: none; }" in mobile or "#chokepoint-label, .chokepoint-btns { display: none; }" in mobile