test(036): evidence tests (4) + denial tests (5) — 80 backend, 14 frontend

This commit is contained in:
2026-07-28 18:57:48 +03:00
parent d0aa5f0278
commit f2d844cd91
2 changed files with 185 additions and 0 deletions

View File

@@ -0,0 +1,112 @@
# backend/tests/services/agent_runs/test_evidence.py
# #region Test.AgentRuns.Evidence [C:3] [TYPE Module] [SEMANTICS test,agent-run,evidence,capture,meta]
# @BRIEF L1 tests for evidence adapter — capture_meta validation, masking, required fields.
# @RELATION BINDS_TO -> [Services.AgentRuns.Evidence]
# @TEST_EDGE missing_required_fields -> ValueError.
# @TEST_EDGE mask_selectors_required -> contract enforced.
import pytest
from sqlalchemy import create_engine, event
from sqlalchemy.orm import sessionmaker
from src.models.agent_run import AgentRun
from src.services.agent_runs.evidence import register_screenshot_draft, register_masked_derivative
from src.services.agent_runs.service import create_agent_run
from src.schemas.agent_run import CreateAgentRunRequest, UIContextV2
def _make_session():
engine = create_engine("sqlite:///:memory:")
event.listen(engine, "connect", lambda c, _: c.execute("PRAGMA foreign_keys=ON"))
from src.models.mapping import Base
Base.metadata.create_all(bind=engine)
return sessionmaker(bind=engine)(), engine
def _make_context() -> UIContextV2:
return UIContextV2(
objectType="dashboard", objectId="42", envId="dev",
route="/dashboards/42", contextVersion=2,
intent="build_dashboard_test_scenario",
)
@pytest.fixture
def db_session():
db, _engine = _make_session()
try:
yield db
finally:
db.close()
@pytest.fixture
def run_id(db_session):
req = CreateAgentRunRequest(context=_make_context())
snap = create_agent_run(db_session, req, user_id="user-1")
db_session.commit()
return snap.id
class TestRegisterScreenshotDraft:
def test_valid_capture_meta(self, db_session, run_id):
result = register_screenshot_draft(db_session, run_id, "user-1",
name="screenshot_001.png",
intended_path="evidence/screenshot_001.png",
sha256="a" * 64,
capture_meta={
"viewport": {"width": 1920, "height": 1200},
"capture_method": "cdp",
"filter_context_hash": "b" * 64,
"readiness_strategy": "network_idle",
"readiness_timeout_ms": 15000,
"mask_selectors": [".user-info", ".api-key"],
},
validation_status="valid",
)
db_session.commit()
assert result.id is not None
assert result.kind == "screenshot_evidence"
assert result.capture_meta is not None
def test_missing_required_fields_raises(self, db_session, run_id):
with pytest.raises(ValueError, match="missing required fields"):
register_screenshot_draft(db_session, run_id, "user-1",
name="bad.png", intended_path="bad.png",
sha256="a" * 64,
capture_meta={},
)
def test_missing_viewport_raises(self, db_session, run_id):
with pytest.raises(ValueError, match="missing required fields"):
register_screenshot_draft(db_session, run_id, "user-1",
name="bad.png", intended_path="bad.png",
sha256="a" * 64,
capture_meta={"capture_method": "cdp"},
)
class TestRegisterMaskedDerivative:
def test_masked_derivative_stored_separately(self, db_session, run_id):
orig = register_screenshot_draft(db_session, run_id, "user-1",
name="screenshot_001.png",
intended_path="evidence/screenshot_001.png",
sha256="a" * 64,
capture_meta={
"viewport": {"width": 1920, "height": 1200},
"capture_method": "cdp",
},
)
db_session.commit()
masked = register_masked_derivative(db_session, run_id, "user-1",
original_artifact_id=orig.id,
derivative_sha256="b" * 64,
intended_path="evidence/screenshot_001_masked.png",
)
db_session.commit()
assert masked.id is not None
assert masked.id != orig.id
assert masked.kind == "other"
assert "_masked" in masked.name
# #endregion Test.AgentRuns.Evidence