Repository: getsentry/sentry

Issue:
Refactor alerting integration tests
Consolidate repeated logic in tests for issue alerting integrations.

https://github.com/getsentry/sentry/pull/42110#pullrequestreview-1212114551


Discussion:

Resolving patch:
diff --git a/src/sentry/testutils/cases.py b/src/sentry/testutils/cases.py
--- a/src/sentry/testutils/cases.py
+++ b/src/sentry/testutils/cases.py
@@ -31,7 +31,6 @@
     "ReplaysSnubaTestCase",
     "MonitorTestCase",
 )
-
 import hashlib
 import inspect
 import os.path
@@ -127,6 +126,7 @@
 from sentry.tagstore.snuba import SnubaTagStorage
 from sentry.testutils.factories import get_fixture_path
 from sentry.testutils.helpers.datetime import before_now, iso_format
+from sentry.testutils.helpers.notifications import TEST_ISSUE_OCCURRENCE
 from sentry.testutils.helpers.slack import install_slack
 from sentry.types.integrations import ExternalProviders
 from sentry.types.issues import GroupType
@@ -2062,6 +2062,29 @@ def setUp(self):
         self.name = self.user.get_display_name()
         self.short_id = self.group.qualified_short_id
 
+    def assert_performance_issue_attachments(
+        self, attachment, project_slug, referrer, alert_type="workflow"
+    ):
+        assert attachment["title"] == "N+1 Query"
+        assert (
+            attachment["text"]
+            == "db - SELECT `books_author`.`id`, `books_author`.`name` FROM `books_author` WHERE `books_author`.`id` = %s LIMIT 21"
+        )
+        assert (
+            attachment["footer"]
+            == f"{project_slug} | production | <http://testserver/settings/account/notifications/{alert_type}/?referrer={referrer}|Notification Settings>"
+        )
+
+    def assert_generic_issue_attachments(
+        self, attachment, project_slug, referrer, alert_type="workflow"
+    ):
+        assert attachment["title"] == TEST_ISSUE_OCCURRENCE.issue_title
+        assert attachment["text"] == TEST_ISSUE_OCCURRENCE.evidence_display[0].value
+        assert (
+            attachment["footer"]
+            == f"{project_slug} | <http://testserver/settings/account/notifications/{alert_type}/?referrer={referrer}|Notification Settings>"
+        )
+
 
 class MSTeamsActivityNotificationTest(ActivityTestCase):
     def setUp(self):


Test patch:
diff --git a/tests/sentry/integrations/slack/notifications/test_assigned.py b/tests/sentry/integrations/slack/notifications/test_assigned.py
--- a/tests/sentry/integrations/slack/notifications/test_assigned.py
+++ b/tests/sentry/integrations/slack/notifications/test_assigned.py
@@ -13,6 +13,17 @@
 
 
 class SlackAssignedNotificationTest(SlackActivityNotificationTest, PerformanceIssueTestCase):
+    def create_notification(self, group, notification):
+        return notification(
+            Activity(
+                project=self.project,
+                group=group,
+                user=self.user,
+                type=ActivityType.ASSIGNED,
+                data={"assignee": self.user.id},
+            )
+        )
+
     @responses.activate
     @mock.patch("sentry.notifications.notify.notify", side_effect=send_notification)
     def test_multiple_identities(self, mock_func):
@@ -46,17 +57,8 @@ def test_multiple_identities(self, mock_func):
             content_type="application/json",
         )
 
-        notification = AssignedActivityNotification(
-            Activity(
-                project=self.project,
-                group=self.group,
-                user=self.user,
-                type=ActivityType.ASSIGNED,
-                data={"assignee": self.user.id},
-            )
-        )
         with self.tasks():
-            notification.send()
+            self.create_notification(self.group, AssignedActivityNotification).send()
 
         assert len(responses.calls) >= 2
         data = parse_qs(responses.calls[0].request.body)
