gendesign/backend/tests/test_noise_loader.py
Light1YT 50555821fb
Some checks failed
CI / changes (push) Successful in 7s
CI / frontend-tests (push) Has been skipped
CI / changes (pull_request) Successful in 7s
CI / frontend-tests (pull_request) Has been skipped
CI / backend-tests (push) Successful in 7m42s
CI / backend-tests (pull_request) Successful in 7m40s
Deploy / changes (push) Has been cancelled
Deploy / build-backend (push) Has been cancelled
Deploy / build-worker (push) Has been cancelled
Deploy / build-frontend (push) Has been cancelled
Deploy / deploy (push) Has been cancelled
feat(site_finder): routing POI decay (#41) + OSM utility distances (#44) + ЗОУИТ geom (#255bk)
#41: per-category routing-radius decay через reusable ORS /matrix client (foot-walk
время + per-category пороги + decay-curves), opt-in ?decay=routing, graceful straight-line
fallback (analyze не 500 при ORS down) + length-guard durations==destinations.
#44: +5 OSM-категорий (transformer/gas/water/sewerage/heat) via Overpass nwr;
nearest_{water_main,substation,gas,heat}_m в analyze.utilities.
#255bk: ST_AsGeoJSON(CAST(geom AS geometry)) в _get_cad_zouit_overlaps → geom_geojson.

Closes #41
Closes #44
2026-06-13 22:31:56 +05:00

100 lines
4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Unit tests для noise_loader — OSM-источники шума + инж.сети (#44).
Mock-based / pure — без Overpass и БД. Покрывает:
- расширенный набор инж.-сетевых категорий (#44: gas/water/sewerage/transformer/
heat_substation)
- _build_overpass_query: node / way / nwr варианты
- el_type dispatch для point-like utility (nwr) vs линейных (way)
"""
from __future__ import annotations
from app.services.site_finder.noise_loader import (
_NOISE_QUERIES,
_UTILITY_POINT_VALUES,
_build_overpass_query,
_way_to_linestring_wkt,
)
# ── расширенные инж.-сетевые категории (#44) ─────────────────────────────────
def _road_classes() -> set[str | None]:
return {road_class for _k, _v, src, road_class in _NOISE_QUERIES if src == "utility"}
def test_new_utility_categories_present() -> None:
"""#44: добавлены недостающие инж.сети — газ/вода/канализация/трансформатор/ЦТП."""
classes = _road_classes()
for expected in (
"gas_pipeline",
"water_main",
"sewerage",
"transformer",
"heat_substation",
):
assert expected in classes, f"road_class {expected!r} должен быть в _NOISE_QUERIES"
def test_existing_utility_categories_retained() -> None:
"""Старые категории не потеряны при расширении (regression guard)."""
classes = _road_classes()
for kept in ("power_line", "pipeline", "water_works", "wastewater_plant", "substation"):
assert kept in classes
def test_pipeline_queries_use_pipeline_key() -> None:
"""pipeline=gas/water/sewerage маппится на OSM tag `pipeline`, не man_made."""
pipeline_entries = [(k, v) for k, v, src, _rc in _NOISE_QUERIES if k == "pipeline"]
values = {v for _k, v in pipeline_entries}
assert values == {"gas", "water", "sewerage"}
def test_utility_point_values_cover_new_nodes() -> None:
"""Точечные/площадные инж.объекты помечены для nwr-запроса."""
for v in ("substation", "transformer", "heat_substation", "water_works"):
assert v in _UTILITY_POINT_VALUES
# ── _build_overpass_query ─────────────────────────────────────────────────────
def test_build_query_node() -> None:
q = _build_overpass_query("aeroway", "aerodrome", "node")
assert q.startswith("[out:json][timeout:30];")
assert 'node["aeroway"="aerodrome"]' in q
assert "out body;" in q
def test_build_query_way_uses_out_geom() -> None:
"""way → out geom (нужны координаты узлов для LineString)."""
q = _build_overpass_query("highway", "motorway", "way")
assert 'way["highway"="motorway"]' in q
assert "out geom;" in q
def test_build_query_nwr_for_utility_points() -> None:
"""nwr ловит и node, и way (точка/площадка), с out geom."""
q = _build_overpass_query("power", "transformer", "nwr")
assert 'nwr["power"="transformer"]' in q
assert "out geom;" in q
def test_build_query_bbox_present() -> None:
"""Bbox ЕКБ присутствует во всех вариантах запроса."""
q = _build_overpass_query("power", "substation", "nwr")
# south,west,north,east из EKB_BBOX
assert "(56.7,60.5,56.95,60.75)" in q
# ── _way_to_linestring_wkt (используется для way-результатов nwr) ────────────
def test_way_to_linestring_valid() -> None:
nodes = [{"lat": 56.8, "lon": 60.6}, {"lat": 56.81, "lon": 60.61}]
wkt = _way_to_linestring_wkt(nodes)
assert wkt == "LINESTRING(60.6 56.8, 60.61 56.81)"
def test_way_to_linestring_too_few_points() -> None:
assert _way_to_linestring_wkt([{"lat": 56.8, "lon": 60.6}]) is None