Files
RadioPropagationApi/api/tests/test_buildings.py
T
2026-06-23 09:53:39 +03:00

90 lines
2.8 KiB
Python

import json
import pytest
from app.core.geo import PathPoint
from app.models.buildings import BuildingsQueryRequest
from app.models.terrain import TerrainProfileRequest
from app.services import buildings as buildings_service
from app.services import terrain as terrain_service
class FakeResult:
def __init__(self, rows: list[dict[str, object]]) -> None:
self._rows = rows
def mappings(self) -> "FakeResult":
return self
def all(self) -> list[dict[str, object]]:
return self._rows
class FakeSession:
def __init__(self, rows: list[dict[str, object]]) -> None:
self.rows = rows
self.calls: list[dict[str, object]] = []
def execute(self, statement: object, params: dict[str, object]) -> FakeResult:
self.calls.append({"statement": str(statement), "params": params})
return FakeResult(self.rows)
def test_buildings_query_bbox_returns_feature_collection() -> None:
feature = {
"type": "Feature",
"id": 123,
"geometry": {"type": "Polygon", "coordinates": []},
"properties": {
"height_m": 12.0,
"levels": 4,
"building_type": "apartments",
"source": "estimated",
},
}
db = FakeSession(rows=[{"feature": json.dumps(feature)}])
request = BuildingsQueryRequest(bbox=(30.0, 59.0, 31.0, 60.0))
response = buildings_service.query_buildings(request, db, limit=10)
assert response.type == "FeatureCollection"
assert response.features == [feature]
assert db.calls[0]["params"]["limit"] == 10
def test_building_heights_along_returns_height_per_point() -> None:
db = FakeSession(rows=[{"i": 0, "height_m": 15.0}, {"i": 1, "height_m": 0.0}])
points = [
PathPoint(lat=59.0, lon=30.0, distance_m=0),
PathPoint(lat=59.1, lon=30.1, distance_m=1),
]
heights = buildings_service.building_heights_along(points, db)
assert heights == [15.0, 0.0]
assert "jsonb_to_recordset" in db.calls[0]["statement"]
def test_buildings_query_rejects_invalid_bbox() -> None:
with pytest.raises(ValueError, match="bbox"):
BuildingsQueryRequest(bbox=(31.0, 59.0, 30.0, 60.0))
def test_terrain_profile_applies_building_heights(monkeypatch: pytest.MonkeyPatch) -> None:
def fake_heights(points: list[PathPoint], db: object) -> list[float]:
return [12.0] + [0.0] * (len(points) - 1)
monkeypatch.setattr(buildings_service, "building_heights_along", fake_heights)
request = TerrainProfileRequest(
start={"lat": 59.0, "lon": 30.0},
end={"lat": 59.1, "lon": 30.1},
samples=2,
include_buildings=True,
include_canopy=False,
)
response = terrain_service.terrain_profile(request, db=object())
assert response.samples[0].building_m == 12.0
assert response.samples[0].surface_m == response.samples[0].ground_m + 12.0