Browse Source

chore(hybrid-cloud): Allow slack/opsgenie/pagerduty tests to be region by default (#63972)

Last of the integration region-by-default PRs, no hiccups here :shipit:
Leander Rodrigues 1 year ago
parent
commit
93e6d69bfb

+ 6 - 0
src/sentry/testutils/factories.py

@@ -86,6 +86,7 @@ from sentry.models.notificationaction import (
     ActionTrigger,
     NotificationAction,
 )
+from sentry.models.notificationsettingprovider import NotificationSettingProvider
 from sentry.models.organization import Organization
 from sentry.models.organizationmapping import OrganizationMapping
 from sentry.models.organizationmember import OrganizationMember
@@ -1724,6 +1725,11 @@ class Factories:
 
         return action
 
+    @staticmethod
+    @assume_test_silo_mode(SiloMode.CONTROL)
+    def create_notification_settings_provider(*args, **kwargs) -> NotificationSettingProvider:
+        return NotificationSettingProvider.objects.create(*args, **kwargs)
+
     @staticmethod
     def create_basic_auth_header(username: str, password: str = "") -> str:
         return b"Basic " + b64encode(f"{username}:{password}".encode())

+ 3 - 0
src/sentry/testutils/fixtures.py

@@ -404,6 +404,9 @@ class Fixtures:
             organization=organization, projects=projects, **kwargs
         )
 
+    def create_notification_settings_provider(self, *args, **kwargs):
+        return Factories.create_notification_settings_provider(*args, **kwargs)
+
     def create_external_user(self, user=None, organization=None, integration=None, **kwargs):
         if not user:
             user = self.user

+ 14 - 17
tests/sentry/integrations/opsgenie/test_client.py

@@ -3,6 +3,7 @@ import responses
 
 from sentry.models.rule import Rule
 from sentry.testutils.cases import APITestCase
+from sentry.testutils.silo import region_silo_test
 from sentry.testutils.skips import requires_snuba
 from sentry.utils import json
 
@@ -16,28 +17,24 @@ METADATA = {
 }
 
 
+@region_silo_test
 class OpsgenieClientTest(APITestCase):
