From ab57b181072374bfd4ec233d9e45140e2e990b7a Mon Sep 17 00:00:00 2001 From: jchristgit Date: Sun, 31 Mar 2024 09:15:28 +0200 Subject: Revert "Bump djangorestframework from 3.14.0 to 3.15.1" --- pydis_site/apps/api/tests/test_bumped_threads.py | 2 +- pydis_site/apps/api/tests/test_filters.py | 7 +------ pydis_site/apps/api/tests/test_infractions.py | 2 +- pydis_site/apps/api/tests/test_nominations.py | 4 ++-- pydis_site/apps/api/tests/test_roles.py | 2 +- pydis_site/apps/api/urls.py | 3 +-- pydis_site/apps/api/viewsets/bot/infraction.py | 26 ++++++++++++++++++++++++ 7 files changed, 33 insertions(+), 13 deletions(-) (limited to 'pydis_site/apps') diff --git a/pydis_site/apps/api/tests/test_bumped_threads.py b/pydis_site/apps/api/tests/test_bumped_threads.py index 72f475c6..2e3892c7 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 @@ class BumpedThreadAPITests(AuthenticatedAPITestCase): response = self.client.get(url) self.assertEqual(response.status_code, 404) - self.assertEqual(response.json(), {"detail": "No BumpedThread matches the given query."}) + self.assertEqual(response.json(), {"detail": "Not found."}) diff --git a/pydis_site/apps/api/tests/test_filters.py b/pydis_site/apps/api/tests/test_filters.py index 9771bacc..4cef1c8f 100644 --- a/pydis_site/apps/api/tests/test_filters.py +++ b/pydis_site/apps/api/tests/test_filters.py @@ -211,12 +211,7 @@ class GenericFilterTests(AuthenticatedAPITestCase): response = self.client.get(f"{sequence.url()}/42") self.assertEqual(response.status_code, 404) - parsed = response.json() - self.assertIn('detail', parsed) - self.assertIn(parsed['detail'], ( - "No Filter matches the given query.", - "No FilterList matches the given query." - )) + self.assertDictEqual(response.json(), {'detail': 'Not found.'}) 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 b82fb66c..f1e54b1e 100644 --- a/pydis_site/apps/api/tests/test_infractions.py +++ b/pydis_site/apps/api/tests/test_infractions.py @@ -559,7 +559,7 @@ class CreationTests(AuthenticatedAPITestCase): second_response.json(), { 'non_field_errors': [ - 'The fields user, type must make a unique set.' + 'This user already has an active infraction of this type.' ] } ) diff --git a/pydis_site/apps/api/tests/test_nominations.py b/pydis_site/apps/api/tests/test_nominations.py index 7c6f1bbb..e4dfe36a 100644 --- a/pydis_site/apps/api/tests/test_nominations.py +++ b/pydis_site/apps/api/tests/test_nominations.py @@ -379,7 +379,7 @@ class NominationTests(AuthenticatedAPITestCase): response = self.client.get(url, data={}) self.assertEqual(response.status_code, 404) self.assertEqual(response.json(), { - "detail": "No Nomination matches the given query." + "detail": "Not found." }) def test_returns_404_on_patch_unknown_nomination(self): @@ -391,7 +391,7 @@ class NominationTests(AuthenticatedAPITestCase): response = self.client.patch(url, data={}) self.assertEqual(response.status_code, 404) self.assertEqual(response.json(), { - "detail": "No Nomination matches the given query." + "detail": "Not found." }) 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 8ca6e7c1..d3031990 100644 --- a/pydis_site/apps/api/tests/test_roles.py +++ b/pydis_site/apps/api/tests/test_roles.py @@ -208,4 +208,4 @@ class CreationTests(AuthenticatedAPITestCase): for method in ('get', 'put', 'patch', 'delete'): response = getattr(self.client, method)(url) self.assertEqual(response.status_code, 404) - self.assertJSONEqual(response.content, '{"detail": "No Role matches the given query."}') + self.assertJSONEqual(response.content, '{"detail": "Not found."}') diff --git a/pydis_site/apps/api/urls.py b/pydis_site/apps/api/urls.py index 58e4878b..5cda033a 100644 --- a/pydis_site/apps/api/urls.py +++ b/pydis_site/apps/api/urls.py @@ -30,8 +30,7 @@ from .viewsets import ( bot_router = DefaultRouter(trailing_slash=False) bot_router.register( 'filter/filter_lists', - FilterListViewSet, - basename='filter-filter-lists', + FilterListViewSet ) 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 254a588d..8da82822 100644 --- a/pydis_site/apps/api/viewsets/bot/infraction.py +++ b/pydis_site/apps/api/viewsets/bot/infraction.py @@ -1,5 +1,6 @@ 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 @@ -274,3 +275,28 @@ class InfractionViewSet( """ 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 -- cgit v1.2.3