141 lines
4.0 KiB
Python
141 lines
4.0 KiB
Python
import asyncio
|
|
from datetime import datetime, timezone
|
|
from unittest.mock import AsyncMock
|
|
from uuid import uuid4
|
|
|
|
from app.api.v1.endpoints import scada as scada_endpoint
|
|
from app.services import timeseries_analysis as composite_queries
|
|
|
|
|
|
PROJECT_SCADA = {
|
|
"device_id": "fengyang-pressure-1",
|
|
"device_type": "pressure",
|
|
"node_id": "J1",
|
|
"link_id": None,
|
|
"api_query_id": "query-1",
|
|
"transmission_mode": "realtime",
|
|
"transmission_frequency": None,
|
|
"reliability": 1.0,
|
|
"x": 117.1,
|
|
"y": 32.9,
|
|
"longitude": 121.5,
|
|
"latitude": 30.9,
|
|
}
|
|
START_TIME = datetime(2026, 6, 1, tzinfo=timezone.utc)
|
|
END_TIME = datetime(2026, 6, 2, tzinfo=timezone.utc)
|
|
|
|
|
|
def _patch_project_scadas(monkeypatch):
|
|
monkeypatch.setattr(
|
|
composite_queries.ScadaInfoRepository,
|
|
"get_scadas",
|
|
AsyncMock(return_value=[PROJECT_SCADA.copy()]),
|
|
)
|
|
|
|
|
|
def test_realtime_scada_simulation_uses_current_project_metadata(monkeypatch):
|
|
_patch_project_scadas(monkeypatch)
|
|
query_mock = AsyncMock(
|
|
return_value={"J1": [{"time": START_TIME, "value": 26.5}]}
|
|
)
|
|
monkeypatch.setattr(
|
|
composite_queries.RealtimeRepository,
|
|
"get_node_fields_by_ids_time_range",
|
|
query_mock,
|
|
)
|
|
monkeypatch.setattr(
|
|
composite_queries.RealtimeRepository,
|
|
"get_link_fields_by_ids_time_range",
|
|
AsyncMock(return_value={}),
|
|
)
|
|
|
|
result = asyncio.run(
|
|
composite_queries.TimeseriesAnalysisService.get_scada_associated_realtime_simulation_data(
|
|
object(),
|
|
object(),
|
|
[PROJECT_SCADA["device_id"]],
|
|
START_TIME,
|
|
END_TIME,
|
|
)
|
|
)
|
|
|
|
assert result[PROJECT_SCADA["device_id"]][0]["scada_id"] == PROJECT_SCADA["device_id"]
|
|
assert query_mock.await_count == 1
|
|
assert query_mock.await_args.args[1:] == (
|
|
START_TIME,
|
|
END_TIME,
|
|
["J1"],
|
|
"pressure",
|
|
)
|
|
|
|
|
|
def test_analysis_scada_simulation_uses_current_project_metadata(monkeypatch):
|
|
_patch_project_scadas(monkeypatch)
|
|
async def query_series(_conn, _run_id, element_type, element_ids, *_args):
|
|
if element_type == "node":
|
|
return {"J1": [{"time": START_TIME, "value": 26.5}]}
|
|
return {}
|
|
|
|
query_mock = AsyncMock(side_effect=query_series)
|
|
monkeypatch.setattr(
|
|
composite_queries.AnalysisResultsRepository,
|
|
"get_series_by_ids",
|
|
query_mock,
|
|
)
|
|
|
|
result = asyncio.run(
|
|
composite_queries.TimeseriesAnalysisService.get_scada_associated_analysis_simulation_data(
|
|
object(),
|
|
object(),
|
|
[PROJECT_SCADA["device_id"]],
|
|
START_TIME,
|
|
END_TIME,
|
|
uuid4(),
|
|
)
|
|
)
|
|
|
|
assert result[PROJECT_SCADA["device_id"]][0]["scada_id"] == PROJECT_SCADA["device_id"]
|
|
assert query_mock.await_count == 2
|
|
node_call = next(
|
|
call for call in query_mock.await_args_list if call.args[2] == "node"
|
|
)
|
|
assert node_call.args[3:] == (["J1"], START_TIME, END_TIME, "pressure")
|
|
|
|
|
|
def test_element_scada_query_uses_current_project_metadata(monkeypatch):
|
|
_patch_project_scadas(monkeypatch)
|
|
query_mock = AsyncMock(
|
|
return_value={
|
|
PROJECT_SCADA["device_id"]: [{"time": START_TIME, "value": 26.5}]
|
|
}
|
|
)
|
|
monkeypatch.setattr(
|
|
composite_queries.ScadaRepository,
|
|
"get_scada_field_by_id_time_range",
|
|
query_mock,
|
|
)
|
|
|
|
result = asyncio.run(
|
|
composite_queries.TimeseriesAnalysisService.get_element_associated_scada_data(
|
|
object(),
|
|
object(),
|
|
"J1",
|
|
START_TIME,
|
|
END_TIME,
|
|
)
|
|
)
|
|
|
|
assert result == {"J1": [{"time": START_TIME, "value": 26.5}]}
|
|
|
|
|
|
def test_scada_info_endpoint_uses_current_project_connection(monkeypatch):
|
|
monkeypatch.setattr(
|
|
scada_endpoint.ScadaInfoRepository,
|
|
"get_scadas",
|
|
AsyncMock(return_value=[PROJECT_SCADA.copy()]),
|
|
)
|
|
|
|
result = asyncio.run(scada_endpoint.get_scada_devices(object()))
|
|
|
|
assert result == [PROJECT_SCADA]
|