feat: enhance message handling with content pattern matching and update environment configuration
Build and Deploy Docker Container / test (push) Successful in 14s
Build and Deploy Docker Container / build-and-deploy (push) Successful in 29s

This commit is contained in:
2026-05-10 14:24:07 +02:00
parent 915c55d7ed
commit 3412a5ccaa
5 changed files with 221 additions and 9 deletions
+98
View File
@@ -23,3 +23,101 @@ def test_get_next_scheduled_event():
nxt = main.get_next_scheduled_event(now)
assert nxt["type"] == "reminder"
assert nxt["at"].hour == 11 and nxt["at"].minute == 15
def test_schedule_startup_test_cleanup_when_sent(monkeypatch):
captured: dict[str, object] = {}
delete_calls: list[tuple[int, str | None]] = []
class FakeEvery:
@property
def minutes(self):
return self
def do(self, fn, *args, **kwargs):
captured["job"] = lambda: fn(*args, **kwargs)
return object()
monkeypatch.setattr(main.schedule, "every", lambda n: FakeEvery())
monkeypatch.setattr(
main,
"delete_old_messages",
lambda minutes, content_pattern=None: delete_calls.append(
(minutes, content_pattern)),
)
main._schedule_startup_test_cleanup(True)
assert "job" in captured
result = captured["job"]()
assert result == main.schedule.CancelJob
assert delete_calls == [(1, main.TEST_MESSAGE_DELETE_PATTERN)]
def test_schedule_startup_test_cleanup_skips_when_not_sent(monkeypatch):
called = {"value": False}
class FakeEvery:
@property
def minutes(self):
return self
def do(self, fn, *args, **kwargs):
called["value"] = True
return object()
monkeypatch.setattr(main.schedule, "every", lambda n: FakeEvery())
main._schedule_startup_test_cleanup(False)
assert called["value"] is False
def test_main_sends_startup_test_and_deletes_it(monkeypatch):
send_calls: list[str] = []
delete_calls: list[tuple[int, str | None]] = []
scheduled_jobs: dict[int, list[object]] = {1: [], 5: []}
monkeypatch.setattr(main, "start_dashboard", lambda: None)
monkeypatch.setattr(main, "schedule_notification",
lambda interval, at, type: None)
class FakeEvery:
def __init__(self, minutes_value: int):
self.minutes_value = minutes_value
@property
def minutes(self):
return self
def do(self, fn, *args, **kwargs):
scheduled_jobs.setdefault(self.minutes_value, []).append(
lambda: fn(*args, **kwargs)
)
return object()
monkeypatch.setattr(main.schedule, "every", lambda n: FakeEvery(n))
def fake_send_notification(message: str) -> bool:
send_calls.append(message)
return True
def fake_delete_old_messages(minutes: int = 6, content_pattern: str | None = None):
delete_calls.append((minutes, content_pattern))
def fake_run_pending():
for job in scheduled_jobs.get(1, []):
job()
raise KeyboardInterrupt()
monkeypatch.setattr(main, "send_notification", fake_send_notification)
monkeypatch.setattr(main, "delete_old_messages", fake_delete_old_messages)
monkeypatch.setattr(main.schedule, "run_pending", fake_run_pending)
monkeypatch.setattr(main.time, "sleep", lambda s: None)
monkeypatch.setenv("DISCORD_WEBHOOK_URL", "http://example.com/webhook")
main.WEBHOOK_URL = "http://example.com/webhook"
main.main()
assert send_calls == ["test"]
assert delete_calls == [(1, main.TEST_MESSAGE_DELETE_PATTERN)]
+38
View File
@@ -53,6 +53,44 @@ def test_should_delete_message():
)
def test_message_matches_pattern_content_and_embeds():
message = {
"content": "This is a smoke test payload",
"embeds": [
{"title": "Reminder", "description": "Half-time in 5 minutes"}
],
}
assert maintenance.message_matches_pattern(message, r"smoke test")
assert maintenance.message_matches_pattern(message, r"half-time")
assert not maintenance.message_matches_pattern(message, r"does-not-match")
def test_should_delete_message_with_content_pattern():
ts = int(datetime(2026, 1, 1, 10, 0, 0, tzinfo=timezone.utc).timestamp())
message = {
"timestamp": "2026-01-01T10:00:00Z",
"webhook_id": "w",
"author": {"id": "a"},
"embeds": [{"description": "This is a test notification."}],
}
assert maintenance.should_delete_message(
message,
webhook_id="w",
author_id="a",
cutoff=ts,
content_pattern=r"test notification",
)
assert not maintenance.should_delete_message(
message,
webhook_id="w",
author_id="a",
cutoff=ts,
content_pattern=r"production-only",
)
def test_get_rate_limit_retry_after_header_priority():
response = DummyResponse(
headers={