@@ -104,17 +106,8 @@ def test_multiple_orgs(self, mock_func):
             content_type="application/json",
         )
 
-        notification = AssignedActivityNotification(
-            Activity(
-                project=self.project,
-                group=self.group,
-                user=self.user,
-                type=ActivityType.ASSIGNED,
-                data={"assignee": self.user.id},
-            )
-        )
         with self.tasks():
-            notification.send()
+            self.create_notification(self.group, AssignedActivityNotification).send()
 
         assert len(responses.calls) == 1
         data = parse_qs(responses.calls[0].request.body)
@@ -128,17 +121,8 @@ def test_assignment(self, mock_func):
         """
         Test that a Slack message is sent with the expected payload when an issue is assigned
         """
-        notification = AssignedActivityNotification(
-            Activity(
-                project=self.project,
-                group=self.group,
-                user=self.user,
-                type=ActivityType.ASSIGNED,
-                data={"assignee": self.user.id},
-            )
-        )
         with self.tasks():
-            notification.send()
+            self.create_notification(self.group, AssignedActivityNotification).send()
         attachment, text = get_attachment()
         assert text == f"Issue assigned to {self.name} by themselves"
         assert attachment["title"] == self.group.title
@@ -163,24 +147,12 @@ def test_assignment_generic_issue(self, mock_func, occurrence):
         )
         event = event.for_group(event.groups[0])
 
-        notification = AssignedActivityNotification(
-            Activity(
-                project=self.project,
-                group=event.group,
-                user=self.user,
-                type=ActivityType.ASSIGNED,
-                data={"assignee": self.user.id},
-            )
-        )
         with self.tasks():
-            notification.send()
+            self.create_notification(event.group, AssignedActivityNotification).send()
         attachment, text = get_attachment()
         assert text == f"Issue assigned to {self.name} by themselves"
