Repository: getsentry/sentry

Issue:
Add check to default notifications for rule snooze
We will want to check to see if the alert is being snoozed + how it is being snoozed to determine if we send out the default notification for the metric alert. Tests will be very important here to make sure we are correctly muting the alert. 

Similar PR from V1 of Mute Alerts: https://github.com/getsentry/sentry/commit/0e779826e56f69c1e247943fc46a5754bee6039d


Discussion:

Resolving patch:
diff --git a/src/sentry/incidents/action_handlers.py b/src/sentry/incidents/action_handlers.py
--- a/src/sentry/incidents/action_handlers.py
+++ b/src/sentry/incidents/action_handlers.py
@@ -19,6 +19,7 @@
     IncidentStatus,
     TriggerStatus,
 )
+from sentry.models import RuleSnooze
 from sentry.models.notificationsetting import NotificationSetting
 from sentry.models.options.user_option import UserOption
 from sentry.models.user import User
@@ -68,7 +69,17 @@ def _get_targets(self) -> Set[int]:
         if not target:
             return set()
 
+        if RuleSnooze.objects.filter(
+            alert_rule=self.incident.alert_rule, user_id__isnull=True
+        ).exists():
+            return set()
+
         if self.action.target_type == AlertRuleTriggerAction.TargetType.USER.value:
+            if RuleSnooze.objects.filter(
+                alert_rule=self.incident.alert_rule, user_id=target.id
+            ).exists():
+                return set()
+
             return {target.id}
 
         elif self.action.target_type == AlertRuleTriggerAction.TargetType.TEAM.value:
@@ -76,7 +87,10 @@ def _get_targets(self) -> Set[int]:
                 self.project,
                 {RpcUser(id=member.user_id) for member in target.member_set},
             )[ExternalProviders.EMAIL]
-            return {user.id for user in users}
+            snoozed_users = RuleSnooze.objects.filter(
+                alert_rule=self.incident.alert_rule, user_id__in=[user.id for user in users]
+            ).values_list("user_id", flat=True)
+            return {user.id for user in users if user.id not in snoozed_users}
 
         return set()
 


Test patch:
diff --git a/tests/sentry/incidents/action_handlers/test_email.py b/tests/sentry/incidents/action_handlers/test_email.py
--- a/tests/sentry/incidents/action_handlers/test_email.py
+++ b/tests/sentry/incidents/action_handlers/test_email.py
@@ -23,6 +23,7 @@
     TriggerStatus,
 )
 from sentry.models import NotificationSetting, UserEmail, UserOption
+from sentry.models.rulesnooze import RuleSnooze
 from sentry.notifications.types import NotificationSettingOptionValues, NotificationSettingTypes
 from sentry.sentry_metrics import indexer
 from sentry.sentry_metrics.use_case_id_registry import UseCaseID
@@ -74,6 +75,24 @@ def test_user(self):
         handler = EmailActionHandler(action, self.incident, self.project)
         assert handler.get_targets() == [(self.user.id, self.user.email)]
 
+    def test_rule_snoozed_by_user(self):
+        action = self.create_alert_rule_trigger_action(
+            target_type=AlertRuleTriggerAction.TargetType.USER,
+            target_identifier=str(self.user.id),
+        )
+        handler = EmailActionHandler(action, self.incident, self.project)
+        RuleSnooze.objects.create(alert_rule=self.incident.alert_rule, user_id=self.user.id)
+        assert handler.get_targets() == []
+
+    def test_user_rule_snoozed(self):
+        action = self.create_alert_rule_trigger_action(
+            target_type=AlertRuleTriggerAction.TargetType.USER,
+            target_identifier=str(self.user.id),
+        )
+        handler = EmailActionHandler(action, self.incident, self.project)
+        RuleSnooze.objects.create(alert_rule=self.incident.alert_rule)
+        assert handler.get_targets() == []
+
     def test_user_alerts_disabled(self):
         NotificationSetting.objects.update_settings(
             ExternalProviders.EMAIL,
@@ -102,6 +121,30 @@ def test_team(self):
             (new_user.id, new_user.email),
         }
 
+    def test_rule_snoozed_by_one_user_in_team(self):
+        new_user = self.create_user()
+        self.create_team_membership(team=self.team, user=new_user)
+        action = self.create_alert_rule_trigger_action(
+            target_type=AlertRuleTriggerAction.TargetType.TEAM,
+            target_identifier=str(self.team.id),
+        )
+        handler = EmailActionHandler(action, self.incident, self.project)
+        RuleSnooze.objects.create(alert_rule=self.incident.alert_rule, user_id=new_user.id)
+        assert set(handler.get_targets()) == {
+            (self.user.id, self.user.email),
+        }
+
+    def test_team_rule_snoozed(self):
+        new_user = self.create_user()
+        self.create_team_membership(team=self.team, user=new_user)
+        action = self.create_alert_rule_trigger_action(
+            target_type=AlertRuleTriggerAction.TargetType.TEAM,
+            target_identifier=str(self.team.id),
+        )
+        handler = EmailActionHandler(action, self.incident, self.project)
+        RuleSnooze.objects.create(alert_rule=self.incident.alert_rule)
+        assert handler.get_targets() == []
+
     def test_team_alert_disabled(self):
         NotificationSetting.objects.update_settings(
             ExternalProviders.EMAIL,