You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
motief/tests/test_sync_motion_content.py

97 lines
2.9 KiB

"""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 = '<Besluit id="b1' + '">\n<Zaak ref="z1"/>\n</Besluit>'
parsed = s.parse_besluit(xml)
assert parsed["id"] == "b1"
def test_fetch_body_text_retries_on_transient_error(monkeypatch):
"""_fetch_body_text retries after a ConnectionError and returns text on success."""
session = MagicMock()
call_count = {"n": 0}
def fake_get(url, timeout=30):
call_count["n"] += 1
if call_count["n"] == 1:
raise requests.exceptions.ConnectionError("timeout")
# Second attempt succeeds
resp = MagicMock()
resp.status_code = 200
resp.text = "<p>body text here</p>"
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