aboutsummaryrefslogtreecommitdiffstats
path: root/api
diff options
context:
space:
mode:
Diffstat (limited to 'api')
-rw-r--r--api/tests/test_off_topic_channel_names.py57
-rw-r--r--api/viewsets.py29
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]