"""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