diff options
author | 2018-09-01 18:21:32 +0200 | |
---|---|---|
committer | 2018-09-01 18:21:32 +0200 | |
commit | 4d65c7186ee66d3c2d95605d6dca6f375e806811 (patch) | |
tree | d34bb7b11af927cf920efe23674a3a5926e2396a /api | |
parent | Add a test for the off-topic channel name API. (diff) |
Add a creation route.
Diffstat (limited to 'api')
-rw-r--r-- | api/tests/test_off_topic_channel_names.py | 57 | ||||
-rw-r--r-- | api/viewsets.py | 29 |
2 files changed, 74 insertions, 12 deletions
diff --git a/api/tests/test_off_topic_channel_names.py b/api/tests/test_off_topic_channel_names.py index 984b8258..96cb3b34 100644 --- a/api/tests/test_off_topic_channel_names.py +++ b/api/tests/test_off_topic_channel_names.py @@ -42,13 +42,16 @@ class EmptyDatabaseTests(APISubdomainTestCase): response = self.client.get(f'{url}?random_items=totally-a-valid-integer') self.assertEqual(response.status_code, 400) - self.assertEqual(response.json(), {'random_items': "Must be a valid integer."}) + self.assertEqual(response.json(), { + 'random_items': ["Must be a valid integer."] + }) -class ListRouteTests(APISubdomainTestCase): +class ListTests(APISubdomainTestCase): @classmethod def setUpTestData(cls): cls.test_name = OffTopicChannelName.objects.create(name='lemons-lemonade-stand') + cls.test_name_2 = OffTopicChannelName.objects.create(name='bbq-with-bisk') def test_returns_name_in_list(self): url = reverse('bot:offtopicchannelname-list', host='api') @@ -58,18 +61,54 @@ class ListRouteTests(APISubdomainTestCase): self.assertEqual( response.json(), [ - self.test_name.name + self.test_name.name, + self.test_name_2.name ] ) - def test_returns_name_in_list_with_random_items_param(self): + def test_returns_single_item_with_random_items_param_set_to_1(self): url = reverse('bot:offtopicchannelname-list', host='api') response = self.client.get(f'{url}?random_items=1') self.assertEqual(response.status_code, 200) - self.assertEqual( - response.json(), - [ - self.test_name.name - ] + self.assertEqual(len(response.json()), 1) + + +class CreationTests(APISubdomainTestCase): + def setUp(self): + super().setUp() + + url = reverse('bot:offtopicchannelname-list', host='api') + self.name = "lemonade-shop" + response = self.client.post(f'{url}?name={self.name}') + self.assertEqual(response.status_code, 201) + + def test_name_in_full_list(self): + url = reverse('bot:offtopicchannelname-list', host='api') + response = self.client.get(url) + + self.assertEqual(response.status_code, 200) + self.assertEqual(response.json(), [self.name]) + + def test_returns_400_for_missing_name_param(self): + url = reverse('bot:offtopicchannelname-list', host='api') + response = self.client.post(url) + self.assertEqual(response.status_code, 400) + self.assertEqual(response.json(), { + 'name': ["This query parameter is required."] + }) + + def test_returns_400_for_bad_name_param(self): + url = reverse('bot:offtopicchannelname-list', host='api') + invalid_names = ( + 'space between words', + 'UPPERCASE', + '$$$$$$$$' ) + + for name in invalid_names: + response = self.client.post(f'{url}?name={name}') + self.assertEqual(response.status_code, 400) + self.assertEqual(response.json(), { + 'name': ["Enter a valid value."] + }) diff --git a/api/viewsets.py b/api/viewsets.py index 37ba885d..0bbb70f2 100644 --- a/api/viewsets.py +++ b/api/viewsets.py @@ -1,6 +1,7 @@ from rest_framework.exceptions import ParseError from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, ListModelMixin, RetrieveModelMixin from rest_framework.response import Response +from rest_framework.status import HTTP_201_CREATED from rest_framework.viewsets import GenericViewSet, ViewSet from .models import DocumentationLink, OffTopicChannelName, SnakeName @@ -82,7 +83,7 @@ class OffTopicChannelNameViewSet(ViewSet): ... then the API will return `5` random items from the database. #### Response format - Returns a list of off-topic-channel names: + Return a list of off-topic-channel names: >>> [ ... "lemons-lemonade-stand", ... "bbq-with-bisk" @@ -92,6 +93,15 @@ class OffTopicChannelNameViewSet(ViewSet): - 200: returned on success - 400: returned when `random_items` is not a positive integer + ### POST /bot/off-topic-channel-names + Create a new off-topic-channel name in the database. + The name must be given as a query parameter, for example: + $ curl api.pythondiscord.local:8000/bot/off-topic-channel-names?name=lemons-lemonade-shop + + #### Status codes + - 201: returned on success + - 400: if the request body has invalid fields, see the response for details + ## Authentication Requires a API token. """ @@ -101,17 +111,30 @@ class OffTopicChannelNameViewSet(ViewSet): def get_queryset(self): return OffTopicChannelName.objects.all() + def create(self, request): + if 'name' in request.query_params: + create_data = {'name': request.query_params['name']} + serializer = OffTopicChannelNameSerializer(data=create_data) + serializer.is_valid(raise_exception=True) + serializer.save() + return Response(create_data, status=HTTP_201_CREATED) + + else: + raise ParseError(detail={ + 'name': ["This query parameter is required."] + }) + def list(self, request): if 'random_items' in request.query_params: param = request.query_params['random_items'] try: random_count = int(param) except ValueError: - raise ParseError(detail={'random_items': "Must be a valid integer."}) + raise ParseError(detail={'random_items': ["Must be a valid integer."]}) if random_count <= 0: raise ParseError(detail={ - 'random_items': "Must be a positive integer." + 'random_items': ["Must be a positive integer."] }) queryset = self.get_queryset().order_by('?')[:random_count] |