"""Tests for scripts/sync_motion_content.py.
Tests retry logic in _fetch_body_text and permanent-failure audit recording.
"""
import requests
from unittest.mock import MagicMock, patch
import scripts.sync_motion_content as s
def test_parse_besluit_simple():
xml = '
body text here
" resp.raise_for_status.return_value = None return resp session.get.side_effect = fake_get # Patch time.sleep to avoid delays in tests monkeypatch.setattr("time.sleep", lambda s: None) result = s._fetch_body_text("ext123", session, retries=3) assert result is not None assert "body text here" in result assert call_count["n"] == 2 # failed once, succeeded on second def test_fetch_body_text_permanent_failure_records_audit(monkeypatch): """When all retries are exhausted, audit_event is recorded via database.db.""" session = MagicMock() session.get.side_effect = requests.exceptions.ConnectionError("always fails") monkeypatch.setattr("time.sleep", lambda s: None) # Capture the audit event call audit_calls = [] import database monkeypatch.setattr( database.db, "append_audit_event", lambda actor_id, action, **kwargs: ( audit_calls.append({"action": action, **kwargs}) or True ), ) result = s._fetch_body_text("ext_fail", session, retries=3) assert result is None assert len(audit_calls) >= 1 assert audit_calls[0]["action"] == "body_fetch_failed" assert audit_calls[0]["target_id"] == "ext_fail" def test_fetch_body_text_retries_on_5xx(monkeypatch): """5xx responses are treated as transient; retried before giving up.""" session = MagicMock() call_count = {"n": 0} def fake_get(url, timeout=30): call_count["n"] += 1 resp = MagicMock() if call_count["n"] < 3: resp.status_code = 503 resp.raise_for_status.return_value = None else: resp.status_code = 200 resp.text = "clean text" resp.raise_for_status.return_value = None return resp session.get.side_effect = fake_get monkeypatch.setattr("time.sleep", lambda s: None) result = s._fetch_body_text("ext_5xx", session, retries=3) assert result is not None assert call_count["n"] == 3