diff options
author | 2019-07-12 13:14:30 +0200 | |
---|---|---|
committer | 2019-07-12 13:14:30 +0200 | |
commit | c78bcd5ec1f2b65a2017fb700d3a26ec657ee847 (patch) | |
tree | 5217be3fbc44c5d23c0ffe859cd3bd7db10ae1a9 /pydis_site/apps/api/tests | |
parent | Adding a tools page to the More menu (diff) | |
parent | Changing logic so an end_reason can never be specified when updating an activ... (diff) |
Merge pull request #220 from python-discord/django-api-bot-nomination-changes
Changing the way nominations work in the backend
Diffstat (limited to 'pydis_site/apps/api/tests')
-rw-r--r-- | pydis_site/apps/api/tests/test_nominations.py | 446 |
1 files changed, 427 insertions, 19 deletions
diff --git a/pydis_site/apps/api/tests/test_nominations.py b/pydis_site/apps/api/tests/test_nominations.py index 1f03d1b0..add5a7e4 100644 --- a/pydis_site/apps/api/tests/test_nominations.py +++ b/pydis_site/apps/api/tests/test_nominations.py @@ -1,41 +1,449 @@ +from datetime import datetime as dt, timedelta, timezone + from django_hosts.resolvers import reverse from .base import APISubdomainTestCase from ..models import Nomination, User +class CreationTests(APISubdomainTestCase): + @classmethod + def setUpTestData(cls): # noqa + cls.user = User.objects.create( + id=1234, + name='joe dart', + discriminator=1111, + avatar_hash=None + ) + + def test_accepts_valid_data(self): + url = reverse('bot:nomination-list', host='api') + data = { + 'actor': self.user.id, + 'reason': 'Joe Dart on Fender Bass', + 'user': self.user.id, + } + + response = self.client.post(url, data=data) + self.assertEqual(response.status_code, 201) + + nomination = Nomination.objects.get(id=response.json()['id']) + self.assertAlmostEqual( + nomination.inserted_at, + dt.now(timezone.utc), + delta=timedelta(seconds=2) + ) + self.assertEqual(nomination.user.id, data['user']) + self.assertEqual(nomination.actor.id, data['actor']) + self.assertEqual(nomination.reason, data['reason']) + self.assertEqual(nomination.active, True) + + def test_returns_400_on_second_active_nomination(self): + url = reverse('bot:nomination-list', host='api') + data = { + 'actor': self.user.id, + 'reason': 'Joe Dart on Fender Bass', + 'user': self.user.id, + } + + response1 = self.client.post(url, data=data) + self.assertEqual(response1.status_code, 201) + + response2 = self.client.post(url, data=data) + self.assertEqual(response2.status_code, 400) + self.assertEqual(response2.json(), { + 'active': ['There can only be one active nomination.'] + }) + + def test_returns_400_for_missing_user(self): + url = reverse('bot:nomination-list', host='api') + data = { + 'actor': self.user.id, + 'reason': 'Joe Dart on Fender Bass', + } + + response = self.client.post(url, data=data) + self.assertEqual(response.status_code, 400) + self.assertEqual(response.json(), { + 'user': ['This field is required.'] + }) + + def test_returns_400_for_missing_actor(self): + url = reverse('bot:nomination-list', host='api') + data = { + 'user': self.user.id, + 'reason': 'Joe Dart on Fender Bass', + } + + response = self.client.post(url, data=data) + self.assertEqual(response.status_code, 400) + self.assertEqual(response.json(), { + 'actor': ['This field is required.'] + }) + + def test_returns_400_for_missing_reason(self): + url = reverse('bot:nomination-list', host='api') + data = { + 'user': self.user.id, + 'actor': self.user.id, + } + + response = self.client.post(url, data=data) + self.assertEqual(response.status_code, 400) + self.assertEqual(response.json(), { + 'reason': ['This field is required.'] + }) + + def test_returns_400_for_bad_user(self): + url = reverse('bot:nomination-list', host='api') + data = { + 'user': 1024, + 'reason': 'Joe Dart on Fender Bass', + 'actor': self.user.id, + } + + response = self.client.post(url, data=data) + self.assertEqual(response.status_code, 400) + self.assertEqual(response.json(), { + 'user': ['Invalid pk "1024" - object does not exist.'] + }) + + def test_returns_400_for_bad_actor(self): + url = reverse('bot:nomination-list', host='api') + data = { + 'user': self.user.id, + 'reason': 'Joe Dart on Fender Bass', + 'actor': 1024, + } + + response = self.client.post(url, data=data) + self.assertEqual(response.status_code, 400) + self.assertEqual(response.json(), { + 'actor': ['Invalid pk "1024" - object does not exist.'] + }) + + 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, + '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(), { + 'end_reason': ['This field cannot be set at creation.'] + }) + + def test_returns_400_for_ended_at_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, + 'ended_at': "Joe Dart on the Joe Dart Bass" + } + + response = self.client.post(url, data=data) + self.assertEqual(response.status_code, 400) + self.assertEqual(response.json(), { + 'ended_at': ['This field cannot be set at creation.'] + }) + + def test_returns_400_for_inserted_at_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, + 'inserted_at': "Joe Dart on the Joe Dart Bass" + } + + response = self.client.post(url, data=data) + self.assertEqual(response.status_code, 400) + self.assertEqual(response.json(), { + 'inserted_at': ['This field cannot be set at creation.'] + }) + + def test_returns_400_for_active_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, + 'active': False + } + + response = self.client.post(url, data=data) + self.assertEqual(response.status_code, 400) + self.assertEqual(response.json(), { + 'active': ['This field cannot be set at creation.'] + }) + + class NominationTests(APISubdomainTestCase): @classmethod def setUpTestData(cls): # noqa - cls.author = User.objects.create( - id=5152, - name='Ro Bert', - discriminator=256, + cls.user = User.objects.create( + id=1234, + name='joe dart', + discriminator=1111, avatar_hash=None ) - cls.user = cls.author - cls.nomination = Nomination.objects.create( - author=cls.author, - reason="he's good", - user=cls.author + cls.active_nomination = Nomination.objects.create( + user=cls.user, + actor=cls.user, + reason="He's pretty funky" + ) + cls.inactive_nomination = Nomination.objects.create( + user=cls.user, + actor=cls.user, + reason="He's pretty funky", + active=False, + end_reason="His neck couldn't hold the funk", + ended_at="5018-11-20T15:52:00+00:00" ) - def test_returns_400_on_attempt_to_update_frozen_field(self): - url = reverse('bot:nomination-detail', args=(self.user.id,), host='api') - response = self.client.put( - url, - data={'inserted_at': 'something bad'} + def test_returns_200_update_reason_on_active(self): + url = reverse('bot:nomination-detail', args=(self.active_nomination.id,), host='api') + data = { + 'reason': "He's one funky duck" + } + + response = self.client.patch(url, data=data) + self.assertEqual(response.status_code, 200) + + nomination = Nomination.objects.get(id=response.json()['id']) + self.assertEqual(nomination.reason, data['reason']) + + def test_returns_400_on_frozen_field_update(self): + url = reverse('bot:nomination-detail', args=(self.active_nomination.id,), host='api') + data = { + 'user': "Theo Katzman" + } + + response = self.client.patch(url, data=data) + self.assertEqual(response.status_code, 400) + self.assertEqual(response.json(), { + 'user': ['This field cannot be updated.'] + }) + + def test_returns_400_update_end_reason_on_active(self): + url = reverse('bot:nomination-detail', args=(self.active_nomination.id,), host='api') + data = { + 'end_reason': 'He started playing jazz' + } + + response = self.client.patch(url, data=data) + self.assertEqual(response.status_code, 400) + self.assertEqual(response.json(), { + 'end_reason': ["An active nomination can't have an end reason."] + }) + + def test_returns_200_update_reason_on_inactive(self): + url = reverse('bot:nomination-detail', args=(self.inactive_nomination.id,), host='api') + data = { + 'reason': "He's one funky duck" + } + + response = self.client.patch(url, data=data) + self.assertEqual(response.status_code, 200) + + nomination = Nomination.objects.get(id=response.json()['id']) + self.assertEqual(nomination.reason, data['reason']) + + def test_returns_200_update_end_reason_on_inactive(self): + url = reverse('bot:nomination-detail', args=(self.inactive_nomination.id,), host='api') + data = { + '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.end_reason, data['end_reason']) + + def test_returns_200_on_valid_end_nomination(self): + url = reverse( + 'bot:nomination-detail', + args=(self.active_nomination.id,), + host='api' + ) + data = { + 'active': False, + '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.assertAlmostEqual( + nomination.ended_at, + dt.now(timezone.utc), + delta=timedelta(seconds=2) ) + self.assertFalse(nomination.active) + self.assertEqual(nomination.end_reason, data['end_reason']) + + def test_returns_400_on_invalid_field_end_nomination(self): + url = reverse( + 'bot:nomination-detail', + args=(self.active_nomination.id,), + host='api' + ) + data = { + 'active': False, + 'reason': 'Why does a whale have feet?', + } + response = self.client.patch(url, data=data) self.assertEqual(response.status_code, 400) self.assertEqual(response.json(), { - 'inserted_at': ['This field cannot be updated.'] + 'reason': ['This field cannot be set when ending a nomination.'] }) - def test_returns_200_on_successful_update(self): - url = reverse('bot:nomination-detail', args=(self.user.id,), host='api') - response = self.client.patch( + def test_returns_400_on_missing_end_reason_end_nomination(self): + url = reverse( + 'bot:nomination-detail', + args=(self.active_nomination.id,), + host='api' + ) + data = { + 'active': False, + } + + response = self.client.patch(url, data=data) + self.assertEqual(response.status_code, 400) + self.assertEqual(response.json(), { + 'end_reason': ['This field is required when ending a nomination.'] + }) + + def test_returns_400_on_invalid_use_of_active(self): + url = reverse( + 'bot:nomination-detail', + args=(self.inactive_nomination.id,), + host='api' + ) + data = { + 'active': False, + } + + response = self.client.patch(url, data=data) + self.assertEqual(response.status_code, 400) + self.assertEqual(response.json(), { + 'active': ['This field can only be used to end a nomination'] + }) + + def test_returns_404_on_get_unknown_nomination(self): + url = reverse( + 'bot:nomination-detail', + args=(9999,), + host='api' + ) + + response = self.client.get(url, data={}) + self.assertEqual(response.status_code, 404) + self.assertEqual(response.json(), { + "detail": "Not found." + }) + + def test_returns_404_on_patch_unknown_nomination(self): + url = reverse( + 'bot:nomination-detail', + args=(9999,), + host='api' + ) + + response = self.client.patch(url, data={}) + self.assertEqual(response.status_code, 404) + self.assertEqual(response.json(), { + "detail": "Not found." + }) + + def test_returns_405_on_list_put(self): + url = reverse('bot:nomination-list', 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_list_patch(self): + url = reverse('bot:nomination-list', host='api') + + response = self.client.patch(url, data={}) + self.assertEqual(response.status_code, 405) + self.assertEqual(response.json(), { + "detail": "Method \"PATCH\" not allowed." + }) + + def test_returns_405_on_list_delete(self): + url = reverse('bot:nomination-list', 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_detail_post(self): + url = reverse('bot:nomination-detail', args=(self.active_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_detail_delete(self): + url = reverse('bot:nomination-detail', args=(self.active_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_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_filter_returns_0_objects_unknown_user__id(self): + url = reverse('bot:nomination-list', host='api') + + response = self.client.get( url, - data={'reason': 'there are many like it, but this test is mine'} + data={ + "user__id": 99998888 + } ) + self.assertEqual(response.status_code, 200) + infractions = response.json() + + self.assertEqual(len(infractions), 0) + + def test_filter_returns_2_objects_for_testdata(self): + url = reverse('bot:nomination-list', host='api') + + response = self.client.get( + url, + data={ + "user__id": self.user.id + } + ) + + self.assertEqual(response.status_code, 200) + infractions = response.json() + + self.assertEqual(len(infractions), 2) |