From 12b7f9f422584f2e97e84c9bd6aa4137f19ab850 Mon Sep 17 00:00:00 2001 From: grabowski Date: Wed, 22 Jul 2026 14:02:06 +0700 Subject: [PATCH] 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. --- tests/conftest.py | 12 ++++ tests/test_matrix_formatting.py | 98 +++++++++++++++++++++++++++++++ tests/test_station_persistence.py | 77 ++++++++++++++++++++++++ 3 files changed, 187 insertions(+) create mode 100644 tests/conftest.py create mode 100644 tests/test_matrix_formatting.py create mode 100644 tests/test_station_persistence.py diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..72521e0 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,12 @@ +"""Shared pytest configuration. + +Ensures the repository root is on sys.path so tests can import the ``src`` +package regardless of the working directory pytest is invoked from. +""" + +import os +import sys + +REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +if REPO_ROOT not in sys.path: + sys.path.insert(0, REPO_ROOT) diff --git a/tests/test_matrix_formatting.py b/tests/test_matrix_formatting.py new file mode 100644 index 0000000..ed1c082 --- /dev/null +++ b/tests/test_matrix_formatting.py @@ -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**") == "hi" + + +def test_url_is_linkified(): + out = markdown_to_matrix_html("see https://x.example/z") + assert 'https://x.example/z' in out + + +def test_newlines_become_br(): + assert markdown_to_matrix_html("a\nb") == "a
b" + + +def test_html_is_escaped(): + out = markdown_to_matrix_html("