Browse Source

fix serializer alert rule projects (#69276)

Serializer was incorrectly serializing projects for alert rules.

- we were improperly attempting to add an iterable to a set
- we were improperly catchign an exception IF the `.get()` of a model
failed and passing
- We had no tests to validate the serialization
Nathan Hsieh 10 months ago
parent
commit
24e427af0f

+ 6 - 5
src/sentry/api/serializers/models/alert_rule.py

@@ -148,17 +148,18 @@ class AlertRuleSerializer(Serializer):
 
         alert_rule_projects = set()
         for alert_rule in alert_rules.values():
-            try:
-                alert_rule_projects.add([alert_rule.id, alert_rule.projects.get().slug])
-            except Exception:
-                pass
+            if alert_rule.projects.exists():
+                for project in alert_rule.projects.all():
+                    alert_rule_projects.add((alert_rule.id, project.slug))
 
         # TODO - Cleanup Subscription Project Mapping
         snuba_alert_rule_projects = AlertRule.objects.filter(
             id__in=[item.id for item in item_list]
         ).values_list("id", "snuba_query__subscriptions__project__slug")
 
-        alert_rule_projects.update(snuba_alert_rule_projects)
+        alert_rule_projects.update(
+            [(id, project_slug) for id, project_slug in snuba_alert_rule_projects if project_slug]
+        )
 
         for alert_rule_id, project_slug in alert_rule_projects:
             rule_result = result[alert_rules[alert_rule_id]].setdefault("projects", [])

+ 23 - 0
tests/sentry/api/serializers/test_alert_rule.py

@@ -9,6 +9,7 @@ from sentry.incidents.logic import create_alert_rule_trigger, create_alert_rule_
 from sentry.incidents.models.alert_rule import (
     AlertRule,
     AlertRuleMonitorType,
+    AlertRuleProjects,
     AlertRuleThresholdType,
     AlertRuleTriggerAction,
 )
@@ -155,6 +156,28 @@ class AlertRuleSerializerTest(BaseAlertRuleSerializerTest, TestCase):
         assert len(result[0]["activations"]) == 10
         assert len(result[1]["activations"]) == 6
 
+    def test_projects(self):
+        regular_alert_rule = self.create_alert_rule()
+        activated_alert_rule = self.create_alert_rule(monitor_type=AlertRuleMonitorType.ACTIVATED)
+        alert_rule_no_projects = self.create_alert_rule()
+
+        AlertRuleProjects.objects.filter(alert_rule_id=alert_rule_no_projects.id).delete()
+
+        assert activated_alert_rule.projects
+        assert regular_alert_rule.projects
+        assert not alert_rule_no_projects.projects.exists()
+        result = serialize([regular_alert_rule, activated_alert_rule, alert_rule_no_projects])
+
+        assert result[0]["projects"] == [
+            project.slug for project in regular_alert_rule.projects.all()
+        ]
+        assert result[1]["projects"] == [
+            project.slug for project in activated_alert_rule.projects.all()
+        ]
+        assert result[2]["projects"] == [
+            project.slug for project in activated_alert_rule.projects.all()
+        ]
+
     def test_environment(self):
         alert_rule = self.create_alert_rule(environment=self.environment)
         result = serialize(alert_rule)