"""Tests für Evidence-Vault.""" from __future__ import annotations import json import os from pathlib import Path import pytest @pytest.fixture def tmp_vault(tmp_path, monkeypatch): monkeypatch.setenv("EVIDENCE_VAULT_ROOT", str(tmp_path)) import compliance.services.specialist_agents._evidence_vault as v yield v def test_open_vault_creates_structure(tmp_vault): vault = tmp_vault.open_vault("impressum", "2.0") assert vault.root.exists() for sub in ("screenshots", "videos", "csv", "findings", "raw"): assert (vault.root / sub).is_dir() assert vault.manifest_path.exists() def test_put_bytes_appends_manifest(tmp_vault): vault = tmp_vault.open_vault("impressum", "2.0") rel = vault.put_bytes("screenshot", "url1", "test.png", b"\x89PNG\r\n\x1a\n", mime="image/png") assert rel.startswith("screenshots/") assert (vault.root / rel).exists() assets = vault.list_assets() assert len(assets) == 1 assert assets[0]["sha256"] assert assets[0]["mime"] == "image/png" assert assets[0]["size_bytes"] == 8 def test_put_json_stores_finding(tmp_vault): vault = tmp_vault.open_vault("cookie_policy", "1.0") rel = vault.put_json("finding", "url1", "output.json", {"findings": [{"check_id": "X"}]}) p = vault.root / rel data = json.loads(p.read_text()) assert data["findings"][0]["check_id"] == "X" def test_assets_for_slot_isolation(tmp_vault): vault = tmp_vault.open_vault("agent", "1.0") vault.put_bytes("screenshot", "url1", "a.png", b"a") vault.put_bytes("screenshot", "url2", "b.png", b"b") vault.put_bytes("video", "url1", "w.mp4", b"v") assert len(vault.assets_for_slot("url1")) == 2 assert len(vault.assets_for_slot("url2")) == 1 def test_asset_path_blocks_traversal(tmp_vault): vault = tmp_vault.open_vault("agent", "1.0") p = vault.asset_path("../../../etc/passwd") assert p is None def test_finalize_writes_finished_at(tmp_vault): vault = tmp_vault.open_vault("agent", "1.0") snap = vault.finalize() assert "finished_at" in snap manifest = json.loads(vault.manifest_path.read_text()) assert "finished_at" in manifest def test_list_runs_returns_recent(tmp_vault): tmp_vault.open_vault("a", "1.0", run_id="run1") tmp_vault.open_vault("b", "1.0", run_id="run2") runs = tmp_vault.list_runs(limit=10) ids = {r["run_id"] for r in runs} assert {"run1", "run2"} <= ids def test_delete_run_removes_dir(tmp_vault): vault = tmp_vault.open_vault("a", "1.0", run_id="kill-me") vault.put_bytes("screenshot", "u", "x.png", b"x") assert tmp_vault.delete_run("kill-me") assert not vault.root.exists() assert not tmp_vault.delete_run("kill-me") # idempotent def test_safe_filename_strips_path_chars(tmp_vault): vault = tmp_vault.open_vault("a", "1.0") rel = vault.put_bytes("raw", "slot", "../../etc/passwd", b"x") assert "passwd" in rel assert ".." not in rel