Related to https://github.com/grafana/oncall/issues/96 --------- Co-authored-by: Ravishankar <ravishankar.gnanaprakasam@gmail.com>
495 lines
20 KiB
Python
495 lines
20 KiB
Python
import json
|
|
from unittest.mock import patch
|
|
|
|
import httpretty
|
|
import pytest
|
|
from django.conf import settings
|
|
from django.utils import timezone
|
|
from rest_framework import status
|
|
|
|
from apps.alerts.models import AlertGroupLogRecord
|
|
from apps.base.models import UserNotificationPolicyLogRecord
|
|
from apps.base.models.user_notification_policy import UserNotificationPolicy
|
|
from apps.mattermost.client import MattermostAPIException
|
|
from apps.mattermost.models import MattermostMessage
|
|
from apps.mattermost.tasks import (
|
|
notify_user_about_alert_async,
|
|
on_alert_group_action_triggered_async,
|
|
on_create_alert_async,
|
|
)
|
|
|
|
|
|
@pytest.mark.django_db
|
|
@httpretty.activate(verbose=True, allow_net_connect=False)
|
|
def test_on_create_alert_async_success(
|
|
make_organization_and_user,
|
|
make_alert_receive_channel,
|
|
make_alert_group,
|
|
make_alert,
|
|
make_mattermost_channel,
|
|
make_mattermost_post_response,
|
|
):
|
|
organization, _ = make_organization_and_user()
|
|
alert_receive_channel = make_alert_receive_channel(organization)
|
|
alert_group = make_alert_group(alert_receive_channel)
|
|
alert = make_alert(alert_group=alert_group, raw_request_data=alert_receive_channel.config.example_payload)
|
|
make_mattermost_channel(organization=organization, is_default_channel=True)
|
|
|
|
url = "{}/api/v4/posts".format(settings.MATTERMOST_HOST)
|
|
data = make_mattermost_post_response()
|
|
mock_response = httpretty.Response(json.dumps(data), status=status.HTTP_200_OK)
|
|
httpretty.register_uri(httpretty.POST, url, responses=[mock_response])
|
|
|
|
on_create_alert_async(alert_pk=alert.pk)
|
|
|
|
mattermost_message = alert_group.mattermost_messages.order_by("created_at").first()
|
|
assert mattermost_message.post_id == data["id"]
|
|
assert mattermost_message.channel_id == data["channel_id"]
|
|
assert mattermost_message.message_type == MattermostMessage.ALERT_GROUP_MESSAGE
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_on_create_alert_async_skip_post_for_duplicate(
|
|
make_organization_and_user,
|
|
make_alert_receive_channel,
|
|
make_alert_group,
|
|
make_alert,
|
|
make_mattermost_channel,
|
|
make_mattermost_message,
|
|
):
|
|
organization, _ = make_organization_and_user()
|
|
alert_receive_channel = make_alert_receive_channel(organization)
|
|
alert_group = make_alert_group(alert_receive_channel)
|
|
alert = make_alert(alert_group=alert_group, raw_request_data=alert_receive_channel.config.example_payload)
|
|
make_mattermost_channel(organization=organization, is_default_channel=True)
|
|
make_mattermost_message(alert_group, MattermostMessage.ALERT_GROUP_MESSAGE)
|
|
|
|
with patch("apps.mattermost.client.MattermostClient.create_post") as mock_post_call:
|
|
on_create_alert_async(alert_pk=alert.pk)
|
|
|
|
mock_post_call.assert_not_called()
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_on_create_alert_async_skip_post_for_no_channel(
|
|
make_organization_and_user,
|
|
make_alert_receive_channel,
|
|
make_alert_group,
|
|
make_alert,
|
|
make_mattermost_message,
|
|
):
|
|
organization, _ = make_organization_and_user()
|
|
alert_receive_channel = make_alert_receive_channel(organization)
|
|
alert_group = make_alert_group(alert_receive_channel)
|
|
alert = make_alert(alert_group=alert_group, raw_request_data=alert_receive_channel.config.example_payload)
|
|
make_mattermost_message(alert_group, MattermostMessage.ALERT_GROUP_MESSAGE)
|
|
|
|
with patch("apps.mattermost.client.MattermostClient.create_post") as mock_post_call:
|
|
on_create_alert_async(alert_pk=alert.pk)
|
|
|
|
mock_post_call.assert_not_called()
|
|
|
|
|
|
@pytest.mark.django_db
|
|
@httpretty.activate(verbose=True, allow_net_connect=False)
|
|
@pytest.mark.parametrize("status_code", [400, 401])
|
|
def test_on_create_alert_async_mattermost_api_failure(
|
|
make_organization_and_user,
|
|
make_alert_receive_channel,
|
|
make_alert_group,
|
|
make_alert,
|
|
make_mattermost_channel,
|
|
make_mattermost_post_response_failure,
|
|
status_code,
|
|
):
|
|
organization, _ = make_organization_and_user()
|
|
alert_receive_channel = make_alert_receive_channel(organization)
|
|
alert_group = make_alert_group(alert_receive_channel)
|
|
alert = make_alert(alert_group=alert_group, raw_request_data=alert_receive_channel.config.example_payload)
|
|
make_mattermost_channel(organization=organization, is_default_channel=True)
|
|
|
|
url = "{}/api/v4/posts".format(settings.MATTERMOST_HOST)
|
|
data = make_mattermost_post_response_failure(status_code=status_code)
|
|
mock_response = httpretty.Response(json.dumps(data), status=status_code)
|
|
httpretty.register_uri(httpretty.POST, url, status=status_code, responses=[mock_response])
|
|
|
|
on_create_alert_async(alert_pk=alert.pk)
|
|
|
|
mattermost_message = alert_group.mattermost_messages.order_by("created_at").first()
|
|
assert mattermost_message is None
|
|
|
|
|
|
@pytest.mark.django_db
|
|
@httpretty.activate(verbose=True, allow_net_connect=False)
|
|
def test_on_alert_group_action_triggered_async_success(
|
|
make_organization_and_user,
|
|
make_alert_receive_channel,
|
|
make_alert_group,
|
|
make_alert,
|
|
make_mattermost_channel,
|
|
make_mattermost_post_response,
|
|
make_alert_group_log_record,
|
|
make_mattermost_message,
|
|
):
|
|
organization, _ = make_organization_and_user()
|
|
alert_receive_channel = make_alert_receive_channel(organization)
|
|
ack_alert_group = make_alert_group(alert_receive_channel, acknowledged_at=timezone.now(), acknowledged=True)
|
|
make_alert(alert_group=ack_alert_group, raw_request_data=alert_receive_channel.config.example_payload)
|
|
make_mattermost_channel(organization=organization, is_default_channel=True)
|
|
ack_log_record = make_alert_group_log_record(ack_alert_group, type=AlertGroupLogRecord.TYPE_ACK, author=None)
|
|
mattermost_message = make_mattermost_message(ack_alert_group, MattermostMessage.ALERT_GROUP_MESSAGE)
|
|
expected_button_ids = ["unacknowledge", "resolve"]
|
|
|
|
url = "{}/api/v4/posts/{}".format(settings.MATTERMOST_HOST, mattermost_message.post_id)
|
|
data = make_mattermost_post_response()
|
|
mock_response = httpretty.Response(json.dumps(data), status=status.HTTP_200_OK)
|
|
httpretty.register_uri(httpretty.PUT, url, responses=[mock_response])
|
|
|
|
on_alert_group_action_triggered_async(ack_log_record.pk)
|
|
|
|
last_request = httpretty.last_request()
|
|
assert last_request.method == "PUT"
|
|
assert last_request.url == url
|
|
|
|
request_body = json.loads(last_request.body)
|
|
ids = [a["id"] for a in request_body["props"]["attachments"][0]["actions"]]
|
|
for id in ids:
|
|
assert id in expected_button_ids
|
|
|
|
|
|
@pytest.mark.django_db
|
|
@httpretty.activate(verbose=True, allow_net_connect=False)
|
|
def test_on_alert_group_action_triggered_async_fails_without_alert_group_message(
|
|
make_organization_and_user,
|
|
make_alert_receive_channel,
|
|
make_alert_group,
|
|
make_alert,
|
|
make_mattermost_channel,
|
|
make_alert_group_log_record,
|
|
):
|
|
organization, _ = make_organization_and_user()
|
|
alert_receive_channel = make_alert_receive_channel(organization)
|
|
ack_alert_group = make_alert_group(alert_receive_channel, acknowledged_at=timezone.now(), acknowledged=True)
|
|
make_alert(alert_group=ack_alert_group, raw_request_data=alert_receive_channel.config.example_payload)
|
|
make_mattermost_channel(organization=organization, is_default_channel=True)
|
|
ack_log_record = make_alert_group_log_record(ack_alert_group, type=AlertGroupLogRecord.TYPE_ACK, author=None)
|
|
|
|
with pytest.raises(MattermostMessage.DoesNotExist):
|
|
on_alert_group_action_triggered_async(ack_log_record.pk)
|
|
|
|
|
|
@pytest.mark.django_db
|
|
@httpretty.activate(verbose=True, allow_net_connect=False)
|
|
@pytest.mark.parametrize("status_code", [400, 401])
|
|
def test_on_alert_group_action_triggered_async_failure(
|
|
make_organization_and_user,
|
|
make_alert_receive_channel,
|
|
make_alert_group,
|
|
make_alert,
|
|
make_mattermost_channel,
|
|
make_alert_group_log_record,
|
|
make_mattermost_message,
|
|
make_mattermost_post_response_failure,
|
|
status_code,
|
|
):
|
|
organization, _ = make_organization_and_user()
|
|
alert_receive_channel = make_alert_receive_channel(organization)
|
|
ack_alert_group = make_alert_group(alert_receive_channel, acknowledged_at=timezone.now(), acknowledged=True)
|
|
make_alert(alert_group=ack_alert_group, raw_request_data=alert_receive_channel.config.example_payload)
|
|
make_mattermost_channel(organization=organization, is_default_channel=True)
|
|
ack_log_record = make_alert_group_log_record(ack_alert_group, type=AlertGroupLogRecord.TYPE_ACK, author=None)
|
|
mattermost_message = make_mattermost_message(ack_alert_group, MattermostMessage.ALERT_GROUP_MESSAGE)
|
|
|
|
url = "{}/api/v4/posts/{}".format(settings.MATTERMOST_HOST, mattermost_message.post_id)
|
|
data = make_mattermost_post_response_failure(status_code=status_code)
|
|
mock_response = httpretty.Response(json.dumps(data), status=status_code)
|
|
httpretty.register_uri(httpretty.PUT, url, status=status_code, responses=[mock_response])
|
|
|
|
if status_code != 401:
|
|
with pytest.raises(MattermostAPIException):
|
|
on_alert_group_action_triggered_async(ack_log_record.pk)
|
|
else:
|
|
on_alert_group_action_triggered_async(ack_log_record.pk)
|
|
|
|
last_request = httpretty.last_request()
|
|
assert last_request.method == "PUT"
|
|
assert last_request.url == url
|
|
|
|
|
|
@pytest.mark.django_db
|
|
@httpretty.activate(verbose=True, allow_net_connect=False)
|
|
def test_notify_user_about_alert_async_success(
|
|
make_organization_and_user,
|
|
make_alert_receive_channel,
|
|
make_alert_group,
|
|
make_alert,
|
|
make_mattermost_channel,
|
|
make_mattermost_post_response,
|
|
make_mattermost_message,
|
|
make_user_notification_policy,
|
|
make_mattermost_user,
|
|
):
|
|
organization, user = make_organization_and_user()
|
|
|
|
alert_receive_channel = make_alert_receive_channel(organization)
|
|
alert_group = make_alert_group(alert_receive_channel)
|
|
make_alert(alert_group=alert_group, raw_request_data=alert_receive_channel.config.example_payload)
|
|
|
|
make_mattermost_channel(organization=organization, is_default_channel=True)
|
|
make_mattermost_message(alert_group, MattermostMessage.ALERT_GROUP_MESSAGE)
|
|
|
|
make_mattermost_user(user=user)
|
|
user_notification_policy = make_user_notification_policy(
|
|
user=user,
|
|
step=UserNotificationPolicy.Step.NOTIFY,
|
|
notify_by=UserNotificationPolicy.NotificationChannel.TESTONLY,
|
|
)
|
|
|
|
url = "{}/api/v4/posts".format(settings.MATTERMOST_HOST)
|
|
data = make_mattermost_post_response()
|
|
mock_response = httpretty.Response(json.dumps(data), status=status.HTTP_200_OK)
|
|
httpretty.register_uri(httpretty.POST, url, responses=[mock_response])
|
|
|
|
notify_user_about_alert_async(
|
|
user_pk=user.pk, alert_group_pk=alert_group.pk, notification_policy_pk=user_notification_policy.pk
|
|
)
|
|
|
|
log_record = alert_group.personal_log_records.last()
|
|
assert log_record.type == UserNotificationPolicyLogRecord.TYPE_PERSONAL_NOTIFICATION_SUCCESS
|
|
assert log_record.alert_group.pk == alert_group.pk
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_notify_user_about_alert_async_user_does_not_exist(
|
|
make_organization_and_user,
|
|
make_alert_receive_channel,
|
|
make_alert_group,
|
|
make_alert,
|
|
make_mattermost_channel,
|
|
make_mattermost_message,
|
|
make_mattermost_user,
|
|
make_user_notification_policy,
|
|
):
|
|
organization, user = make_organization_and_user()
|
|
|
|
alert_receive_channel = make_alert_receive_channel(organization)
|
|
alert_group = make_alert_group(alert_receive_channel)
|
|
make_alert(alert_group=alert_group, raw_request_data=alert_receive_channel.config.example_payload)
|
|
make_mattermost_channel(organization=organization, is_default_channel=True)
|
|
make_mattermost_message(alert_group, MattermostMessage.ALERT_GROUP_MESSAGE)
|
|
make_mattermost_user(user=user)
|
|
user_notification_policy = make_user_notification_policy(
|
|
user=user,
|
|
step=UserNotificationPolicy.Step.NOTIFY,
|
|
notify_by=UserNotificationPolicy.NotificationChannel.TESTONLY,
|
|
)
|
|
|
|
with patch("apps.mattermost.client.MattermostClient.create_post") as mock_post_call:
|
|
notify_user_about_alert_async(
|
|
user_pk=123, alert_group_pk=alert_group.pk, notification_policy_pk=user_notification_policy.pk
|
|
)
|
|
|
|
mock_post_call.assert_not_called()
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_notify_user_about_alert_async_alert_does_not_exist(
|
|
make_organization_and_user,
|
|
make_mattermost_channel,
|
|
make_mattermost_user,
|
|
make_user_notification_policy,
|
|
):
|
|
organization, user = make_organization_and_user()
|
|
make_mattermost_channel(organization=organization, is_default_channel=True)
|
|
make_mattermost_user(user=user)
|
|
user_notification_policy = make_user_notification_policy(
|
|
user=user,
|
|
step=UserNotificationPolicy.Step.NOTIFY,
|
|
notify_by=UserNotificationPolicy.NotificationChannel.TESTONLY,
|
|
)
|
|
|
|
with patch("apps.mattermost.client.MattermostClient.create_post") as mock_post_call:
|
|
notify_user_about_alert_async(
|
|
user_pk=user.pk, alert_group_pk=123, notification_policy_pk=user_notification_policy.pk
|
|
)
|
|
|
|
mock_post_call.assert_not_called()
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_notify_user_about_alert_async_notification_policy_does_not_exist(
|
|
make_organization_and_user,
|
|
make_alert_receive_channel,
|
|
make_alert_group,
|
|
make_alert,
|
|
make_mattermost_channel,
|
|
make_mattermost_message,
|
|
make_mattermost_user,
|
|
):
|
|
organization, user = make_organization_and_user()
|
|
|
|
alert_receive_channel = make_alert_receive_channel(organization)
|
|
alert_group = make_alert_group(alert_receive_channel)
|
|
make_alert(alert_group=alert_group, raw_request_data=alert_receive_channel.config.example_payload)
|
|
make_mattermost_channel(organization=organization, is_default_channel=True)
|
|
make_mattermost_message(alert_group, MattermostMessage.ALERT_GROUP_MESSAGE)
|
|
make_mattermost_user(user=user)
|
|
|
|
with patch("apps.mattermost.client.MattermostClient.create_post") as mock_post_call:
|
|
notify_user_about_alert_async(user_pk=user.pk, alert_group_pk=alert_group.pk, notification_policy_pk=123)
|
|
|
|
mock_post_call.assert_not_called()
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_notify_user_about_alert_async_mattermost_message_does_not_exist(
|
|
make_organization_and_user,
|
|
make_alert_receive_channel,
|
|
make_alert_group,
|
|
make_alert,
|
|
make_mattermost_channel,
|
|
make_mattermost_user,
|
|
make_user_notification_policy,
|
|
):
|
|
organization, user = make_organization_and_user()
|
|
|
|
alert_receive_channel = make_alert_receive_channel(organization)
|
|
alert_group = make_alert_group(alert_receive_channel)
|
|
make_alert(alert_group=alert_group, raw_request_data=alert_receive_channel.config.example_payload)
|
|
make_mattermost_channel(organization=organization, is_default_channel=True)
|
|
make_mattermost_user(user=user)
|
|
user_notification_policy = make_user_notification_policy(
|
|
user=user,
|
|
step=UserNotificationPolicy.Step.NOTIFY,
|
|
notify_by=UserNotificationPolicy.NotificationChannel.TESTONLY,
|
|
)
|
|
|
|
with pytest.raises(MattermostMessage.DoesNotExist):
|
|
notify_user_about_alert_async(
|
|
user_pk=user.pk, alert_group_pk=alert_group.pk, notification_policy_pk=user_notification_policy.pk
|
|
)
|
|
|
|
|
|
@pytest.mark.django_db
|
|
@httpretty.activate(verbose=True, allow_net_connect=False)
|
|
def test_notify_user_about_alert_async_mattermost_user_does_not_exist(
|
|
make_organization_and_user,
|
|
make_alert_receive_channel,
|
|
make_alert_group,
|
|
make_alert,
|
|
make_mattermost_channel,
|
|
make_mattermost_message,
|
|
make_user_notification_policy,
|
|
make_mattermost_post_response,
|
|
):
|
|
organization, user = make_organization_and_user()
|
|
|
|
alert_receive_channel = make_alert_receive_channel(organization)
|
|
alert_group = make_alert_group(alert_receive_channel)
|
|
make_alert(alert_group=alert_group, raw_request_data=alert_receive_channel.config.example_payload)
|
|
make_mattermost_channel(organization=organization, is_default_channel=True)
|
|
make_mattermost_message(alert_group, MattermostMessage.ALERT_GROUP_MESSAGE)
|
|
user_notification_policy = make_user_notification_policy(
|
|
user=user,
|
|
step=UserNotificationPolicy.Step.NOTIFY,
|
|
notify_by=UserNotificationPolicy.NotificationChannel.TESTONLY,
|
|
)
|
|
|
|
url = "{}/api/v4/posts".format(settings.MATTERMOST_HOST)
|
|
data = make_mattermost_post_response()
|
|
mock_response = httpretty.Response(json.dumps(data), status=status.HTTP_200_OK)
|
|
httpretty.register_uri(httpretty.POST, url, responses=[mock_response])
|
|
|
|
notify_user_about_alert_async(
|
|
user_pk=user.pk, alert_group_pk=alert_group.pk, notification_policy_pk=user_notification_policy.pk
|
|
)
|
|
|
|
assert alert_group.personal_log_records.filter(
|
|
notification_error_code=UserNotificationPolicyLogRecord.ERROR_NOTIFICATION_IN_MATTERMOST_USER_NOT_IN_MATTERMOST
|
|
).exists()
|
|
log_record = alert_group.personal_log_records.last()
|
|
assert log_record.type == UserNotificationPolicyLogRecord.TYPE_PERSONAL_NOTIFICATION_SUCCESS
|
|
assert log_record.alert_group.pk == alert_group.pk
|
|
|
|
|
|
@pytest.mark.django_db
|
|
@httpretty.activate(verbose=True, allow_net_connect=False)
|
|
@pytest.mark.parametrize("status_code", [400, 401])
|
|
def test_notify_user_about_alert_async_api_failure(
|
|
make_organization_and_user,
|
|
make_alert_receive_channel,
|
|
make_alert_group,
|
|
make_alert,
|
|
make_mattermost_channel,
|
|
make_mattermost_message,
|
|
make_mattermost_post_response_failure,
|
|
make_user_notification_policy,
|
|
make_mattermost_user,
|
|
status_code,
|
|
):
|
|
organization, user = make_organization_and_user()
|
|
alert_receive_channel = make_alert_receive_channel(organization)
|
|
alert_group = make_alert_group(alert_receive_channel)
|
|
make_alert(alert_group=alert_group, raw_request_data=alert_receive_channel.config.example_payload)
|
|
make_mattermost_channel(organization=organization, is_default_channel=True)
|
|
make_mattermost_message(alert_group, MattermostMessage.ALERT_GROUP_MESSAGE)
|
|
make_mattermost_user(user=user)
|
|
user_notification_policy = make_user_notification_policy(
|
|
user=user,
|
|
step=UserNotificationPolicy.Step.NOTIFY,
|
|
notify_by=UserNotificationPolicy.NotificationChannel.TESTONLY,
|
|
)
|
|
|
|
url = "{}/api/v4/posts".format(settings.MATTERMOST_HOST)
|
|
data = make_mattermost_post_response_failure(status_code=status_code)
|
|
mock_response = httpretty.Response(json.dumps(data), status=status_code)
|
|
httpretty.register_uri(httpretty.POST, url, status=status_code, responses=[mock_response])
|
|
|
|
if status_code != 401:
|
|
with pytest.raises(MattermostAPIException):
|
|
notify_user_about_alert_async(
|
|
user_pk=user.pk, alert_group_pk=alert_group.pk, notification_policy_pk=user_notification_policy.pk
|
|
)
|
|
else:
|
|
notify_user_about_alert_async(
|
|
user_pk=user.pk, alert_group_pk=alert_group.pk, notification_policy_pk=user_notification_policy.pk
|
|
)
|
|
log_record = alert_group.personal_log_records.last()
|
|
assert (
|
|
log_record.notification_error_code
|
|
== UserNotificationPolicyLogRecord.ERROR_NOTIFICATION_IN_MATTERMOST_API_UNAUTHORIZED
|
|
)
|
|
|
|
last_request = httpretty.last_request()
|
|
assert last_request.method == "POST"
|
|
assert last_request.url == url
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_notify_user_about_alert_async_skip_post_for_no_channel(
|
|
make_organization_and_user,
|
|
make_alert_receive_channel,
|
|
make_alert_group,
|
|
make_alert,
|
|
make_mattermost_message,
|
|
make_mattermost_user,
|
|
make_user_notification_policy,
|
|
):
|
|
organization, user = make_organization_and_user()
|
|
alert_receive_channel = make_alert_receive_channel(organization)
|
|
alert_group = make_alert_group(alert_receive_channel)
|
|
make_alert(alert_group=alert_group, raw_request_data=alert_receive_channel.config.example_payload)
|
|
make_mattermost_message(alert_group, MattermostMessage.ALERT_GROUP_MESSAGE)
|
|
make_mattermost_user(user=user)
|
|
user_notification_policy = make_user_notification_policy(
|
|
user=user,
|
|
step=UserNotificationPolicy.Step.NOTIFY,
|
|
notify_by=UserNotificationPolicy.NotificationChannel.TESTONLY,
|
|
)
|
|
|
|
with patch("apps.mattermost.client.MattermostClient.create_post") as mock_post_call:
|
|
notify_user_about_alert_async(
|
|
user_pk=user.pk, alert_group_pk=alert_group.pk, notification_policy_pk=user_notification_policy.pk
|
|
)
|
|
|
|
mock_post_call.assert_not_called()
|