-        assert attachment["title"] == TEST_ISSUE_OCCURRENCE.issue_title
-        assert attachment["text"] == TEST_ISSUE_OCCURRENCE.evidence_display[0].value
-        assert (
-            attachment["footer"]
-            == f"{self.project.slug} | <http://testserver/settings/account/notifications/workflow/?referrer=assigned_activity-slack-user|Notification Settings>"
+        self.assert_generic_issue_attachments(
+            attachment, self.project.slug, "assigned_activity-slack-user"
         )
 
     @responses.activate
@@ -190,28 +162,13 @@ def test_assignment_performance_issue(self, mock_func):
         Test that a Slack message is sent with the expected payload when a performance issue is assigned
         """
         event = self.create_performance_issue()
-        notification = AssignedActivityNotification(
-            Activity(
-                project=self.project,
-                group=event.group,
-                user=self.user,
-                type=ActivityType.ASSIGNED,
-                data={"assignee": self.user.id},
-            )
-        )
         with self.tasks():
-            notification.send()
+            self.create_notification(event.group, AssignedActivityNotification).send()
 
         attachment, text = get_attachment()
         assert text == f"Issue assigned to {self.name} by themselves"
-        assert attachment["title"] == "N+1 Query"
-        assert (
-            attachment["text"]
-            == "db - SELECT `books_author`.`id`, `books_author`.`name` FROM `books_author` WHERE `books_author`.`id` = %s LIMIT 21"
-        )
-        assert (
-            attachment["footer"]
-            == f"{self.project.slug} | production | <http://testserver/settings/account/notifications/workflow/?referrer=assigned_activity-slack-user|Notification Settings>"
+        self.assert_performance_issue_attachments(
+            attachment, self.project.slug, "assigned_activity-slack-user"
         )
 
     def test_automatic_assignment(self):
diff --git a/tests/sentry/integrations/slack/notifications/test_issue_alert.py b/tests/sentry/integrations/slack/notifications/test_issue_alert.py
--- a/tests/sentry/integrations/slack/notifications/test_issue_alert.py
+++ b/tests/sentry/integrations/slack/notifications/test_issue_alert.py
@@ -93,14 +93,8 @@ def test_performance_issue_alert_user(self, mock_func):
             notification.send()
 
         attachment, text = get_attachment()
-        assert attachment["title"] == "N+1 Query"
-        assert (
-            attachment["text"]
-            == "db - SELECT `books_author`.`id`, `books_author`.`name` FROM `books_author` WHERE `books_author`.`id` = %s LIMIT 21"
-        )
-        assert (
-            attachment["footer"]
-            == f"{self.project.slug} | production | <http://testserver/settings/account/notifications/alerts/?referrer=issue_alert-slack-user|Notification Settings>"
+        self.assert_performance_issue_attachments(
+            attachment, self.project.slug, "issue_alert-slack-user", "alerts"
         )
 
     @responses.activate
@@ -124,11 +118,8 @@ def test_generic_issue_alert_user(self, mock_func, occurrence):
             notification.send()
 
         attachment, text = get_attachment()
-        assert attachment["title"] == TEST_ISSUE_OCCURRENCE.issue_title
-        assert attachment["text"] == TEST_ISSUE_OCCURRENCE.evidence_display[0].value
-        assert (
-            attachment["footer"]
-            == f"{self.project.slug} | <http://testserver/settings/account/notifications/alerts/?referrer=issue_alert-slack-user|Notification Settings>"
+        self.assert_generic_issue_attachments(
+            attachment, self.project.slug, "issue_alert-slack-user", "alerts"
         )
 
     @responses.activate
diff --git a/tests/sentry/integrations/slack/notifications/test_note.py b/tests/sentry/integrations/slack/notifications/test_note.py
--- a/tests/sentry/integrations/slack/notifications/test_note.py
+++ b/tests/sentry/integrations/slack/notifications/test_note.py
@@ -11,21 +11,24 @@
 
 
 class SlackNoteNotificationTest(SlackActivityNotificationTest, PerformanceIssueTestCase):
-    @responses.activate
-    @mock.patch("sentry.notifications.notify.notify", side_effect=send_notification)
-    def test_note(self, mock_func):
-        """
-        Test that a Slack message is sent with the expected payload when a comment is made on an issue
-        """
-        notification = NoteActivityNotification(
+    def create_notification(self, group):
+        return NoteActivityNotification(
             Activity(
                 project=self.project,
-                group=self.group,
+                group=group,
                 user=self.user,
                 type=ActivityType.NOTE,
                 data={"text": "text", "mentions": []},
             )
         )
+
+    @responses.activate
+    @mock.patch("sentry.notifications.notify.notify", side_effect=send_notification)
+    def test_note(self, mock_func):
+        """
+        Test that a Slack message is sent with the expected payload when a comment is made on an issue
+        """
+        notification = self.create_notification(self.group)
         with self.tasks():
             notification.send()
 
@@ -50,15 +53,8 @@ def test_note_performance_issue(self, mock_func):
         Test that a Slack message is sent with the expected payload when a comment is made on a performance issue
         """
         event = self.create_performance_issue()
-        notification = NoteActivityNotification(
-            Activity(
-                project=self.project,
-                group=event.group,
-                user=self.user,
-                type=ActivityType.NOTE,
-                data={"text": "text", "mentions": []},
-            )
-        )
+        notification = self.create_notification(event.group)
+
         with self.tasks():
             notification.send()
 
@@ -90,15 +86,8 @@ def test_note_generic_issue(self, mock_func, occurrence):
             data={"message": "Hellboy's world", "level": "error"}, project_id=self.project.id
         )
         event = event.for_group(event.groups[0])
-        notification = NoteActivityNotification(
-            Activity(
-                project=self.project,
-                group=event.group,
-                user=self.user,
-                type=ActivityType.NOTE,
-                data={"text": "text", "mentions": []},
-            )
-        )
+        notification = self.create_notification(event.group)
+
         with self.tasks():
             notification.send()
 
