Skip to content

Commit a97aea6

Browse files
committed
fix slack resend notification channel filter
1 parent d9d0092 commit a97aea6

File tree

2 files changed

+118
-18
lines changed

2 files changed

+118
-18
lines changed

src/plugins/slack/actions/actions.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import logging
2-
from typing import Any, cast
2+
from typing import Any
33

44
import registry
55
from models import Monitor, Notification, NotificationStatus
@@ -19,24 +19,24 @@ async def _resend_notification(notification: Notification):
1919
return # pragma: no cover
2020

2121
# Get the SlackNotification option from the monitor code
22-
notification_option = None
2322
for notification_option in monitor.code.notification_options:
24-
if isinstance(notification_option, slack_notification.SlackNotification):
23+
if not isinstance(notification_option, slack_notification.SlackNotification):
24+
continue
25+
26+
if notification_option.channel == notification.data["channel"]:
27+
# Clear the notification and send it again
28+
await slack_notification.clear_slack_notification(notification)
29+
await slack_notification.slack_notification(
30+
event_payload={
31+
"event_data": {
32+
"id": notification.alert_id,
33+
}
34+
},
35+
notification_options=notification_option,
36+
)
2537
break
26-
if notification_option is None:
38+
else:
2739
_logger.warning(f"No 'SlackNotification' option for {monitor}")
28-
return
29-
30-
# Clear the notification and send it again
31-
await slack_notification.clear_slack_notification(notification)
32-
await slack_notification.slack_notification(
33-
event_payload={
34-
"event_data": {
35-
"id": notification.alert_id,
36-
}
37-
},
38-
notification_options=cast(slack_notification.SlackNotification, notification_option),
39-
)
4040

4141

4242
async def resend_notifications(message_payload: dict[Any, Any]):

tests/plugins/slack/actions/test_actions.py

Lines changed: 102 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import plugins.slack.notifications.slack_notification as slack_notification
77
import registry as registry
88
from models import Alert, Monitor, Notification, NotificationStatus
9-
from tests.test_utils import assert_message_in_log
9+
from tests.test_utils import assert_message_in_log, assert_message_not_in_log
1010

1111
pytestmark = pytest.mark.asyncio(loop_scope="session")
1212

@@ -39,8 +39,107 @@ async def test_resend_notification_no_slack_notification_option(
3939
assert_message_in_log(caplog, f"No 'SlackNotification' option for {sample_monitor}")
4040

4141

42+
async def test_resend_notification_slack_notification_different_channels(
43+
caplog, monkeypatch, sample_monitor: Monitor
44+
):
45+
"""'_resend_notification' should use the correct SlackNotification option when there're
46+
multiple ones defined in the monitor"""
47+
clear_notification_mock = AsyncMock()
48+
monkeypatch.setattr(slack_notification, "clear_slack_notification", clear_notification_mock)
49+
slack_notification_mock = AsyncMock()
50+
monkeypatch.setattr(slack_notification, "slack_notification", slack_notification_mock)
51+
52+
channel_1_notification_option = slack_notification.SlackNotification(
53+
channel="channel1",
54+
title="title",
55+
issues_fields=["col"],
56+
min_priority_to_send=3,
57+
mention="mention",
58+
min_priority_to_mention=2,
59+
)
60+
channel_2_notification_option = slack_notification.SlackNotification(
61+
channel="channel2",
62+
title="title",
63+
issues_fields=["col"],
64+
min_priority_to_send=3,
65+
mention="mention",
66+
min_priority_to_mention=2,
67+
)
68+
monkeypatch.setattr(
69+
sample_monitor.code,
70+
"notification_options",
71+
[channel_1_notification_option, channel_2_notification_option],
72+
raising=False
73+
)
74+
75+
alert = await Alert.create(
76+
monitor_id=sample_monitor.id,
77+
priority=2,
78+
)
79+
notification = await Notification.create(
80+
monitor_id=alert.monitor_id,
81+
alert_id=alert.id,
82+
target="slack",
83+
data={"channel": "channel2", "ts": "123"},
84+
)
85+
86+
await actions._resend_notification(notification)
87+
88+
clear_notification_mock.assert_awaited_once_with(notification)
89+
slack_notification_mock.assert_awaited_once_with(
90+
event_payload={"event_data": {"id": notification.alert_id}},
91+
notification_options=channel_2_notification_option,
92+
)
93+
assert_message_not_in_log(caplog, "No 'SlackNotification' option")
94+
95+
96+
async def test_resend_notification_other_notification_types(
97+
caplog, monkeypatch, sample_monitor: Monitor
98+
):
99+
"""'_resend_notification' should ignore notifications options that are not SlackNotifications"""
100+
clear_notification_mock = AsyncMock()
101+
monkeypatch.setattr(slack_notification, "clear_slack_notification", clear_notification_mock)
102+
slack_notification_mock = AsyncMock()
103+
monkeypatch.setattr(slack_notification, "slack_notification", slack_notification_mock)
104+
105+
slack_notification_option = slack_notification.SlackNotification(
106+
channel="channel",
107+
title="title",
108+
issues_fields=["col"],
109+
min_priority_to_send=3,
110+
mention="mention",
111+
min_priority_to_mention=2,
112+
)
113+
monkeypatch.setattr(
114+
sample_monitor.code,
115+
"notification_options",
116+
["other_notification", slack_notification_option],
117+
raising=False
118+
)
119+
120+
alert = await Alert.create(
121+
monitor_id=sample_monitor.id,
122+
priority=2,
123+
)
124+
notification = await Notification.create(
125+
monitor_id=alert.monitor_id,
126+
alert_id=alert.id,
127+
target="slack",
128+
data={"channel": "channel", "ts": "123"},
129+
)
130+
131+
await actions._resend_notification(notification)
132+
133+
clear_notification_mock.assert_awaited_once_with(notification)
134+
slack_notification_mock.assert_awaited_once_with(
135+
event_payload={"event_data": {"id": notification.alert_id}},
136+
notification_options=slack_notification_option,
137+
)
138+
assert_message_not_in_log(caplog, "No 'SlackNotification' option")
139+
140+
42141
async def test_resend_notification(
43-
mocker, monkeypatch, sample_monitor: Monitor
142+
caplog, mocker, monkeypatch, sample_monitor: Monitor
44143
):
45144
"""'_resend_notification' should clear the notification and send it again"""
46145
wait_monitor_loaded_spy: AsyncMock = mocker.spy(registry, "wait_monitor_loaded")
@@ -76,6 +175,7 @@ async def test_resend_notification(
76175
wait_monitor_loaded_spy.assert_awaited_once_with(sample_monitor.id)
77176
clear_notification_mock.assert_awaited_once()
78177
slack_notification_mock.assert_awaited_once()
178+
assert_message_not_in_log(caplog, "No 'SlackNotification' option")
79179

80180

81181
async def test_resend_notifications(monkeypatch, sample_monitor: Monitor):

0 commit comments

Comments
 (0)