Browse Source

fix(integration): Have factory method match code change (#65360)

Seiji Chew 1 year ago
parent
commit
4dd5abe182

+ 28 - 15
src/sentry/testutils/factories.py

@@ -82,6 +82,7 @@ from sentry.models.integrations.integration_feature import (
 )
 from sentry.models.integrations.organization_integration import OrganizationIntegration
 from sentry.models.integrations.repository_project_path_config import RepositoryProjectPathConfig
+from sentry.models.integrations.sentry_app import SentryApp
 from sentry.models.integrations.sentry_app_installation import SentryAppInstallation
 from sentry.models.integrations.sentry_app_installation_for_provider import (
     SentryAppInstallationForProvider,
@@ -1050,28 +1051,36 @@ class Factories:
 
     @staticmethod
     @assume_test_silo_mode(SiloMode.CONTROL)
-    def create_internal_integration(**kwargs):
+    def create_internal_integration(**kwargs) -> SentryApp:
         args = Factories._sentry_app_kwargs(**kwargs)
         args["verify_install"] = False
         user = args.pop("user", None)
-        app = SentryAppCreator(is_internal=True, **args).run(user=user, request=None)
+        app = SentryAppCreator(is_internal=True, **args).run(
+            user=user, request=None, skip_default_auth_token=True
+        )
         return app
 
     @staticmethod
     @assume_test_silo_mode(SiloMode.CONTROL)
-    def create_internal_integration_token(user, install=None, request=None, org=None, scopes=None):
-        if scopes is None:
-            scopes = []
+    def create_internal_integration_token(
+        user,
+        internal_integration: SentryApp | None = None,
+        install: SentryAppInstallation | None = None,
+        request=None,
+    ) -> ApiToken:
+        if internal_integration and install:
+            raise ValueError("Only one of internal_integration or install arg can be provided")
+        if internal_integration is None and install is None:
+            raise ValueError("Must pass in either internal_integration or install arg")
+
         if install is None:
-            assert org
-            sentry_app = Factories.create_sentry_app(
-                name="Integration Token",
-                organization=org,
-                scopes=scopes,
-            )
-            install = Factories.create_sentry_app_installation(
-                organization=org, slug=sentry_app.slug, user=user
-            )
+            # Fetch install from provided or created internal integration
+            with assume_test_silo_mode(SiloMode.CONTROL):
+                install = SentryAppInstallation.objects.get(
+                    sentry_app=internal_integration.id,
+                    organization_id=internal_integration.owner_id,
+                )
+
         return SentryAppInstallationTokenCreator(sentry_app_installation=install).run(
             user=user, request=request
         )
@@ -1098,7 +1107,11 @@ class Factories:
     @staticmethod
     @assume_test_silo_mode(SiloMode.REGION)
     def create_sentry_app_installation(
-        organization=None, slug=None, user=None, status=None, prevent_token_exchange=False
+        organization=None,
+        slug=None,
+        user=None,
+        status=None,
+        prevent_token_exchange=False,
     ):
         if not organization:
             organization = Factories.create_organization()

+ 1 - 0
tests/acceptance/test_organization_developer_settings.py

@@ -102,6 +102,7 @@ class OrganizationDeveloperSettingsEditAcceptanceTest(AcceptanceTestCase):
 
     def test_remove_tokens_internal_app(self):
         internal_app = self.create_internal_integration(name="Internal App", organization=self.org)
+        self.create_internal_integration_token(user=self.user, internal_integration=internal_app)
         url = f"/settings/{self.org.slug}/developer-settings/{internal_app.slug}"
 
         self.load_page(url)

+ 4 - 1
tests/sentry/api/endpoints/test_group_details.py

@@ -211,7 +211,10 @@ class GroupDetailsTest(APITestCase, SnubaTestCase):
             organization=self.organization,
             scopes=("project:read", "org:read", "event:write"),
         )
-        token = internal_app.installations.first().api_token
+        token = self.create_internal_integration_token(
+            user=self.user,
+            internal_integration=internal_app,
+        )
 
         group = self.create_group(project=project)
         url = f"/api/0/issues/{group.id}/"

+ 5 - 6
tests/sentry/api/endpoints/test_organization_member_details.py

@@ -9,7 +9,6 @@ from sentry.auth.authenticators.recovery_code import RecoveryCodeInterface
 from sentry.auth.authenticators.totp import TotpInterface
 from sentry.models.authenticator import Authenticator
 from sentry.models.authprovider import AuthProvider
-from sentry.models.integrations.sentry_app_installation_token import SentryAppInstallationToken
 from sentry.models.options.user_option import UserOption
 from sentry.models.organization import Organization
 from sentry.models.organizationmember import InviteStatus, OrganizationMember
@@ -523,20 +522,20 @@ class UpdateOrganizationMemberTest(OrganizationMemberTestBase, HybridCloudTestMi
     def test_with_internal_integration(self):
         member = self.create_user("baz@example.com")
         member_om = self.create_member(organization=self.organization, user=member, role="member")
-        self.create_internal_integration(
+        internal_integration = self.create_internal_integration(
             name="my_app",
             organization=self.organization,
             scopes=("member:admin",),
             webhook_url="http://example.com",
         )
-        with assume_test_silo_mode(SiloMode.CONTROL):
-            # there should only be one record created so just grab the first one
-            token = SentryAppInstallationToken.objects.first()
+        token = self.create_internal_integration_token(
+            user=self.user, internal_integration=internal_integration
+        )
 
         response = self.client.put(
             reverse(self.endpoint, args=[self.organization.slug, member_om.id]),
             {"role": "manager"},
-            HTTP_AUTHORIZATION=f"Bearer {token.api_token.token}",
+            HTTP_AUTHORIZATION=f"Bearer {token}",
         )
 
         # The app token has no associated OrganizationMember and therefore no role.

+ 5 - 2
tests/sentry/api/endpoints/test_organization_member_index.py

@@ -691,9 +691,12 @@ class OrganizationMemberListPostTest(OrganizationMemberListTestBase, HybridCloud
         mock_send_invite_email.assert_called_with("test_referrer")
 
     @patch.object(OrganizationMember, "send_invite_email")
-    def test_integration_token_can_only_invite_member_role(self, mock_send_invite_email):
+    def test_internal_integration_token_can_only_invite_member_role(self, mock_send_invite_email):
+        internal_integration = self.create_internal_integration(
+            name="Internal App", organization=self.organization, scopes=["member:write"]
+        )
         token = self.create_internal_integration_token(
-            user=self.user, org=self.organization, scopes=["member:write"]
+            user=self.user, internal_integration=internal_integration
         )
         err_message = (
             "Integration tokens are restricted to inviting new members with the member role only."

+ 4 - 1
tests/sentry/api/endpoints/test_organization_member_team_details.py

@@ -398,9 +398,12 @@ class CreateWithClosedMembershipTest(CreateOrganizationMemberTeamTest):
         ).exists()
 
     def test_integration_token_needs_elevated_permissions(self):
+        internal_integration = self.create_internal_integration(
+            name="Internal App", organization=self.org, scopes=["org:read"]
+        )
         # Integration tokens with org:read should generate an access request when open membership is off
         integration_token = self.create_internal_integration_token(
-            user=self.user, org=self.org, scopes=["org:read"]
+            user=self.user, internal_integration=internal_integration
         )
 
         self.get_success_response(

+ 11 - 10
tests/sentry/api/endpoints/test_project_index.py

@@ -188,32 +188,33 @@ class ProjectsListTest(APITestCase):
 
     def test_valid_with_internal_integration(self):
         project = self.create_project(organization=self.organization, teams=[self.team])
-        self.create_internal_integration(
+        internal_integration = self.create_internal_integration(
             name="my_app",
             organization=self.organization,
             scopes=("project:read",),
             webhook_url="http://example.com",
         )
-        # there should only be one record created so just grab the first one
-        with assume_test_silo_mode(SiloMode.CONTROL):
-            token = SentryAppInstallationToken.objects.first()
+        token = self.create_internal_integration_token(
+            user=self.user, internal_integration=internal_integration
+        )
         path = reverse(self.endpoint)
-        response = self.client.get(path, HTTP_AUTHORIZATION=f"Bearer {token.api_token.token}")
+        response = self.client.get(path, HTTP_AUTHORIZATION=f"Bearer {token}")
         assert project.name.encode("utf-8") in response.content
 
     def test_deleted_token_with_internal_integration(self):
-        self.create_internal_integration(
+        internal_integration = self.create_internal_integration(
             name="my_app",
             organization=self.organization,
             scopes=("project:read",),
             webhook_url="http://example.com",
         )
+        token = self.create_internal_integration_token(
+            user=self.user, internal_integration=internal_integration
+        )
 
         with self.tasks(), assume_test_silo_mode(SiloMode.CONTROL), outbox_runner():
-            # there should only be one record created so just grab the first one
-            install_token = SentryAppInstallationToken.objects.first()
-            api_token = install_token.api_token
-            token = api_token.token
+            # Fetch the record using the created token
+            install_token = SentryAppInstallationToken.objects.get(api_token=token)
             # Delete the token
             install_token.delete()
             schedule_hybrid_cloud_foreign_key_jobs_control()

+ 3 - 0
tests/sentry/api/endpoints/test_sentry_apps.py

@@ -67,6 +67,9 @@ class SentryAppsTest(APITestCase):
         self.internal_app = self.create_internal_integration(
             name="Internal", organization=self.internal_organization
         )
+        self.create_internal_integration_token(
+            user=self.user, internal_integration=self.internal_app
+        )
 
     def assert_response_has_serialized_sentry_app(
         self,

+ 6 - 3
tests/sentry/api/endpoints/test_sentry_internal_app_token_details.py

@@ -20,8 +20,9 @@ class SentryInternalAppTokenCreationTest(APITestCase):
         self.internal_sentry_app = self.create_internal_integration(
             name="My Internal App", organization=self.org
         )
-
-        self.api_token = ApiToken.objects.get(application=self.internal_sentry_app.application)
+        self.api_token = self.create_internal_integration_token(
+            user=self.user, internal_integration=self.internal_sentry_app
+        )
 
         self.superuser = self.create_user(is_superuser=True)
 
@@ -45,7 +46,9 @@ class SentryInternalAppTokenCreationTest(APITestCase):
 
     def test_delete_token_another_app(self):
         another_app = self.create_internal_integration(name="Another app", organization=self.org)
-        api_token = ApiToken.objects.get(application=another_app.application)
+        api_token = self.create_internal_integration_token(
+            user=self.user, internal_integration=another_app
+        )
 
         self.login_as(user=self.user)
         self.get_error_response(

+ 12 - 4
tests/sentry/api/endpoints/test_sentry_internal_app_tokens.py

@@ -19,6 +19,9 @@ class SentryInternalAppTokenTest(APITestCase):
         self.internal_sentry_app = self.create_internal_integration(
             name="My Internal App", organization=self.org
         )
+        self.token = self.create_internal_integration_token(
+            user=self.user, internal_integration=self.internal_sentry_app
+        )
         self.superuser = self.create_user(is_superuser=True)
 
 
@@ -96,15 +99,18 @@ class GetSentryInternalAppTokenTest(SentryInternalAppTokenTest):
     def test_get_tokens(self):
         self.login_as(self.user)
 
-        self.create_internal_integration(name="OtherInternal", organization=self.org)
-
-        token = ApiToken.objects.get(application_id=self.internal_sentry_app.application_id)
+        other_internal_app = self.create_internal_integration(
+            name="OtherInternal", organization=self.org
+        )
+        self.create_internal_integration_token(
+            user=self.user, internal_integration=other_internal_app
+        )
 
         response = self.get_success_response(self.internal_sentry_app.slug)
 
         # should not include tokens from other internal app
         assert len(response.data) == 1
-        assert response.data[0]["id"] == str(token.id)
+        assert response.data[0]["id"] == str(self.token.id)
 
     def no_access_for_members(self):
         user = self.create_user(email="meep@example.com")
@@ -122,6 +128,7 @@ class GetSentryInternalAppTokenTest(SentryInternalAppTokenTest):
         sentry_app = self.create_internal_integration(
             name="AnothaOne", organization=self.org, scopes=("org:admin",)
         )
+        self.create_internal_integration_token(user=self.user, internal_integration=sentry_app)
 
         self.login_as(user)
 
@@ -135,6 +142,7 @@ class GetSentryInternalAppTokenTest(SentryInternalAppTokenTest):
         token = ApiToken.objects.create(user=self.user, scope_list=["org:write"])
 
         sentry_app = self.create_internal_integration(name="OtherInternal", organization=self.org)
+        self.create_internal_integration_token(user=self.user, internal_integration=sentry_app)
 
         self.get_error_response(
             sentry_app.slug,

Some files were not shown because too many files changed in this diff