fix: enforce SCADA chart device coverage

This commit is contained in:
2026-11-12 10:38:55 +08:00
parent b853b61a0b
commit 2e8fe86f3f
17 changed files with 1220 additions and 13 deletions
@@ -98,3 +98,57 @@ async def test_presentation_history_storage_filters_project_task_and_committed_c
assert "project_id=%s" in query and "aggregate_id=%s" in query
assert "operational.presentation.requested" in query and "event_seq<=%s" in query
assert "ORDER BY event_seq LIMIT %s" in query
@pytest.mark.anyio
async def test_missing_scada_manifest_migration_fails_closed():
connection = SimpleNamespace(execute=AsyncMock(return_value=SimpleNamespace(
fetchone=AsyncMock(return_value={"available": False}),
)))
repository = OperationalTaskRepository(connection, uuid4())
with pytest.raises(DomainError) as failure:
await repository.get_scada_presentation(str(uuid4()), str(uuid4()))
assert failure.value.code == "DEPENDENCY_UNAVAILABLE"
assert failure.value.status == 503
assert "035_scada_presentation_coverage.sql" in failure.value.message
@pytest.mark.anyio
async def test_scada_manifest_is_scoped_to_project_task_and_run_and_preserves_other_run_facts():
from datetime import datetime, timezone
project, task, run = map(str, (uuid4(), uuid4(), uuid4()))
document = {"version": 1, "targets": ["524529"], "charts": {}}
connection = SimpleNamespace(execute=AsyncMock(side_effect=[
SimpleNamespace(fetchone=AsyncMock(return_value={"available": True})),
SimpleNamespace(fetchone=AsyncMock(return_value={"document": document})),
SimpleNamespace(rowcount=1),
]))
repository = OperationalTaskRepository(connection, project)
assert await repository.get_scada_presentation(task, run) == document
query, params = connection.execute.call_args.args
assert "artifact_manifest->'scada_presentation'" in query
assert params == (project, task, run)
await repository.save_scada_presentation(task, run, document, datetime.now(timezone.utc))
query, params = connection.execute.call_args.args
assert "jsonb_set(artifact_manifest,'{scada_presentation}'" in query
assert params[1:] == (project, task, run)
assert "revision=" not in query and "status=" not in query
@pytest.mark.anyio
async def test_internal_manifest_does_not_change_public_run_schemas_after_migration():
from datetime import datetime, timezone
from app.domain.schemas.operational_task import OperationalTaskRun
from tests.support.operational_task_repository import _active_run, _context, _task_document
context = _context()
task = _task_document(context, datetime.now(timezone.utc))
run = _active_run(task, datetime.now(timezone.utc))
connection = SimpleNamespace(execute=AsyncMock(return_value=SimpleNamespace(fetchall=AsyncMock(return_value=[{
**run, "project_id": context.project_id, "artifact_manifest": {"scada_presentation": {"targets": ["524529"]}},
}]))))
repository = OperationalTaskRepository(connection, context.project_id)
public = (await repository.list_task_runs(task["task_id"], 10, 0))[0]
assert "artifact_manifest" not in public
assert OperationalTaskRun.model_validate(public).run_id == OperationalTaskRun.model_validate(run).run_id