From c998d475440cf4819bad7ebc3ed19f31ce82baf4 Mon Sep 17 00:00:00 2001 From: Johannes Christ Date: Tue, 8 Jun 2021 00:26:40 +0200 Subject: Move subdomains to query paths. In more detail: - Use Django URL namespaces (e.g. `api:bot:infractions`) instead of `django_hosts` host argument. - Update the hosts file setup documentation to remove subdomain entries. - Update the hosts file setup documentation to mention that the entry of `pythondiscord.local` is not required and mainly for convenience. - Rename the `APISubdomainTestCase` to the more fitting `AuthenticatedAPITestCase`, as authentication is all that is left that the class is doing. - Drop dependency to `django_hosts`. --- pydis_site/apps/api/tests/base.py | 27 +++--- pydis_site/apps/api/tests/test_deleted_messages.py | 16 ++-- .../apps/api/tests/test_documentation_links.py | 50 +++++----- pydis_site/apps/api/tests/test_filterlists.py | 16 ++-- pydis_site/apps/api/tests/test_healthcheck.py | 8 +- pydis_site/apps/api/tests/test_infractions.py | 104 ++++++++++----------- pydis_site/apps/api/tests/test_nominations.py | 86 ++++++++--------- .../apps/api/tests/test_off_topic_channel_names.py | 48 +++++----- .../apps/api/tests/test_offensive_message.py | 24 ++--- pydis_site/apps/api/tests/test_reminders.py | 48 +++++----- pydis_site/apps/api/tests/test_roles.py | 24 ++--- pydis_site/apps/api/tests/test_rules.py | 12 +-- pydis_site/apps/api/tests/test_users.py | 66 ++++++------- 13 files changed, 259 insertions(+), 270 deletions(-) (limited to 'pydis_site/apps/api/tests') diff --git a/pydis_site/apps/api/tests/base.py b/pydis_site/apps/api/tests/base.py index 61c23b0f..c9f3cb7e 100644 --- a/pydis_site/apps/api/tests/base.py +++ b/pydis_site/apps/api/tests/base.py @@ -11,7 +11,7 @@ test_user, _created = User.objects.get_or_create( ) -class APISubdomainTestCase(APITestCase): +class AuthenticatedAPITestCase(APITestCase): """ Configures the test client. @@ -24,14 +24,13 @@ class APISubdomainTestCase(APITestCase): `self.client.force_authenticate(user=created_user)` to force authentication through the created user. - Using this performs the following niceties for you which ease writing tests: - - setting the `HTTP_HOST` request header to `api.pythondiscord.local:8000`, and + Using this performs the following nicety for you which eases writing tests: - forcing authentication for the test user. If you don't want to force authentication (for example, to test a route's response for an unauthenticated user), un-force authentication by using the following: - >>> from pydis_site.apps.api.tests.base import APISubdomainTestCase - >>> class UnauthedUserTestCase(APISubdomainTestCase): + >>> from pydis_site.apps.api.tests.base import AuthenticatedAPITestCase + >>> class UnauthedUserTestCase(AuthenticatedAPITestCase): ... def setUp(self): ... super().setUp() ... self.client.force_authentication(user=None) @@ -42,30 +41,26 @@ class APISubdomainTestCase(APITestCase): ... resp = self.client.delete('/my-publicly-readable-endpoint/42') ... self.assertEqual(resp.status_code, 401) - Make sure to include the `super().setUp(self)` call, otherwise, you may get - status code 404 for some URLs due to the missing `HTTP_HOST` header. - ## Example Using this in a test case is rather straightforward: - >>> from pydis_site.apps.api.tests.base import APISubdomainTestCase - >>> class MyAPITestCase(APISubdomainTestCase): + >>> from pydis_site.apps.api.tests.base import AuthenticatedAPITestCase + >>> class MyAPITestCase(AuthenticatedAPITestCase): ... def test_that_it_works(self): ... response = self.client.get('/my-endpoint') ... self.assertEqual(response.status_code, 200) - To reverse URLs of the API host, you need to use `django_hosts`: + To reverse URLs of the API host, you need to use `django.urls`: - >>> from django_hosts.resolvers import reverse - >>> from pydis_site.apps.api.tests.base import APISubdomainTestCase - >>> class MyReversedTestCase(APISubdomainTestCase): + >>> from django.urls import reverse + >>> from pydis_site.apps.api.tests.base import AuthenticatedAPITestCase + >>> class MyReversedTestCase(AuthenticatedAPITestCase): ... def test_my_endpoint(self): - ... url = reverse('user-detail', host='api') + ... url = reverse('api:user-detail') ... response = self.client.get(url) ... self.assertEqual(response.status_code, 200) """ def setUp(self): super().setUp() - self.client.defaults['HTTP_HOST'] = 'api.pythondiscord.local:8000' self.client.force_authenticate(test_user) diff --git a/pydis_site/apps/api/tests/test_deleted_messages.py b/pydis_site/apps/api/tests/test_deleted_messages.py index 40450844..1eb535d8 100644 --- a/pydis_site/apps/api/tests/test_deleted_messages.py +++ b/pydis_site/apps/api/tests/test_deleted_messages.py @@ -1,13 +1,13 @@ from datetime import datetime +from django.urls import reverse from django.utils import timezone -from django_hosts.resolvers import reverse -from .base import APISubdomainTestCase +from .base import AuthenticatedAPITestCase from ..models import MessageDeletionContext, User -class DeletedMessagesWithoutActorTests(APISubdomainTestCase): +class DeletedMessagesWithoutActorTests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): cls.author = User.objects.create( @@ -40,14 +40,14 @@ class DeletedMessagesWithoutActorTests(APISubdomainTestCase): } def test_accepts_valid_data(self): - url = reverse('bot:messagedeletioncontext-list', host='api') + url = reverse('api:bot:messagedeletioncontext-list') response = self.client.post(url, data=self.data) self.assertEqual(response.status_code, 201) [context] = MessageDeletionContext.objects.all() self.assertIsNone(context.actor) -class DeletedMessagesWithActorTests(APISubdomainTestCase): +class DeletedMessagesWithActorTests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): cls.author = cls.actor = User.objects.create( @@ -72,14 +72,14 @@ class DeletedMessagesWithActorTests(APISubdomainTestCase): } def test_accepts_valid_data_and_sets_actor(self): - url = reverse('bot:messagedeletioncontext-list', host='api') + url = reverse('api:bot:messagedeletioncontext-list') response = self.client.post(url, data=self.data) self.assertEqual(response.status_code, 201) [context] = MessageDeletionContext.objects.all() self.assertEqual(context.actor.id, self.actor.id) -class DeletedMessagesLogURLTests(APISubdomainTestCase): +class DeletedMessagesLogURLTests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): cls.author = cls.actor = User.objects.create( @@ -94,6 +94,6 @@ class DeletedMessagesLogURLTests(APISubdomainTestCase): ) def test_valid_log_url(self): - expected_url = reverse('logs', host="staff", args=(1,)) + expected_url = reverse('staff:logs', args=(1,)) [context] = MessageDeletionContext.objects.all() self.assertEqual(context.log_url, expected_url) diff --git a/pydis_site/apps/api/tests/test_documentation_links.py b/pydis_site/apps/api/tests/test_documentation_links.py index 39fb08f3..4e238cbb 100644 --- a/pydis_site/apps/api/tests/test_documentation_links.py +++ b/pydis_site/apps/api/tests/test_documentation_links.py @@ -1,61 +1,61 @@ -from django_hosts.resolvers import reverse +from django.urls import reverse -from .base import APISubdomainTestCase +from .base import AuthenticatedAPITestCase from ..models import DocumentationLink -class UnauthedDocumentationLinkAPITests(APISubdomainTestCase): +class UnauthedDocumentationLinkAPITests(AuthenticatedAPITestCase): def setUp(self): super().setUp() self.client.force_authenticate(user=None) def test_detail_lookup_returns_401(self): - url = reverse('bot:documentationlink-detail', args=('whatever',), host='api') + url = reverse('api:bot:documentationlink-detail', args=('whatever',)) response = self.client.get(url) self.assertEqual(response.status_code, 401) def test_list_returns_401(self): - url = reverse('bot:documentationlink-list', host='api') + url = reverse('api:bot:documentationlink-list') response = self.client.get(url) self.assertEqual(response.status_code, 401) def test_create_returns_401(self): - url = reverse('bot:documentationlink-list', host='api') + url = reverse('api:bot:documentationlink-list') response = self.client.post(url, data={'hi': 'there'}) self.assertEqual(response.status_code, 401) def test_delete_returns_401(self): - url = reverse('bot:documentationlink-detail', args=('whatever',), host='api') + url = reverse('api:bot:documentationlink-detail', args=('whatever',)) response = self.client.delete(url) self.assertEqual(response.status_code, 401) -class EmptyDatabaseDocumentationLinkAPITests(APISubdomainTestCase): +class EmptyDatabaseDocumentationLinkAPITests(AuthenticatedAPITestCase): def test_detail_lookup_returns_404(self): - url = reverse('bot:documentationlink-detail', args=('whatever',), host='api') + url = reverse('api:bot:documentationlink-detail', args=('whatever',)) response = self.client.get(url) self.assertEqual(response.status_code, 404) def test_list_all_returns_empty_list(self): - url = reverse('bot:documentationlink-list', host='api') + url = reverse('api:bot:documentationlink-list') response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertEqual(response.json(), []) def test_delete_returns_404(self): - url = reverse('bot:documentationlink-detail', args=('whatever',), host='api') + url = reverse('api:bot:documentationlink-detail', args=('whatever',)) response = self.client.delete(url) self.assertEqual(response.status_code, 404) -class DetailLookupDocumentationLinkAPITests(APISubdomainTestCase): +class DetailLookupDocumentationLinkAPITests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): cls.doc_link = DocumentationLink.objects.create( @@ -71,27 +71,27 @@ class DetailLookupDocumentationLinkAPITests(APISubdomainTestCase): } def test_detail_lookup_unknown_package_returns_404(self): - url = reverse('bot:documentationlink-detail', args=('whatever',), host='api') + url = reverse('api:bot:documentationlink-detail', args=('whatever',)) response = self.client.get(url) self.assertEqual(response.status_code, 404) def test_detail_lookup_created_package_returns_package(self): - url = reverse('bot:documentationlink-detail', args=(self.doc_link.package,), host='api') + url = reverse('api:bot:documentationlink-detail', args=(self.doc_link.package,)) response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertEqual(response.json(), self.doc_json) def test_list_all_packages_shows_created_package(self): - url = reverse('bot:documentationlink-list', host='api') + url = reverse('api:bot:documentationlink-list') response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertEqual(response.json(), [self.doc_json]) def test_create_invalid_body_returns_400(self): - url = reverse('bot:documentationlink-list', host='api') + url = reverse('api:bot:documentationlink-list') response = self.client.post(url, data={'i': 'am', 'totally': 'valid'}) self.assertEqual(response.status_code, 400) @@ -103,7 +103,7 @@ class DetailLookupDocumentationLinkAPITests(APISubdomainTestCase): 'inventory_url': 'totally an url' } - url = reverse('bot:documentationlink-list', host='api') + url = reverse('api:bot:documentationlink-list') response = self.client.post(url, data=body) self.assertEqual(response.status_code, 400) @@ -114,13 +114,13 @@ class DetailLookupDocumentationLinkAPITests(APISubdomainTestCase): with self.subTest(package_name=case): body = self.doc_json.copy() body['package'] = case - url = reverse('bot:documentationlink-list', host='api') + url = reverse('api:bot:documentationlink-list') response = self.client.post(url, data=body) self.assertEqual(response.status_code, 400) -class DocumentationLinkCreationTests(APISubdomainTestCase): +class DocumentationLinkCreationTests(AuthenticatedAPITestCase): def setUp(self): super().setUp() @@ -130,27 +130,27 @@ class DocumentationLinkCreationTests(APISubdomainTestCase): 'inventory_url': 'https://docs.example.com' } - url = reverse('bot:documentationlink-list', host='api') + url = reverse('api:bot:documentationlink-list') response = self.client.post(url, data=self.body) self.assertEqual(response.status_code, 201) def test_package_in_full_list(self): - url = reverse('bot:documentationlink-list', host='api') + url = reverse('api:bot:documentationlink-list') response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertEqual(response.json(), [self.body]) def test_detail_lookup_works_with_package(self): - url = reverse('bot:documentationlink-detail', args=(self.body['package'],), host='api') + url = reverse('api:bot:documentationlink-detail', args=(self.body['package'],)) response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertEqual(response.json(), self.body) -class DocumentationLinkDeletionTests(APISubdomainTestCase): +class DocumentationLinkDeletionTests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): cls.doc_link = DocumentationLink.objects.create( @@ -160,13 +160,13 @@ class DocumentationLinkDeletionTests(APISubdomainTestCase): ) def test_unknown_package_returns_404(self): - url = reverse('bot:documentationlink-detail', args=('whatever',), host='api') + url = reverse('api:bot:documentationlink-detail', args=('whatever',)) response = self.client.delete(url) self.assertEqual(response.status_code, 404) def test_delete_known_package_returns_204(self): - url = reverse('bot:documentationlink-detail', args=(self.doc_link.package,), host='api') + url = reverse('api:bot:documentationlink-detail', args=(self.doc_link.package,)) response = self.client.delete(url) self.assertEqual(response.status_code, 204) diff --git a/pydis_site/apps/api/tests/test_filterlists.py b/pydis_site/apps/api/tests/test_filterlists.py index 188c0fff..5a5bca60 100644 --- a/pydis_site/apps/api/tests/test_filterlists.py +++ b/pydis_site/apps/api/tests/test_filterlists.py @@ -1,9 +1,9 @@ -from django_hosts.resolvers import reverse +from django.urls import reverse from pydis_site.apps.api.models import FilterList -from pydis_site.apps.api.tests.base import APISubdomainTestCase +from pydis_site.apps.api.tests.base import AuthenticatedAPITestCase -URL = reverse('bot:filterlist-list', host='api') +URL = reverse('api:bot:filterlist-list') JPEG_ALLOWLIST = { "type": 'FILE_FORMAT', "allowed": True, @@ -16,7 +16,7 @@ PNG_ALLOWLIST = { } -class UnauthenticatedTests(APISubdomainTestCase): +class UnauthenticatedTests(AuthenticatedAPITestCase): def setUp(self): super().setUp() self.client.force_authenticate(user=None) @@ -27,7 +27,7 @@ class UnauthenticatedTests(APISubdomainTestCase): self.assertEqual(response.status_code, 401) -class EmptyDatabaseTests(APISubdomainTestCase): +class EmptyDatabaseTests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): FilterList.objects.all().delete() @@ -39,7 +39,7 @@ class EmptyDatabaseTests(APISubdomainTestCase): self.assertEqual(response.json(), []) -class FetchTests(APISubdomainTestCase): +class FetchTests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): FilterList.objects.all().delete() @@ -68,7 +68,7 @@ class FetchTests(APISubdomainTestCase): self.assertEquals(api_type[1], model_type[1]) -class CreationTests(APISubdomainTestCase): +class CreationTests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): FilterList.objects.all().delete() @@ -103,7 +103,7 @@ class CreationTests(APISubdomainTestCase): self.assertEqual(response.status_code, 400) -class DeletionTests(APISubdomainTestCase): +class DeletionTests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): FilterList.objects.all().delete() diff --git a/pydis_site/apps/api/tests/test_healthcheck.py b/pydis_site/apps/api/tests/test_healthcheck.py index b0fd71bf..650403ad 100644 --- a/pydis_site/apps/api/tests/test_healthcheck.py +++ b/pydis_site/apps/api/tests/test_healthcheck.py @@ -1,15 +1,15 @@ -from django_hosts.resolvers import reverse +from django.urls import reverse -from .base import APISubdomainTestCase +from .base import AuthenticatedAPITestCase -class UnauthedHealthcheckAPITests(APISubdomainTestCase): +class UnauthedHealthcheckAPITests(AuthenticatedAPITestCase): def setUp(self): super().setUp() self.client.force_authenticate(user=None) def test_can_access_healthcheck_view(self): - url = reverse('healthcheck', host='api') + url = reverse('api:healthcheck') response = self.client.get(url) self.assertEqual(response.status_code, 200) diff --git a/pydis_site/apps/api/tests/test_infractions.py b/pydis_site/apps/api/tests/test_infractions.py index 9aae16c0..b3dd16ee 100644 --- a/pydis_site/apps/api/tests/test_infractions.py +++ b/pydis_site/apps/api/tests/test_infractions.py @@ -4,44 +4,44 @@ from unittest.mock import patch from urllib.parse import quote from django.db.utils import IntegrityError -from django_hosts.resolvers import reverse +from django.urls import reverse -from .base import APISubdomainTestCase +from .base import AuthenticatedAPITestCase from ..models import Infraction, User from ..serializers import InfractionSerializer -class UnauthenticatedTests(APISubdomainTestCase): +class UnauthenticatedTests(AuthenticatedAPITestCase): def setUp(self): super().setUp() self.client.force_authenticate(user=None) def test_detail_lookup_returns_401(self): - url = reverse('bot:infraction-detail', args=(6,), host='api') + url = reverse('api:bot:infraction-detail', args=(6,)) response = self.client.get(url) self.assertEqual(response.status_code, 401) def test_list_returns_401(self): - url = reverse('bot:infraction-list', host='api') + url = reverse('api:bot:infraction-list') response = self.client.get(url) self.assertEqual(response.status_code, 401) def test_create_returns_401(self): - url = reverse('bot:infraction-list', host='api') + url = reverse('api:bot:infraction-list') response = self.client.post(url, data={'reason': 'Have a nice day.'}) self.assertEqual(response.status_code, 401) def test_partial_update_returns_401(self): - url = reverse('bot:infraction-detail', args=(6,), host='api') + url = reverse('api:bot:infraction-detail', args=(6,)) response = self.client.patch(url, data={'reason': 'Have a nice day.'}) self.assertEqual(response.status_code, 401) -class InfractionTests(APISubdomainTestCase): +class InfractionTests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): cls.user = User.objects.create( @@ -92,7 +92,7 @@ class InfractionTests(APISubdomainTestCase): def test_list_all(self): """Tests the list-view, which should be ordered by inserted_at (newest first).""" - url = reverse('bot:infraction-list', host='api') + url = reverse('api:bot:infraction-list') response = self.client.get(url) self.assertEqual(response.status_code, 200) @@ -106,7 +106,7 @@ class InfractionTests(APISubdomainTestCase): self.assertEqual(infractions[4]['id'], self.ban_hidden.id) def test_filter_search(self): - url = reverse('bot:infraction-list', host='api') + url = reverse('api:bot:infraction-list') pattern = quote(r'^James(\s\w+){3},') response = self.client.get(f'{url}?search={pattern}') @@ -117,7 +117,7 @@ class InfractionTests(APISubdomainTestCase): self.assertEqual(infractions[0]['id'], self.ban_inactive.id) def test_filter_field(self): - url = reverse('bot:infraction-list', host='api') + url = reverse('api:bot:infraction-list') response = self.client.get(f'{url}?type=ban&hidden=true') self.assertEqual(response.status_code, 200) @@ -127,7 +127,7 @@ class InfractionTests(APISubdomainTestCase): self.assertEqual(infractions[0]['id'], self.ban_hidden.id) def test_filter_permanent_false(self): - url = reverse('bot:infraction-list', host='api') + url = reverse('api:bot:infraction-list') response = self.client.get(f'{url}?type=mute&permanent=false') self.assertEqual(response.status_code, 200) @@ -136,7 +136,7 @@ class InfractionTests(APISubdomainTestCase): self.assertEqual(len(infractions), 0) def test_filter_permanent_true(self): - url = reverse('bot:infraction-list', host='api') + url = reverse('api:bot:infraction-list') response = self.client.get(f'{url}?type=mute&permanent=true') self.assertEqual(response.status_code, 200) @@ -145,7 +145,7 @@ class InfractionTests(APISubdomainTestCase): self.assertEqual(infractions[0]['id'], self.mute_permanent.id) def test_filter_after(self): - url = reverse('bot:infraction-list', host='api') + url = reverse('api:bot:infraction-list') target_time = datetime.datetime.utcnow() + datetime.timedelta(hours=5) response = self.client.get(f'{url}?type=superstar&expires_after={target_time.isoformat()}') @@ -154,7 +154,7 @@ class InfractionTests(APISubdomainTestCase): self.assertEqual(len(infractions), 0) def test_filter_before(self): - url = reverse('bot:infraction-list', host='api') + url = reverse('api:bot:infraction-list') target_time = datetime.datetime.utcnow() + datetime.timedelta(hours=5) response = self.client.get(f'{url}?type=superstar&expires_before={target_time.isoformat()}') @@ -164,21 +164,21 @@ class InfractionTests(APISubdomainTestCase): self.assertEqual(infractions[0]['id'], self.superstar_expires_soon.id) def test_filter_after_invalid(self): - url = reverse('bot:infraction-list', host='api') + url = reverse('api:bot:infraction-list') response = self.client.get(f'{url}?expires_after=gibberish') self.assertEqual(response.status_code, 400) self.assertEqual(list(response.json())[0], "expires_after") def test_filter_before_invalid(self): - url = reverse('bot:infraction-list', host='api') + url = reverse('api:bot:infraction-list') response = self.client.get(f'{url}?expires_before=000000000') self.assertEqual(response.status_code, 400) self.assertEqual(list(response.json())[0], "expires_before") def test_after_before_before(self): - url = reverse('bot:infraction-list', host='api') + url = reverse('api:bot:infraction-list') target_time = datetime.datetime.utcnow() + datetime.timedelta(hours=4) target_time_late = datetime.datetime.utcnow() + datetime.timedelta(hours=6) response = self.client.get( @@ -191,7 +191,7 @@ class InfractionTests(APISubdomainTestCase): self.assertEqual(response.json()[0]["id"], self.superstar_expires_soon.id) def test_after_after_before_invalid(self): - url = reverse('bot:infraction-list', host='api') + url = reverse('api:bot:infraction-list') target_time = datetime.datetime.utcnow() + datetime.timedelta(hours=5) target_time_late = datetime.datetime.utcnow() + datetime.timedelta(hours=9) response = self.client.get( @@ -205,7 +205,7 @@ class InfractionTests(APISubdomainTestCase): self.assertIn("expires_after", errors) def test_permanent_after_invalid(self): - url = reverse('bot:infraction-list', host='api') + url = reverse('api:bot:infraction-list') target_time = datetime.datetime.utcnow() + datetime.timedelta(hours=5) response = self.client.get(f'{url}?permanent=true&expires_after={target_time.isoformat()}') @@ -214,7 +214,7 @@ class InfractionTests(APISubdomainTestCase): self.assertEqual("permanent", errors[0]) def test_permanent_before_invalid(self): - url = reverse('bot:infraction-list', host='api') + url = reverse('api:bot:infraction-list') target_time = datetime.datetime.utcnow() + datetime.timedelta(hours=5) response = self.client.get(f'{url}?permanent=true&expires_before={target_time.isoformat()}') @@ -223,7 +223,7 @@ class InfractionTests(APISubdomainTestCase): self.assertEqual("permanent", errors[0]) def test_nonpermanent_before(self): - url = reverse('bot:infraction-list', host='api') + url = reverse('api:bot:infraction-list') target_time = datetime.datetime.utcnow() + datetime.timedelta(hours=6) response = self.client.get( f'{url}?permanent=false&expires_before={target_time.isoformat()}' @@ -234,7 +234,7 @@ class InfractionTests(APISubdomainTestCase): self.assertEqual(response.json()[0]["id"], self.superstar_expires_soon.id) def test_filter_manytypes(self): - url = reverse('bot:infraction-list', host='api') + url = reverse('api:bot:infraction-list') response = self.client.get(f'{url}?types=mute,ban') self.assertEqual(response.status_code, 200) @@ -242,7 +242,7 @@ class InfractionTests(APISubdomainTestCase): self.assertEqual(len(infractions), 3) def test_types_type_invalid(self): - url = reverse('bot:infraction-list', host='api') + url = reverse('api:bot:infraction-list') response = self.client.get(f'{url}?types=mute,ban&type=superstar') self.assertEqual(response.status_code, 400) @@ -250,7 +250,7 @@ class InfractionTests(APISubdomainTestCase): self.assertEqual("types", errors[0]) def test_sort_expiresby(self): - url = reverse('bot:infraction-list', host='api') + url = reverse('api:bot:infraction-list') response = self.client.get(f'{url}?ordering=expires_at&permanent=false') self.assertEqual(response.status_code, 200) infractions = response.json() @@ -261,34 +261,34 @@ class InfractionTests(APISubdomainTestCase): self.assertEqual(infractions[2]['id'], self.ban_hidden.id) def test_returns_empty_for_no_match(self): - url = reverse('bot:infraction-list', host='api') + url = reverse('api:bot:infraction-list') response = self.client.get(f'{url}?type=ban&search=poop') self.assertEqual(response.status_code, 200) self.assertEqual(len(response.json()), 0) def test_ignores_bad_filters(self): - url = reverse('bot:infraction-list', host='api') + url = reverse('api:bot:infraction-list') response = self.client.get(f'{url}?type=ban&hidden=maybe&foo=bar') self.assertEqual(response.status_code, 200) self.assertEqual(len(response.json()), 2) def test_retrieve_single_from_id(self): - url = reverse('bot:infraction-detail', args=(self.ban_inactive.id,), host='api') + url = reverse('api:bot:infraction-detail', args=(self.ban_inactive.id,)) response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertEqual(response.json()['id'], self.ban_inactive.id) def test_retrieve_returns_404_for_absent_id(self): - url = reverse('bot:infraction-detail', args=(1337,), host='api') + url = reverse('api:bot:infraction-detail', args=(1337,)) response = self.client.get(url) self.assertEqual(response.status_code, 404) def test_partial_update(self): - url = reverse('bot:infraction-detail', args=(self.ban_hidden.id,), host='api') + url = reverse('api:bot:infraction-detail', args=(self.ban_hidden.id,)) data = { 'expires_at': '4143-02-15T21:04:31+00:00', 'active': False, @@ -313,7 +313,7 @@ class InfractionTests(APISubdomainTestCase): self.assertEqual(infraction.hidden, self.ban_hidden.hidden) def test_partial_update_returns_400_for_frozen_field(self): - url = reverse('bot:infraction-detail', args=(self.ban_hidden.id,), host='api') + url = reverse('api:bot:infraction-detail', args=(self.ban_hidden.id,)) data = {'user': 6} response = self.client.patch(url, data=data) @@ -323,7 +323,7 @@ class InfractionTests(APISubdomainTestCase): }) -class CreationTests(APISubdomainTestCase): +class CreationTests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): cls.user = User.objects.create( @@ -338,7 +338,7 @@ class CreationTests(APISubdomainTestCase): ) def test_accepts_valid_data(self): - url = reverse('bot:infraction-list', host='api') + url = reverse('api:bot:infraction-list') data = { 'user': self.user.id, 'actor': self.user.id, @@ -367,7 +367,7 @@ class CreationTests(APISubdomainTestCase): self.assertEqual(infraction.active, True) def test_returns_400_for_missing_user(self): - url = reverse('bot:infraction-list', host='api') + url = reverse('api:bot:infraction-list') data = { 'actor': self.user.id, 'type': 'kick', @@ -381,7 +381,7 @@ class CreationTests(APISubdomainTestCase): }) def test_returns_400_for_bad_user(self): - url = reverse('bot:infraction-list', host='api') + url = reverse('api:bot:infraction-list') data = { 'user': 1337, 'actor': self.user.id, @@ -396,7 +396,7 @@ class CreationTests(APISubdomainTestCase): }) def test_returns_400_for_bad_type(self): - url = reverse('bot:infraction-list', host='api') + url = reverse('api:bot:infraction-list') data = { 'user': self.user.id, 'actor': self.user.id, @@ -411,7 +411,7 @@ class CreationTests(APISubdomainTestCase): }) def test_returns_400_for_bad_expired_at_format(self): - url = reverse('bot:infraction-list', host='api') + url = reverse('api:bot:infraction-list') data = { 'user': self.user.id, 'actor': self.user.id, @@ -430,7 +430,7 @@ class CreationTests(APISubdomainTestCase): }) def test_returns_400_for_expiring_non_expirable_type(self): - url = reverse('bot:infraction-list', host='api') + url = reverse('api:bot:infraction-list') for infraction_type in ('kick', 'warning'): data = { @@ -448,7 +448,7 @@ class CreationTests(APISubdomainTestCase): }) def test_returns_400_for_hidden_non_hideable_type(self): - url = reverse('bot:infraction-list', host='api') + url = reverse('api:bot:infraction-list') for infraction_type in ('superstar', 'warning'): data = { @@ -466,7 +466,7 @@ class CreationTests(APISubdomainTestCase): }) def test_returns_400_for_non_hidden_required_hidden_type(self): - url = reverse('bot:infraction-list', host='api') + url = reverse('api:bot:infraction-list') data = { 'user': self.user.id, @@ -484,7 +484,7 @@ class CreationTests(APISubdomainTestCase): def test_returns_400_for_active_infraction_of_type_that_cannot_be_active(self): """Test if the API rejects active infractions for types that cannot be active.""" - url = reverse('bot:infraction-list', host='api') + url = reverse('api:bot:infraction-list') restricted_types = ( ('note', True), ('warning', False), @@ -511,7 +511,7 @@ class CreationTests(APISubdomainTestCase): def test_returns_400_for_second_active_infraction_of_the_same_type(self): """Test if the API rejects a second active infraction of the same type for a given user.""" - url = reverse('bot:infraction-list', host='api') + url = reverse('api:bot:infraction-list') active_infraction_types = ('mute', 'ban', 'superstar') for infraction_type in active_infraction_types: @@ -550,7 +550,7 @@ class CreationTests(APISubdomainTestCase): def test_returns_201_for_second_active_infraction_of_different_type(self): """Test if the API accepts a second active infraction of a different type than the first.""" - url = reverse('bot:infraction-list', host='api') + url = reverse('api:bot:infraction-list') first_active_infraction = { 'user': self.user.id, 'actor': self.user.id, @@ -677,7 +677,7 @@ class CreationTests(APISubdomainTestCase): ) -class InfractionDeletionTests(APISubdomainTestCase): +class InfractionDeletionTests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): cls.user = User.objects.create( @@ -694,20 +694,20 @@ class InfractionDeletionTests(APISubdomainTestCase): ) def test_delete_unknown_infraction_returns_404(self): - url = reverse('bot:infraction-detail', args=('something',), host='api') + url = reverse('api:bot:infraction-detail', args=('something',)) response = self.client.delete(url) self.assertEqual(response.status_code, 404) def test_delete_known_infraction_returns_204(self): - url = reverse('bot:infraction-detail', args=(self.warning.id,), host='api') + url = reverse('api:bot:infraction-detail', args=(self.warning.id,)) response = self.client.delete(url) self.assertEqual(response.status_code, 204) self.assertRaises(Infraction.DoesNotExist, Infraction.objects.get, id=self.warning.id) -class ExpandedTests(APISubdomainTestCase): +class ExpandedTests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): cls.user = User.objects.create( @@ -735,7 +735,7 @@ class ExpandedTests(APISubdomainTestCase): self.assertTrue(field in obj, msg=f'field "{field}" missing from {key}') def test_list_expanded(self): - url = reverse('bot:infraction-list-expanded', host='api') + url = reverse('api:bot:infraction-list-expanded') response = self.client.get(url) self.assertEqual(response.status_code, 200) @@ -747,7 +747,7 @@ class ExpandedTests(APISubdomainTestCase): self.check_expanded_fields(infraction) def test_create_expanded(self): - url = reverse('bot:infraction-list-expanded', host='api') + url = reverse('api:bot:infraction-list-expanded') data = { 'user': self.user.id, 'actor': self.user.id, @@ -762,7 +762,7 @@ class ExpandedTests(APISubdomainTestCase): self.check_expanded_fields(response.json()) def test_retrieve_expanded(self): - url = reverse('bot:infraction-detail-expanded', args=(self.warning.id,), host='api') + url = reverse('api:bot:infraction-detail-expanded', args=(self.warning.id,)) response = self.client.get(url) self.assertEqual(response.status_code, 200) @@ -772,7 +772,7 @@ class ExpandedTests(APISubdomainTestCase): self.check_expanded_fields(infraction) def test_partial_update_expanded(self): - url = reverse('bot:infraction-detail-expanded', args=(self.kick.id,), host='api') + url = reverse('api:bot:infraction-detail-expanded', args=(self.kick.id,)) data = {'active': False} response = self.client.patch(url, data=data) @@ -783,7 +783,7 @@ class ExpandedTests(APISubdomainTestCase): self.check_expanded_fields(response.json()) -class SerializerTests(APISubdomainTestCase): +class SerializerTests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): cls.user = User.objects.create( diff --git a/pydis_site/apps/api/tests/test_nominations.py b/pydis_site/apps/api/tests/test_nominations.py index 9cefbd8f..62b2314c 100644 --- a/pydis_site/apps/api/tests/test_nominations.py +++ b/pydis_site/apps/api/tests/test_nominations.py @@ -1,12 +1,12 @@ from datetime import datetime as dt, timedelta, timezone -from django_hosts.resolvers import reverse +from django.urls import reverse -from .base import APISubdomainTestCase +from .base import AuthenticatedAPITestCase from ..models import Nomination, NominationEntry, User -class CreationTests(APISubdomainTestCase): +class CreationTests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): cls.user = User.objects.create( @@ -21,7 +21,7 @@ class CreationTests(APISubdomainTestCase): ) def test_accepts_valid_data(self): - url = reverse('bot:nomination-list', host='api') + url = reverse('api:bot:nomination-list') data = { 'actor': self.user.id, 'reason': 'Joe Dart on Fender Bass', @@ -46,7 +46,7 @@ class CreationTests(APISubdomainTestCase): self.assertEqual(nomination.active, True) def test_returns_200_on_second_active_nomination_by_different_user(self): - url = reverse('bot:nomination-list', host='api') + url = reverse('api:bot:nomination-list') first_data = { 'actor': self.user.id, 'reason': 'Joe Dart on Fender Bass', @@ -65,7 +65,7 @@ class CreationTests(APISubdomainTestCase): self.assertEqual(response2.status_code, 201) def test_returns_400_on_second_active_nomination_by_existing_nominator(self): - url = reverse('bot:nomination-list', host='api') + url = reverse('api:bot:nomination-list') data = { 'actor': self.user.id, 'reason': 'Joe Dart on Fender Bass', @@ -82,7 +82,7 @@ class CreationTests(APISubdomainTestCase): }) def test_returns_400_for_missing_user(self): - url = reverse('bot:nomination-list', host='api') + url = reverse('api:bot:nomination-list') data = { 'actor': self.user.id, 'reason': 'Joe Dart on Fender Bass', @@ -95,7 +95,7 @@ class CreationTests(APISubdomainTestCase): }) def test_returns_400_for_missing_actor(self): - url = reverse('bot:nomination-list', host='api') + url = reverse('api:bot:nomination-list') data = { 'user': self.user.id, 'reason': 'Joe Dart on Fender Bass', @@ -108,7 +108,7 @@ class CreationTests(APISubdomainTestCase): }) def test_returns_201_for_missing_reason(self): - url = reverse('bot:nomination-list', host='api') + url = reverse('api:bot:nomination-list') data = { 'user': self.user.id, 'actor': self.user.id, @@ -118,7 +118,7 @@ class CreationTests(APISubdomainTestCase): self.assertEqual(response.status_code, 201) def test_returns_400_for_bad_user(self): - url = reverse('bot:nomination-list', host='api') + url = reverse('api:bot:nomination-list') data = { 'user': 1024, 'reason': 'Joe Dart on Fender Bass', @@ -132,7 +132,7 @@ class CreationTests(APISubdomainTestCase): }) def test_returns_400_for_bad_actor(self): - url = reverse('bot:nomination-list', host='api') + url = reverse('api:bot:nomination-list') data = { 'user': self.user.id, 'reason': 'Joe Dart on Fender Bass', @@ -146,7 +146,7 @@ class CreationTests(APISubdomainTestCase): }) def test_returns_400_for_end_reason_at_creation(self): - url = reverse('bot:nomination-list', host='api') + url = reverse('api:bot:nomination-list') data = { 'user': self.user.id, 'reason': 'Joe Dart on Fender Bass', @@ -161,7 +161,7 @@ class CreationTests(APISubdomainTestCase): }) def test_returns_400_for_ended_at_at_creation(self): - url = reverse('bot:nomination-list', host='api') + url = reverse('api:bot:nomination-list') data = { 'user': self.user.id, 'reason': 'Joe Dart on Fender Bass', @@ -176,7 +176,7 @@ class CreationTests(APISubdomainTestCase): }) def test_returns_400_for_inserted_at_at_creation(self): - url = reverse('bot:nomination-list', host='api') + url = reverse('api:bot:nomination-list') data = { 'user': self.user.id, 'reason': 'Joe Dart on Fender Bass', @@ -191,7 +191,7 @@ class CreationTests(APISubdomainTestCase): }) def test_returns_400_for_active_at_creation(self): - url = reverse('bot:nomination-list', host='api') + url = reverse('api:bot:nomination-list') data = { 'user': self.user.id, 'reason': 'Joe Dart on Fender Bass', @@ -206,7 +206,7 @@ class CreationTests(APISubdomainTestCase): }) -class NominationTests(APISubdomainTestCase): +class NominationTests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): cls.user = User.objects.create( @@ -236,7 +236,7 @@ class NominationTests(APISubdomainTestCase): ) def test_returns_200_update_reason_on_active_with_actor(self): - url = reverse('bot:nomination-detail', args=(self.active_nomination.id,), host='api') + url = reverse('api:bot:nomination-detail', args=(self.active_nomination.id,)) data = { 'reason': "He's one funky duck", 'actor': self.user.id @@ -252,7 +252,7 @@ class NominationTests(APISubdomainTestCase): self.assertEqual(nomination_entry.reason, data['reason']) def test_returns_400_on_frozen_field_update(self): - url = reverse('bot:nomination-detail', args=(self.active_nomination.id,), host='api') + url = reverse('api:bot:nomination-detail', args=(self.active_nomination.id,)) data = { 'user': "Theo Katzman" } @@ -264,7 +264,7 @@ class NominationTests(APISubdomainTestCase): }) def test_returns_400_update_end_reason_on_active(self): - url = reverse('bot:nomination-detail', args=(self.active_nomination.id,), host='api') + url = reverse('api:bot:nomination-detail', args=(self.active_nomination.id,)) data = { 'end_reason': 'He started playing jazz' } @@ -276,7 +276,7 @@ class NominationTests(APISubdomainTestCase): }) def test_returns_200_update_reason_on_inactive(self): - url = reverse('bot:nomination-detail', args=(self.inactive_nomination.id,), host='api') + url = reverse('api:bot:nomination-detail', args=(self.inactive_nomination.id,)) data = { 'reason': "He's one funky duck", 'actor': self.user.id @@ -292,7 +292,7 @@ class NominationTests(APISubdomainTestCase): self.assertEqual(nomination_entry.reason, data['reason']) def test_returns_200_update_end_reason_on_inactive(self): - url = reverse('bot:nomination-detail', args=(self.inactive_nomination.id,), host='api') + url = reverse('api:bot:nomination-detail', args=(self.inactive_nomination.id,)) data = { 'end_reason': 'He started playing jazz' } @@ -305,9 +305,8 @@ class NominationTests(APISubdomainTestCase): def test_returns_200_on_valid_end_nomination(self): url = reverse( - 'bot:nomination-detail', + 'api:bot:nomination-detail', args=(self.active_nomination.id,), - host='api' ) data = { 'active': False, @@ -328,9 +327,8 @@ class NominationTests(APISubdomainTestCase): def test_returns_400_on_invalid_field_end_nomination(self): url = reverse( - 'bot:nomination-detail', + 'api:bot:nomination-detail', args=(self.active_nomination.id,), - host='api' ) data = { 'active': False, @@ -344,9 +342,8 @@ class NominationTests(APISubdomainTestCase): def test_returns_400_on_missing_end_reason_end_nomination(self): url = reverse( - 'bot:nomination-detail', + 'api:bot:nomination-detail', args=(self.active_nomination.id,), - host='api' ) data = { 'active': False, @@ -360,9 +357,8 @@ class NominationTests(APISubdomainTestCase): def test_returns_400_on_invalid_use_of_active(self): url = reverse( - 'bot:nomination-detail', + 'api:bot:nomination-detail', args=(self.inactive_nomination.id,), - host='api' ) data = { 'active': False, @@ -376,9 +372,8 @@ class NominationTests(APISubdomainTestCase): def test_returns_404_on_get_unknown_nomination(self): url = reverse( - 'bot:nomination-detail', + 'api:bot:nomination-detail', args=(9999,), - host='api' ) response = self.client.get(url, data={}) @@ -389,9 +384,8 @@ class NominationTests(APISubdomainTestCase): def test_returns_404_on_patch_unknown_nomination(self): url = reverse( - 'bot:nomination-detail', + 'api:bot:nomination-detail', args=(9999,), - host='api' ) response = self.client.patch(url, data={}) @@ -401,7 +395,7 @@ class NominationTests(APISubdomainTestCase): }) def test_returns_405_on_list_put(self): - url = reverse('bot:nomination-list', host='api') + url = reverse('api:bot:nomination-list') response = self.client.put(url, data={}) self.assertEqual(response.status_code, 405) @@ -410,7 +404,7 @@ class NominationTests(APISubdomainTestCase): }) def test_returns_405_on_list_patch(self): - url = reverse('bot:nomination-list', host='api') + url = reverse('api:bot:nomination-list') response = self.client.patch(url, data={}) self.assertEqual(response.status_code, 405) @@ -419,7 +413,7 @@ class NominationTests(APISubdomainTestCase): }) def test_returns_405_on_list_delete(self): - url = reverse('bot:nomination-list', host='api') + url = reverse('api:bot:nomination-list') response = self.client.delete(url, data={}) self.assertEqual(response.status_code, 405) @@ -428,7 +422,7 @@ class NominationTests(APISubdomainTestCase): }) def test_returns_405_on_detail_post(self): - url = reverse('bot:nomination-detail', args=(self.active_nomination.id,), host='api') + url = reverse('api:bot:nomination-detail', args=(self.active_nomination.id,)) response = self.client.post(url, data={}) self.assertEqual(response.status_code, 405) @@ -437,7 +431,7 @@ class NominationTests(APISubdomainTestCase): }) def test_returns_405_on_detail_delete(self): - url = reverse('bot:nomination-detail', args=(self.active_nomination.id,), host='api') + url = reverse('api:bot:nomination-detail', args=(self.active_nomination.id,)) response = self.client.delete(url, data={}) self.assertEqual(response.status_code, 405) @@ -446,7 +440,7 @@ class NominationTests(APISubdomainTestCase): }) def test_returns_405_on_detail_put(self): - url = reverse('bot:nomination-detail', args=(self.active_nomination.id,), host='api') + url = reverse('api:bot:nomination-detail', args=(self.active_nomination.id,)) response = self.client.put(url, data={}) self.assertEqual(response.status_code, 405) @@ -455,7 +449,7 @@ class NominationTests(APISubdomainTestCase): }) def test_filter_returns_0_objects_unknown_user__id(self): - url = reverse('bot:nomination-list', host='api') + url = reverse('api:bot:nomination-list') response = self.client.get( url, @@ -470,7 +464,7 @@ class NominationTests(APISubdomainTestCase): self.assertEqual(len(infractions), 0) def test_filter_returns_2_objects_for_testdata(self): - url = reverse('bot:nomination-list', host='api') + url = reverse('api:bot:nomination-list') response = self.client.get( url, @@ -485,14 +479,14 @@ class NominationTests(APISubdomainTestCase): self.assertEqual(len(infractions), 2) def test_patch_nomination_set_reviewed_of_active_nomination(self): - url = reverse('api:nomination-detail', args=(self.active_nomination.id,), host='api') + url = reverse('api:bot:nomination-detail', args=(self.active_nomination.id,)) data = {'reviewed': True} response = self.client.patch(url, data=data) self.assertEqual(response.status_code, 200) def test_patch_nomination_set_reviewed_of_inactive_nomination(self): - url = reverse('api:nomination-detail', args=(self.inactive_nomination.id,), host='api') + url = reverse('api:bot:nomination-detail', args=(self.inactive_nomination.id,)) data = {'reviewed': True} response = self.client.patch(url, data=data) @@ -502,7 +496,7 @@ class NominationTests(APISubdomainTestCase): }) def test_patch_nomination_set_reviewed_and_end(self): - url = reverse('api:nomination-detail', args=(self.active_nomination.id,), host='api') + url = reverse('api:bot:nomination-detail', args=(self.active_nomination.id,)) data = {'reviewed': True, 'active': False, 'end_reason': "What?"} response = self.client.patch(url, data=data) @@ -512,7 +506,7 @@ class NominationTests(APISubdomainTestCase): }) def test_modifying_reason_without_actor(self): - url = reverse('api:nomination-detail', args=(self.active_nomination.id,), host='api') + url = reverse('api:bot:nomination-detail', args=(self.active_nomination.id,)) data = {'reason': 'That is my reason!'} response = self.client.patch(url, data=data) @@ -522,7 +516,7 @@ class NominationTests(APISubdomainTestCase): }) def test_modifying_reason_with_unknown_actor(self): - url = reverse('api:nomination-detail', args=(self.active_nomination.id,), host='api') + url = reverse('api:bot:nomination-detail', args=(self.active_nomination.id,)) data = {'reason': 'That is my reason!', 'actor': 90909090909090} response = self.client.patch(url, data=data) diff --git a/pydis_site/apps/api/tests/test_off_topic_channel_names.py b/pydis_site/apps/api/tests/test_off_topic_channel_names.py index 3ab8b22d..63993978 100644 --- a/pydis_site/apps/api/tests/test_off_topic_channel_names.py +++ b/pydis_site/apps/api/tests/test_off_topic_channel_names.py @@ -1,33 +1,33 @@ -from django_hosts.resolvers import reverse +from django.urls import reverse -from .base import APISubdomainTestCase +from .base import AuthenticatedAPITestCase from ..models import OffTopicChannelName -class UnauthenticatedTests(APISubdomainTestCase): +class UnauthenticatedTests(AuthenticatedAPITestCase): def setUp(self): super().setUp() self.client.force_authenticate(user=None) def test_cannot_read_off_topic_channel_name_list(self): """Return a 401 response when not authenticated.""" - url = reverse('bot:offtopicchannelname-list', host='api') + url = reverse('api:bot:offtopicchannelname-list') response = self.client.get(url) self.assertEqual(response.status_code, 401) def test_cannot_read_off_topic_channel_name_list_with_random_item_param(self): """Return a 401 response when `random_items` provided and not authenticated.""" - url = reverse('bot:offtopicchannelname-list', host='api') + url = reverse('api:bot:offtopicchannelname-list') response = self.client.get(f'{url}?random_items=no') self.assertEqual(response.status_code, 401) -class EmptyDatabaseTests(APISubdomainTestCase): +class EmptyDatabaseTests(AuthenticatedAPITestCase): def test_returns_empty_object(self): """Return empty list when no names in database.""" - url = reverse('bot:offtopicchannelname-list', host='api') + url = reverse('api:bot:offtopicchannelname-list') response = self.client.get(url) self.assertEqual(response.status_code, 200) @@ -35,7 +35,7 @@ class EmptyDatabaseTests(APISubdomainTestCase): def test_returns_empty_list_with_get_all_param(self): """Return empty list when no names and `random_items` param provided.""" - url = reverse('bot:offtopicchannelname-list', host='api') + url = reverse('api:bot:offtopicchannelname-list') response = self.client.get(f'{url}?random_items=5') self.assertEqual(response.status_code, 200) @@ -43,7 +43,7 @@ class EmptyDatabaseTests(APISubdomainTestCase): def test_returns_400_for_bad_random_items_param(self): """Return error message when passing not integer as `random_items`.""" - url = reverse('bot:offtopicchannelname-list', host='api') + url = reverse('api:bot:offtopicchannelname-list') response = self.client.get(f'{url}?random_items=totally-a-valid-integer') self.assertEqual(response.status_code, 400) @@ -53,7 +53,7 @@ class EmptyDatabaseTests(APISubdomainTestCase): def test_returns_400_for_negative_random_items_param(self): """Return error message when passing negative int as `random_items`.""" - url = reverse('bot:offtopicchannelname-list', host='api') + url = reverse('api:bot:offtopicchannelname-list') response = self.client.get(f'{url}?random_items=-5') self.assertEqual(response.status_code, 400) @@ -62,7 +62,7 @@ class EmptyDatabaseTests(APISubdomainTestCase): }) -class ListTests(APISubdomainTestCase): +class ListTests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): cls.test_name = OffTopicChannelName.objects.create(name='lemons-lemonade-stand', used=False) @@ -70,7 +70,7 @@ class ListTests(APISubdomainTestCase): def test_returns_name_in_list(self): """Return all off-topic channel names.""" - url = reverse('bot:offtopicchannelname-list', host='api') + url = reverse('api:bot:offtopicchannelname-list') response = self.client.get(url) self.assertEqual(response.status_code, 200) @@ -84,7 +84,7 @@ class ListTests(APISubdomainTestCase): def test_returns_single_item_with_random_items_param_set_to_1(self): """Return not-used name instead used.""" - url = reverse('bot:offtopicchannelname-list', host='api') + url = reverse('api:bot:offtopicchannelname-list') response = self.client.get(f'{url}?random_items=1') self.assertEqual(response.status_code, 200) @@ -93,25 +93,25 @@ class ListTests(APISubdomainTestCase): def test_running_out_of_names_with_random_parameter(self): """Reset names `used` parameter to `False` when running out of names.""" - url = reverse('bot:offtopicchannelname-list', host='api') + url = reverse('api:bot:offtopicchannelname-list') response = self.client.get(f'{url}?random_items=2') self.assertEqual(response.status_code, 200) self.assertEqual(response.json(), [self.test_name.name, self.test_name_2.name]) -class CreationTests(APISubdomainTestCase): +class CreationTests(AuthenticatedAPITestCase): def setUp(self): super().setUp() - url = reverse('bot:offtopicchannelname-list', host='api') + url = reverse('api:bot:offtopicchannelname-list') self.name = "abcdefghijklmnopqrstuvwxyz-0123456789" response = self.client.post(f'{url}?name={self.name}') self.assertEqual(response.status_code, 201) def test_returns_201_for_unicode_chars(self): """Accept all valid characters.""" - url = reverse('bot:offtopicchannelname-list', host='api') + url = reverse('api:bot:offtopicchannelname-list') names = ( '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', 'ǃ?’', @@ -123,7 +123,7 @@ class CreationTests(APISubdomainTestCase): def test_returns_400_for_missing_name_param(self): """Return error message when name not provided.""" - url = reverse('bot:offtopicchannelname-list', host='api') + url = reverse('api:bot:offtopicchannelname-list') response = self.client.post(url) self.assertEqual(response.status_code, 400) self.assertEqual(response.json(), { @@ -132,7 +132,7 @@ class CreationTests(APISubdomainTestCase): def test_returns_400_for_bad_name_param(self): """Return error message when invalid characters provided.""" - url = reverse('bot:offtopicchannelname-list', host='api') + url = reverse('api:bot:offtopicchannelname-list') invalid_names = ( 'space between words', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', @@ -147,7 +147,7 @@ class CreationTests(APISubdomainTestCase): }) -class DeletionTests(APISubdomainTestCase): +class DeletionTests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): cls.test_name = OffTopicChannelName.objects.create(name='lemons-lemonade-stand') @@ -155,25 +155,25 @@ class DeletionTests(APISubdomainTestCase): def test_deleting_unknown_name_returns_404(self): """Return 404 reponse when trying to delete unknown name.""" - url = reverse('bot:offtopicchannelname-detail', args=('unknown-name',), host='api') + url = reverse('api:bot:offtopicchannelname-detail', args=('unknown-name',)) response = self.client.delete(url) self.assertEqual(response.status_code, 404) def test_deleting_known_name_returns_204(self): """Return 204 response when deleting was successful.""" - url = reverse('bot:offtopicchannelname-detail', args=(self.test_name.name,), host='api') + url = reverse('api:bot:offtopicchannelname-detail', args=(self.test_name.name,)) response = self.client.delete(url) self.assertEqual(response.status_code, 204) def test_name_gets_deleted(self): """Name gets actually deleted.""" - url = reverse('bot:offtopicchannelname-detail', args=(self.test_name_2.name,), host='api') + url = reverse('api:bot:offtopicchannelname-detail', args=(self.test_name_2.name,)) response = self.client.delete(url) self.assertEqual(response.status_code, 204) - url = reverse('bot:offtopicchannelname-list', host='api') + url = reverse('api:bot:offtopicchannelname-list') response = self.client.get(url) self.assertNotIn(self.test_name_2.name, response.json()) diff --git a/pydis_site/apps/api/tests/test_offensive_message.py b/pydis_site/apps/api/tests/test_offensive_message.py index 0f3dbffa..9b79b38c 100644 --- a/pydis_site/apps/api/tests/test_offensive_message.py +++ b/pydis_site/apps/api/tests/test_offensive_message.py @@ -1,14 +1,14 @@ import datetime -from django_hosts.resolvers import reverse +from django.urls import reverse -from .base import APISubdomainTestCase +from .base import AuthenticatedAPITestCase from ..models import OffensiveMessage -class CreationTests(APISubdomainTestCase): +class CreationTests(AuthenticatedAPITestCase): def test_accept_valid_data(self): - url = reverse('bot:offensivemessage-list', host='api') + url = reverse('api:bot:offensivemessage-list') delete_at = datetime.datetime.now() + datetime.timedelta(days=1) data = { 'id': '602951077675139072', @@ -31,7 +31,7 @@ class CreationTests(APISubdomainTestCase): self.assertEqual(data['channel_id'], str(offensive_message.channel_id)) def test_returns_400_on_non_future_date(self): - url = reverse('bot:offensivemessage-list', host='api') + url = reverse('api:bot:offensivemessage-list') delete_at = datetime.datetime.now() - datetime.timedelta(days=1) data = { 'id': '602951077675139072', @@ -45,7 +45,7 @@ class CreationTests(APISubdomainTestCase): }) def test_returns_400_on_negative_id_or_channel_id(self): - url = reverse('bot:offensivemessage-list', host='api') + url = reverse('api:bot:offensivemessage-list') delete_at = datetime.datetime.now() + datetime.timedelta(days=1) data = { 'id': '602951077675139072', @@ -69,7 +69,7 @@ class CreationTests(APISubdomainTestCase): }) -class ListTests(APISubdomainTestCase): +class ListTests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): delete_at = datetime.datetime.now() + datetime.timedelta(days=1) @@ -100,7 +100,7 @@ class ListTests(APISubdomainTestCase): cls.messages[1]['delete_date'] = delete_at.isoformat() + 'Z' def test_get_data(self): - url = reverse('bot:offensivemessage-list', host='api') + url = reverse('api:bot:offensivemessage-list') response = self.client.get(url) self.assertEqual(response.status_code, 200) @@ -108,7 +108,7 @@ class ListTests(APISubdomainTestCase): self.assertEqual(response.json(), self.messages) -class DeletionTests(APISubdomainTestCase): +class DeletionTests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): delete_at = datetime.datetime.now(tz=datetime.timezone.utc) + datetime.timedelta(days=1) @@ -121,7 +121,7 @@ class DeletionTests(APISubdomainTestCase): def test_delete_data(self): url = reverse( - 'bot:offensivemessage-detail', host='api', args=(self.valid_offensive_message.id,) + 'api:bot:offensivemessage-detail', args=(self.valid_offensive_message.id,) ) response = self.client.delete(url) @@ -132,7 +132,7 @@ class DeletionTests(APISubdomainTestCase): ) -class NotAllowedMethodsTests(APISubdomainTestCase): +class NotAllowedMethodsTests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): delete_at = datetime.datetime.now(tz=datetime.timezone.utc) + datetime.timedelta(days=1) @@ -145,7 +145,7 @@ class NotAllowedMethodsTests(APISubdomainTestCase): def test_returns_405_for_patch_and_put_requests(self): url = reverse( - 'bot:offensivemessage-detail', host='api', args=(self.valid_offensive_message.id,) + 'api:bot:offensivemessage-detail', args=(self.valid_offensive_message.id,) ) not_allowed_methods = (self.client.patch, self.client.put) diff --git a/pydis_site/apps/api/tests/test_reminders.py b/pydis_site/apps/api/tests/test_reminders.py index 9dffb668..709685bc 100644 --- a/pydis_site/apps/api/tests/test_reminders.py +++ b/pydis_site/apps/api/tests/test_reminders.py @@ -1,52 +1,52 @@ from datetime import datetime from django.forms.models import model_to_dict -from django_hosts.resolvers import reverse +from django.urls import reverse -from .base import APISubdomainTestCase +from .base import AuthenticatedAPITestCase from ..models import Reminder, User -class UnauthedReminderAPITests(APISubdomainTestCase): +class UnauthedReminderAPITests(AuthenticatedAPITestCase): def setUp(self): super().setUp() self.client.force_authenticate(user=None) def test_list_returns_401(self): - url = reverse('bot:reminder-list', host='api') + url = reverse('api:bot:reminder-list') response = self.client.get(url) self.assertEqual(response.status_code, 401) def test_create_returns_401(self): - url = reverse('bot:reminder-list', host='api') + url = reverse('api:bot:reminder-list') response = self.client.post(url, data={'not': 'important'}) self.assertEqual(response.status_code, 401) def test_delete_returns_401(self): - url = reverse('bot:reminder-detail', args=('1234',), host='api') + url = reverse('api:bot:reminder-detail', args=('1234',)) response = self.client.delete(url) self.assertEqual(response.status_code, 401) -class EmptyDatabaseReminderAPITests(APISubdomainTestCase): +class EmptyDatabaseReminderAPITests(AuthenticatedAPITestCase): def test_list_all_returns_empty_list(self): - url = reverse('bot:reminder-list', host='api') + url = reverse('api:bot:reminder-list') response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertEqual(response.json(), []) def test_delete_returns_404(self): - url = reverse('bot:reminder-detail', args=('1234',), host='api') + url = reverse('api:bot:reminder-detail', args=('1234',)) response = self.client.delete(url) self.assertEqual(response.status_code, 404) -class ReminderCreationTests(APISubdomainTestCase): +class ReminderCreationTests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): cls.author = User.objects.create( @@ -64,7 +64,7 @@ class ReminderCreationTests(APISubdomainTestCase): 'channel_id': 123, 'mentions': [8888, 9999], } - url = reverse('bot:reminder-list', host='api') + url = reverse('api:bot:reminder-list') response = self.client.post(url, data=data) self.assertEqual(response.status_code, 201) self.assertIsNotNone(Reminder.objects.filter(id=1).first()) @@ -73,13 +73,13 @@ class ReminderCreationTests(APISubdomainTestCase): data = { 'author': self.author.id, # Missing multiple required fields } - url = reverse('bot:reminder-list', host='api') + url = reverse('api:bot:reminder-list') response = self.client.post(url, data=data) self.assertEqual(response.status_code, 400) self.assertRaises(Reminder.DoesNotExist, Reminder.objects.get, id=1) -class ReminderDeletionTests(APISubdomainTestCase): +class ReminderDeletionTests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): cls.author = User.objects.create( @@ -97,20 +97,20 @@ class ReminderDeletionTests(APISubdomainTestCase): ) def test_delete_unknown_reminder_returns_404(self): - url = reverse('bot:reminder-detail', args=('something',), host='api') + url = reverse('api:bot:reminder-detail', args=('something',)) response = self.client.delete(url) self.assertEqual(response.status_code, 404) def test_delete_known_reminder_returns_204(self): - url = reverse('bot:reminder-detail', args=(self.reminder.id,), host='api') + url = reverse('api:bot:reminder-detail', args=(self.reminder.id,)) response = self.client.delete(url) self.assertEqual(response.status_code, 204) self.assertRaises(Reminder.DoesNotExist, Reminder.objects.get, id=self.reminder.id) -class ReminderListTests(APISubdomainTestCase): +class ReminderListTests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): cls.author = User.objects.create( @@ -142,28 +142,28 @@ class ReminderListTests(APISubdomainTestCase): cls.rem_dict_two['expiration'] += 'Z' # Massaging a quirk of the response time format def test_reminders_in_full_list(self): - url = reverse('bot:reminder-list', host='api') + url = reverse('api:bot:reminder-list') response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertCountEqual(response.json(), [self.rem_dict_one, self.rem_dict_two]) def test_filter_search(self): - url = reverse('bot:reminder-list', host='api') + url = reverse('api:bot:reminder-list') response = self.client.get(f'{url}?search={self.author.name}') self.assertEqual(response.status_code, 200) self.assertCountEqual(response.json(), [self.rem_dict_one, self.rem_dict_two]) def test_filter_field(self): - url = reverse('bot:reminder-list', host='api') + url = reverse('api:bot:reminder-list') response = self.client.get(f'{url}?active=true') self.assertEqual(response.status_code, 200) self.assertEqual(response.json(), [self.rem_dict_one]) -class ReminderRetrieveTests(APISubdomainTestCase): +class ReminderRetrieveTests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): cls.author = User.objects.create( @@ -181,17 +181,17 @@ class ReminderRetrieveTests(APISubdomainTestCase): ) def test_retrieve_unknown_returns_404(self): - url = reverse('bot:reminder-detail', args=("not_an_id",), host='api') + url = reverse('api:bot:reminder-detail', args=("not_an_id",)) response = self.client.get(url) self.assertEqual(response.status_code, 404) def test_retrieve_known_returns_200(self): - url = reverse('bot:reminder-detail', args=(self.reminder.id,), host='api') + url = reverse('api:bot:reminder-detail', args=(self.reminder.id,)) response = self.client.get(url) self.assertEqual(response.status_code, 200) -class ReminderUpdateTests(APISubdomainTestCase): +class ReminderUpdateTests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): cls.author = User.objects.create( @@ -211,7 +211,7 @@ class ReminderUpdateTests(APISubdomainTestCase): cls.data = {'content': 'Oops I forgot'} def test_patch_updates_record(self): - url = reverse('bot:reminder-detail', args=(self.reminder.id,), host='api') + url = reverse('api:bot:reminder-detail', args=(self.reminder.id,)) response = self.client.patch(url, data=self.data) self.assertEqual(response.status_code, 200) diff --git a/pydis_site/apps/api/tests/test_roles.py b/pydis_site/apps/api/tests/test_roles.py index 4d1a430c..d39cea4d 100644 --- a/pydis_site/apps/api/tests/test_roles.py +++ b/pydis_site/apps/api/tests/test_roles.py @@ -1,10 +1,10 @@ -from django_hosts.resolvers import reverse +from django.urls import reverse -from .base import APISubdomainTestCase +from .base import AuthenticatedAPITestCase from ..models import Role -class CreationTests(APISubdomainTestCase): +class CreationTests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): cls.admins_role = Role.objects.create( @@ -78,7 +78,7 @@ class CreationTests(APISubdomainTestCase): def test_role_list(self): """Tests the GET list-view and validates the contents.""" - url = reverse('bot:role-list', host='api') + url = reverse('api:bot:role-list') response = self.client.get(url) self.assertContains(response, text="id", count=4, status_code=200) @@ -92,7 +92,7 @@ class CreationTests(APISubdomainTestCase): def test_role_get_detail_success(self): """Tests GET detail view of an existing role.""" - url = reverse('bot:role-detail', host='api', args=(self.admins_role.id, )) + url = reverse('api:bot:role-detail', args=(self.admins_role.id, )) response = self.client.get(url) self.assertContains(response, text="id", count=1, status_code=200) @@ -107,7 +107,7 @@ class CreationTests(APISubdomainTestCase): def test_role_post_201(self): """Tests creation of a role with a valid request.""" - url = reverse('bot:role-list', host='api') + url = reverse('api:bot:role-list') data = { "id": 1234567890, "name": "Role Creation Test", @@ -120,7 +120,7 @@ class CreationTests(APISubdomainTestCase): def test_role_post_invalid_request_body(self): """Tests creation of a role with an invalid request body.""" - url = reverse('bot:role-list', host='api') + url = reverse('api:bot:role-list') data = { "name": "Role Creation Test", "permissions": 0b01010010101, @@ -133,7 +133,7 @@ class CreationTests(APISubdomainTestCase): def test_role_put_200(self): """Tests PUT role request with valid request body.""" - url = reverse('bot:role-detail', host='api', args=(self.admins_role.id,)) + url = reverse('api:bot:role-detail', args=(self.admins_role.id,)) data = { "id": 123454321, "name": "Role Put Alteration Test", @@ -153,7 +153,7 @@ class CreationTests(APISubdomainTestCase): def test_role_put_invalid_request_body(self): """Tests PUT role request with invalid request body.""" - url = reverse('bot:role-detail', host='api', args=(self.admins_role.id,)) + url = reverse('api:bot:role-detail', args=(self.admins_role.id,)) data = { "name": "Role Put Alteration Test", "permissions": 255, @@ -165,7 +165,7 @@ class CreationTests(APISubdomainTestCase): def test_role_patch_200(self): """Tests PATCH role request with valid request body.""" - url = reverse('bot:role-detail', host='api', args=(self.admins_role.id,)) + url = reverse('api:bot:role-detail', args=(self.admins_role.id,)) data = { "name": "Owners" } @@ -177,13 +177,13 @@ class CreationTests(APISubdomainTestCase): def test_role_delete_200(self): """Tests DELETE requests for existing role.""" - url = reverse('bot:role-detail', host='api', args=(self.admins_role.id,)) + url = reverse('api:bot:role-detail', args=(self.admins_role.id,)) response = self.client.delete(url) self.assertEqual(response.status_code, 204) def test_role_detail_404_all_methods(self): """Tests detail view with non-existing ID.""" - url = reverse('bot:role-detail', host='api', args=(20190815,)) + url = reverse('api:bot:role-detail', args=(20190815,)) for method in ('get', 'put', 'patch', 'delete'): response = getattr(self.client, method)(url) diff --git a/pydis_site/apps/api/tests/test_rules.py b/pydis_site/apps/api/tests/test_rules.py index c94f89cc..d08c5fae 100644 --- a/pydis_site/apps/api/tests/test_rules.py +++ b/pydis_site/apps/api/tests/test_rules.py @@ -1,23 +1,23 @@ -from django_hosts.resolvers import reverse +from django.urls import reverse -from .base import APISubdomainTestCase +from .base import AuthenticatedAPITestCase from ..views import RulesView -class RuleAPITests(APISubdomainTestCase): +class RuleAPITests(AuthenticatedAPITestCase): def setUp(self): super().setUp() self.client.force_authenticate(user=None) def test_can_access_rules_view(self): - url = reverse('rules', host='api') + url = reverse('api:rules') response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertIsInstance(response.json(), list) def test_link_format_query_param_produces_different_results(self): - url = reverse('rules', host='api') + url = reverse('api:rules') markdown_links_response = self.client.get(url + '?link_format=md') html_links_response = self.client.get(url + '?link_format=html') self.assertNotEqual( @@ -30,6 +30,6 @@ class RuleAPITests(APISubdomainTestCase): RulesView._format_link("a", "b", "c") def test_get_returns_400_for_wrong_link_format(self): - url = reverse('rules', host='api') + url = reverse('api:rules') response = self.client.get(url + '?link_format=unknown') self.assertEqual(response.status_code, 400) diff --git a/pydis_site/apps/api/tests/test_users.py b/pydis_site/apps/api/tests/test_users.py index c43b916a..bed6342e 100644 --- a/pydis_site/apps/api/tests/test_users.py +++ b/pydis_site/apps/api/tests/test_users.py @@ -1,44 +1,44 @@ from unittest.mock import patch from django.core.exceptions import ObjectDoesNotExist -from django_hosts.resolvers import reverse +from django.urls import reverse -from .base import APISubdomainTestCase +from .base import AuthenticatedAPITestCase from ..models import Role, User from ..models.bot.metricity import NotFound -class UnauthedUserAPITests(APISubdomainTestCase): +class UnauthedUserAPITests(AuthenticatedAPITestCase): def setUp(self): super().setUp() self.client.force_authenticate(user=None) def test_detail_lookup_returns_401(self): - url = reverse('bot:user-detail', args=('whatever',), host='api') + url = reverse('api:bot:user-detail', args=('whatever',)) response = self.client.get(url) self.assertEqual(response.status_code, 401) def test_list_returns_401(self): - url = reverse('bot:user-list', host='api') + url = reverse('api:bot:user-list') response = self.client.get(url) self.assertEqual(response.status_code, 401) def test_create_returns_401(self): - url = reverse('bot:user-list', host='api') + url = reverse('api:bot:user-list') response = self.client.post(url, data={'hi': 'there'}) self.assertEqual(response.status_code, 401) def test_delete_returns_401(self): - url = reverse('bot:user-detail', args=('whatever',), host='api') + url = reverse('api:bot:user-detail', args=('whatever',)) response = self.client.delete(url) self.assertEqual(response.status_code, 401) -class CreationTests(APISubdomainTestCase): +class CreationTests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): cls.role = Role.objects.create( @@ -57,7 +57,7 @@ class CreationTests(APISubdomainTestCase): ) def test_accepts_valid_data(self): - url = reverse('bot:user-list', host='api') + url = reverse('api:bot:user-list') data = { 'id': 42, 'name': "Test", @@ -78,7 +78,7 @@ class CreationTests(APISubdomainTestCase): self.assertEqual(user.in_guild, data['in_guild']) def test_supports_multi_creation(self): - url = reverse('bot:user-list', host='api') + url = reverse('api:bot:user-list') data = [ { 'id': 5, @@ -103,7 +103,7 @@ class CreationTests(APISubdomainTestCase): self.assertEqual(response.json(), []) def test_returns_400_for_unknown_role_id(self): - url = reverse('bot:user-list', host='api') + url = reverse('api:bot:user-list') data = { 'id': 5, 'name': "test man", @@ -117,7 +117,7 @@ class CreationTests(APISubdomainTestCase): self.assertEqual(response.status_code, 400) def test_returns_400_for_bad_data(self): - url = reverse('bot:user-list', host='api') + url = reverse('api:bot:user-list') data = { 'id': True, 'discriminator': "totally!" @@ -128,7 +128,7 @@ class CreationTests(APISubdomainTestCase): def test_returns_400_for_user_recreation(self): """Return 201 if User is already present in database as it skips User creation.""" - url = reverse('bot:user-list', host='api') + url = reverse('api:bot:user-list') data = [{ 'id': 11, 'name': 'You saw nothing.', @@ -140,7 +140,7 @@ class CreationTests(APISubdomainTestCase): def test_returns_400_for_duplicate_request_users(self): """Return 400 if 2 Users with same ID is passed in the request data.""" - url = reverse('bot:user-list', host='api') + url = reverse('api:bot:user-list') data = [ { 'id': 11, @@ -160,7 +160,7 @@ class CreationTests(APISubdomainTestCase): def test_returns_400_for_existing_user(self): """Returns 400 if user is already present in DB.""" - url = reverse('bot:user-list', host='api') + url = reverse('api:bot:user-list') data = { 'id': 11, 'name': 'You saw nothing part 3.', @@ -171,7 +171,7 @@ class CreationTests(APISubdomainTestCase): self.assertEqual(response.status_code, 400) -class MultiPatchTests(APISubdomainTestCase): +class MultiPatchTests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): cls.role_developer = Role.objects.create( @@ -195,7 +195,7 @@ class MultiPatchTests(APISubdomainTestCase): ) def test_multiple_users_patch(self): - url = reverse("bot:user-bulk-patch", host="api") + url = reverse("api:bot:user-bulk-patch") data = [ { "id": 1, @@ -218,7 +218,7 @@ class MultiPatchTests(APISubdomainTestCase): self.assertEqual(user_2.name, data[1]["name"]) def test_returns_400_for_missing_user_id(self): - url = reverse("bot:user-bulk-patch", host="api") + url = reverse("api:bot:user-bulk-patch") data = [ { "name": "I am ghost user!", @@ -234,7 +234,7 @@ class MultiPatchTests(APISubdomainTestCase): self.assertEqual(response.status_code, 400) def test_returns_404_for_not_found_user(self): - url = reverse("bot:user-bulk-patch", host="api") + url = reverse("api:bot:user-bulk-patch") data = [ { "id": 1, @@ -252,7 +252,7 @@ class MultiPatchTests(APISubdomainTestCase): self.assertEqual(response.status_code, 404) def test_returns_400_for_bad_data(self): - url = reverse("bot:user-bulk-patch", host="api") + url = reverse("api:bot:user-bulk-patch") data = [ { "id": 1, @@ -268,7 +268,7 @@ class MultiPatchTests(APISubdomainTestCase): self.assertEqual(response.status_code, 400) def test_returns_400_for_insufficient_data(self): - url = reverse("bot:user-bulk-patch", host="api") + url = reverse("api:bot:user-bulk-patch") data = [ { "id": 1, @@ -282,7 +282,7 @@ class MultiPatchTests(APISubdomainTestCase): def test_returns_400_for_duplicate_request_users(self): """Return 400 if 2 Users with same ID is passed in the request data.""" - url = reverse("bot:user-bulk-patch", host="api") + url = reverse("api:bot:user-bulk-patch") data = [ { 'id': 1, @@ -297,7 +297,7 @@ class MultiPatchTests(APISubdomainTestCase): self.assertEqual(response.status_code, 400) -class UserModelTests(APISubdomainTestCase): +class UserModelTests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): cls.role_top = Role.objects.create( @@ -353,7 +353,7 @@ class UserModelTests(APISubdomainTestCase): self.assertEqual(self.user_with_roles.username, "Test User with two roles#0001") -class UserPaginatorTests(APISubdomainTestCase): +class UserPaginatorTests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): users = [] @@ -367,7 +367,7 @@ class UserPaginatorTests(APISubdomainTestCase): cls.users = User.objects.bulk_create(users) def test_returns_single_page_response(self): - url = reverse("bot:user-list", host="api") + url = reverse("api:bot:user-list") response = self.client.get(url).json() self.assertIsNone(response["next_page_no"]) self.assertIsNone(response["previous_page_no"]) @@ -379,7 +379,7 @@ class UserPaginatorTests(APISubdomainTestCase): discriminator=1111, in_guild=True ) - url = reverse("bot:user-list", host="api") + url = reverse("api:bot:user-list") response = self.client.get(url).json() self.assertEqual(2, response["next_page_no"]) @@ -390,12 +390,12 @@ class UserPaginatorTests(APISubdomainTestCase): discriminator=1111, in_guild=True ) - url = reverse("bot:user-list", host="api") + url = reverse("api:bot:user-list") response = self.client.get(url, {"page": 2}).json() self.assertEqual(1, response["previous_page_no"]) -class UserMetricityTests(APISubdomainTestCase): +class UserMetricityTests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): User.objects.create( @@ -413,7 +413,7 @@ class UserMetricityTests(APISubdomainTestCase): self.mock_metricity_user(joined_at, total_messages, total_blocks, []) # When - url = reverse('bot:user-metricity-data', args=[0], host='api') + url = reverse('api:bot:user-metricity-data', args=[0]) response = self.client.get(url) # Then @@ -430,7 +430,7 @@ class UserMetricityTests(APISubdomainTestCase): self.mock_no_metricity_user() # When - url = reverse('bot:user-metricity-data', args=[0], host='api') + url = reverse('api:bot:user-metricity-data', args=[0]) response = self.client.get(url) # Then @@ -441,7 +441,7 @@ class UserMetricityTests(APISubdomainTestCase): self.mock_no_metricity_user() # When - url = reverse('bot:user-metricity-review-data', args=[0], host='api') + url = reverse('api:bot:user-metricity-review-data', args=[0]) response = self.client.get(url) # Then @@ -460,7 +460,7 @@ class UserMetricityTests(APISubdomainTestCase): with patch("pydis_site.apps.api.viewsets.bot.user.Infraction.objects.get") as p: p.side_effect = case['exception'] - url = reverse('bot:user-metricity-data', args=[0], host='api') + url = reverse('api:bot:user-metricity-data', args=[0]) response = self.client.get(url) self.assertEqual(response.status_code, 200) @@ -475,7 +475,7 @@ class UserMetricityTests(APISubdomainTestCase): self.mock_metricity_user(joined_at, total_messages, total_blocks, channel_activity) # When - url = reverse('bot:user-metricity-review-data', args=[0], host='api') + url = reverse('api:bot:user-metricity-review-data', args=[0]) response = self.client.get(url) # Then -- cgit v1.2.3 From 832880cfac4206aaba0e7de8f005c6425da7a8f3 Mon Sep 17 00:00:00 2001 From: RohanJnr Date: Thu, 10 Jun 2021 02:11:40 +0530 Subject: Add tests for active params. --- .../apps/api/tests/test_off_topic_channel_names.py | 38 +++++++++++++++++++--- 1 file changed, 34 insertions(+), 4 deletions(-) (limited to 'pydis_site/apps/api/tests') diff --git a/pydis_site/apps/api/tests/test_off_topic_channel_names.py b/pydis_site/apps/api/tests/test_off_topic_channel_names.py index 3ab8b22d..a407654c 100644 --- a/pydis_site/apps/api/tests/test_off_topic_channel_names.py +++ b/pydis_site/apps/api/tests/test_off_topic_channel_names.py @@ -65,8 +65,15 @@ class EmptyDatabaseTests(APISubdomainTestCase): class ListTests(APISubdomainTestCase): @classmethod def setUpTestData(cls): - cls.test_name = OffTopicChannelName.objects.create(name='lemons-lemonade-stand', used=False) - cls.test_name_2 = OffTopicChannelName.objects.create(name='bbq-with-bisk', used=True) + cls.test_name = OffTopicChannelName.objects.create( + name='lemons-lemonade-stand', used=False, active=True + ) + cls.test_name_2 = OffTopicChannelName.objects.create( + name='bbq-with-bisk', used=True, active=True + ) + cls.test_name_3 = OffTopicChannelName.objects.create( + name="frozen-with-iceman", used=True, active=False + ) def test_returns_name_in_list(self): """Return all off-topic channel names.""" @@ -78,7 +85,8 @@ class ListTests(APISubdomainTestCase): response.json(), [ self.test_name.name, - self.test_name_2.name + self.test_name_2.name, + self.test_name_3.name ] ) @@ -97,7 +105,29 @@ class ListTests(APISubdomainTestCase): response = self.client.get(f'{url}?random_items=2') self.assertEqual(response.status_code, 200) - self.assertEqual(response.json(), [self.test_name.name, self.test_name_2.name]) + self.assertEqual(response.json(), [self.test_name.name, self.test_name_3.name]) + + def test_returns_inactive_ot_names(self): + """Return inactive off topic names.""" + url = reverse('bot:offtopicchannelname-list', host="api") + response = self.client.get(f"{url}?active=false") + + self.assertEqual(response.status_code, 200) + self.assertEqual( + response.json(), + [self.test_name_3.name] + ) + + def test_returns_active_ot_names(self): + """Return active off topic names.""" + url = reverse('bot:offtopicchannelname-list', host="api") + response = self.client.get(f"{url}?active=true") + + self.assertEqual(response.status_code, 200) + self.assertEqual( + response.json(), + [self.test_name.name, self.test_name_2.name] + ) class CreationTests(APISubdomainTestCase): -- cgit v1.2.3 From 3795b6d6de005f0ed00c37cf042eaca01d0a4769 Mon Sep 17 00:00:00 2001 From: RohanJnr Date: Thu, 10 Jun 2021 02:32:17 +0530 Subject: Use assertListEqual where applicable instead of assertEqual. --- .../apps/api/tests/test_off_topic_channel_names.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'pydis_site/apps/api/tests') diff --git a/pydis_site/apps/api/tests/test_off_topic_channel_names.py b/pydis_site/apps/api/tests/test_off_topic_channel_names.py index a407654c..ebb1224a 100644 --- a/pydis_site/apps/api/tests/test_off_topic_channel_names.py +++ b/pydis_site/apps/api/tests/test_off_topic_channel_names.py @@ -69,7 +69,7 @@ class ListTests(APISubdomainTestCase): name='lemons-lemonade-stand', used=False, active=True ) cls.test_name_2 = OffTopicChannelName.objects.create( - name='bbq-with-bisk', used=True, active=True + name='bbq-with-bisk', used=False, active=True ) cls.test_name_3 = OffTopicChannelName.objects.create( name="frozen-with-iceman", used=True, active=False @@ -81,7 +81,7 @@ class ListTests(APISubdomainTestCase): response = self.client.get(url) self.assertEqual(response.status_code, 200) - self.assertEqual( + self.assertListEqual( response.json(), [ self.test_name.name, @@ -90,22 +90,24 @@ class ListTests(APISubdomainTestCase): ] ) - def test_returns_single_item_with_random_items_param_set_to_1(self): + def test_returns_two_items_with_random_items_param_set_to_2(self): """Return not-used name instead used.""" url = reverse('bot:offtopicchannelname-list', host='api') - response = self.client.get(f'{url}?random_items=1') + response = self.client.get(f'{url}?random_items=2') self.assertEqual(response.status_code, 200) - self.assertEqual(len(response.json()), 1) - self.assertEqual(response.json(), [self.test_name.name]) + self.assertEqual(len(response.json()), 2) + self.assertEqual(response.json(), [self.test_name.name, self.test_name_2.name]) def test_running_out_of_names_with_random_parameter(self): """Reset names `used` parameter to `False` when running out of names.""" url = reverse('bot:offtopicchannelname-list', host='api') - response = self.client.get(f'{url}?random_items=2') + response = self.client.get(f'{url}?random_items=3') self.assertEqual(response.status_code, 200) - self.assertEqual(response.json(), [self.test_name.name, self.test_name_3.name]) + self.assertListEqual( + response.json(), [self.test_name.name, self.test_name_2.name, self.test_name_3.name] + ) def test_returns_inactive_ot_names(self): """Return inactive off topic names.""" -- cgit v1.2.3 From 8fdabfb4c08931b1e2352e98b307b3bfa3a121f1 Mon Sep 17 00:00:00 2001 From: RohanJnr Date: Thu, 10 Jun 2021 02:45:55 +0530 Subject: Use sets to compare 2 un-ordered lists. --- .../apps/api/tests/test_off_topic_channel_names.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'pydis_site/apps/api/tests') diff --git a/pydis_site/apps/api/tests/test_off_topic_channel_names.py b/pydis_site/apps/api/tests/test_off_topic_channel_names.py index ebb1224a..34dde7c6 100644 --- a/pydis_site/apps/api/tests/test_off_topic_channel_names.py +++ b/pydis_site/apps/api/tests/test_off_topic_channel_names.py @@ -81,13 +81,13 @@ class ListTests(APISubdomainTestCase): response = self.client.get(url) self.assertEqual(response.status_code, 200) - self.assertListEqual( - response.json(), - [ + self.assertEqual( + set(response.json()), + { self.test_name.name, self.test_name_2.name, self.test_name_3.name - ] + } ) def test_returns_two_items_with_random_items_param_set_to_2(self): @@ -97,7 +97,7 @@ class ListTests(APISubdomainTestCase): self.assertEqual(response.status_code, 200) self.assertEqual(len(response.json()), 2) - self.assertEqual(response.json(), [self.test_name.name, self.test_name_2.name]) + self.assertEqual(set(response.json()), {self.test_name.name, self.test_name_2.name}) def test_running_out_of_names_with_random_parameter(self): """Reset names `used` parameter to `False` when running out of names.""" @@ -105,8 +105,9 @@ class ListTests(APISubdomainTestCase): response = self.client.get(f'{url}?random_items=3') self.assertEqual(response.status_code, 200) - self.assertListEqual( - response.json(), [self.test_name.name, self.test_name_2.name, self.test_name_3.name] + self.assertEqual( + set(response.json()), + {self.test_name.name, self.test_name_2.name, self.test_name_3.name} ) def test_returns_inactive_ot_names(self): @@ -127,8 +128,8 @@ class ListTests(APISubdomainTestCase): self.assertEqual(response.status_code, 200) self.assertEqual( - response.json(), - [self.test_name.name, self.test_name_2.name] + set(response.json()), + {self.test_name.name, self.test_name_2.name} ) -- cgit v1.2.3 From 6abf47abd515ec789ad2f271dcbc48403a3e0d7e Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Wed, 22 Sep 2021 10:49:36 +0100 Subject: Rename an error to have a correct error suffix --- pydis_site/apps/api/models/bot/metricity.py | 10 +++++----- pydis_site/apps/api/tests/test_users.py | 10 +++++----- pydis_site/apps/api/viewsets/bot/user.py | 6 +++--- 3 files changed, 13 insertions(+), 13 deletions(-) (limited to 'pydis_site/apps/api/tests') diff --git a/pydis_site/apps/api/models/bot/metricity.py b/pydis_site/apps/api/models/bot/metricity.py index 5daa5c66..33fb7ad7 100644 --- a/pydis_site/apps/api/models/bot/metricity.py +++ b/pydis_site/apps/api/models/bot/metricity.py @@ -10,7 +10,7 @@ EXCLUDE_CHANNELS = [ ] -class NotFound(Exception): +class NotFoundError(Exception): """Raised when an entity cannot be found.""" pass @@ -37,7 +37,7 @@ class Metricity: values = self.cursor.fetchone() if not values: - raise NotFound() + raise NotFoundError() return dict(zip(columns, values)) @@ -58,7 +58,7 @@ class Metricity: values = self.cursor.fetchone() if not values: - raise NotFound() + raise NotFoundError() return values[0] @@ -88,7 +88,7 @@ class Metricity: values = self.cursor.fetchone() if not values: - raise NotFound() + raise NotFoundError() return values[0] @@ -127,6 +127,6 @@ class Metricity: values = self.cursor.fetchall() if not values: - raise NotFound() + raise NotFoundError() return values diff --git a/pydis_site/apps/api/tests/test_users.py b/pydis_site/apps/api/tests/test_users.py index c43b916a..ed5b4ce3 100644 --- a/pydis_site/apps/api/tests/test_users.py +++ b/pydis_site/apps/api/tests/test_users.py @@ -5,7 +5,7 @@ from django_hosts.resolvers import reverse from .base import APISubdomainTestCase from ..models import Role, User -from ..models.bot.metricity import NotFound +from ..models.bot.metricity import NotFoundError class UnauthedUserAPITests(APISubdomainTestCase): @@ -501,7 +501,7 @@ class UserMetricityTests(APISubdomainTestCase): self.metricity = patcher.start() self.addCleanup(patcher.stop) self.metricity = self.metricity.return_value.__enter__.return_value - self.metricity.user.side_effect = NotFound() - self.metricity.total_messages.side_effect = NotFound() - self.metricity.total_message_blocks.side_effect = NotFound() - self.metricity.top_channel_activity.side_effect = NotFound() + self.metricity.user.side_effect = NotFoundError() + self.metricity.total_messages.side_effect = NotFoundError() + self.metricity.total_message_blocks.side_effect = NotFoundError() + self.metricity.top_channel_activity.side_effect = NotFoundError() diff --git a/pydis_site/apps/api/viewsets/bot/user.py b/pydis_site/apps/api/viewsets/bot/user.py index 25722f5a..0356e193 100644 --- a/pydis_site/apps/api/viewsets/bot/user.py +++ b/pydis_site/apps/api/viewsets/bot/user.py @@ -11,7 +11,7 @@ from rest_framework.serializers import ModelSerializer from rest_framework.viewsets import ModelViewSet from pydis_site.apps.api.models.bot.infraction import Infraction -from pydis_site.apps.api.models.bot.metricity import Metricity, NotFound +from pydis_site.apps.api.models.bot.metricity import Metricity, NotFoundError from pydis_site.apps.api.models.bot.user import User from pydis_site.apps.api.serializers import UserSerializer @@ -275,7 +275,7 @@ class UserViewSet(ModelViewSet): data["voice_banned"] = voice_banned data["activity_blocks"] = metricity.total_message_blocks(user.id) return Response(data, status=status.HTTP_200_OK) - except NotFound: + except NotFoundError: return Response(dict(detail="User not found in metricity"), status=status.HTTP_404_NOT_FOUND) @@ -290,6 +290,6 @@ class UserViewSet(ModelViewSet): data["total_messages"] = metricity.total_messages(user.id) data["top_channel_activity"] = metricity.top_channel_activity(user.id) return Response(data, status=status.HTTP_200_OK) - except NotFound: + except NotFoundError: return Response(dict(detail="User not found in metricity"), status=status.HTTP_404_NOT_FOUND) -- cgit v1.2.3 From 4c527e702a90bd108844ed59f93f41cbc3631df6 Mon Sep 17 00:00:00 2001 From: Johannes Christ Date: Sat, 9 Oct 2021 18:17:53 +0200 Subject: Automatically adjust test to `page_size`. --- pydis_site/apps/api/tests/test_users.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'pydis_site/apps/api/tests') diff --git a/pydis_site/apps/api/tests/test_users.py b/pydis_site/apps/api/tests/test_users.py index 77876d6f..295bcf64 100644 --- a/pydis_site/apps/api/tests/test_users.py +++ b/pydis_site/apps/api/tests/test_users.py @@ -6,6 +6,7 @@ from django.urls import reverse from .base import AuthenticatedAPITestCase from ..models import Role, User from ..models.bot.metricity import NotFoundError +from ..viewsets.bot.user import UserListPagination class UnauthedUserAPITests(AuthenticatedAPITestCase): @@ -357,7 +358,7 @@ class UserPaginatorTests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): users = [] - for i in range(1, 10_001): + for i in range(1, UserListPagination.page_size + 1): users.append(User( id=i, name=f"user{i}", @@ -373,9 +374,10 @@ class UserPaginatorTests(AuthenticatedAPITestCase): self.assertIsNone(response["previous_page_no"]) def test_returns_next_page_number(self): + user_id = UserListPagination.page_size + 1 User.objects.create( - id=10_001, - name="user10001", + id=user_id, + name=f"user{user_id}", discriminator=1111, in_guild=True ) @@ -384,9 +386,10 @@ class UserPaginatorTests(AuthenticatedAPITestCase): self.assertEqual(2, response["next_page_no"]) def test_returns_previous_page_number(self): + user_id = UserListPagination.page_size + 1 User.objects.create( - id=10_001, - name="user10001", + id=user_id, + name=f"user{user_id}", discriminator=1111, in_guild=True ) -- cgit v1.2.3 From 569c2c2d2540fda797ade699c7acb67e402114e5 Mon Sep 17 00:00:00 2001 From: Hedy Li Date: Sun, 17 Oct 2021 21:29:53 +0800 Subject: Fix typos across codebase ./pydis_site/apps/resources/resources/tools/ides/thonny.yaml:1: specifically ./pydis_site/apps/content/resources/guides/pydis-guides/helping-others.md:115: considered ./pydis_site/apps/content/resources/guides/pydis-guides/contributing/issues.md:59 labels ./pydis_site/apps/content/resources/guides/pydis-guides/contributing/sir-lancebot.md:99: recommend ./pydis_site/apps/content/resources/guides/pydis-guides/contributing/site.md:111: particularly ./pydis_site/apps/content/resources/guides/pydis-guides/contributing/sir-lancebot/env-var-reference.md:29: Integer ./pydis_site/apps/content/resources/guides/pydis-guides/contributing/sir-lancebot/env-var-reference.md:67: calculating ./pydis_site/apps/api/tests/test_off_topic_channel_names.py:157: response I didn't touch the code jam and game jam typos because I'm not sure if they should be preserved as is. There were a few 'seperated' typos which I didn't change because I *think* it's just another way of spelling it? In the offensive words test there was a keyword argument named `fied` which I didn't touch because I wasn't sure where that was from. --- pydis_site/apps/api/tests/test_off_topic_channel_names.py | 2 +- .../apps/content/resources/guides/pydis-guides/contributing/issues.md | 2 +- .../resources/guides/pydis-guides/contributing/sir-lancebot.md | 2 +- .../pydis-guides/contributing/sir-lancebot/env-var-reference.md | 4 ++-- .../apps/content/resources/guides/pydis-guides/contributing/site.md | 2 +- .../apps/content/resources/guides/pydis-guides/helping-others.md | 2 +- pydis_site/apps/resources/resources/tools/ides/thonny.yaml | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) (limited to 'pydis_site/apps/api/tests') diff --git a/pydis_site/apps/api/tests/test_off_topic_channel_names.py b/pydis_site/apps/api/tests/test_off_topic_channel_names.py index 63993978..1825f6e6 100644 --- a/pydis_site/apps/api/tests/test_off_topic_channel_names.py +++ b/pydis_site/apps/api/tests/test_off_topic_channel_names.py @@ -154,7 +154,7 @@ class DeletionTests(AuthenticatedAPITestCase): cls.test_name_2 = OffTopicChannelName.objects.create(name='bbq-with-bisk') def test_deleting_unknown_name_returns_404(self): - """Return 404 reponse when trying to delete unknown name.""" + """Return 404 response when trying to delete unknown name.""" url = reverse('api:bot:offtopicchannelname-detail', args=('unknown-name',)) response = self.client.delete(url) diff --git a/pydis_site/apps/content/resources/guides/pydis-guides/contributing/issues.md b/pydis_site/apps/content/resources/guides/pydis-guides/contributing/issues.md index 9151e5e3..0c6d3513 100644 --- a/pydis_site/apps/content/resources/guides/pydis-guides/contributing/issues.md +++ b/pydis_site/apps/content/resources/guides/pydis-guides/contributing/issues.md @@ -56,7 +56,7 @@ Definitely try to: Labels allow us to better organise Issues by letting us view what type of Issue it is, how it might impact the codebase and at what stage it's at. -In our repositories, we try to prefix labels belonging to the same group, for example the label groups `status` or `type`. We will be trying to keep to the same general structure across our project repositories, but just have a look at the full lables list in the respective repository to get a clear idea what's available. +In our repositories, we try to prefix labels belonging to the same group, for example the label groups `status` or `type`. We will be trying to keep to the same general structure across our project repositories, but just have a look at the full labels list in the respective repository to get a clear idea what's available. If you're a contributor, you can add relevant labels yourself to any new Issue ticket you create. diff --git a/pydis_site/apps/content/resources/guides/pydis-guides/contributing/sir-lancebot.md b/pydis_site/apps/content/resources/guides/pydis-guides/contributing/sir-lancebot.md index 60169c01..a0d3d463 100644 --- a/pydis_site/apps/content/resources/guides/pydis-guides/contributing/sir-lancebot.md +++ b/pydis_site/apps/content/resources/guides/pydis-guides/contributing/sir-lancebot.md @@ -96,7 +96,7 @@ Otherwise, please see the below linked guide for Redis related variables. --- # Run the project -The sections below describe the two ways you can run this project. We recomend Docker as it requires less setup. +The sections below describe the two ways you can run this project. We recommend Docker as it requires less setup. ## Run with Docker Make sure to have Docker running, then use the Docker command `docker-compose up` in the project root. diff --git a/pydis_site/apps/content/resources/guides/pydis-guides/contributing/sir-lancebot/env-var-reference.md b/pydis_site/apps/content/resources/guides/pydis-guides/contributing/sir-lancebot/env-var-reference.md index eba737ad..9ad014a2 100644 --- a/pydis_site/apps/content/resources/guides/pydis-guides/contributing/sir-lancebot/env-var-reference.md +++ b/pydis_site/apps/content/resources/guides/pydis-guides/contributing/sir-lancebot/env-var-reference.md @@ -26,7 +26,7 @@ Additionally, you may find the following environment variables useful during dev | `BOT_DEBUG` | Debug mode of the bot | False | | `PREFIX` | The bot's invocation prefix | `.` | | `CYCLE_FREQUENCY` | Amount of days between cycling server icon | 3 | -| `MONTH_OVERRIDE` | Interger in range `[0, 12]`, overrides current month w.r.t. seasonal decorators | +| `MONTH_OVERRIDE` | Integer in range `[0, 12]`, overrides current month w.r.t. seasonal decorators | | `REDIS_HOST` | The address to connect to for the Redis database. | | `REDIS_PORT` | | | `REDIS_PASSWORD` | | @@ -64,7 +64,7 @@ These variables might come in handy while working on certain cogs: | Advent of Code | `AOC_LEADERBOARDS` | List of leaderboards seperated by `::`. Each entry should have an `id,session cookie,join code` seperated by commas in that order. | | Advent of Code | `AOC_STAFF_LEADERBOARD_ID` | Integer ID of the staff leaderboard. | | Advent of Code | `AOC_ROLE_ID` | ID of the advent of code role. -| Advent of Code | `AOC_IGNORED_DAYS` | Comma seperated list of days to ignore while calulating score. | +| Advent of Code | `AOC_IGNORED_DAYS` | Comma seperated list of days to ignore while calculating score. | | Advent of Code | `AOC_YEAR` | Debug variable to change the year used for AoC. | | Advent of Code | `AOC_CHANNEL_ID` | The ID of the #advent-of-code channel | | Advent of Code | `AOC_COMMANDS_CHANNEL_ID` | The ID of the #advent-of-code-commands channel | diff --git a/pydis_site/apps/content/resources/guides/pydis-guides/contributing/site.md b/pydis_site/apps/content/resources/guides/pydis-guides/contributing/site.md index df75e81a..f2c3bd95 100644 --- a/pydis_site/apps/content/resources/guides/pydis-guides/contributing/site.md +++ b/pydis_site/apps/content/resources/guides/pydis-guides/contributing/site.md @@ -108,7 +108,7 @@ If you get any Docker related errors, reference the [Possible Issues](https://py ## Run on the host -Running on the host is particularily useful if you wish to debug the site. The [environment variables](#2-environment-variables) shown in a previous section need to have been configured. +Running on the host is particularly useful if you wish to debug the site. The [environment variables](#2-environment-variables) shown in a previous section need to have been configured. ### Database diff --git a/pydis_site/apps/content/resources/guides/pydis-guides/helping-others.md b/pydis_site/apps/content/resources/guides/pydis-guides/helping-others.md index d126707d..a7f1ce1d 100644 --- a/pydis_site/apps/content/resources/guides/pydis-guides/helping-others.md +++ b/pydis_site/apps/content/resources/guides/pydis-guides/helping-others.md @@ -112,7 +112,7 @@ Presenting a solution that is considered a bad practice might be useful in certa > for i in range(len(your_list)): > print(your_list[i]) > -> The second replier gave a valid solution, but it's important that he clarifies that it is concidered a bad practice in Python, and that the first solution should usually be used in this case. +> The second replier gave a valid solution, but it's important that he clarifies that it is considered a bad practice in Python, and that the first solution should usually be used in this case. ## It's OK to Step Away diff --git a/pydis_site/apps/resources/resources/tools/ides/thonny.yaml b/pydis_site/apps/resources/resources/tools/ides/thonny.yaml index 3581e1cd..d7f03a74 100644 --- a/pydis_site/apps/resources/resources/tools/ides/thonny.yaml +++ b/pydis_site/apps/resources/resources/tools/ides/thonny.yaml @@ -1,4 +1,4 @@ -description: A Python IDE specifially aimed at learning programming. Has a lot of +description: A Python IDE specifically aimed at learning programming. Has a lot of helpful features to help you understand your code. name: Thonny title_url: https://thonny.org/ -- cgit v1.2.3 From 5972560e59f98fced0c56d70039b0d0ba15532d0 Mon Sep 17 00:00:00 2001 From: Hedy Li Date: Mon, 18 Oct 2021 08:57:54 +0800 Subject: Fix typo 'fied' in apps/api/tests/test_offensive_message.py --- pydis_site/apps/api/tests/test_offensive_message.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'pydis_site/apps/api/tests') diff --git a/pydis_site/apps/api/tests/test_offensive_message.py b/pydis_site/apps/api/tests/test_offensive_message.py index 9b79b38c..3cf95b75 100644 --- a/pydis_site/apps/api/tests/test_offensive_message.py +++ b/pydis_site/apps/api/tests/test_offensive_message.py @@ -58,7 +58,7 @@ class CreationTests(AuthenticatedAPITestCase): ) for field, invalid_value in cases: - with self.subTest(fied=field, invalid_value=invalid_value): + with self.subTest(field=field, invalid_value=invalid_value): test_data = data.copy() test_data.update({field: invalid_value}) -- cgit v1.2.3 From 876daaf6eb34e620710473c0311e23f36fd4e7eb Mon Sep 17 00:00:00 2001 From: RohanJnr Date: Fri, 5 Nov 2021 10:55:09 +0530 Subject: Update test cases to adhere to recent changes made that removed hosts. --- pydis_site/apps/api/tests/test_off_topic_channel_names.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'pydis_site/apps/api/tests') diff --git a/pydis_site/apps/api/tests/test_off_topic_channel_names.py b/pydis_site/apps/api/tests/test_off_topic_channel_names.py index 354cda9c..2d273756 100644 --- a/pydis_site/apps/api/tests/test_off_topic_channel_names.py +++ b/pydis_site/apps/api/tests/test_off_topic_channel_names.py @@ -112,7 +112,7 @@ class ListTests(AuthenticatedAPITestCase): def test_returns_inactive_ot_names(self): """Return inactive off topic names.""" - url = reverse('bot:offtopicchannelname-list') + url = reverse('api:bot:offtopicchannelname-list') response = self.client.get(f"{url}?active=false") self.assertEqual(response.status_code, 200) @@ -123,7 +123,7 @@ class ListTests(AuthenticatedAPITestCase): def test_returns_active_ot_names(self): """Return active off topic names.""" - url = reverse('bot:offtopicchannelname-list') + url = reverse('api:bot:offtopicchannelname-list') response = self.client.get(f"{url}?active=true") self.assertEqual(response.status_code, 200) -- cgit v1.2.3 From c8d1513b8f8cb21482180ce19d69a107adefe4e2 Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Mon, 22 Nov 2021 20:38:41 +0000 Subject: Make metricity test order insensitive We only actually care that thee key:value pairs are equal, the order of them isn't actually important. The naming of `assertCountEqual` is a little misleading, since it actually tests that the first sequence contains the same elements as second, regardless of their order. See https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertCountEqual --- pydis_site/apps/api/tests/test_users.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'pydis_site/apps/api/tests') diff --git a/pydis_site/apps/api/tests/test_users.py b/pydis_site/apps/api/tests/test_users.py index 295bcf64..550c7240 100644 --- a/pydis_site/apps/api/tests/test_users.py +++ b/pydis_site/apps/api/tests/test_users.py @@ -408,7 +408,7 @@ class UserMetricityTests(AuthenticatedAPITestCase): in_guild=True, ) - def test_get_metricity_data(self): + def test_get_metricity_data_under_1k(self): # Given joined_at = "foo" total_messages = 1 @@ -421,7 +421,7 @@ class UserMetricityTests(AuthenticatedAPITestCase): # Then self.assertEqual(response.status_code, 200) - self.assertEqual(response.json(), { + self.assertCountEqual(response.json(), { "joined_at": joined_at, "total_messages": total_messages, "voice_banned": False, -- cgit v1.2.3 From 78b2f3b8ed46d23015ab2f765504572f672f4567 Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Mon, 22 Nov 2021 20:38:58 +0000 Subject: Add metricity test for users >1k messages --- pydis_site/apps/api/tests/test_users.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'pydis_site/apps/api/tests') diff --git a/pydis_site/apps/api/tests/test_users.py b/pydis_site/apps/api/tests/test_users.py index 550c7240..81bfd43b 100644 --- a/pydis_site/apps/api/tests/test_users.py +++ b/pydis_site/apps/api/tests/test_users.py @@ -428,6 +428,25 @@ class UserMetricityTests(AuthenticatedAPITestCase): "activity_blocks": total_blocks }) + def test_get_metricity_data_over_1k(self): + # Given + joined_at = "foo" + total_messages = 1001 + total_blocks = 1001 + self.mock_metricity_user(joined_at, total_messages, total_blocks, []) + + # When + url = reverse('api:bot:user-metricity-data', args=[0]) + response = self.client.get(url) + + # Then + self.assertEqual(response.status_code, 200) + self.assertCountEqual(response.json(), { + "joined_at": joined_at, + "total_messages": total_messages, + "voice_banned": False, + }) + def test_no_metricity_user(self): # Given self.mock_no_metricity_user() -- cgit v1.2.3 From 0f24bdcd0ba261da045ac73e8567239eb63c6fc6 Mon Sep 17 00:00:00 2001 From: D0rs4n <41237606+D0rs4n@users.noreply.github.com> Date: Tue, 31 Aug 2021 17:54:39 +0200 Subject: Add test to check role unassignment Create a test that checks if a role gets deleted it will also get unassigned from the user --- pydis_site/apps/api/tests/test_roles.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'pydis_site/apps/api/tests') diff --git a/pydis_site/apps/api/tests/test_roles.py b/pydis_site/apps/api/tests/test_roles.py index d39cea4d..7c968852 100644 --- a/pydis_site/apps/api/tests/test_roles.py +++ b/pydis_site/apps/api/tests/test_roles.py @@ -1,7 +1,8 @@ from django.urls import reverse from .base import AuthenticatedAPITestCase -from ..models import Role +from ..models import Role, User + class CreationTests(AuthenticatedAPITestCase): @@ -35,6 +36,20 @@ class CreationTests(AuthenticatedAPITestCase): permissions=6, position=0, ) + cls.role_to_delete = Role.objects.create( + id=7, + name="role to delete", + colour=7, + permissions=7, + position=0, + ) + cls.role_unassigned_test_user = User.objects.create( + id=8, + name="role_unassigned_test_user", + discriminator="0000", + roles=[cls.role_to_delete.id], + in_guild=True + ) def _validate_roledict(self, role_dict: dict) -> None: """Helper method to validate a dict representing a role.""" @@ -181,6 +196,11 @@ class CreationTests(AuthenticatedAPITestCase): response = self.client.delete(url) self.assertEqual(response.status_code, 204) + def test_role_delete_unassigned(self): + """Tests if the deleted Role gets unassigned from the user.""" + self.role_to_delete.delete() + self.assertEqual(self.role_unassigned_test_user.roles, []) + def test_role_detail_404_all_methods(self): """Tests detail view with non-existing ID.""" url = reverse('api:bot:role-detail', args=(20190815,)) -- cgit v1.2.3 From 9d255dcf3daafde71071ad75b000077a861da659 Mon Sep 17 00:00:00 2001 From: D0rs4n <41237606+D0rs4n@users.noreply.github.com> Date: Tue, 31 Aug 2021 18:49:21 +0200 Subject: Patch roles test to use fresh instance from the DB --- pydis_site/apps/api/tests/test_roles.py | 1 + 1 file changed, 1 insertion(+) (limited to 'pydis_site/apps/api/tests') diff --git a/pydis_site/apps/api/tests/test_roles.py b/pydis_site/apps/api/tests/test_roles.py index 7c968852..88c0256b 100644 --- a/pydis_site/apps/api/tests/test_roles.py +++ b/pydis_site/apps/api/tests/test_roles.py @@ -199,6 +199,7 @@ class CreationTests(AuthenticatedAPITestCase): def test_role_delete_unassigned(self): """Tests if the deleted Role gets unassigned from the user.""" self.role_to_delete.delete() + self.role_unassigned_test_user.refresh_from_db() self.assertEqual(self.role_unassigned_test_user.roles, []) def test_role_detail_404_all_methods(self): -- cgit v1.2.3 From f34a52016bd5a7d50c1146d6fbd213ce889f58c7 Mon Sep 17 00:00:00 2001 From: D0rs4n <41237606+D0rs4n@users.noreply.github.com> Date: Tue, 31 Aug 2021 19:21:36 +0200 Subject: Patch signals to use post_delete, instead of pre_delete From now on the signal will only get executed after the Role has been deleted The commit also introduces minor changes in the tests of roles --- pydis_site/apps/api/signals.py | 4 ++-- pydis_site/apps/api/tests/test_roles.py | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'pydis_site/apps/api/tests') diff --git a/pydis_site/apps/api/signals.py b/pydis_site/apps/api/signals.py index c69704b1..5c26bfb6 100644 --- a/pydis_site/apps/api/signals.py +++ b/pydis_site/apps/api/signals.py @@ -1,10 +1,10 @@ -from django.db.models.signals import pre_delete +from django.db.models.signals import post_delete from django.dispatch import receiver from pydis_site.apps.api.models.bot import Role, User -@receiver(signal=pre_delete, sender=Role) +@receiver(signal=post_delete, sender=Role) def delete_role_from_user(sender: Role, instance: Role, **kwargs) -> None: """Unassigns the Role (instance) that is being deleted from every user that has it.""" for user in User.objects.filter(roles__contains=[instance.id]): diff --git a/pydis_site/apps/api/tests/test_roles.py b/pydis_site/apps/api/tests/test_roles.py index 88c0256b..73c80c77 100644 --- a/pydis_site/apps/api/tests/test_roles.py +++ b/pydis_site/apps/api/tests/test_roles.py @@ -4,7 +4,6 @@ from .base import AuthenticatedAPITestCase from ..models import Role, User - class CreationTests(AuthenticatedAPITestCase): @classmethod def setUpTestData(cls): @@ -96,11 +95,11 @@ class CreationTests(AuthenticatedAPITestCase): url = reverse('api:bot:role-list') response = self.client.get(url) - self.assertContains(response, text="id", count=4, status_code=200) + self.assertContains(response, text="id", count=5, status_code=200) roles = response.json() self.assertIsInstance(roles, list) - self.assertEqual(len(roles), 4) + self.assertEqual(len(roles), 5) for role in roles: self._validate_roledict(role) -- cgit v1.2.3 From 59e4a5c8316464e116630a329064decac4c2a075 Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Thu, 16 Dec 2021 22:29:11 +0000 Subject: Always include metricity message blocks Thanks to a recent database maintenance (https://pythondiscord.freshstatus.io/incident/139811) querying out metricity message data is far cheaper. So there is no longer a reason to only fetch blocks if the member has a low message count. --- pydis_site/apps/api/tests/test_users.py | 21 +-------------------- pydis_site/apps/api/viewsets/bot/user.py | 6 +----- 2 files changed, 2 insertions(+), 25 deletions(-) (limited to 'pydis_site/apps/api/tests') diff --git a/pydis_site/apps/api/tests/test_users.py b/pydis_site/apps/api/tests/test_users.py index 81bfd43b..9b91380b 100644 --- a/pydis_site/apps/api/tests/test_users.py +++ b/pydis_site/apps/api/tests/test_users.py @@ -408,7 +408,7 @@ class UserMetricityTests(AuthenticatedAPITestCase): in_guild=True, ) - def test_get_metricity_data_under_1k(self): + def test_get_metricity_data(self): # Given joined_at = "foo" total_messages = 1 @@ -428,25 +428,6 @@ class UserMetricityTests(AuthenticatedAPITestCase): "activity_blocks": total_blocks }) - def test_get_metricity_data_over_1k(self): - # Given - joined_at = "foo" - total_messages = 1001 - total_blocks = 1001 - self.mock_metricity_user(joined_at, total_messages, total_blocks, []) - - # When - url = reverse('api:bot:user-metricity-data', args=[0]) - response = self.client.get(url) - - # Then - self.assertEqual(response.status_code, 200) - self.assertCountEqual(response.json(), { - "joined_at": joined_at, - "total_messages": total_messages, - "voice_banned": False, - }) - def test_no_metricity_user(self): # Given self.mock_no_metricity_user() diff --git a/pydis_site/apps/api/viewsets/bot/user.py b/pydis_site/apps/api/viewsets/bot/user.py index ed661323..1a5e79f8 100644 --- a/pydis_site/apps/api/viewsets/bot/user.py +++ b/pydis_site/apps/api/viewsets/bot/user.py @@ -273,11 +273,7 @@ class UserViewSet(ModelViewSet): data = metricity.user(user.id) data["total_messages"] = metricity.total_messages(user.id) - if data["total_messages"] < 1000: - # Only calculate and return activity_blocks if the user has a small amount - # of messages, as calculating activity_blocks is expensive. - # 1000 message chosen as an arbitrarily large number. - data["activity_blocks"] = metricity.total_message_blocks(user.id) + data["activity_blocks"] = metricity.total_message_blocks(user.id) data["voice_banned"] = voice_banned return Response(data, status=status.HTTP_200_OK) -- cgit v1.2.3