-    def create_integration(self):
-        integration, org_integration = self.create_provider_integration_for(
-            self.organization,
-            self.user,
+    def setUp(self) -> None:
+        self.login_as(self.user)
+        self.integration = self.create_integration(
+            organization=self.organization,
+            external_id=EXTERNAL_ID,
             provider="opsgenie",
             name="test-app",
-            external_id=EXTERNAL_ID,
             metadata=METADATA,
+            oi_params={
+                "config": {
+                    "team_table": [
+                        {"id": "team-123", "integration_key": "1234-ABCD", "team": "default team"},
+                    ]
+                },
+            },
         )
-        org_integration.config = {
-            "team_table": [
-                {"id": "team-123", "integration_key": "1234-ABCD", "team": "default team"},
-            ],
-        }
-        org_integration.save()
-
-        return integration
-
-    def setUp(self) -> None:
-        self.login_as(self.user)
-        self.integration = self.create_integration()
         self.installation = self.integration.get_installation(self.organization.id)
 
     def test_get_client(self):

+ 11 - 12
tests/sentry/integrations/pagerduty/test_client.py

@@ -15,7 +15,7 @@ from sentry.silo.util import PROXY_BASE_PATH, PROXY_OI_HEADER, PROXY_SIGNATURE_H
 from sentry.testutils.cases import APITestCase
 from sentry.testutils.factories import DEFAULT_EVENT_DATA
 from sentry.testutils.helpers.datetime import before_now, iso_format
-from sentry.testutils.silo import control_silo_test
+from sentry.testutils.silo import assume_test_silo_mode, control_silo_test, region_silo_test
 from sentry.testutils.skips import requires_snuba
 
 pytestmark = [requires_snuba]
@@ -139,25 +139,24 @@ def assert_proxy_request(request, is_proxy=True):
         assert request.headers[PROXY_OI_HEADER] is not None
 
 
-@override_settings(
-    SENTRY_SUBNET_SECRET="hush-hush-im-invisible",
-    SENTRY_CONTROL_ADDRESS="http://controlserver",
-)
+@region_silo_test
 class PagerDutyProxyApiClientTest(APITestCase):
     def setUp(self):
         self.login_as(self.user)
-        self.integration = self.create_provider_integration(
+
+        self.integration = self.create_integration(
+            organization=self.organization,
             provider="pagerduty",
             name="Example PagerDuty",
             external_id=EXTERNAL_ID,
             metadata={"services": SERVICES},
         )
-        self.integration.add_organization(self.organization, self.user)
-        self.service = add_service(
-            self.integration.organizationintegration_set.first(),
-            service_name=SERVICES[0]["service_name"],
-            integration_key=SERVICES[0]["integration_key"],
-        )
+        with assume_test_silo_mode(SiloMode.CONTROL):
+            self.service = add_service(
+                self.integration.organizationintegration_set.first(),
+                service_name=SERVICES[0]["service_name"],
+                integration_key=SERVICES[0]["integration_key"],
+            )
         self.installation = self.integration.get_installation(self.organization.id)
         self.min_ago = iso_format(before_now(minutes=1))
 

+ 12 - 17
tests/sentry/integrations/slack/notifications/test_assigned.py

@@ -4,12 +4,12 @@ from urllib.parse import parse_qs
 import responses
 
 from sentry.models.activity import Activity
-from sentry.models.identity import Identity, IdentityStatus
 from sentry.notifications.notifications.activity.assigned import AssignedActivityNotification
 from sentry.testutils.cases import PerformanceIssueTestCase, SlackActivityNotificationTest
 from sentry.testutils.helpers.features import with_feature
 from sentry.testutils.helpers.notifications import TEST_ISSUE_OCCURRENCE, TEST_PERF_ISSUE_OCCURRENCE
 from sentry.testutils.helpers.slack import get_attachment, get_blocks_and_fallback_text
+from sentry.testutils.silo import region_silo_test
 from sentry.testutils.skips import requires_snuba
 from sentry.types.activity import ActivityType
 from sentry.types.integrations import ExternalProviders
@@ -17,6 +17,7 @@ from sentry.types.integrations import ExternalProviders
 pytestmark = [requires_snuba]
 
 
+@region_silo_test
 class SlackAssignedNotificationTest(SlackActivityNotificationTest, PerformanceIssueTestCase):
     def create_notification(self, group, notification):
         return notification(
@@ -34,7 +35,9 @@ class SlackAssignedNotificationTest(SlackActivityNotificationTest, PerformanceIs
         """
         Test that we notify a user with multiple Identities in each place
         """
-        integration2 = self.create_provider_integration(
+        integration2, _ = self.create_provider_integration_for(
+            organization=self.organization,
+            user=self.user,
             provider="slack",
             name="Team B",
             external_id="TXXXXXXX2",
@@ -43,14 +46,11 @@ class SlackAssignedNotificationTest(SlackActivityNotificationTest, PerformanceIs
                 "installation_type": "born_as_bot",
             },
         )
-        integration2.add_organization(self.organization, self.user)
         idp2 = self.create_identity_provider(type="slack", external_id="TXXXXXXX2")
-        identity2 = Identity.objects.create(
-            external_id="UXXXXXXX2",
-            idp=idp2,
+        identity2 = self.create_identity(
             user=self.user,
-            status=IdentityStatus.VALID,
-            scopes=[],
+            external_id="UXXXXXXX2",
+            identity_provider=idp2,
         )
         # create a second response
         responses.add(
@@ -82,7 +82,9 @@ class SlackAssignedNotificationTest(SlackActivityNotificationTest, PerformanceIs
         we're only going to notify them for the relevant org
         """
         org2 = self.create_organization(owner=self.user)
-        integration2 = self.create_provider_integration(
+        self.create_provider_integration_for(
+            organization=org2,
+            user=self.user,
             provider="slack",
             name="Team B",
             external_id="TXXXXXXX2",
@@ -91,15 +93,8 @@ class SlackAssignedNotificationTest(SlackActivityNotificationTest, PerformanceIs
                 "installation_type": "born_as_bot",
             },
         )
-        integration2.add_organization(org2, self.user)
         idp2 = self.create_identity_provider(type="slack", external_id="TXXXXXXX2")
-        Identity.objects.create(
-            external_id="UXXXXXXX2",
-            idp=idp2,
-            user=self.user,
-            status=IdentityStatus.VALID,
-            scopes=[],
-        )
+        self.create_identity(external_id="UXXXXXXX2", identity_provider=idp2, user=self.user)
         # create a second response that won't actually be used, but here to make sure it's not a false positive
         responses.add(
             method=responses.POST,

+ 23 - 12
tests/sentry/integrations/slack/test_client.py

@@ -5,33 +5,25 @@ from django.test import override_settings
 from responses import matchers
 
 from sentry.integrations.slack.client import SlackClient
-from sentry.models.integrations.organization_integration import OrganizationIntegration
 from sentry.silo.base import SiloMode
 from sentry.silo.util import PROXY_BASE_PATH, PROXY_OI_HEADER, PROXY_PATH, PROXY_SIGNATURE_HEADER
 from sentry.testutils.cases import TestCase
+from sentry.testutils.silo import assume_test_silo_mode, region_silo_test
 from tests.sentry.integrations.test_helpers import add_control_silo_proxy_response
 
-control_address = "http://controlserver"
-secret = "hush-hush-im-invisible"
 
-
-@override_settings(
-    SENTRY_SUBNET_SECRET=secret,
-    SENTRY_CONTROL_ADDRESS=control_address,
-)
+@region_silo_test
 class SlackClientTest(TestCase):
     def setUp(self):
         self.user_access_token = "xoxp-user-access-token"
         self.access_token = "xoxb-access-token"
-        self.integration = self.create_integration(
+        self.integration, self.organization_integration = self.create_provider_integration_for(
             organization=self.organization,
+            user=self.user,
             external_id="slack:1",
             provider="slack",
             metadata={"access_token": self.access_token},
         )
-        self.organization_integration = OrganizationIntegration.objects.get(
-            integration_id=self.integration.id
-        )
         self.payload = {"channel": "#announcements", "message": "i'm ooo next week"}
         self.mock_user_access_token_response = {"ok": True, "auth": "user"}
         self.mock_access_token_response = {"ok": True, "auth": "token"}
@@ -130,20 +122,39 @@ class SlackClientTest(TestCase):
         assert response == self.mock_user_access_token_response
 
     @responses.activate
+    @assume_test_silo_mode(SiloMode.CONTROL)
     def test_authorize_with_org_integration_id(self):
         client = SlackClient(org_integration_id=self.organization_integration.id)
         response = client.post("/chat.postMessage", data=self.payload)
         assert response == self.mock_access_token_response
 
     @responses.activate
+    @assume_test_silo_mode(SiloMode.CONTROL)
     def test_authorize_with_integration_id(self):
         client = SlackClient(integration_id=self.integration.id)
         response = client.post("/chat.postMessage", data=self.payload)
         assert response == self.mock_access_token_response
 
     @responses.activate
+    @assume_test_silo_mode(SiloMode.CONTROL)
     def test_authorize_user_access_token(self):
         self.integration.update(metadata={"user_access_token": self.user_access_token})
         client = SlackClient(org_integration_id=self.organization_integration.id)
         response = client.post("/chat.postMessage", data=self.payload)
         assert response == self.mock_user_access_token_response
+
+    @responses.activate
+    def test_no_authorization_in_region_mode(self):
+        client = SlackClient(org_integration_id=self.organization_integration.id)
+        response = client.post("/chat.postMessage", data=self.payload)
+        assert response == self.mock_not_authed_response
+
+        client = SlackClient(integration_id=self.integration.id)
+        response = client.post("/chat.postMessage", data=self.payload)
+        assert response == self.mock_not_authed_response
+
+        with assume_test_silo_mode(SiloMode.CONTROL):
+            self.integration.update(metadata={"user_access_token": self.user_access_token})
+        client = SlackClient(org_integration_id=self.organization_integration.id)
+        response = client.post("/chat.postMessage", data=self.payload)
+        assert response == self.mock_not_authed_response

+ 0 - 8
tests/sentry/integrations/slack/test_disable.py

@@ -4,7 +4,6 @@ from datetime import datetime, timedelta
 import pytest
 import responses
 from django.core import mail
-from django.test import override_settings
 
 from sentry import audit_log
 from sentry.constants import ObjectStatus
@@ -24,14 +23,7 @@ from sentry.utils import json
 
 pytestmark = [requires_snuba]
 
-control_address = "http://controlserver"
-secret = "hush-hush-im-invisible"
 
-
-@override_settings(
-    SENTRY_SUBNET_SECRET=secret,
-    SENTRY_CONTROL_ADDRESS=control_address,
-)
 @region_silo_test
 class SlackClientDisable(TestCase):
     def setUp(self):

+ 26 - 10
tests/sentry/integrations/slack/test_notify_action.py

@@ -6,11 +6,11 @@ import responses
 from sentry.constants import ObjectStatus
 from sentry.integrations.slack import SlackNotifyServiceAction
 from sentry.integrations.slack.utils import SLACK_RATE_LIMITED_MESSAGE
-from sentry.models.integrations.organization_integration import OrganizationIntegration
 from sentry.notifications.additional_attachment_manager import manager
+from sentry.silo.base import SiloMode
 from sentry.testutils.cases import RuleTestCase
-from sentry.testutils.helpers import install_slack
 from sentry.testutils.helpers.features import with_feature
+from sentry.testutils.silo import assume_test_silo_mode, region_silo_test
 from sentry.testutils.skips import requires_snuba
 from sentry.types.integrations import ExternalProviders
 from sentry.utils import json
@@ -23,11 +23,24 @@ def additional_attachment_generator(integration, organization):
     return {"title": organization.slug, "text": integration.id}
 
 
+@region_silo_test
 class SlackNotifyActionTest(RuleTestCase):
     rule_cls = SlackNotifyServiceAction
 
     def setUp(self):
-        self.integration = install_slack(self.get_event().project.organization)
+        self.organization = self.get_event().project.organization
+        self.integration, self.org_integration = self.create_provider_integration_for(
+            organization=self.organization,
+            user=self.user,
+            external_id="TXXXXXXX1",
+            metadata={
+                "access_token": "xoxb-xxxxxxxxx-xxxxxxxxxx-xxxxxxxxxxxx",
+                "domain_name": "sentry.slack.com",
+                "installation_type": "born_as_bot",
+            },
+            name="Awesome Team",
+            provider="slack",
+        )
 
     def assert_form_valid(self, form, expected_channel_id, expected_channel):
         assert form.is_valid()
@@ -94,7 +107,8 @@ class SlackNotifyActionTest(RuleTestCase):
         )
 
     def test_render_label_without_integration(self):
-        self.integration.delete()
+        with assume_test_silo_mode(SiloMode.CONTROL):
+            self.integration.delete()
 
         rule = self.get_rule(
             data={
@@ -113,7 +127,9 @@ class SlackNotifyActionTest(RuleTestCase):
 
     @responses.activate
     def test_valid_bot_channel_selected(self):
-        integration = self.create_provider_integration(
+        integration, _ = self.create_provider_integration_for(
+            organization=self.event.project.organization,
+            user=self.user,
             provider="slack",
             name="Awesome Team",
             external_id="TXXXXXXX2",
@@ -123,7 +139,6 @@ class SlackNotifyActionTest(RuleTestCase):
                 "installation_type": "born_as_bot",
             },
         )
-        integration.add_organization(self.event.project.organization, self.user)
         rule = self.get_rule(
             data={"workspace": integration.id, "channel": "#my-channel", "tags": ""}
         )
@@ -357,10 +372,11 @@ class SlackNotifyActionTest(RuleTestCase):
 
     def test_disabled_org_integration(self):
         org = self.create_organization(owner=self.user)
-        self.create_organization_integration(organization_id=org.id, integration=self.integration)
-        OrganizationIntegration.objects.get(
-            integration=self.integration, organization_id=self.event.project.organization.id
-        ).update(status=ObjectStatus.DISABLED)
+        self.create_organization_integration(
+            organization_id=org.id, integration=self.integration, status=ObjectStatus.DISABLED
+        )
+        with assume_test_silo_mode(SiloMode.CONTROL):
+            self.org_integration.update(status=ObjectStatus.DISABLED)
         event = self.get_event()
 
         rule = self.get_rule(data={"workspace": self.integration.id, "channel": "#my-channel"})

+ 27 - 28
tests/sentry/integrations/slack/webhooks/actions/test_enable_notifications.py

@@ -4,12 +4,14 @@ from sentry.integrations.slack.webhooks.action import (
 )
 from sentry.models.identity import Identity
 from sentry.models.notificationsettingprovider import NotificationSettingProvider
-from sentry.models.user import User
+from sentry.silo.base import SiloMode
+from sentry.testutils.silo import assume_test_silo_mode, region_silo_test
 from sentry.utils import json
 
 from . import BaseEventTest
 
 
+@region_silo_test
 class EnableNotificationsActionTest(BaseEventTest):
     def setUp(self):
         super().setUp()
@@ -17,7 +19,12 @@ class EnableNotificationsActionTest(BaseEventTest):
         self.team_id = "TXXXXXXX1"
 
     def test_enable_all_slack_no_identity(self):
-        Identity.objects.delete_identity(user=self.user, idp=self.idp, external_id=self.external_id)
+        with assume_test_silo_mode(SiloMode.CONTROL):
+            Identity.objects.delete_identity(
+                user=self.user,
+                idp=self.idp,
+                external_id=self.external_id,
+            )
         response = self.post_webhook(
             action_data=[{"name": "enable_notifications", "value": "all_slack"}]
         )
@@ -26,7 +33,7 @@ class EnableNotificationsActionTest(BaseEventTest):
         assert response.data["text"] == NO_IDENTITY_MESSAGE
 
     def test_enable_all_slack_already_enabled(self):
-        NotificationSettingProvider.objects.create(
+        provider = self.create_notification_settings_provider(
             user_id=self.user.id,
             scope_type="user",
             scope_identifier=self.user.id,
@@ -37,44 +44,37 @@ class EnableNotificationsActionTest(BaseEventTest):
         response = self.post_webhook(
             action_data=[{"name": "enable_notifications", "value": "all_slack"}]
         )
-        self.user = User.objects.get(id=self.user.id)  # Reload to fetch actor
         assert response.status_code == 200, response.content
         assert response.data["text"] == ENABLE_SLACK_SUCCESS_MESSAGE
 
-        assert (
-            NotificationSettingProvider.objects.get(
-                user_id=self.user.id,
-                scope_type="user",
-                scope_identifier=self.user.id,
-                type="alerts",
-                provider="slack",
-            ).value
-            == "always"
-        )
+        self.user.refresh_from_db()  # Reload to fetch actor
+        provider.refresh_from_db()
+        assert provider.value == "always"
 
     def test_enable_all_slack(self):
-        assert not NotificationSettingProvider.objects.all().exists()
+        with assume_test_silo_mode(SiloMode.CONTROL):
+            assert not NotificationSettingProvider.objects.all().exists()
 
         response = self.post_webhook(
             action_data=[{"name": "enable_notifications", "value": "all_slack"}]
         )
-        self.user = User.objects.get(id=self.user.id)  # Reload to fetch actor
+        self.user.refresh_from_db()  # Reload to fetch actor
         assert response.status_code == 200, response.content
         assert response.data["text"] == ENABLE_SLACK_SUCCESS_MESSAGE
 
-        assert (
-            NotificationSettingProvider.objects.get(
+        with assume_test_silo_mode(SiloMode.CONTROL):
+            provider = NotificationSettingProvider.objects.get(
                 user_id=self.user.id,
                 scope_type="user",
                 scope_identifier=self.user.id,
                 type="alerts",
                 provider="slack",
-            ).value
-            == "always"
-        )
+            )
+            assert provider.value == "always"
 
     def test_enable_all_slack_block_kit(self):
-        assert not NotificationSettingProvider.objects.all().exists()
+        with assume_test_silo_mode(SiloMode.CONTROL):
+            assert not NotificationSettingProvider.objects.all().exists()
         original_message = {
             "blocks": [
                 {
@@ -106,17 +106,16 @@ class EnableNotificationsActionTest(BaseEventTest):
                 original_message=original_message,
                 data={"callback_id": json.dumps({"enable_notifications": True})},
             )
-        self.user = User.objects.get(id=self.user.id)  # Reload to fetch actor
+        self.user.refresh_from_db()  # Reload to fetch actor
         assert response.status_code == 200, response.content
         assert response.data["text"] == ENABLE_SLACK_SUCCESS_MESSAGE
 
-        assert (
-            NotificationSettingProvider.objects.get(
+        with assume_test_silo_mode(SiloMode.CONTROL):
+            provider = NotificationSettingProvider.objects.get(
                 user_id=self.user.id,
                 scope_type="user",
                 scope_identifier=self.user.id,
                 type="alerts",
                 provider="slack",
-            ).value
-            == "always"
-        )
+            )
+            assert provider.value == "always"