"""Тесты reservation_lookup (#1091, #1062) — read-side lookup из land_reservation.""" from __future__ import annotations from datetime import date from typing import Any from sqlalchemy.exc import OperationalError, ProgrammingError from app.services.site_finder.reservation_lookup import parcel_reservations # ── Моки БД (аналог test_ird_overlay_lookup.py) ─────────────────────────────── 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) # ── Фикстура строк ──────────────────────────────────────────────────────────── _ROWS = [ { "reservation_kind": "изъятие", "basis_act": "Постановление Правительства СО № 509-ПП", "act_number": "509-ПП", "act_date": date(2024, 3, 12), "purpose": "реконструкция улицы Татищева", "doc_url": "https://pravo.gov66.ru/documents/view/509-pp", }, { "reservation_kind": "резервирование", "basis_act": "Постановление Правительства СО № 210-ПП", "act_number": "210-ПП", "act_date": date(2024, 6, 5), "purpose": "строительство дороги", "doc_url": "https://pravo.gov66.ru/documents/view/210-pp", }, ] # ── Тесты ──────────────────────────────────────────────────────────────────── def test_maps_rows_correctly() -> None: """Строки из БД корректно маппируются в список словарей.""" result = parcel_reservations(_FakeDB(_ROWS), "66:41:0101001:123") assert len(result) == 2 assert result[0]["reservation_kind"] == "изъятие" assert result[0]["act_number"] == "509-ПП" assert result[0]["act_date"] == date(2024, 3, 12) assert result[1]["reservation_kind"] == "резервирование" def test_expected_keys_present() -> None: """Каждый элемент содержит все ожидаемые ключи.""" result = parcel_reservations(_FakeDB(_ROWS), "66:41:0101001:123") expected_keys = { "reservation_kind", "basis_act", "act_number", "act_date", "purpose", "doc_url", } for item in result: assert set(item.keys()) == expected_keys def test_empty_when_no_rows() -> None: """Нет записей в БД → пустой список.""" result = parcel_reservations(_FakeDB([]), "66:41:0101001:999") assert result == [] def test_empty_when_cad_num_none() -> None: """cad_num=None → пустой список, БД не вызывается.""" result = parcel_reservations(_FakeDB(_ROWS), None) assert result == [] def test_empty_when_cad_num_empty_string() -> None: """cad_num='' → пустой список (falsy guard).""" result = parcel_reservations(_FakeDB(_ROWS), "") assert result == [] def test_graceful_on_operational_error() -> None: """OperationalError (таблица не задеплоена) → [] без падения.""" db = _FakeDB(raise_exc=OperationalError("stmt", {}, Exception("no such table"))) result = parcel_reservations(db, "66:41:0101001:123") assert result == [] def test_graceful_on_programming_error() -> None: """ProgrammingError → [] без падения.""" db = _FakeDB(raise_exc=ProgrammingError("stmt", {}, Exception("column not found"))) result = parcel_reservations(db, "66:41:0101001:123") assert result == []