"""Tests for network-obremenenie классификатор (#1070) — pure function, no DB. type_zone-строки взяты из реальных distinct-значений cad_zouit (PROD, 2026-06-14). """ from app.services.site_finder.gate_verdict import compute_gate_verdict from app.services.site_finder.network_obremenenie import ( classify_network_zone, is_network_obremenenie, network_kind_label, ) # ── classify_network_zone: реальные type_zone из cad_zouit ──────────────────── def test_thermal_zone(): assert classify_network_zone("Охранная зона тепловых сетей") == "thermal" def test_electricity_zone(): tz = ( "Охранная зона объектов электроэнергетики (объектов электросетевого хозяйства " "и объектов по производству электрической энергии)" ) assert classify_network_zone(tz) == "electricity" def test_pipeline_zone_gas_first(): # «трубопроводов (газопроводов, нефтепроводов …)» — газ ловится раньше pipeline. tz = ( "Охранная зона трубопроводов (газопроводов, нефтепроводов " "и нефтепродуктопроводов, аммиакопроводов)" ) assert classify_network_zone(tz) == "gas" def test_communication_zone(): assert classify_network_zone("Охранная зона линий и сооружений связи") == "communication" def test_general_engineering_zone(): assert classify_network_zone("Охранная зона инженерных коммуникаций") == "general" # ── негативные: НЕ сетевые ЗОУИТ ────────────────────────────────────────────── def test_servitude_not_network(): assert classify_network_zone("Зона публичного сервитута") is None def test_szz_not_network(): assert classify_network_zone("Санитарно-защитная зона") is None def test_natural_zouit_not_network(): assert classify_network_zone("Зоны с особыми условиями использования территории") is None def test_none_and_empty(): assert classify_network_zone(None) is None assert classify_network_zone("") is None def test_general_keyword_without_protection_marker_is_skipped(): # «инженерные коммуникации» без «охранная зона» → не ловим (избегаем ложных). assert classify_network_zone("Размещение инженерных коммуникаций") is None # ── helpers ─────────────────────────────────────────────────────────────────── def test_is_network_obremenenie(): assert is_network_obremenenie("Охранная зона тепловых сетей") is True assert is_network_obremenenie("Зона публичного сервитута") is False def test_network_kind_label(): assert network_kind_label("thermal") == "теплоснабжение" assert network_kind_label("general") == "инженерные коммуникации" assert network_kind_label(None) is None # ── gate_verdict: сетевое обременение → выделенный blocker ───────────────────── def _dump_available() -> dict: return {"available": True, "stale": False} def test_gate_verdict_thermal_network_blocker(): """Теплосеть (#1070 ООО Брик) покрывающая участок → ZOUIT_NETWORK_OBREMENENIE blocker. Area-gated: при полном покрытии (coverage > порога) сетевое обременение блокирует. """ overlaps = [ { "source": "cad_zouit", "type_zone": "Охранная зона тепловых сетей", "name": "ТС-123", "is_network_zone": True, "network_kind": "thermal", "network_kind_label": "теплоснабжение", "coverage_pct": 0.8, } ] verdict = compute_gate_verdict(None, overlaps, None, _dump_available()) codes = [b["code"] for b in verdict["blockers"]] assert "ZOUIT_NETWORK_OBREMENENIE" in codes assert verdict["can_build_mkd"] is False detail = next( b["detail"] for b in verdict["blockers"] if b["code"] == "ZOUIT_NETWORK_OBREMENENIE" ) assert "теплоснабжение" in detail def test_gate_verdict_servitude_not_network_blocker(): """Сервитут (не сеть) → НЕ ZOUIT_NETWORK_OBREMENENIE.""" overlaps = [ { "source": "cad_zouit", "type_zone": "Зона публичного сервитута", "name": "", "is_network_zone": False, "network_kind": None, "network_kind_label": None, } ] verdict = compute_gate_verdict(None, overlaps, None, _dump_available()) codes = [b["code"] for b in verdict["blockers"]] assert "ZOUIT_NETWORK_OBREMENENIE" not in codes def test_gate_verdict_network_classified_when_flag_absent(): """Back-compat: overlap без флага → gate_verdict классифицирует сам (area-gated blocker).""" overlaps = [ { "source": "cad_zouit", "type_zone": "Охранная зона объектов электроэнергетики", "name": "ВЛ-10кВ", "coverage_pct": 0.75, } ] verdict = compute_gate_verdict(None, overlaps, None, _dump_available()) codes = [b["code"] for b in verdict["blockers"]] assert "ZOUIT_NETWORK_OBREMENENIE" in codes