fix(scada): align location capability and investigation guidance
This commit is contained in:
@@ -10,7 +10,7 @@ from fastapi import HTTPException
|
||||
|
||||
from app.mcp.analysis_models import BurstLocationInput
|
||||
from app.mcp.catalog import TOOLS
|
||||
from app.mcp.models import BoundContext
|
||||
from app.mcp.models import BoundContext, ScadaInput
|
||||
from app.mcp import query_service
|
||||
from app.services.scada_replay_queries import replay_burst_location_inputs, replay_snapshot_rows
|
||||
|
||||
@@ -18,6 +18,30 @@ from app.services.scada_replay_queries import replay_burst_location_inputs, repl
|
||||
START = datetime(2026, 10, 8, tzinfo=timezone.utc)
|
||||
|
||||
|
||||
def test_replay_origin_is_preserved_without_a_provenance_only_data_gap(monkeypatch):
|
||||
from app.services import scada_replay_queries
|
||||
|
||||
monkeypatch.setattr(query_service, "authorize_query", AsyncMock())
|
||||
reading = {"time": START.isoformat(), "device_id": "P1", "cleaned_value": 20.0,
|
||||
"monitored_value": 20.0, "quality": "valid"}
|
||||
read = AsyncMock(return_value=[reading])
|
||||
monkeypatch.setattr(scada_replay_queries, "replay_snapshot_rows", read)
|
||||
project_id = uuid4()
|
||||
context = {"replay_id": str(uuid4()), "knowledge_cutoff": (START + timedelta(minutes=15)).isoformat(),
|
||||
"batch_sequence": 9}
|
||||
connection = object()
|
||||
scope = SimpleNamespace(connection=connection, project=SimpleNamespace(project_id=project_id))
|
||||
binding = SimpleNamespace(replay_context=context)
|
||||
args = ScadaInput(context_handle="a" * 43, device_ids=["P1"], start=START,
|
||||
end=START + timedelta(minutes=15))
|
||||
result = asyncio.run(query_service.execute_query(scope, binding, TOOLS["query_scada_readings"], args))
|
||||
assert result.origin == "synthetic"
|
||||
assert result.data[0]["device_id"] == "P1"
|
||||
assert result.data_gaps == []
|
||||
read.assert_awaited_once_with(connection, project_id, context, ["P1"], args.start, args.end,
|
||||
args.limit + 1, args.offset)
|
||||
|
||||
|
||||
class Cursor:
|
||||
def __init__(self, rows): self.rows = rows
|
||||
async def fetchone(self): return self.rows[0] if self.rows else None
|
||||
|
||||
Reference in New Issue
Block a user