Add assert-based pytest coverage for recent fixes

- tests/conftest.py: put repo root on sys.path so `import src...` resolves
  under pytest regardless of invocation directory.
- test_matrix_formatting.py: lock in HTML formatted_body + plain-text fallback,
  URL linkification, HTML escaping, and send_alert field rendering.
- test_station_persistence.py: cover default-load, save/reload round-trip
  (incl. Thai text), runtime-file precedence, and atomic-write cleanup.

These are real assert-based tests (unlike the existing print-style scripts) so
CI can gate on them. 13 tests, all passing.
This commit is contained in:
2026-07-22 14:02:06 +07:00
parent ce31a5254e
commit 12b7f9f422
3 changed files with 187 additions and 0 deletions
+98
View File
@@ -0,0 +1,98 @@
"""Assert-based tests for Matrix message formatting.
Matrix clients only render formatting from an HTML ``formatted_body``; Markdown
in the plain ``body`` shows as literal characters. These tests lock in that the
notifier emits real HTML plus a clean plain-text fallback, and that untrusted
station data is HTML-escaped.
"""
import datetime
from src.alerting import AlertLevel, MatrixNotifier, WaterAlert, markdown_to_matrix_html, strip_markdown
class _FakeResponse:
def raise_for_status(self):
pass
def json(self):
return {"event_id": "$test"}
def _notifier_capturing(captured):
"""A MatrixNotifier whose HTTP PUT records the JSON payload into ``captured``."""
notifier = MatrixNotifier("https://hs.example", "token", "!room:hs.example")
def fake_put(url, headers=None, json=None, timeout=None):
captured.update(json)
return _FakeResponse()
notifier.session.put = fake_put
return notifier
def test_bold_becomes_strong():
assert markdown_to_matrix_html("**hi**") == "<strong>hi</strong>"
def test_url_is_linkified():
out = markdown_to_matrix_html("see https://x.example/z")
assert '<a href="https://x.example/z">https://x.example/z</a>' in out
def test_newlines_become_br():
assert markdown_to_matrix_html("a\nb") == "a<br/>b"
def test_html_is_escaped():
out = markdown_to_matrix_html("<script> & 'stuff'")
assert "&lt;script&gt;" in out
assert "&amp;" in out
assert "<script>" not in out
def test_strip_markdown_removes_bold_markers():
assert strip_markdown("**WATER LEVEL ALERT**") == "WATER LEVEL ALERT"
def test_send_message_sends_html_and_plain_fallback():
captured = {}
notifier = _notifier_capturing(captured)
assert notifier.send_message("**hi** http://x.example") is True
assert captured["format"] == "org.matrix.custom.html"
assert "<strong>hi</strong>" in captured["formatted_body"]
# Plain body has the markdown markers stripped.
assert captured["body"] == "hi http://x.example"
def test_send_message_plain_when_markdown_disabled():
captured = {}
notifier = _notifier_capturing(captured)
assert notifier.send_message("**raw**", markdown=False) is True
assert "formatted_body" not in captured
assert captured["body"] == "**raw**"
def test_send_alert_renders_alert_fields():
captured = {}
notifier = _notifier_capturing(captured)
alert = WaterAlert(
station_code="P.1",
station_name="สะพานนวรัฐ",
alert_type="Zone 7 - Critical",
level=AlertLevel.CRITICAL,
water_level=4.62,
threshold=4.60,
discharge=612.0,
timestamp=datetime.datetime(2026, 7, 22, 14, 30, 0),
)
assert notifier.send_alert(alert) is True
html = captured["formatted_body"]
assert "<strong>WATER LEVEL ALERT</strong>" in html
assert "สะพานนวรัฐ" in html # Thai station name preserved
assert "<strong>Current Level:</strong>" in html
# Plain fallback carries no leftover markdown markers.
assert "**" not in captured["body"]