diff options
| author | 2019-06-28 20:34:32 +0200 | |
|---|---|---|
| committer | 2019-06-28 20:34:32 +0200 | |
| commit | e714fe3750181ac49c790f6724b566885fcc5a10 (patch) | |
| tree | bb69b53adab0cd528a60b86313813c5d5d29a9b1 | |
| parent | Changing tests back to 'end' endpoint and adding two tests to test filtering (diff) | |
Moving end nomination to PUT method and removing separate end point
| -rw-r--r-- | pydis_site/apps/api/models/bot/nomination.py | 2 | ||||
| -rw-r--r-- | pydis_site/apps/api/serializers.py | 2 | ||||
| -rw-r--r-- | pydis_site/apps/api/tests/test_nominations.py | 113 | ||||
| -rw-r--r-- | pydis_site/apps/api/viewsets/bot/nomination.py | 29 | 
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() | 