diff --git a/tests/sentry/integrations/slack/notifications/test_regression.py b/tests/sentry/integrations/slack/notifications/test_regression.py
--- a/tests/sentry/integrations/slack/notifications/test_regression.py
+++ b/tests/sentry/integrations/slack/notifications/test_regression.py
@@ -11,23 +11,25 @@
 
 
 class SlackRegressionNotificationTest(SlackActivityNotificationTest, PerformanceIssueTestCase):
-    @responses.activate
-    @mock.patch("sentry.notifications.notify.notify", side_effect=send_notification)
-    def test_regression(self, mock_func):
-        """
-        Test that a Slack message is sent with the expected payload when an issue regresses
-        """
-        notification = RegressionActivityNotification(
+    def create_notification(self, group):
+        return RegressionActivityNotification(
             Activity(
                 project=self.project,
-                group=self.group,
+                group=group,
                 user=self.user,
                 type=ActivityType.SET_REGRESSION,
                 data={},
             )
         )
+
+    @responses.activate
+    @mock.patch("sentry.notifications.notify.notify", side_effect=send_notification)
+    def test_regression(self, mock_func):
+        """
+        Test that a Slack message is sent with the expected payload when an issue regresses
+        """
         with self.tasks():
-            notification.send()
+            self.create_notification(self.group).send()
 
         attachment, text = get_attachment()
         assert text == "Issue marked as regression"
@@ -45,28 +47,13 @@ def test_regression_performance_issue(self, mock_func):
         Test that a Slack message is sent with the expected payload when a performance issue regresses
         """
         event = self.create_performance_issue()
-        notification = RegressionActivityNotification(
-            Activity(
-                project=self.project,
-                group=event.group,
-                user=self.user,
-                type=ActivityType.SET_REGRESSION,
-                data={},
-            )
-        )
         with self.tasks():
-            notification.send()
+            self.create_notification(event.group).send()
 
         attachment, text = get_attachment()
         assert text == "Issue marked as regression"
-        assert attachment["title"] == "N+1 Query"
-        assert (
-            attachment["text"]
-            == "db - SELECT `books_author`.`id`, `books_author`.`name` FROM `books_author` WHERE `books_author`.`id` = %s LIMIT 21"
-        )
-        assert (
-            attachment["footer"]
-            == f"{self.project.slug} | production | <http://testserver/settings/account/notifications/workflow/?referrer=regression_activity-slack-user|Notification Settings>"
+        self.assert_performance_issue_attachments(
+            attachment, self.project.slug, "regression_activity-slack-user"
         )
 
     @responses.activate
@@ -84,23 +71,12 @@ def test_regression_generic_issue(self, mock_func, occurrence):
             data={"message": "Hellboy's world", "level": "error"}, project_id=self.project.id
         )
         event = event.for_group(event.groups[0])
-        notification = RegressionActivityNotification(
-            Activity(
-                project=self.project,
-                group=event.group,
-                user=self.user,
-                type=ActivityType.SET_REGRESSION,
-                data={},
-            )
-        )
+
         with self.tasks():
-            notification.send()
+            self.create_notification(event.group).send()
 
         attachment, text = get_attachment()
         assert text == "Issue marked as regression"
-        assert attachment["title"] == TEST_ISSUE_OCCURRENCE.issue_title
-        assert attachment["text"] == TEST_ISSUE_OCCURRENCE.evidence_display[0].value
-        assert (
-            attachment["footer"]
-            == f"{self.project.slug} | <http://testserver/settings/account/notifications/workflow/?referrer=regression_activity-slack-user|Notification Settings>"
+        self.assert_generic_issue_attachments(
+            attachment, self.project.slug, "regression_activity-slack-user"
         )
diff --git a/tests/sentry/integrations/slack/notifications/test_resolved.py b/tests/sentry/integrations/slack/notifications/test_resolved.py
--- a/tests/sentry/integrations/slack/notifications/test_resolved.py
+++ b/tests/sentry/integrations/slack/notifications/test_resolved.py
@@ -11,23 +11,25 @@
 
 
 class SlackResolvedNotificationTest(SlackActivityNotificationTest, PerformanceIssueTestCase):
-    @responses.activate
-    @mock.patch("sentry.notifications.notify.notify", side_effect=send_notification)
-    def test_resolved(self, mock_func):
-        """
-        Test that a Slack message is sent with the expected payload when an issue is resolved
-        """
-        notification = ResolvedActivityNotification(
+    def create_notification(self, group):
+        return ResolvedActivityNotification(
             Activity(
                 project=self.project,
-                group=self.group,
+                group=group,
                 user=self.user,
                 type=ActivityType.SET_RESOLVED,
                 data={"assignee": ""},
             )
         )
+
+    @responses.activate
+    @mock.patch("sentry.notifications.notify.notify", side_effect=send_notification)
+    def test_resolved(self, mock_func):
+        """
+        Test that a Slack message is sent with the expected payload when an issue is resolved
+        """
         with self.tasks():
-            notification.send()
+            self.create_notification(self.group).send()
 
         attachment, text = get_attachment()
         assert (
@@ -46,31 +48,16 @@ def test_resolved_performance_issue(self, mock_func):
         Test that a Slack message is sent with the expected payload when a performance issue is resolved
         """
         event = self.create_performance_issue()
-        notification = ResolvedActivityNotification(
-            Activity(
-                project=self.project,
-                group=event.group,
-                user=self.user,
-                type=ActivityType.SET_RESOLVED,
-                data={"assignee": ""},
-            )
-        )
         with self.tasks():
-            notification.send()
+            self.create_notification(event.group).send()
 
         attachment, text = get_attachment()
         assert (
             text
             == f"{self.name} marked <http://testserver/organizations/{self.organization.slug}/issues/{event.group.id}/?referrer=activity_notification|{self.project.slug.upper()}-{event.group.short_id}> as resolved"
         )
-        assert attachment["title"] == "N+1 Query"
-        assert (
-            attachment["text"]
-            == "db - SELECT `books_author`.`id`, `books_author`.`name` FROM `books_author` WHERE `books_author`.`id` = %s LIMIT 21"
-        )
-        assert (
-            attachment["footer"]
-            == f"{self.project.slug} | production | <http://testserver/settings/account/notifications/workflow/?referrer=resolved_activity-slack-user|Notification Settings>"
+        self.assert_performance_issue_attachments(
+            attachment, self.project.slug, "resolved_activity-slack-user"
         )
 
     @responses.activate
@@ -88,26 +75,14 @@ def test_resolved_generic_issue(self, mock_func, occurrence):
             data={"message": "Hellboy's world", "level": "error"}, project_id=self.project.id
         )
         event = event.for_group(event.groups[0])
-        notification = ResolvedActivityNotification(
-            Activity(
-                project=self.project,
-                group=event.group,
-                user=self.user,
-                type=ActivityType.SET_RESOLVED,
-                data={"assignee": ""},
-            )
-        )
         with self.tasks():
-            notification.send()
+            self.create_notification(event.group).send()
 
         attachment, text = get_attachment()
         assert (
             text
             == f"{self.name} marked <http://testserver/organizations/{self.organization.slug}/issues/{event.group.id}/?referrer=activity_notification|{self.project.slug.upper()}-{event.group.short_id}> as resolved"
         )
-        assert attachment["title"] == TEST_ISSUE_OCCURRENCE.issue_title
-        assert attachment["text"] == TEST_ISSUE_OCCURRENCE.evidence_display[0].value
-        assert (
-            attachment["footer"]
-            == f"{self.project.slug} | <http://testserver/settings/account/notifications/workflow/?referrer=resolved_activity-slack-user|Notification Settings>"
+        self.assert_generic_issue_attachments(
+            attachment, self.project.slug, "resolved_activity-slack-user"
         )
diff --git a/tests/sentry/integrations/slack/notifications/test_resolved_in_release.py b/tests/sentry/integrations/slack/notifications/test_resolved_in_release.py
--- a/tests/sentry/integrations/slack/notifications/test_resolved_in_release.py
+++ b/tests/sentry/integrations/slack/notifications/test_resolved_in_release.py
@@ -13,21 +13,24 @@
 class SlackResolvedInReleaseNotificationTest(
     SlackActivityNotificationTest, PerformanceIssueTestCase
 ):
-    @responses.activate
-    @mock.patch("sentry.notifications.notify.notify", side_effect=send_notification)
-    def test_resolved_in_release(self, mock_func):
-        """
-        Test that a Slack message is sent with the expected payload when an issue is resolved in a release
-        """
-        notification = ResolvedInReleaseActivityNotification(
+    def create_notification(self, group):
+        return ResolvedInReleaseActivityNotification(
             Activity(
                 project=self.project,
-                group=self.group,
+                group=group,
                 user=self.user,
                 type=ActivityType.SET_RESOLVED_IN_RELEASE,
                 data={"version": "meow"},
             )
         )
+
+    @responses.activate
+    @mock.patch("sentry.notifications.notify.notify", side_effect=send_notification)
+    def test_resolved_in_release(self, mock_func):
+        """
+        Test that a Slack message is sent with the expected payload when an issue is resolved in a release
+        """
+        notification = self.create_notification(self.group)
         with self.tasks():
             notification.send()
 
@@ -46,29 +49,15 @@ def test_resolved_in_release_performance_issue(self, mock_func):
         Test that a Slack message is sent with the expected payload when a performance issue is resolved in a release
         """
         event = self.create_performance_issue()
-        notification = ResolvedInReleaseActivityNotification(
-            Activity(
-                project=self.project,
-                group=event.group,
-                user=self.user,
-                type=ActivityType.SET_RESOLVED_IN_RELEASE,
-                data={"version": "meow"},
-            )
-        )
+        notification = self.create_notification(event.group)
         with self.tasks():
             notification.send()
 
         attachment, text = get_attachment()
         release_name = notification.activity.data["version"]
         assert text == f"Issue marked as resolved in {release_name} by {self.name}"
-        assert attachment["title"] == "N+1 Query"
-        assert (
-            attachment["text"]
-            == "db - SELECT `books_author`.`id`, `books_author`.`name` FROM `books_author` WHERE `books_author`.`id` = %s LIMIT 21"
-        )
-        assert (
-            attachment["footer"]
-            == f"{self.project.slug} | production | <http://testserver/settings/account/notifications/workflow/?referrer=resolved_in_release_activity-slack-user|Notification Settings>"
+        self.assert_performance_issue_attachments(
+            attachment, self.project.slug, "resolved_in_release_activity-slack-user"
         )
 
     @responses.activate
@@ -86,24 +75,13 @@ def test_resolved_in_release_generic_issue(self, mock_func, occurrence):
             data={"message": "Hellboy's world", "level": "error"}, project_id=self.project.id
         )
         event = event.for_group(event.groups[0])
-        notification = ResolvedInReleaseActivityNotification(
-            Activity(
-                project=self.project,
-                group=event.group,
-                user=self.user,
-                type=ActivityType.SET_RESOLVED_IN_RELEASE,
-                data={"version": "meow"},
-            )
-        )
+        notification = self.create_notification(event.group)
         with self.tasks():
             notification.send()
 
         attachment, text = get_attachment()
         release_name = notification.activity.data["version"]
         assert text == f"Issue marked as resolved in {release_name} by {self.name}"
-        assert attachment["title"] == TEST_ISSUE_OCCURRENCE.issue_title
-        assert attachment["text"] == TEST_ISSUE_OCCURRENCE.evidence_display[0].value
-        assert (
-            attachment["footer"]
-            == f"{self.project.slug} | <http://testserver/settings/account/notifications/workflow/?referrer=resolved_in_release_activity-slack-user|Notification Settings>"
+        self.assert_generic_issue_attachments(
+            attachment, self.project.slug, "resolved_in_release_activity-slack-user"
         )
diff --git a/tests/sentry/integrations/slack/notifications/test_unassigned.py b/tests/sentry/integrations/slack/notifications/test_unassigned.py
--- a/tests/sentry/integrations/slack/notifications/test_unassigned.py
+++ b/tests/sentry/integrations/slack/notifications/test_unassigned.py
@@ -11,23 +11,25 @@
 
 
 class SlackUnassignedNotificationTest(SlackActivityNotificationTest, PerformanceIssueTestCase):
-    @responses.activate
-    @mock.patch("sentry.notifications.notify.notify", side_effect=send_notification)
-    def test_unassignment(self, mock_func):
-        """
-        Test that a Slack message is sent with the expected payload when an issue is unassigned
-        """
-        notification = UnassignedActivityNotification(
+    def create_notification(self, group):
+        return UnassignedActivityNotification(
             Activity(
                 project=self.project,
-                group=self.group,
+                group=group,
                 user=self.user,
                 type=ActivityType.ASSIGNED,
                 data={"assignee": ""},
             )
         )
+
+    @responses.activate
+    @mock.patch("sentry.notifications.notify.notify", side_effect=send_notification)
+    def test_unassignment(self, mock_func):
+        """
+        Test that a Slack message is sent with the expected payload when an issue is unassigned
+        """
         with self.tasks():
-            notification.send()
+            self.create_notification(self.group).send()
 
         attachment, text = get_attachment()
         assert text == f"Issue unassigned by {self.name}"
@@ -44,28 +46,13 @@ def test_unassignment_performance_issue(self, mock_func):
         Test that a Slack message is sent with the expected payload when a performance issue is unassigned
         """
         event = self.create_performance_issue()
-        notification = UnassignedActivityNotification(
-            Activity(
-                project=self.project,
-                group=event.group,
-                user=self.user,
-                type=ActivityType.ASSIGNED,
-                data={"assignee": ""},
-            )
-        )
         with self.tasks():
-            notification.send()
+            self.create_notification(event.group).send()
 
         attachment, text = get_attachment()
         assert text == f"Issue unassigned by {self.name}"
-        assert attachment["title"] == "N+1 Query"
-        assert (
-            attachment["text"]
-            == "db - SELECT `books_author`.`id`, `books_author`.`name` FROM `books_author` WHERE `books_author`.`id` = %s LIMIT 21"
-        )
-        assert (
-            attachment["footer"]
-            == f"{self.project.slug} | production | <http://testserver/settings/account/notifications/workflow/?referrer=unassigned_activity-slack-user|Notification Settings>"
+        self.assert_performance_issue_attachments(
+            attachment, self.project.slug, "unassigned_activity-slack-user"
         )
 
     @responses.activate
@@ -83,23 +70,11 @@ def test_unassignment_generic_issue(self, mock_func, occurrence):
             data={"message": "Hellboy's world", "level": "error"}, project_id=self.project.id
         )
         event = event.for_group(event.groups[0])
-        notification = UnassignedActivityNotification(
-            Activity(
-                project=self.project,
-                group=event.group,
-                user=self.user,
-                type=ActivityType.ASSIGNED,
-                data={"assignee": ""},
-            )
-        )
         with self.tasks():
-            notification.send()
+            self.create_notification(event.group).send()
 
         attachment, text = get_attachment()
         assert text == f"Issue unassigned by {self.name}"
-        assert attachment["title"] == TEST_ISSUE_OCCURRENCE.issue_title
-        assert attachment["text"] == TEST_ISSUE_OCCURRENCE.evidence_display[0].value
-        assert (
-            attachment["footer"]
-            == f"{self.project.slug} | <http://testserver/settings/account/notifications/workflow/?referrer=unassigned_activity-slack-user|Notification Settings>"
+        self.assert_generic_issue_attachments(
+            attachment, self.project.slug, "unassigned_activity-slack-user"
         )