Switch from email notifications to Discord webhook for bind changes
This commit is contained in:
1 parent
e96948080f
commit
0bc8daeabc
6 files changed
+292
-26
No files matched your search
@@ -0,0 +1,75 @@
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from mdb.services import discord
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def webhook_url(settings):
|
||||
settings.DISCORD_NOTIFICATION_WEBHOOK = "https://discord.example/webhook"
|
||||
|
||||
|
||||
def test_notify_does_nothing_without_webhook(settings):
|
||||
settings.DISCORD_NOTIFICATION_WEBHOOK = None
|
||||
with patch("mdb.services.discord._send_json") as mock:
|
||||
discord.notify("Subject", "message")
|
||||
mock.assert_not_called()
|
||||
|
||||
|
||||
def test_notify_sends_json_for_short_content():
|
||||
with patch("mdb.services.discord._send_json") as mock:
|
||||
discord.notify("Subject", "message")
|
||||
mock.assert_called_once()
|
||||
_, content = mock.call_args.args
|
||||
assert "**Subject**" in content
|
||||
assert "message" in content
|
||||
|
||||
|
||||
def test_notify_includes_preformatted_as_diff_code_block():
|
||||
with patch("mdb.services.discord._send_json") as mock:
|
||||
discord.notify("Subject", "message", preformatted="- old\n+ new")
|
||||
_, content = mock.call_args.args
|
||||
assert "```diff\n- old\n+ new\n```" in content
|
||||
|
||||
|
||||
def test_notify_sends_file_when_content_exceeds_limit():
|
||||
long_diff = "x" * discord.MAX_CONTENT_LENGTH
|
||||
with patch("mdb.services.discord._send_as_file") as mock:
|
||||
discord.notify("Subject", "message", preformatted=long_diff)
|
||||
mock.assert_called_once()
|
||||
|
||||
|
||||
def test_notify_sends_json_when_content_fits():
|
||||
with patch("mdb.services.discord._send_json") as mock:
|
||||
discord.notify("Subject", "short message")
|
||||
mock.assert_called_once()
|
||||
|
||||
|
||||
def test_send_json_posts_with_mdb_username():
|
||||
mock_resp = MagicMock()
|
||||
with patch("requests.post", return_value=mock_resp) as mock_post:
|
||||
discord._send_json("https://discord.example/webhook", "hello")
|
||||
payload = mock_post.call_args.kwargs["json"]
|
||||
assert payload["username"] == "MDB"
|
||||
assert payload["content"] == "hello"
|
||||
mock_resp.raise_for_status.assert_called_once()
|
||||
|
||||
|
||||
def test_send_as_file_posts_multipart_with_attachment():
|
||||
mock_resp = MagicMock()
|
||||
with patch("requests.post", return_value=mock_resp) as mock_post:
|
||||
discord._send_as_file("https://discord.example/webhook", "Subject", "full content")
|
||||
assert mock_post.call_args.kwargs.get("files") or "files" in str(mock_post.call_args)
|
||||
mock_resp.raise_for_status.assert_called_once()
|
||||
|
||||
|
||||
def test_send_as_file_content_mentions_attachment():
|
||||
import json
|
||||
mock_resp = MagicMock()
|
||||
with patch("requests.post", return_value=mock_resp) as mock_post:
|
||||
discord._send_as_file("https://discord.example/webhook", "MySubject", "full content")
|
||||
data = mock_post.call_args.kwargs["data"]
|
||||
payload = json.loads(data["payload_json"])
|
||||
assert "MySubject" in payload["content"]
|
||||
assert "attachment" in payload["content"]
|
||||
@@ -47,42 +47,51 @@ def test_run_reload_commands_stops_on_first_failure(service):
|
||||
|
||||
def test_reload_and_notify_success_writes_ok(cmd):
|
||||
svc = make_service()
|
||||
with patch("mdb.management.commands.zone_sync.mail_admins"):
|
||||
cmd.reload_and_notify(svc, errors="", diffs="diff", zones="example.org")
|
||||
with patch("mdb.management.commands.zone_sync.discord") as mock_discord:
|
||||
cmd.reload_and_notify(svc, errors="", diffs="diff", zones=["example.org"])
|
||||
assert "ok" in cmd.stdout.getvalue()
|
||||
|
||||
|
||||
def test_reload_and_notify_success_sends_mail(cmd):
|
||||
def test_reload_and_notify_success_calls_discord(cmd):
|
||||
svc = make_service()
|
||||
with patch("mdb.management.commands.zone_sync.mail_admins") as mock_mail:
|
||||
cmd.reload_and_notify(svc, errors="", diffs="diff", zones="example.org")
|
||||
mock_mail.assert_called_once()
|
||||
assert "Success" in mock_mail.call_args.kwargs["subject"]
|
||||
with patch("mdb.management.commands.zone_sync.discord") as mock_discord:
|
||||
cmd.reload_and_notify(svc, errors="", diffs="diff", zones=["example.org"])
|
||||
mock_discord.notify.assert_called_once()
|
||||
assert "✅" in mock_discord.notify.call_args.kwargs["subject"]
|
||||
assert "- example.org" in mock_discord.notify.call_args.kwargs["message"]
|
||||
|
||||
|
||||
def test_reload_and_notify_success_passes_diff_as_preformatted(cmd):
|
||||
svc = make_service()
|
||||
with patch("mdb.management.commands.zone_sync.discord") as mock_discord:
|
||||
cmd.reload_and_notify(svc, errors="", diffs="- old\n+ new", zones=["example.org"])
|
||||
assert mock_discord.notify.call_args.kwargs["preformatted"] == "- old\n+ new"
|
||||
|
||||
|
||||
def test_reload_and_notify_failure_writes_fail_and_exits(cmd):
|
||||
svc = make_service()
|
||||
svc.run_reload_commands.return_value = (False, "/usr/sbin/rndc freeze", "timed out")
|
||||
with patch("mdb.management.commands.zone_sync.mail_admins"):
|
||||
with patch("mdb.management.commands.zone_sync.discord"):
|
||||
with patch("os.getlogin", return_value="testuser"):
|
||||
with pytest.raises(SystemExit) as exc:
|
||||
cmd.reload_and_notify(svc, errors="", diffs="", zones="example.org")
|
||||
cmd.reload_and_notify(svc, errors="", diffs="", zones=["example.org"])
|
||||
assert exc.value.code == 1
|
||||
assert "fail" in cmd.stdout.getvalue()
|
||||
|
||||
|
||||
def test_reload_and_notify_failure_mail_includes_command_and_output(cmd):
|
||||
def test_reload_and_notify_failure_discord_includes_command_and_output(cmd):
|
||||
svc = make_service()
|
||||
svc.run_reload_commands.return_value = (False, "/usr/sbin/rndc freeze", "timed out")
|
||||
with patch("mdb.management.commands.zone_sync.mail_admins") as mock_mail:
|
||||
with patch("mdb.management.commands.zone_sync.discord") as mock_discord:
|
||||
with patch("os.getlogin", return_value="testuser"):
|
||||
with pytest.raises(SystemExit):
|
||||
cmd.reload_and_notify(svc, errors="", diffs="", zones="example.org")
|
||||
subject = mock_mail.call_args.kwargs["subject"]
|
||||
message = mock_mail.call_args.kwargs["message"]
|
||||
assert "FAIL" in subject
|
||||
cmd.reload_and_notify(svc, errors="", diffs="", zones=["example.org"])
|
||||
subject = mock_discord.notify.call_args.kwargs["subject"]
|
||||
message = mock_discord.notify.call_args.kwargs["message"]
|
||||
assert "⚠️" in subject
|
||||
assert "rndc freeze" in message
|
||||
assert "timed out" in message
|
||||
assert "- example.org" in message
|
||||
|
||||
|
||||
# --- handle ---
|
||||
|
||||
Reference in new issue
Block a user