wip(test): category_tester + audit_walk_zip_builder (salvaged)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,87 @@
|
|||||||
|
"""Tests for the audit-walk ZIP-builder."""
|
||||||
|
|
||||||
|
import io
|
||||||
|
import json
|
||||||
|
import zipfile
|
||||||
|
from unittest.mock import patch, MagicMock
|
||||||
|
|
||||||
|
from compliance.services.audit_walk_zip_builder import (
|
||||||
|
_readme,
|
||||||
|
build_audit_walk_zip,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
_FAKE_WALK = {
|
||||||
|
"walk_id": "abc123def456",
|
||||||
|
"url": "https://example.com/",
|
||||||
|
"started_at": "2026-06-07T10:00:00+00:00",
|
||||||
|
"completed_at": "2026-06-07T10:00:30+00:00",
|
||||||
|
"video": {
|
||||||
|
"filename": "video.webm",
|
||||||
|
"size_bytes": 12345,
|
||||||
|
"sha256": "a" * 64,
|
||||||
|
"dsms": {"cid": "QmFakeCidVideo"},
|
||||||
|
},
|
||||||
|
"walk_json_dsms": {"cid": "QmFakeCidMeta"},
|
||||||
|
"actions": [
|
||||||
|
{"action": "navigate", "url": "https://example.com/dse"},
|
||||||
|
{"action": "navigate", "url": "https://example.com/imprint"},
|
||||||
|
{"action": "expand_accordions", "expanded": 3},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class TestReadme:
|
||||||
|
def test_contains_walk_id_and_url(self):
|
||||||
|
r = _readme(_FAKE_WALK)
|
||||||
|
assert "abc123def456" in r
|
||||||
|
assert "https://example.com/" in r
|
||||||
|
|
||||||
|
def test_contains_dsms_cids(self):
|
||||||
|
r = _readme(_FAKE_WALK)
|
||||||
|
assert "QmFakeCidVideo" in r
|
||||||
|
assert "QmFakeCidMeta" in r
|
||||||
|
|
||||||
|
def test_counts_navigates_and_accordions(self):
|
||||||
|
r = _readme(_FAKE_WALK)
|
||||||
|
assert "2 Compliance-Seiten" in r
|
||||||
|
assert "3 Akkordeon" in r
|
||||||
|
|
||||||
|
|
||||||
|
class TestBuildZip:
|
||||||
|
def test_empty_walk_returns_empty(self):
|
||||||
|
assert build_audit_walk_zip({}) == b""
|
||||||
|
|
||||||
|
def test_zip_contains_three_entries(self):
|
||||||
|
# Mock the video fetch to return tiny content
|
||||||
|
with patch(
|
||||||
|
"compliance.services.audit_walk_zip_builder.httpx.Client"
|
||||||
|
) as mock_client:
|
||||||
|
instance = mock_client.return_value.__enter__.return_value
|
||||||
|
instance.get.return_value = MagicMock(
|
||||||
|
status_code=200, content=b"fakevideo",
|
||||||
|
)
|
||||||
|
zip_bytes = build_audit_walk_zip(_FAKE_WALK)
|
||||||
|
assert zip_bytes
|
||||||
|
with zipfile.ZipFile(io.BytesIO(zip_bytes)) as z:
|
||||||
|
names = set(z.namelist())
|
||||||
|
assert {"video.webm", "walk.json", "README.txt"}.issubset(names)
|
||||||
|
walk_content = json.loads(z.read("walk.json"))
|
||||||
|
assert walk_content["walk_id"] == "abc123def456"
|
||||||
|
assert z.read("video.webm") == b"fakevideo"
|
||||||
|
|
||||||
|
def test_video_fetch_failure_still_produces_zip(self):
|
||||||
|
# consent-tester down → no video, but ZIP still contains
|
||||||
|
# walk.json + README so the recipient has the metadata.
|
||||||
|
with patch(
|
||||||
|
"compliance.services.audit_walk_zip_builder.httpx.Client"
|
||||||
|
) as mock_client:
|
||||||
|
instance = mock_client.return_value.__enter__.return_value
|
||||||
|
instance.get.side_effect = Exception("network down")
|
||||||
|
zip_bytes = build_audit_walk_zip(_FAKE_WALK)
|
||||||
|
assert zip_bytes
|
||||||
|
with zipfile.ZipFile(io.BytesIO(zip_bytes)) as z:
|
||||||
|
names = z.namelist()
|
||||||
|
assert "video.webm" not in names
|
||||||
|
assert "walk.json" in names
|
||||||
|
assert "README.txt" in names
|
||||||
Reference in New Issue
Block a user