"""HUD: layer-rail stats, shortcuts, terminator, zoom-gated cams, SWPC chip.""" from __future__ import annotations from pathlib import Path ROOT = Path(__file__).resolve().parent.parent HTML = (ROOT / "app/static/index.html").read_text() def _fn(name: str, nxt: str | None = None) -> str: start = HTML.index(f"function {name}") if nxt: return HTML[start : HTML.index(f"function {nxt}", start + 1)] return HTML[start : start + 4000] def test_stats_poll_uses_api_then_falls_back(): assert "/api/stats" in HTML assert "30000" in HTML.split("pollLayerStats")[1][:2500] or "STATS_POLL_MS" in HTML poll = HTML.split("async function pollLayerStats")[1].split("async function ")[0] assert "404" in poll assert "catch" in poll ids = HTML.split("STATS_COUNT_IDS")[1].split("};")[0] assert "aircraft" in ids and "cameras" in ids and "fires" in ids and "vessels" in ids # Overlay loaders still write array lengths when stats is down. assert "setLayerCount('lp-fires-count'" in HTML or 'setLayerCount("lp-fires-count"' in HTML assert "setLayerCount('lp-cams-count'" in HTML or 'setLayerCount("lp-cams-count"' in HTML assert "setLayerCount('lp-ac-count'" in HTML or 'setLayerCount("lp-ac-count"' in HTML assert "setLayerCount('lp-vessels-count'" in HTML or 'setLayerCount("lp-vessels-count"' in HTML def test_keyboard_shortcuts_do_not_steal_osiris_fs(): keys = HTML.split("function initHudKeys")[1].split("function ")[0] assert "Escape" in keys assert "cheat-sheet" in keys or "toggleCheatSheet" in keys assert "mapResetView" in keys assert "toggleLayerPanel" in keys or "closeLayerPanel" in keys # Do not bind Osiris's conflicting F/S (flights vs fullscreen / search). assert "e.key === 'f'" not in keys.lower() assert "e.key === 's'" not in keys.lower() assert "case 'f'" not in keys.lower() assert "case 's'" not in keys.lower() assert 'id="cheat-sheet"' in HTML assert "?" in keys or "Shift" in keys def test_terminator_toggle_defaults_off(): assert 'id="lp-terminator-on"' in HTML row = HTML.split('id="lp-terminator-on"')[0][-120:] + HTML.split('id="lp-terminator-on"')[1][:80] assert "checked" not in row.split(">")[0] assert "function toggleTerminator" in HTML assert "subsolarPoint" in HTML or "terminator" in HTML.lower() def test_camera_thumbs_gated_at_zoom_12(): assert "CAM_THUMB_MIN_ZOOM" in HTML assert "CAM_THUMB_MIN_ZOOM = 12" in HTML thumb = _fn("camThumb", "camPopupHtml") assert "camThumbsAllowed" in thumb or "CAM_THUMB_MIN_ZOOM" in thumb assert "zoom in for preview" in HTML or "zoom for preview" in HTML assert "preview unavailable" in HTML # RTSP still proxy through snapshot; never emit rtsp hrefs. src = _fn("camSourceLink", "youtubeId") assert "rtsp://" in src assert "href=" not in src.split("rtsp://")[1].split("return")[0] or "Never emit" in src assert 'href="${esc(url)}"' in src or "href=\"${esc(url)}\"" in src assert src.index("rtsp://") < src.index("href=") def test_swpc_chip_browser_direct_correct_urls(): assert 'id="swpc-chip"' in HTML assert "services.swpc.noaa.gov/json/planetary_k_index_1m.json" in HTML assert "services.swpc.noaa.gov/json/goes/primary/xray-flares-latest.json" in HTML assert "services.swpc.noaa.gov/products/alerts.json" in HTML assert "services.swpc.noaa.gov/json/alerts.json" not in HTML sw = HTML.split("async function pollSwpc")[1].split("async function ")[0] assert "hidden" in sw assert "kp_index" in sw assert "90000" in HTML or "SWPC_POLL_MS" in HTML def test_new_chrome_does_not_cover_mobile_layers_zoom(): mobile = HTML.split("@media (max-width: 820px)")[1].split("@media (prefers-reduced-motion")[0] assert "#layer-panel" in mobile assert ".leaflet-top.leaflet-right .leaflet-control-zoom" in mobile assert 'id="cheat-sheet"' in HTML cheat = HTML.split(".cheat-sheet")[1][:500] assert "z-index" in cheat assert "calc(100% - 96px)" in cheat or "96px" in cheat