|
| 1 | +from datetime import timedelta |
| 2 | + |
| 3 | +import arrow |
| 4 | +import pytest |
| 5 | +from moto import mock_ses |
| 6 | + |
| 7 | +from lemur.certificates.schemas import certificate_notification_output_schema |
| 8 | +from lemur.tests.factories import NotificationFactory, CertificateFactory |
| 9 | +from lemur.tests.test_messaging import verify_sender_email |
| 10 | + |
| 11 | + |
| 12 | +def test_formatting(certificate): |
| 13 | + from lemur.plugins.lemur_telegram.plugin import create_expiration_attachments |
| 14 | + data = [certificate_notification_output_schema.dump(certificate).data] |
| 15 | + attachments = create_expiration_attachments(data) |
| 16 | + body = attachments[0] |
| 17 | + assert certificate.name in body |
| 18 | + assert "Owner:" in body |
| 19 | + assert "Expires:" in body |
| 20 | + assert "Endpoints:" in body |
| 21 | + assert "https://" in body |
| 22 | + assert certificate.name in body.split("(")[1] |
| 23 | + |
| 24 | + |
| 25 | +def get_options(): |
| 26 | + return [ |
| 27 | + {"name": "interval", "value": 10}, |
| 28 | + {"name": "unit", "value": "days"}, |
| 29 | + {"name": "chat", "value": "12345"}, |
| 30 | + {"name": "token", "value": "999:TESTTOKEN"}, |
| 31 | + ] |
| 32 | + |
| 33 | + |
| 34 | +def prepare_test(): |
| 35 | + verify_sender_email() |
| 36 | + notification = NotificationFactory(plugin_name="tg-notification") |
| 37 | + notification.options = get_options() |
| 38 | + now = arrow.utcnow() |
| 39 | + in_ten_days = now + timedelta(days=10, hours=1) |
| 40 | + certificate = CertificateFactory() |
| 41 | + certificate.not_after = in_ten_days |
| 42 | + certificate.notifications.append(notification) |
| 43 | + |
| 44 | + |
| 45 | +@mock_ses() |
| 46 | +def test_send_expiration_notification(mocker): |
| 47 | + from lemur.notifications.messaging import send_expiration_notifications |
| 48 | + # Telegram API request mock |
| 49 | + mock_post = mocker.patch( |
| 50 | + "lemur.plugins.lemur_telegram.plugin.requests.post" |
| 51 | + ) |
| 52 | + mock_post.return_value.status_code = 200 |
| 53 | + |
| 54 | + prepare_test() |
| 55 | + |
| 56 | + sent, failed = send_expiration_notifications([], []) |
| 57 | + |
| 58 | + # Why 3: |
| 59 | + # - owner email |
| 60 | + # - security email |
| 61 | + # - telegram notification |
| 62 | + assert (sent, failed) == (3, 0) |
| 63 | + |
| 64 | + # Ensure Telegram was hit |
| 65 | + assert mock_post.called |
| 66 | + data = mock_post.call_args[1]["data"] |
| 67 | + assert "Lemur Expiration Notification" in data["text"] |
| 68 | + assert data["chat_id"] == "12345" |
| 69 | + |
| 70 | + |
| 71 | +@mock_ses() |
| 72 | +def test_send_expiration_notification_telegram_disabled(mocker): |
| 73 | + from lemur.notifications.messaging import send_expiration_notifications |
| 74 | + |
| 75 | + mocker.patch( |
| 76 | + "lemur.plugins.lemur_telegram.plugin.requests.post" |
| 77 | + ) |
| 78 | + |
| 79 | + prepare_test() |
| 80 | + |
| 81 | + # Disabling telegram means: owner+security emails SHOULD NOT be skipped, |
| 82 | + # but messaging rules say: if the *main* plugin (tg-notification) disabled → skip all |
| 83 | + assert send_expiration_notifications([], ["tg-notification"]) == (0, 0) |
| 84 | + |
| 85 | + |
| 86 | +@mock_ses() |
| 87 | +def test_send_expiration_notification_email_disabled(mocker): |
| 88 | + from lemur.notifications.messaging import send_expiration_notifications |
| 89 | + |
| 90 | + mocker.patch( |
| 91 | + "lemur.plugins.lemur_telegram.plugin.requests.post" |
| 92 | + ) |
| 93 | + |
| 94 | + prepare_test() |
| 95 | + |
| 96 | + # Email disabled → Telegram still fires |
| 97 | + # sent, failed = |
| 98 | + assert send_expiration_notifications([], ["email-notification"]) == (0, 1) |
| 99 | + |
| 100 | + |
| 101 | +@mock_ses() |
| 102 | +def test_send_expiration_notification_both_disabled(mocker): |
| 103 | + from lemur.notifications.messaging import send_expiration_notifications |
| 104 | + |
| 105 | + mocker.patch( |
| 106 | + "lemur.plugins.lemur_telegram.plugin.requests.post" |
| 107 | + ) |
| 108 | + |
| 109 | + prepare_test() |
| 110 | + |
| 111 | + assert send_expiration_notifications([], ["tg-notification", "email-notification"]) == (0, 0) |
| 112 | + |
| 113 | + |
| 114 | +def test_send_failure_on_bad_status(mocker, certificate): |
| 115 | + from lemur.plugins.lemur_telegram.plugin import TelegramNotificationPlugin |
| 116 | + |
| 117 | + plugin = TelegramNotificationPlugin() |
| 118 | + |
| 119 | + mock_post = mocker.patch( |
| 120 | + "lemur.plugins.lemur_telegram.plugin.requests.post" |
| 121 | + ) |
| 122 | + mock_post.return_value.status_code = 403 |
| 123 | + |
| 124 | + options = {"chat": "12345", "token": "999:BAD"} |
| 125 | + |
| 126 | + cert_data = [certificate_notification_output_schema.dump(certificate).data] |
| 127 | + |
| 128 | + with pytest.raises(Exception): |
| 129 | + plugin.send("expiration", cert_data, None, options) |
| 130 | + |
| 131 | + |
| 132 | +def test_unsupported_notification_type_raises(mocker): |
| 133 | + from lemur.plugins.lemur_telegram.plugin import TelegramNotificationPlugin |
| 134 | + |
| 135 | + plugin = TelegramNotificationPlugin() |
| 136 | + |
| 137 | + mocker.patch("lemur.plugins.lemur_telegram.plugin.requests.post") |
| 138 | + |
| 139 | + with pytest.raises(Exception) as exc: |
| 140 | + plugin.send("unknown", {}, None, {"chat": "1", "token": "999:X"}) |
| 141 | + |
| 142 | + assert "Unable to create message attachments" in str(exc.value) |
0 commit comments