Files
TJWaterServerBinary/tests/unit/test_sensor_placement_service.py
T

189 lines
5.6 KiB
Python

from datetime import datetime, timezone
from unittest.mock import MagicMock
import pytest
from openpyxl import load_workbook
from app.native.wndb import s42_sensor_placement
from app.services import sensor_placement
def _mock_project_cursor(monkeypatch):
cursor = MagicMock()
connection = MagicMock()
connection.cursor.return_value.__enter__.return_value = cursor
connection_context = MagicMock()
connection_context.__enter__.return_value = connection
monkeypatch.setattr(
s42_sensor_placement,
"project_connection",
lambda _network: connection_context,
)
return cursor
def test_build_workbook_contains_engineering_columns(monkeypatch):
monkeypatch.setattr(
sensor_placement,
"_sensor_points",
lambda network, locations: [
{
"node_id": "J1",
"project_x": 13500000.0,
"project_y": 3600000.0,
"map_x": 13500000.0,
"map_y": 3600000.0,
"longitude": 121.0,
"latitude": 31.0,
"elevation": 4.5,
}
],
)
scheme = {
"id": 7,
"scheme_name": "北区测压点",
"sensor_number": 2,
"min_diameter": 300,
"username": "alice",
"create_time": datetime(2026, 7, 30, tzinfo=timezone.utc),
"sensor_location": ["J1", "J2"],
}
output = sensor_placement.build_sensor_placement_workbook(
network="tjwater",
scheme=scheme,
sensor_location=["J1"],
adjustment_status={"J1": "replaced"},
)
workbook = load_workbook(output)
assert workbook.sheetnames == ["方案信息", "监测点清单"]
headers = [cell.value for cell in workbook["监测点清单"][1]]
assert headers == [
"序号",
"节点 ID",
"经度",
"纬度",
"工程 X",
"工程 Y",
"地图 X",
"地图 Y",
"高程",
"调整状态",
]
assert workbook["监测点清单"]["J2"].value == "替换"
assert workbook["方案信息"]["B8"].value == "未保存草稿"
def test_sensor_points_keep_engineering_coordinates_and_transform_map_coordinates(
monkeypatch,
):
monkeypatch.setattr(
sensor_placement.wndb,
"get_sensor_placement_nodes",
lambda network, node_ids: [
{
"node_id": "J1",
"project_x": 3038.94,
"project_y": -34446.59,
"map_x": 13525191.530279,
"map_y": 3622984.760237,
"elevation": 4.5,
}
],
)
point = sensor_placement._sensor_points("tjwater", ["J1"])[0]
assert point["project_x"] == 3038.94
assert point["project_y"] == -34446.59
assert point["longitude"] == pytest.approx(121.498863, abs=1e-6)
assert point["latitude"] == pytest.approx(30.924784, abs=1e-6)
def test_update_validates_nodes_before_write(monkeypatch):
monkeypatch.setattr(
sensor_placement.wndb,
"get_sensor_placement_nodes",
lambda network, node_ids: [],
)
try:
sensor_placement.update_sensor_placement_scheme(
"tjwater",
7,
expected_sensor_location=["J1"],
sensor_location=["missing"],
)
except sensor_placement.SensorPlacementValidationError as exc:
assert "missing" in str(exc)
else:
raise AssertionError("expected invalid node to be rejected")
def test_sensor_nodes_use_materialized_web_mercator_geometry(monkeypatch):
cursor = _mock_project_cursor(monkeypatch)
cursor.fetchall.return_value = []
s42_sensor_placement.get_sensor_placement_nodes("tjwater", ["J1"])
query = cursor.execute.call_args.args[0]
assert "geo_junctions_mat" in query
assert "ST_X(c.coord)" in query
assert "ST_Y(c.coord)" in query
assert "ST_X(gj.geom)" in query
assert "ST_Y(gj.geom)" in query
def test_workbook_escapes_formula_in_scheme_metadata(monkeypatch):
monkeypatch.setattr(
sensor_placement,
"_sensor_points",
lambda network, locations: [
{
"node_id": "J1",
"project_x": 3038.94,
"project_y": -34446.59,
"map_x": 13525191.53,
"map_y": 3622984.76,
"longitude": 121.49,
"latitude": 30.92,
"elevation": 4.5,
}
],
)
output = sensor_placement.build_sensor_placement_workbook(
network="tjwater",
scheme={
"scheme_name": "=1+1",
"sensor_location": ["J1"],
"min_diameter": 300,
"username": "alice",
"create_time": datetime(2026, 7, 30, tzinfo=timezone.utc),
},
sensor_location=["J1"],
adjustment_status={},
)
workbook = load_workbook(output, data_only=False)
assert workbook["方案信息"]["B2"].value == "'=1+1"
assert workbook["方案信息"]["B2"].data_type == "s"
def test_create_sensor_placement_returns_inserted_record(monkeypatch):
cursor = _mock_project_cursor(monkeypatch)
cursor.fetchone.return_value = {"id": 7, "sensor_location": ["J1", "J2"]}
created = s42_sensor_placement.create_sensor_placement(
"tjwater",
scheme_name="北区测压点",
min_diameter=300,
username="alice",
sensor_location=["J1", "J2"],
)
assert created["id"] == 7
query, parameters = cursor.execute.call_args.args
assert "INSERT INTO sensor_placement" in query
assert parameters == ("北区测压点", 2, 300, "alice", ["J1", "J2"])