Browse Source

feat(webhooks):Add a webhook for issue.escalating (#69997)

issue_escalating is already an existing analytics event that gets thrown
but we don't have a webhook for it. So this PR maps a webhook to
issue_escalating signal.
Athena Moghaddam 10 months ago
parent
commit
ed239ed523

+ 1 - 0
src/sentry/issues/escalating.py

@@ -522,6 +522,7 @@ def manage_issue_states(
                 event=event,
                 sender=manage_issue_states,
                 was_until_escalating=True if has_forecast else False,
+                new_substatus=GroupSubStatus.ESCALATING,
             )
             if data and activity_data and has_forecast:  # Redundant checks needed for typing
                 data.update(activity_data)

+ 27 - 1
src/sentry/receivers/sentry_apps.py

@@ -20,6 +20,7 @@ from sentry.signals import (
     comment_deleted,
     comment_updated,
     issue_assigned,
+    issue_escalating,
     issue_ignored,
     issue_resolved,
     issue_unresolved,
@@ -72,7 +73,32 @@ def send_issue_unresolved_webhook(
     user: User | RpcUser | None = None,
     new_substatus: GroupSubStatus | None = None,
     **kwargs,
-):
+) -> None:
+    send_issue_unresolved_webhook_helper(
+        group=group, project=project, user=user, new_substatus=new_substatus, **kwargs
+    )
+
+
+@issue_escalating.connect(weak=False)
+def send_issue_escalating_webhook(
+    group: Group,
+    project: Project,
+    new_substatus: GroupSubStatus | None = None,
+    **kwargs,
+) -> None:
+    # Escalating is a form of unresolved so we send the same webhook
+    send_issue_unresolved_webhook_helper(
+        group=group, project=project, new_substatus=new_substatus, **kwargs
+    )
+
+
+def send_issue_unresolved_webhook_helper(
+    group: Group,
+    project: Project,
+    user: User | RpcUser | None = None,
+    new_substatus: GroupSubStatus | None = None,
+    **kwargs,
+) -> None:
     organization = project.organization
     if features.has("organizations:webhooks-unresolved", organization):
         send_workflow_webhooks(

+ 22 - 0
tests/sentry/receivers/test_sentry_apps.py

@@ -6,11 +6,13 @@ from unittest.mock import patch
 from sentry.api.serializers import serialize
 from sentry.api.serializers.models.user import UserSerializer
 from sentry.constants import SentryAppInstallationStatus
+from sentry.issues.escalating import manage_issue_states
 from sentry.issues.ongoing import bulk_transition_group_to_ongoing
 from sentry.models.activity import Activity
 from sentry.models.commit import Commit
 from sentry.models.group import GroupStatus
 from sentry.models.groupassignee import GroupAssignee
+from sentry.models.groupinbox import GroupInboxReason
 from sentry.models.grouplink import GroupLink
 from sentry.models.release import Release
 from sentry.models.repository import Repository
@@ -98,6 +100,26 @@ class TestIssueWorkflowNotifications(APITestCase):
         )
         assert delay.call_count == 2
 
+    @with_feature("organizations:webhooks-unresolved")
+    def test_notify_after_escalating(self, delay):
+        # First we need to have an ignored issue
+        self.update_issue({"status": "ignored", "substatus": "until_escalating"})
+        event = self.issue.get_latest_event()
+        manage_issue_states(
+            group=self.issue,
+            group_inbox_reason=GroupInboxReason.ESCALATING,
+            event=event,
+            activity_data={},
+        )
+        delay.assert_any_call(
+            installation_id=self.install.id,
+            issue_id=self.issue.id,
+            type="unresolved",
+            user_id=None,
+            data={"substatus": "escalating"},
+        )
+        assert delay.call_count == 2
+
     def test_notify_after_basic_resolved(self, delay):
         self.update_issue()