diff --git a/poetry.lock b/poetry.lock index 8239793ed..869707575 100644 --- a/poetry.lock +++ b/poetry.lock @@ -462,18 +462,17 @@ dev = ["PyGithub (>=1.43,<2.0)", "flake8 (>=3.8,<4.0)", "flake8-annotations (>=2 [[package]] name = "djangorestframework" -version = "3.14.0" +version = "3.15.1" description = "Web APIs for Django, made easy." optional = false python-versions = ">=3.6" files = [ - {file = "djangorestframework-3.14.0-py3-none-any.whl", hash = "sha256:eb63f58c9f218e1a7d064d17a70751f528ed4e1d35547fdade9aaf4cd103fd08"}, - {file = "djangorestframework-3.14.0.tar.gz", hash = "sha256:579a333e6256b09489cbe0a067e66abe55c6595d8926be6b99423786334350c8"}, + {file = "djangorestframework-3.15.1-py3-none-any.whl", hash = "sha256:3ccc0475bce968608cf30d07fb17d8e52d1d7fc8bfe779c905463200750cbca6"}, + {file = "djangorestframework-3.15.1.tar.gz", hash = "sha256:f88fad74183dfc7144b2756d0d2ac716ea5b4c7c9840995ac3bfd8ec034333c1"}, ] [package.dependencies] django = ">=3.0" -pytz = "*" [[package]] name = "filelock" @@ -912,17 +911,6 @@ PyYAML = "*" docs = ["sphinx"] test = ["mypy", "pyaml", "pytest", "toml", "types-PyYAML", "types-toml"] -[[package]] -name = "pytz" -version = "2024.1" -description = "World timezone definitions, modern and historical" -optional = false -python-versions = "*" -files = [ - {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, - {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, -] - [[package]] name = "pyyaml" version = "6.0.1" @@ -1224,4 +1212,4 @@ brotli = ["Brotli"] [metadata] lock-version = "2.0" python-versions = "3.11.*" -content-hash = "4028778c4e713fb935bcc463c3ed209f6251f09c62db700b95524469022b7895" +content-hash = "4f8439d34f38d81f62fb06e19a913cb8358ddf968aa382378aebc07724dd2dd1" diff --git a/pydis_site/apps/api/tests/test_bumped_threads.py b/pydis_site/apps/api/tests/test_bumped_threads.py index 2e3892c7d..72f475c6c 100644 --- a/pydis_site/apps/api/tests/test_bumped_threads.py +++ b/pydis_site/apps/api/tests/test_bumped_threads.py @@ -60,4 +60,4 @@ def test_returns_404_for_non_existing_data(self): response = self.client.get(url) self.assertEqual(response.status_code, 404) - self.assertEqual(response.json(), {"detail": "Not found."}) + self.assertEqual(response.json(), {"detail": "No BumpedThread matches the given query."}) diff --git a/pydis_site/apps/api/tests/test_filters.py b/pydis_site/apps/api/tests/test_filters.py index 4cef1c8f6..9771bacc4 100644 --- a/pydis_site/apps/api/tests/test_filters.py +++ b/pydis_site/apps/api/tests/test_filters.py @@ -211,7 +211,12 @@ def test_fetch_non_existing(self) -> None: response = self.client.get(f"{sequence.url()}/42") self.assertEqual(response.status_code, 404) - self.assertDictEqual(response.json(), {'detail': 'Not found.'}) + parsed = response.json() + self.assertIn('detail', parsed) + self.assertIn(parsed['detail'], ( + "No Filter matches the given query.", + "No FilterList matches the given query." + )) def test_creation(self) -> None: for name, sequence in get_test_sequences().items(): diff --git a/pydis_site/apps/api/tests/test_infractions.py b/pydis_site/apps/api/tests/test_infractions.py index f1e54b1e0..b82fb66cd 100644 --- a/pydis_site/apps/api/tests/test_infractions.py +++ b/pydis_site/apps/api/tests/test_infractions.py @@ -559,7 +559,7 @@ def test_returns_400_for_second_active_infraction_of_the_same_type(self): second_response.json(), { 'non_field_errors': [ - 'This user already has an active infraction of this type.' + 'The fields user, type must make a unique set.' ] } ) diff --git a/pydis_site/apps/api/tests/test_nominations.py b/pydis_site/apps/api/tests/test_nominations.py index e4dfe36a7..7c6f1bbb5 100644 --- a/pydis_site/apps/api/tests/test_nominations.py +++ b/pydis_site/apps/api/tests/test_nominations.py @@ -379,7 +379,7 @@ def test_returns_404_on_get_unknown_nomination(self): response = self.client.get(url, data={}) self.assertEqual(response.status_code, 404) self.assertEqual(response.json(), { - "detail": "Not found." + "detail": "No Nomination matches the given query." }) def test_returns_404_on_patch_unknown_nomination(self): @@ -391,7 +391,7 @@ def test_returns_404_on_patch_unknown_nomination(self): response = self.client.patch(url, data={}) self.assertEqual(response.status_code, 404) self.assertEqual(response.json(), { - "detail": "Not found." + "detail": "No Nomination matches the given query." }) def test_returns_405_on_list_put(self): diff --git a/pydis_site/apps/api/tests/test_roles.py b/pydis_site/apps/api/tests/test_roles.py index d30319905..8ca6e7c14 100644 --- a/pydis_site/apps/api/tests/test_roles.py +++ b/pydis_site/apps/api/tests/test_roles.py @@ -208,4 +208,4 @@ def test_role_detail_404_all_methods(self): for method in ('get', 'put', 'patch', 'delete'): response = getattr(self.client, method)(url) self.assertEqual(response.status_code, 404) - self.assertJSONEqual(response.content, '{"detail": "Not found."}') + self.assertJSONEqual(response.content, '{"detail": "No Role matches the given query."}') diff --git a/pydis_site/apps/api/urls.py b/pydis_site/apps/api/urls.py index 5cda033ac..58e4878b0 100644 --- a/pydis_site/apps/api/urls.py +++ b/pydis_site/apps/api/urls.py @@ -30,7 +30,8 @@ bot_router = DefaultRouter(trailing_slash=False) bot_router.register( 'filter/filter_lists', - FilterListViewSet + FilterListViewSet, + basename='filter-filter-lists', ) bot_router.register( "aoc-account-links", diff --git a/pydis_site/apps/api/viewsets/bot/infraction.py b/pydis_site/apps/api/viewsets/bot/infraction.py index 8da828228..254a588d1 100644 --- a/pydis_site/apps/api/viewsets/bot/infraction.py +++ b/pydis_site/apps/api/viewsets/bot/infraction.py @@ -1,6 +1,5 @@ import datetime -from django.db import IntegrityError from django.db.models import QuerySet from django.http.request import HttpRequest from django_filters.rest_framework import DjangoFilterBackend @@ -275,28 +274,3 @@ def partial_update_expanded(self, *args, **kwargs) -> Response: """ self.serializer_class = ExpandedInfractionSerializer return self.partial_update(*args, **kwargs) - - def create(self, request: HttpRequest, *args, **kwargs) -> Response: - """ - Create an infraction for a target user. - - Called by the Django Rest Framework in response to the corresponding HTTP request. - """ - try: - return super().create(request, *args, **kwargs) - except IntegrityError as err: - # We need to use `__cause__` here, as Django reraises the internal - # UniqueViolation emitted by psycopg2 (which contains the attribute - # that we actually need) - # - # _meta is documented and mainly named that way to prevent - # name clashes: https://docs.djangoproject.com/en/dev/ref/models/meta/ - if err.__cause__.diag.constraint_name == Infraction._meta.constraints[0].name: - raise ValidationError( - { - 'non_field_errors': [ - 'This user already has an active infraction of this type.', - ] - } - ) - raise # pragma: no cover - no other constraint to test with diff --git a/pyproject.toml b/pyproject.toml index 760ec8192..3b21aa087 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,7 @@ django-environ = "0.11.2" django-filter = "24.2" django-prometheus = "2.3.1" django-simple-bulma = "2.6.0" -djangorestframework = "3.14.0" +djangorestframework = "3.15.1" gunicorn = "21.2.0" httpx = "0.27.0" markdown = "3.6"