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", "measurement_unit": "m", "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]