gendesign/backend/tests/services/test_ird_overlay_lookup.py
bot-backend 8df0f157a7
All checks were successful
CI / changes (push) Successful in 9s
CI / changes (pull_request) Successful in 7s
CI / backend-tests (pull_request) Successful in 5m52s
CI / backend-tests (push) Successful in 6m13s
feat(sf): parcel_ird_overlaps read-side для analyze (#1067 D9a)
ИРД-overlay lookup: ST_Intersects участка по ird_overlays (м.132) → ограничения
(ЗОУИТ/ПЗЗ-границы/ОКН/ООПТ) с reg_numb_border + zone_index/type (когда резолвлено).
Standalone-модуль (нулевой collision с parcels.py). Graceful degrade если таблица
ещё не задеплоена. Комплементарно quarter_dump_lookup (per-quarter blob).

Refs #1067 (D9a). Next D9b: flag-gated wiring в analyze-surface.
2026-06-06 21:52:54 +03:00

88 lines
2.7 KiB
Python

"""Тесты parcel_ird_overlaps (#1067 D9) — ИРД-overlay lookup для analyze."""
from __future__ import annotations
from typing import Any
from sqlalchemy.exc import OperationalError
from app.services.site_finder.ird_overlay_lookup import parcel_ird_overlaps
class _Result:
def __init__(self, rows: list[dict[str, Any]]) -> None:
self._rows = rows
def mappings(self) -> _Result:
return self
def all(self) -> list[dict[str, Any]]:
return self._rows
class _FakeDB:
def __init__(
self, rows: list[dict[str, Any]] | None = None, raise_exc: Exception | None = None
) -> None:
self._rows = rows or []
self._raise = raise_exc
def execute(self, sql: Any, params: dict[str, Any] | None = None) -> _Result:
if self._raise is not None:
raise self._raise
return _Result(self._rows)
_WKT = "POLYGON((60.5 56.8, 60.6 56.8, 60.6 56.9, 60.5 56.9, 60.5 56.8))"
def test_groups_overlaps_by_kind() -> None:
rows = [
{
"layer_kind": "zouit_okn",
"reg_numb_border": "66:41-6.41",
"category": 36940,
"subcategory": 20,
"zone_index": None,
"zone_type_name": None,
},
{
"layer_kind": "zouit_okn",
"reg_numb_border": "66:41-6.42",
"category": 36940,
"subcategory": 20,
"zone_index": None,
"zone_type_name": None,
},
{
"layer_kind": "territorial_zones",
"reg_numb_border": "66:41-7.10",
"category": 472819,
"subcategory": 1,
"zone_index": "Ц-1",
"zone_type_name": None,
},
]
res = parcel_ird_overlaps(_FakeDB(rows), _WKT)
assert len(res["ird_overlaps"]) == 3
assert res["ird_by_kind"] == {"zouit_okn": 2, "territorial_zones": 1}
tz = next(o for o in res["ird_overlaps"] if o["layer_kind"] == "territorial_zones")
assert tz["reg_numb_border"] == "66:41-7.10"
assert tz["zone_index"] == "Ц-1"
def test_empty_when_no_wkt() -> None:
res = parcel_ird_overlaps(_FakeDB([{"layer_kind": "x"}]), None)
assert res == {"ird_overlaps": [], "ird_by_kind": {}}
def test_empty_when_no_overlap() -> None:
res = parcel_ird_overlaps(_FakeDB([]), _WKT)
assert res == {"ird_overlaps": [], "ird_by_kind": {}}
def test_graceful_when_table_missing() -> None:
"""ird_overlays ещё не задеплоена → пусто, без падения analyze."""
db = _FakeDB(raise_exc=OperationalError("stmt", {}, Exception("no such table")))
res = parcel_ird_overlaps(db, _WKT)
assert res == {"ird_overlaps": [], "ird_by_kind": {}}