aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar jchristgit <[email protected]>2024-03-31 09:17:40 +0200
committerGravatar GitHub <[email protected]>2024-03-31 09:17:40 +0200
commit341b00b5e3a1c046a10ae41c557baa91bdd00688 (patch)
tree2e96cd5e93764998046a3b5c14f8bb84e3fb58f3
parentMerge pull request #1276 from python-discord/support-test-keepdb (diff)
parentRevert "Bump djangorestframework from 3.14.0 to 3.15.1" (diff)
Merge pull request #1278 from python-discord/revert-1271-dependabot/pip/djangorestframework-3.15.1
Revert "Bump djangorestframework from 3.14.0 to 3.15.1"
-rw-r--r--poetry.lock20
-rw-r--r--pydis_site/apps/api/tests/test_bumped_threads.py2
-rw-r--r--pydis_site/apps/api/tests/test_filters.py7
-rw-r--r--pydis_site/apps/api/tests/test_infractions.py2
-rw-r--r--pydis_site/apps/api/tests/test_nominations.py4
-rw-r--r--pydis_site/apps/api/tests/test_roles.py2
-rw-r--r--pydis_site/apps/api/urls.py3
-rw-r--r--pydis_site/apps/api/viewsets/bot/infraction.py26
-rw-r--r--pyproject.toml2
9 files changed, 50 insertions, 18 deletions
diff --git a/poetry.lock b/poetry.lock
index 86970757..8239793e 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -462,17 +462,18 @@ dev = ["PyGithub (>=1.43,<2.0)", "flake8 (>=3.8,<4.0)", "flake8-annotations (>=2
[[package]]
name = "djangorestframework"
-version = "3.15.1"
+version = "3.14.0"
description = "Web APIs for Django, made easy."
optional = false
python-versions = ">=3.6"
files = [
- {file = "djangorestframework-3.15.1-py3-none-any.whl", hash = "sha256:3ccc0475bce968608cf30d07fb17d8e52d1d7fc8bfe779c905463200750cbca6"},
- {file = "djangorestframework-3.15.1.tar.gz", hash = "sha256:f88fad74183dfc7144b2756d0d2ac716ea5b4c7c9840995ac3bfd8ec034333c1"},
+ {file = "djangorestframework-3.14.0-py3-none-any.whl", hash = "sha256:eb63f58c9f218e1a7d064d17a70751f528ed4e1d35547fdade9aaf4cd103fd08"},
+ {file = "djangorestframework-3.14.0.tar.gz", hash = "sha256:579a333e6256b09489cbe0a067e66abe55c6595d8926be6b99423786334350c8"},
]
[package.dependencies]
django = ">=3.0"
+pytz = "*"
[[package]]
name = "filelock"
@@ -912,6 +913,17 @@ 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"
description = "YAML parser and emitter for Python"
@@ -1212,4 +1224,4 @@ brotli = ["Brotli"]
[metadata]
lock-version = "2.0"
python-versions = "3.11.*"
-content-hash = "4f8439d34f38d81f62fb06e19a913cb8358ddf968aa382378aebc07724dd2dd1"
+content-hash = "4028778c4e713fb935bcc463c3ed209f6251f09c62db700b95524469022b7895"
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
diff --git a/pyproject.toml b/pyproject.toml
index 3b21aa08..760ec819 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.15.1"
+djangorestframework = "3.14.0"
gunicorn = "21.2.0"
httpx = "0.27.0"
markdown = "3.6"