aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar SebastiaanZ <[email protected]>2019-06-28 20:34:32 +0200
committerGravatar SebastiaanZ <[email protected]>2019-06-28 20:34:32 +0200
commite714fe3750181ac49c790f6724b566885fcc5a10 (patch)
treebb69b53adab0cd528a60b86313813c5d5d29a9b1
parentChanging tests back to 'end' endpoint and adding two tests to test filtering (diff)
Moving end nomination to PUT method and removing separate end point
Diffstat (limited to '')
-rw-r--r--pydis_site/apps/api/models/bot/nomination.py2
-rw-r--r--pydis_site/apps/api/serializers.py2
-rw-r--r--pydis_site/apps/api/tests/test_nominations.py113
-rw-r--r--pydis_site/apps/api/viewsets/bot/nomination.py29
4 files changed, 42 insertions, 104 deletions
diff --git a/pydis_site/apps/api/models/bot/nomination.py b/pydis_site/apps/api/models/bot/nomination.py
index 227a40ec..9a80e956 100644
--- a/pydis_site/apps/api/models/bot/nomination.py
+++ b/pydis_site/apps/api/models/bot/nomination.py
@@ -30,7 +30,7 @@ class Nomination(ModelReprMixin, models.Model):
auto_now_add=True,
help_text="The creation date of this nomination."
)
- unnominate_reason = models.TextField(
+ end_reason = models.TextField(
help_text="Why the nomination was ended.",
default=""
)
diff --git a/pydis_site/apps/api/serializers.py b/pydis_site/apps/api/serializers.py
index abf49393..2a6d8fce 100644
--- a/pydis_site/apps/api/serializers.py
+++ b/pydis_site/apps/api/serializers.py
@@ -276,4 +276,4 @@ class NominationSerializer(ModelSerializer):
model = Nomination
fields = (
'id', 'active', 'actor', 'reason', 'user',
- 'inserted_at', 'unnominate_reason', 'unwatched_at')
+ 'inserted_at', 'end_reason', 'unwatched_at')
diff --git a/pydis_site/apps/api/tests/test_nominations.py b/pydis_site/apps/api/tests/test_nominations.py
index aa6561c4..39b2d159 100644
--- a/pydis_site/apps/api/tests/test_nominations.py
+++ b/pydis_site/apps/api/tests/test_nominations.py
@@ -122,19 +122,19 @@ class CreationTests(APISubdomainTestCase):
'actor': ['Invalid pk "1024" - object does not exist.']
})
- def test_returns_400_for_unnominate_reason_at_creation(self):
+ def test_returns_400_for_end_reason_at_creation(self):
url = reverse('bot:nomination-list', host='api')
data = {
'user': self.user.id,
'reason': 'Joe Dart on Fender Bass',
'actor': self.user.id,
- 'unnominate_reason': "Joe Dart on the Joe Dart Bass"
+ 'end_reason': "Joe Dart on the Joe Dart Bass"
}
response = self.client.post(url, data=data)
self.assertEqual(response.status_code, 400)
self.assertEqual(response.json(), {
- 'unnominate_reason': ['This field cannot be set at creation.']
+ 'end_reason': ['This field cannot be set at creation.']
})
def test_returns_400_for_unwatched_at_at_creation(self):
@@ -203,7 +203,7 @@ class NominationTests(APISubdomainTestCase):
actor=cls.user,
reason="He's pretty funky",
active=False,
- unnominate_reason="His neck couldn't hold the funk",
+ end_reason="His neck couldn't hold the funk",
unwatched_at="5018-11-20T15:52:00+00:00"
)
@@ -231,16 +231,16 @@ class NominationTests(APISubdomainTestCase):
'user': ['This field cannot be updated.']
})
- def test_returns_400_update_unnominate_reason_on_active(self):
+ def test_returns_400_update_end_reason_on_active(self):
url = reverse('bot:nomination-detail', args=(self.active_nomination.id,), host='api')
data = {
- 'unnominate_reason': 'He started playing jazz'
+ 'end_reason': 'He started playing jazz'
}
response = self.client.patch(url, data=data)
self.assertEqual(response.status_code, 400)
self.assertEqual(response.json(), {
- 'unnominate_reason': ["An active nomination can't have an unnominate reason."]
+ 'end_reason': ["An active nomination can't have an unnominate reason."]
})
def test_returns_200_update_reason_on_inactive(self):
@@ -255,28 +255,28 @@ class NominationTests(APISubdomainTestCase):
nomination = Nomination.objects.get(id=response.json()['id'])
self.assertEqual(nomination.reason, data['reason'])
- def test_returns_200_update_unnominate_reason_on_inactive(self):
+ def test_returns_200_update_end_reason_on_inactive(self):
url = reverse('bot:nomination-detail', args=(self.inactive_nomination.id,), host='api')
data = {
- 'unnominate_reason': 'He started playing jazz'
+ 'end_reason': 'He started playing jazz'
}
response = self.client.patch(url, data=data)
self.assertEqual(response.status_code, 200)
nomination = Nomination.objects.get(id=response.json()['id'])
- self.assertEqual(nomination.unnominate_reason, data['unnominate_reason'])
+ self.assertEqual(nomination.end_reason, data['end_reason'])
def test_returns_200_on_valid_end_nomination(self):
url = reverse(
- 'bot:nomination-end',
+ 'bot:nomination-detail',
args=(self.active_nomination.id,),
host='api'
)
data = {
- 'unnominate_reason': 'He started playing jazz'
+ 'end_reason': 'He started playing jazz'
}
- response = self.client.patch(url, data=data)
+ response = self.client.put(url, data=data)
self.assertEqual(response.status_code, 200)
nomination = Nomination.objects.get(id=response.json()['id'])
@@ -287,48 +287,48 @@ class NominationTests(APISubdomainTestCase):
delta=timedelta(seconds=2)
)
self.assertFalse(nomination.active)
- self.assertEqual(nomination.unnominate_reason, data['unnominate_reason'])
+ self.assertEqual(nomination.end_reason, data['end_reason'])
def test_returns_400_on_invalid_field_end_nomination(self):
url = reverse(
- 'bot:nomination-end',
+ 'bot:nomination-detail',
args=(self.active_nomination.id,),
host='api'
)
data = {
'reason': 'Why does a whale have feet?'
}
- response = self.client.patch(url, data=data)
+ response = self.client.put(url, data=data)
self.assertEqual(response.status_code, 400)
self.assertEqual(response.json(), {
'reason': ['This field cannot be set at end_nomination.']
})
- def test_returns_400_on_missing_unnominate_reason_end_nomination(self):
+ def test_returns_400_on_missing_end_reason_end_nomination(self):
url = reverse(
- 'bot:nomination-end',
+ 'bot:nomination-detail',
args=(self.active_nomination.id,),
host='api'
)
data = {}
- response = self.client.patch(url, data=data)
+ response = self.client.put(url, data=data)
self.assertEqual(response.status_code, 400)
self.assertEqual(response.json(), {
- 'unnominate_reason': ['This field is required when ending a nomination.']
+ 'end_reason': ['This field is required when ending a nomination.']
})
def test_returns_400_on_ending_inactive_nomination(self):
url = reverse(
- 'bot:nomination-end',
+ 'bot:nomination-detail',
args=(self.inactive_nomination.id,),
host='api'
)
data = {
- 'unnominate_reason': 'He started playing jazz'
+ 'end_reason': 'He started playing jazz'
}
- response = self.client.patch(url, data=data)
+ response = self.client.put(url, data=data)
self.assertEqual(response.status_code, 400)
self.assertEqual(response.json(), {
'active': ['A nomination must be active to be ended.']
@@ -362,16 +362,16 @@ class NominationTests(APISubdomainTestCase):
def test_returns_404_on_end_unknown_nomination(self):
url = reverse(
- 'bot:nomination-end',
+ 'bot:nomination-detail',
args=(9999,),
host='api'
)
data = {
- 'unnominate_reason': 'He started playing jazz'
+ 'end_reason': 'He started playing jazz'
}
- response = self.client.patch(url, data=data)
+ response = self.client.put(url, data=data)
self.assertEqual(response.status_code, 404)
self.assertEqual(response.json(), {
"detail": "Not found."
@@ -404,15 +404,6 @@ class NominationTests(APISubdomainTestCase):
"detail": "Method \"DELETE\" not allowed."
})
- def test_returns_405_on_detail_put(self):
- url = reverse('bot:nomination-detail', args=(self.active_nomination.id,), host='api')
-
- response = self.client.put(url, data={})
- self.assertEqual(response.status_code, 405)
- self.assertEqual(response.json(), {
- "detail": "Method \"PUT\" not allowed."
- })
-
def test_returns_405_on_detail_post(self):
url = reverse('bot:nomination-detail', args=(self.active_nomination.id,), host='api')
@@ -431,58 +422,6 @@ class NominationTests(APISubdomainTestCase):
"detail": "Method \"DELETE\" not allowed."
})
- def test_returns_405_on_end_nomination_put(self):
- url = reverse(
- 'bot:nomination-end',
- args=(self.inactive_nomination.id,),
- host='api'
- )
-
- response = self.client.put(url, data={})
- self.assertEqual(response.status_code, 405)
- self.assertEqual(response.json(), {
- "detail": "Method \"PUT\" not allowed."
- })
-
- def test_returns_405_on_end_nomination_post(self):
- url = reverse(
- 'bot:nomination-end',
- args=(self.inactive_nomination.id,),
- host='api'
- )
-
- response = self.client.post(url, data={})
- self.assertEqual(response.status_code, 405)
- self.assertEqual(response.json(), {
- "detail": "Method \"POST\" not allowed."
- })
-
- def test_returns_405_on_end_nomination_delete(self):
- url = reverse(
- 'bot:nomination-end',
- args=(self.inactive_nomination.id,),
- host='api'
- )
-
- response = self.client.delete(url, data={})
- self.assertEqual(response.status_code, 405)
- self.assertEqual(response.json(), {
- "detail": "Method \"DELETE\" not allowed."
- })
-
- def test_returns_405_on_end_nomination_get(self):
- url = reverse(
- 'bot:nomination-end',
- args=(self.inactive_nomination.id,),
- host='api'
- )
-
- response = self.client.get(url, data={})
- self.assertEqual(response.status_code, 405)
- self.assertEqual(response.json(), {
- "detail": "Method \"GET\" not allowed."
- })
-
def test_filter_returns_0_objects_unknown_user__id(self):
url = reverse('bot:nomination-list', host='api')
diff --git a/pydis_site/apps/api/viewsets/bot/nomination.py b/pydis_site/apps/api/viewsets/bot/nomination.py
index e8d50728..3d311f72 100644
--- a/pydis_site/apps/api/viewsets/bot/nomination.py
+++ b/pydis_site/apps/api/viewsets/bot/nomination.py
@@ -44,7 +44,7 @@ class NominationViewSet(CreateModelMixin, RetrieveModelMixin, ListModelMixin, Ge
... 'reason': 'They know how to explain difficult concepts',
... 'user': 336843820513755157,
... 'inserted_at': '2019-04-25T14:02:37.775587Z',
- ... 'unnominate_reason': 'They were helpered after a staff-vote',
+ ... 'end_reason': 'They were helpered after a staff-vote',
... 'unwatched_at': '2019-04-26T15:12:22.123587Z'
... }
... ]
@@ -63,7 +63,7 @@ class NominationViewSet(CreateModelMixin, RetrieveModelMixin, ListModelMixin, Ge
... 'reason': 'They know how to explain difficult concepts',
... 'user': 336843820513755157,
... 'inserted_at': '2019-04-25T14:02:37.775587Z',
- ... 'unnominate_reason': 'They were helpered after a staff-vote',
+ ... 'end_reason': 'They were helpered after a staff-vote',
... 'unwatched_at': '2019-04-26T15:12:22.123587Z'
... }
@@ -98,12 +98,12 @@ class NominationViewSet(CreateModelMixin, RetrieveModelMixin, ListModelMixin, Ge
### PATCH /bot/nominations/<id:int>
Update the nomination with the given `id` and return the updated nomination.
For active nominations, only the `reason` may be updated; for inactive
- nominations, both the `reason` and `unnominate_reason` may be updated.
+ nominations, both the `reason` and `end_reason` may be updated.
#### Request body
>>> {
... 'reason': 'He would make a great helper',
- ... 'unnominate_reason': 'He needs some time to mature his Python knowledge'
+ ... 'end_reason': 'He needs some time to mature his Python knowledge'
... }
### Response format
@@ -117,14 +117,14 @@ class NominationViewSet(CreateModelMixin, RetrieveModelMixin, ListModelMixin, Ge
### PATCH /bot/nominations/<id:int>/end_nomination
Ends an active nomination and returns the updated nomination.
- The `unnominate_reason` field is the only allowed and required field
+ The `end_reason` field is the only allowed and required field
for this operation. The nomination will automatically be marked as
`active = false` and the datetime of this operation will be added to
the `unwatched_at` field.
#### Request body
>>> {
- ... 'unnominate_reason': 'He needs some time to mature his Python knowledge'
+ ... 'end_reason': 'He needs some time to mature his Python knowledge'
... }
### Response format
@@ -133,7 +133,7 @@ class NominationViewSet(CreateModelMixin, RetrieveModelMixin, ListModelMixin, Ge
#### Status codes
- 200: returned on success
- 400: returned on failure for the following reasons:
- - `unnominate_reason` is missing from the request body;
+ - `end_reason` is missing from the request body;
- Any other field is present in the request body;
- The nomination was already inactiive.
- 404: if an infraction with the given `id` could not be found
@@ -143,7 +143,7 @@ class NominationViewSet(CreateModelMixin, RetrieveModelMixin, ListModelMixin, Ge
filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
filter_fields = ('user__id', 'actor__id', 'active')
frozen_fields = ('id', 'actor', 'inserted_at', 'user', 'unwatched_at', 'active')
- frozen_on_create = ('unwatched_at', 'unnominate_reason', 'active', 'inserted_at')
+ frozen_on_create = ('unwatched_at', 'end_reason', 'active', 'inserted_at')
def create(self, request, *args, **kwargs):
"""
@@ -182,9 +182,9 @@ class NominationViewSet(CreateModelMixin, RetrieveModelMixin, ListModelMixin, Ge
instance = self.get_object()
- if instance.active and request.data.get('unnominate_reason'):
+ if instance.active and request.data.get('end_reason'):
raise ValidationError(
- {'unnominate_reason': ["An active nomination can't have an unnominate reason."]}
+ {'end_reason': ["An active nomination can't have an unnominate reason."]}
)
serializer = self.get_serializer(instance, data=request.data, partial=True)
@@ -193,8 +193,7 @@ class NominationViewSet(CreateModelMixin, RetrieveModelMixin, ListModelMixin, Ge
return Response(serializer.data)
- @action(detail=True, methods=['patch'])
- def end(self, request, pk=None):
+ def update(self, request, *args, **kwargs):
"""
DRF action for ending an active nomination.
@@ -202,12 +201,12 @@ class NominationViewSet(CreateModelMixin, RetrieveModelMixin, ListModelMixin, Ge
the class docstring for documentation.
"""
for field in request.data:
- if field != "unnominate_reason":
+ if field != "end_reason":
raise ValidationError({field: ['This field cannot be set at end_nomination.']})
- if "unnominate_reason" not in request.data:
+ if "end_reason" not in request.data:
raise ValidationError(
- {'unnominate_reason': ['This field is required when ending a nomination.']}
+ {'end_reason': ['This field is required when ending a nomination.']}
)
instance = self.get_object()