"""Tests for the v0.5.9 GAMMA itd_511 work_zone parser in central_normalizer. Covers the cutover path: itd_511 supplies all Idaho work_zone broadcasts now (state_511_atis ID is skipped). The parser must produce the same flat dict shape as _parse_state_511_atis so format_work_zone_mesh works unchanged. """ from datetime import datetime, timezone import pytest from meshai import central_normalizer as cn # ---------- envelope builder --------------------------------------------- def _itd_work_zone_env(*, roadway="SH-55", direction="North", event_sub_type="roadConstruction", is_full_closure=False, external_id="ITD:469:42", lat=44.103, lon=-116.110, geocoder_city="McCall", start_epoch=1780600000, planned_end_epoch=1781200000, description="Road construction on SH-55 Northbound from MM (140) to MM (145). 6/4/2026 7:00 AM to 6/11/2026 5:00 PM."): return { "id": external_id, "subject": "central.traffic.work_zone.us.id", "data": { "id": external_id, "adapter": "itd_511", "category": "work_zone.itd_511", "severity": 1, "geo": {"centroid": [lon, lat], "primary_region": "US-ID"}, "data": { "event_type_short": "work_zone", "event_sub_type": event_sub_type, "roadway_name": roadway, "direction": direction, "description": description, "lanes_affected": "All lanes affected", "is_full_closure": is_full_closure, "itd_severity": "None", "comment": "", "cause": "roadwork", "organization": "ERS", "recurrence_text": "", "recurrence_schedules": [], "restrictions": {}, "encoded_polyline": "", "id_internal": 42, "source_id": "999", "reported_epoch": start_epoch, "last_updated_epoch": start_epoch, "start_epoch": start_epoch, "planned_end_epoch": planned_end_epoch, "latitude": lat, "longitude": lon, "_enriched": {"geocoder": { "name": None, "city": geocoder_city, "county": "Valley", "state": "ID", "country": "United States", "landclass": None, "elevation_m": 1530.0, }}, }, }, } @pytest.fixture def no_photon(monkeypatch): monkeypatch.setattr(cn, "_photon_reverse_places", lambda lat, lon: []) if hasattr(cn, "_H3_NEAREST_CACHE"): cn._H3_NEAREST_CACHE.clear() # ---------- test (a): all fields populate ----------------------------------- def test_itd_511_work_zone_parses_with_all_fields(no_photon): env = _itd_work_zone_env() n = cn.normalize(env) assert n is not None assert n["source"] == "itd_511" assert n["road"] == "SH-55" # _norm_direction returns 'northbound' (matches state_511 convention) assert n["direction"] == "northbound" assert n["mile_start"] == 140 assert n["mile_end"] == 145 assert n["sub_type"] is not None # is_full_closure=False -> impact 'partial' matches state_511 convention assert n["impact"] == "partial" assert n["town"] == "McCall" # ends_at is a datetime assert isinstance(n["ends_at"], datetime) def test_itd_511_work_zone_full_closure_impact(no_photon): env = _itd_work_zone_env(is_full_closure=True) n = cn.normalize(env) assert n["impact"] == "full_closure" def test_itd_511_work_zone_renderer_produces_wire(no_photon): from meshai.notifications.renderers.work_zone import format_work_zone_mesh env = _itd_work_zone_env() n = cn.normalize(env) wire = format_work_zone_mesh(n) assert wire is not None # Format matches state_511 convention: 🚧 emoji + road assert "🚧" in wire assert "SH-55" in wire assert "McCall" in wire def test_itd_511_work_zone_end_date_formatting(no_photon): """planned_end_epoch should serialize to a datetime that the renderer can format consistently with state_511.""" env = _itd_work_zone_env(planned_end_epoch=1781200000) n = cn.normalize(env) assert isinstance(n["ends_at"], datetime) assert n["ends_at"].tzinfo is not None # UTC-aware def test_itd_511_work_zone_no_end_date(no_photon): """planned_end_epoch == None or 0 -> ends_at is None.""" env = _itd_work_zone_env(planned_end_epoch=None) n = cn.normalize(env) assert n["ends_at"] is None def test_itd_511_incident_does_not_go_through_work_zone_parser(no_photon): """The work_zone parser should NOT be invoked for category=incident.itd_511 -- those still route through the incident_handler. normalize() returns None (defer) for non-work_zone itd_511 categories.""" env = _itd_work_zone_env() env["data"]["category"] = "incident.itd_511" n = cn.normalize(env) # Either None (defer) or not a work_zone dict (no road/direction/etc). if n is not None: assert "_kind" in n # marker, not a parsed work_zone dict