Browse Source

ref: improve error messages for testutils base classes (#35687)

* ref: improve error messages for testutils base classes

* fixes for base-class @ property
anthony sottile 2 years ago
parent
commit
2beeba84e9

+ 26 - 17
src/sentry/testutils/cases.py

@@ -454,9 +454,12 @@ class APITestCase(BaseTestCase, BaseAPITestCase):
     must set the string `endpoint`.
     """
 
-    endpoint = None
     method = "get"
 
+    @property
+    def endpoint(self):
+        raise NotImplementedError(f"implement for {type(self).__module__}.{type(self).__name__}")
+
     def get_response(self, *args, **params):
         """
         Simulate an API call to the test case's URI and method.
@@ -471,9 +474,6 @@ class APITestCase(BaseTestCase, BaseAPITestCase):
             * raw_data: (Optional) Sometimes we want to precompute the JSON body.
         :returns Response object
         """
-        if self.endpoint is None:
-            raise Exception("Implement self.endpoint to use this method.")
-
         url = reverse(self.endpoint, args=args)
         # In some cases we want to pass querystring params to put/post, handle
         # this here.
@@ -626,7 +626,9 @@ class AuthProviderTestCase(TestCase):
 
 
 class RuleTestCase(TestCase):
-    rule_cls = None
+    @property
+    def rule_cls(self):
+        raise NotImplementedError(f"implement for {type(self).__module__}.{type(self).__name__}")
 
     def get_event(self):
         return self.event
@@ -744,7 +746,9 @@ class PermissionTestCase(TestCase):
 
 
 class PluginTestCase(TestCase):
-    plugin = None
+    @property
+    def plugin(self):
+        raise NotImplementedError(f"implement for {type(self).__module__}.{type(self).__name__}")
 
     def setUp(self):
         super().setUp()
@@ -783,7 +787,10 @@ class PluginTestCase(TestCase):
 
 class CliTestCase(TestCase):
     runner = fixture(CliRunner)
-    command = None
+
+    @property
+    def command(self):
+        raise NotImplementedError(f"implement for {type(self).__module__}.{type(self).__name__}")
 
     default_args = []
 
@@ -830,7 +837,9 @@ class AcceptanceTestCase(TransactionTestCase):
 
 
 class IntegrationTestCase(TestCase):
-    provider = None
+    @property
+    def provider(self):
+        raise NotImplementedError(f"implement for {type(self).__module__}.{type(self).__name__}")
 
     def setUp(self):
         from sentry.integrations.pipeline import IntegrationPipeline
@@ -1318,7 +1327,7 @@ class IntegrationRepositoryTestCase(APITestCase):
         self.login_as(self.user)
 
     def add_create_repository_responses(self, repository_config):
-        raise NotImplementedError
+        raise NotImplementedError(f"implement for {type(self).__module__}.{type(self).__name__}")
 
     def create_repository(
         self, repository_config, integration_id, organization_slug=None, add_responses=True
@@ -1362,7 +1371,7 @@ class ReleaseCommitPatchTest(APITestCase):
 
     @fixture
     def url(self):
-        raise NotImplementedError
+        raise NotImplementedError(f"implement for {type(self).__module__}.{type(self).__name__}")
 
     def assert_commit(self, commit, repo_id, key, author_id, message):
         assert commit.organization_id == self.org.id
@@ -1535,16 +1544,16 @@ class TestMigrations(TransactionTestCase):
     def app(self):
         return "sentry"
 
-    migrate_from = None
-    migrate_to = None
+    @property
+    def migrate_from(self):
+        raise NotImplementedError(f"implement for {type(self).__module__}.{type(self).__name__}")
+
+    @property
+    def migrate_to(self):
+        raise NotImplementedError(f"implement for {type(self).__module__}.{type(self).__name__}")
 
     def setUp(self):
         super().setUp()
-        assert (
-            self.migrate_from and self.migrate_to
-        ), "TestCase '{}' must define migrate_from and migrate_to properties".format(
-            type(self).__name__
-        )
         self.migrate_from = [(self.app, self.migrate_from)]
         self.migrate_to = [(self.app, self.migrate_to)]
 

+ 2 - 2
tests/sentry/api/bases/test_integration.py

@@ -3,10 +3,10 @@ from rest_framework.exceptions import APIException
 
 from sentry.api.bases.integration import IntegrationEndpoint
 from sentry.shared_integrations.exceptions import ApiError
-from sentry.testutils import APITestCase
+from sentry.testutils import TestCase
 
 
-class IntegrationEndpointTest(APITestCase):
+class IntegrationEndpointTest(TestCase):
     def setUp(self):
         self.endpoint = IntegrationEndpoint()
 

+ 2 - 1
tests/sentry/api/endpoints/test_organization_code_mapping_details.py

@@ -6,6 +6,8 @@ from sentry.testutils import APITestCase
 
 
 class OrganizationCodeMappingDetailsTest(APITestCase):
+    endpoint = "sentry-api-0-organization-code-mapping-details"
+
     def setUp(self):
         super().setUp()
 
@@ -29,7 +31,6 @@ class OrganizationCodeMappingDetailsTest(APITestCase):
             default_branch="master",
         )
 
-        self.endpoint = "sentry-api-0-organization-code-mapping-details"
         self.url = reverse(
             self.endpoint,
             args=[self.org.slug, self.config.id],

+ 2 - 1
tests/sentry/api/endpoints/test_sentry_app_avatar.py

@@ -5,12 +5,13 @@ from sentry.testutils import APITestCase
 
 
 class SentryAppAvatarTestBase(APITestCase):
+    endpoint = "sentry-api-0-sentry-app-avatar"
+
     def setUp(self):
         super().setUp()
         self.unpublished_app = self.create_sentry_app(name="Meow", organization=self.organization)
         SentryAppAvatar.objects.create(sentry_app=self.unpublished_app, color=True, avatar_type=0)
         SentryAppAvatar.objects.create(sentry_app=self.unpublished_app, color=False, avatar_type=0)
-        self.endpoint = "sentry-api-0-sentry-app-avatar"
         self.login_as(self.user)
 
     def get_avatar(self, resp, is_color=True):

+ 2 - 2
tests/sentry/integrations/github/test_repository.py

@@ -9,7 +9,7 @@ from fixtures.github import COMPARE_COMMITS_EXAMPLE, GET_COMMIT_EXAMPLE, GET_LAS
 from sentry.integrations.github.repository import GitHubRepositoryProvider
 from sentry.models import Integration, PullRequest, Repository
 from sentry.shared_integrations.exceptions import IntegrationError
-from sentry.testutils import PluginTestCase
+from sentry.testutils import TestCase
 from sentry.testutils.asserts import assert_commit_shape
 from sentry.utils import json
 
@@ -23,7 +23,7 @@ def stub_installation_token():
     )
 
 
-class GitHubAppsProviderTest(PluginTestCase):
+class GitHubAppsProviderTest(TestCase):
     def setUp(self):
         super().setUp()
         self.organization = self.create_organization()

+ 8 - 3
tests/sentry/ratelimits/utils/test_enforce_rate_limit.py

@@ -33,19 +33,24 @@ urlpatterns = [
 ]
 
 
-@override_settings(ROOT_URLCONF="tests.sentry.ratelimits.utils.test_enforce_rate_limit")
+@override_settings(ROOT_URLCONF=__name__)
 class EnforceRateLimitTest(APITestCase):
+    endpoint = "enforced-endpoint"
+
     @override_settings(SENTRY_SELF_HOSTED=False)
     def test_enforced_rate_limit(self):
         """Endpoints with enforce_rate_limit enabled should result in 429s"""
-        self.endpoint = "enforced-endpoint"
         with freeze_time("2000-01-01"):
             self.get_success_response()
             self.get_error_response(status_code=status.HTTP_429_TOO_MANY_REQUESTS)
 
+
+@override_settings(ROOT_URLCONF=__name__)
+class UnEnforceRateLimitTest(APITestCase):
+    endpoint = "unenforced-endpoint"
+
     def test_unenforced_rate_limit(self):
         """Endpoints with enforce_rate_limit disabled shouldn't reject requests"""
-        self.endpoint = "unenforced-endpoint"
         with freeze_time("2000-01-01"):
             self.get_success_response()
             self.get_success_response()

+ 2 - 2
tests/sentry_plugins/bitbucket/test_repository_provider.py

@@ -2,13 +2,13 @@ import responses
 from exam import fixture
 
 from sentry.models import Repository
-from sentry.testutils import PluginTestCase
+from sentry.testutils import TestCase
 from sentry_plugins.bitbucket.plugin import BitbucketRepositoryProvider
 from sentry_plugins.bitbucket.testutils import COMMIT_DIFF_PATCH, COMPARE_COMMITS_EXAMPLE
 from social_auth.models import UserSocialAuth
 
 
-class BitbucketPluginTest(PluginTestCase):
+class BitbucketPluginTest(TestCase):
     @fixture
     def provider(self):
         return BitbucketRepositoryProvider("bitbucket")

+ 3 - 3
tests/sentry_plugins/github/test_provider.py

@@ -4,7 +4,7 @@ import responses
 from exam import fixture
 
 from sentry.models import Integration, OrganizationIntegration, Repository
-from sentry.testutils import PluginTestCase
+from sentry.testutils import TestCase
 from sentry.utils import json
 from sentry_plugins.github.client import GitHubAppsClient, GitHubClient
 from sentry_plugins.github.plugin import GitHubAppsRepositoryProvider, GitHubRepositoryProvider
@@ -17,7 +17,7 @@ from sentry_plugins.github.testutils import (
 from social_auth.models import UserSocialAuth
 
 
-class GitHubPluginTest(PluginTestCase):
+class GitHubPluginTest(TestCase):
     @fixture
     def provider(self):
         return GitHubRepositoryProvider("github")
@@ -168,7 +168,7 @@ class GitHubPluginTest(PluginTestCase):
         assert repo.config["webhook_events"] == ["push", "pull_request"]
 
 
-class GitHubAppsProviderTest(PluginTestCase):
+class GitHubAppsProviderTest(TestCase):
     @fixture
     def provider(self):
         return GitHubAppsRepositoryProvider("github_apps")