From 731a3ca4cefd7ed9bc6619b0d98cb0c28f14f290 Mon Sep 17 00:00:00 2001 From: Akarys42 Date: Tue, 22 Oct 2019 18:05:09 +0200 Subject: Create an OffensiveMessage model This model will be used to store message that triggered a filter and that will be deleted one week after it was sent. --- .../apps/api/migrations/0046_offensivemessage.py | 25 ++++++++ pydis_site/apps/api/models/__init__.py | 1 + pydis_site/apps/api/models/bot/__init__.py | 1 + .../apps/api/models/bot/offensive_message.py | 44 +++++++++++++++ pydis_site/apps/api/serializers.py | 11 ++++ pydis_site/apps/api/urls.py | 7 ++- pydis_site/apps/api/viewsets/__init__.py | 1 + pydis_site/apps/api/viewsets/bot/__init__.py | 1 + .../apps/api/viewsets/bot/offensive_message.py | 66 ++++++++++++++++++++++ 9 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 pydis_site/apps/api/migrations/0046_offensivemessage.py create mode 100644 pydis_site/apps/api/models/bot/offensive_message.py create mode 100644 pydis_site/apps/api/viewsets/bot/offensive_message.py diff --git a/pydis_site/apps/api/migrations/0046_offensivemessage.py b/pydis_site/apps/api/migrations/0046_offensivemessage.py new file mode 100644 index 00000000..0ce65946 --- /dev/null +++ b/pydis_site/apps/api/migrations/0046_offensivemessage.py @@ -0,0 +1,25 @@ +# Generated by Django 2.2.6 on 2019-10-24 17:57 + +import django.core.validators +from django.db import migrations, models +import pydis_site.apps.api.models.bot.offensive_message +import pydis_site.apps.api.models.utils + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0045_add_plural_name_for_log_entry'), + ] + + operations = [ + migrations.CreateModel( + name='OffensiveMessage', + fields=[ + ('id', models.BigIntegerField(help_text='The message ID as taken from Discord.', primary_key=True, serialize=False, validators=[django.core.validators.MinValueValidator(limit_value=0, message='Message IDs cannot be negative.')])), + ('channel_id', models.BigIntegerField(help_text='The channel ID that the message was sent in, taken from Discord.', validators=[django.core.validators.MinValueValidator(limit_value=0, message='Channel IDs cannot be negative.')])), + ('delete_date', models.DateField(help_text='The date on which the message will be auto-deleted.', validators=[pydis_site.apps.api.models.bot.offensive_message.future_date_validator])), + ], + bases=(pydis_site.apps.api.models.utils.ModelReprMixin, models.Model), + ), + ] diff --git a/pydis_site/apps/api/models/__init__.py b/pydis_site/apps/api/models/__init__.py index a4656bc3..450d18cd 100644 --- a/pydis_site/apps/api/models/__init__.py +++ b/pydis_site/apps/api/models/__init__.py @@ -7,6 +7,7 @@ from .bot import ( Message, MessageDeletionContext, Nomination, + OffensiveMessage, OffTopicChannelName, Reminder, Role, diff --git a/pydis_site/apps/api/models/bot/__init__.py b/pydis_site/apps/api/models/bot/__init__.py index 46219ea2..8ae47746 100644 --- a/pydis_site/apps/api/models/bot/__init__.py +++ b/pydis_site/apps/api/models/bot/__init__.py @@ -7,6 +7,7 @@ from .message import Message from .message_deletion_context import MessageDeletionContext from .nomination import Nomination from .off_topic_channel_name import OffTopicChannelName +from .offensive_message import OffensiveMessage from .reminder import Reminder from .role import Role from .tag import Tag diff --git a/pydis_site/apps/api/models/bot/offensive_message.py b/pydis_site/apps/api/models/bot/offensive_message.py new file mode 100644 index 00000000..523fd482 --- /dev/null +++ b/pydis_site/apps/api/models/bot/offensive_message.py @@ -0,0 +1,44 @@ +import datetime + +from django.core.exceptions import ValidationError +from django.core.validators import MinValueValidator +from django.db import models + +from pydis_site.apps.api.models.utils import ModelReprMixin + + +def future_date_validator(date: datetime.date) -> None: + """Raise ValidationError if the date isn't a future date.""" + if date < datetime.date.today(): + raise ValidationError("Date must be a future date") + + +class OffensiveMessage(ModelReprMixin, models.Model): + """A message that triggered a filter and that will be deleted one week after it was sent.""" + + id = models.BigIntegerField( + primary_key=True, + help_text="The message ID as taken from Discord.", + validators=( + MinValueValidator( + limit_value=0, + message="Message IDs cannot be negative." + ), + ) + ) + channel_id = models.BigIntegerField( + help_text=( + "The channel ID that the message was " + "sent in, taken from Discord." + ), + validators=( + MinValueValidator( + limit_value=0, + message="Channel IDs cannot be negative." + ), + ) + ) + delete_date = models.DateField( + help_text="The date on which the message will be auto-deleted.", + validators=(future_date_validator,) + ) diff --git a/pydis_site/apps/api/serializers.py b/pydis_site/apps/api/serializers.py index 326e20e1..4ef7ec78 100644 --- a/pydis_site/apps/api/serializers.py +++ b/pydis_site/apps/api/serializers.py @@ -8,6 +8,7 @@ from .models import ( DocumentationLink, Infraction, LogEntry, MessageDeletionContext, Nomination, OffTopicChannelName, + OffensiveMessage, Reminder, Role, Tag, User ) @@ -236,3 +237,13 @@ class NominationSerializer(ModelSerializer): fields = ( 'id', 'active', 'actor', 'reason', 'user', 'inserted_at', 'end_reason', 'ended_at') + + +class OffensiveMessageSerializer(ModelSerializer): + """A class providing (de-)serialization of `OffensiveMessage` instances.""" + + class Meta: + """Metadata defined for the Django REST Framework.""" + + model = OffensiveMessage + fields = ('id', 'channel_id', 'delete_date') diff --git a/pydis_site/apps/api/urls.py b/pydis_site/apps/api/urls.py index ac6704c8..b1864ba7 100644 --- a/pydis_site/apps/api/urls.py +++ b/pydis_site/apps/api/urls.py @@ -6,7 +6,8 @@ from .viewsets import ( BotSettingViewSet, DeletedMessageViewSet, DocumentationLinkViewSet, InfractionViewSet, LogEntryViewSet, NominationViewSet, - OffTopicChannelNameViewSet, ReminderViewSet, + OffTopicChannelNameViewSet, + OffensiveMessageViewSet, ReminderViewSet, RoleViewSet, TagViewSet, UserViewSet ) @@ -33,6 +34,10 @@ bot_router.register( 'nominations', NominationViewSet ) +bot_router.register( + 'offensive-message', + OffensiveMessageViewSet +) bot_router.register( 'off-topic-channel-names', OffTopicChannelNameViewSet, diff --git a/pydis_site/apps/api/viewsets/__init__.py b/pydis_site/apps/api/viewsets/__init__.py index f9a186d9..3cf9f641 100644 --- a/pydis_site/apps/api/viewsets/__init__.py +++ b/pydis_site/apps/api/viewsets/__init__.py @@ -5,6 +5,7 @@ from .bot import ( DocumentationLinkViewSet, InfractionViewSet, NominationViewSet, + OffensiveMessageViewSet, OffTopicChannelNameViewSet, ReminderViewSet, RoleViewSet, diff --git a/pydis_site/apps/api/viewsets/bot/__init__.py b/pydis_site/apps/api/viewsets/bot/__init__.py index f1851e32..b3e0fa4d 100644 --- a/pydis_site/apps/api/viewsets/bot/__init__.py +++ b/pydis_site/apps/api/viewsets/bot/__init__.py @@ -5,6 +5,7 @@ from .documentation_link import DocumentationLinkViewSet from .infraction import InfractionViewSet from .nomination import NominationViewSet from .off_topic_channel_name import OffTopicChannelNameViewSet +from .offensive_message import OffensiveMessageViewSet from .reminder import ReminderViewSet from .role import RoleViewSet from .tag import TagViewSet diff --git a/pydis_site/apps/api/viewsets/bot/offensive_message.py b/pydis_site/apps/api/viewsets/bot/offensive_message.py new file mode 100644 index 00000000..cd200efe --- /dev/null +++ b/pydis_site/apps/api/viewsets/bot/offensive_message.py @@ -0,0 +1,66 @@ +from django_filters.rest_framework import DjangoFilterBackend +from rest_framework.filters import SearchFilter +from rest_framework.mixins import ( + CreateModelMixin, + DestroyModelMixin, + ListModelMixin, + UpdateModelMixin +) +from rest_framework.viewsets import GenericViewSet + +from pydis_site.apps.api.models.bot.offensive_message import OffensiveMessage +from pydis_site.apps.api.serializers import OffensiveMessageSerializer + + +class OffensiveMessageViewSet( + CreateModelMixin, ListModelMixin, DestroyModelMixin, UpdateModelMixin, GenericViewSet +): + """ + View providing CRUD access to reminders. + + ## Routes + ### GET /bot/offensive-message + Returns all offensive messages in the database. + + #### Response format + >>> [ + ... { + ... 'id': '631953598091100200', + ... 'channel_id': '291284109232308226', + ... 'delete_date': '2020-01-01' + ... }, + ... ... + ... ] + + #### Status codes + - 200: returned on success + + ### POST /bot/offensive-message + Create a new offensive message object. + + #### Request body + >>> { + ... 'id': int, + ... 'channel_id': int, + ... 'delete_date': datetime.date # ISO-8601-formatted date + ... } + + #### Status codes + - 201: returned on success + - 400: if the body format is invalid + + ### DELETE /bot/offensive-message/ + Delete the offensive message object with the given `id`. + + #### Status codes + - 204: returned on success + - 404: if a offensive message object with the given `id` does not exist + + ## Authentication + Requires an API token. + """ + + serializer_class = OffensiveMessageSerializer + queryset = OffensiveMessage.objects.all() + filter_backends = (DjangoFilterBackend, SearchFilter) + filter_fields = ('delete_date',) -- cgit v1.2.3 From 171aad04e4135fe3c8fdba4db145a29aaba9a96b Mon Sep 17 00:00:00 2001 From: Akarys42 Date: Fri, 25 Oct 2019 13:07:02 +0200 Subject: Write tests for the future date validator --- pydis_site/apps/api/tests/test_validators.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pydis_site/apps/api/tests/test_validators.py b/pydis_site/apps/api/tests/test_validators.py index 4222f0c0..6e86759c 100644 --- a/pydis_site/apps/api/tests/test_validators.py +++ b/pydis_site/apps/api/tests/test_validators.py @@ -1,7 +1,10 @@ +from datetime import date + from django.core.exceptions import ValidationError from django.test import TestCase from ..models.bot.bot_setting import validate_bot_setting_name +from ..models.bot.offensive_message import future_date_validator from ..models.bot.tag import validate_tag_embed @@ -245,3 +248,12 @@ class TagEmbedValidatorTests(TestCase): 'name': "Bob" } }) + + +class OffensiveMessageValidatorsTests(TestCase): + def test_accepts_future_date(self): + future_date_validator(date(3000, 1, 1)) + + def test_rejects_non_future_date(self): + with self.assertRaises(ValidationError): + future_date_validator(date(1000, 1, 1)) -- cgit v1.2.3 From f42c936bddc43b30a8245306c86b859185b5e913 Mon Sep 17 00:00:00 2001 From: Akarys42 Date: Fri, 25 Oct 2019 19:16:21 +0200 Subject: Change OffensiveMessage.delete_date from datetime.date to datetime.datetime --- pydis_site/apps/api/models/bot/offensive_message.py | 4 ++-- pydis_site/apps/api/tests/test_validators.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pydis_site/apps/api/models/bot/offensive_message.py b/pydis_site/apps/api/models/bot/offensive_message.py index 523fd482..cee5b32c 100644 --- a/pydis_site/apps/api/models/bot/offensive_message.py +++ b/pydis_site/apps/api/models/bot/offensive_message.py @@ -9,7 +9,7 @@ from pydis_site.apps.api.models.utils import ModelReprMixin def future_date_validator(date: datetime.date) -> None: """Raise ValidationError if the date isn't a future date.""" - if date < datetime.date.today(): + if date < datetime.datetime.utcnow(): raise ValidationError("Date must be a future date") @@ -38,7 +38,7 @@ class OffensiveMessage(ModelReprMixin, models.Model): ), ) ) - delete_date = models.DateField( + delete_date = models.DateTimeField( help_text="The date on which the message will be auto-deleted.", validators=(future_date_validator,) ) diff --git a/pydis_site/apps/api/tests/test_validators.py b/pydis_site/apps/api/tests/test_validators.py index 6e86759c..9d993839 100644 --- a/pydis_site/apps/api/tests/test_validators.py +++ b/pydis_site/apps/api/tests/test_validators.py @@ -1,4 +1,4 @@ -from datetime import date +from datetime import datetime from django.core.exceptions import ValidationError from django.test import TestCase @@ -252,8 +252,8 @@ class TagEmbedValidatorTests(TestCase): class OffensiveMessageValidatorsTests(TestCase): def test_accepts_future_date(self): - future_date_validator(date(3000, 1, 1)) + future_date_validator(datetime(3000, 1, 1)) def test_rejects_non_future_date(self): with self.assertRaises(ValidationError): - future_date_validator(date(1000, 1, 1)) + future_date_validator(datetime(1000, 1, 1)) -- cgit v1.2.3 From 6fac1649252c55b6f12592415de8396349b54686 Mon Sep 17 00:00:00 2001 From: Akarys42 Date: Fri, 25 Oct 2019 19:21:24 +0200 Subject: Add merge migration file --- pydis_site/apps/api/migrations/0047_merge_20191025_1920.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 pydis_site/apps/api/migrations/0047_merge_20191025_1920.py diff --git a/pydis_site/apps/api/migrations/0047_merge_20191025_1920.py b/pydis_site/apps/api/migrations/0047_merge_20191025_1920.py new file mode 100644 index 00000000..f70fe24f --- /dev/null +++ b/pydis_site/apps/api/migrations/0047_merge_20191025_1920.py @@ -0,0 +1,14 @@ +# Generated by Django 2.2.6 on 2019-10-25 17:20 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0046_reminder_jump_url'), + ('api', '0046_offensivemessage'), + ] + + operations = [ + ] -- cgit v1.2.3 From 5b291b0708fc78dab439d12e2ddbcfb6cb718bbf Mon Sep 17 00:00:00 2001 From: Akarys42 Date: Fri, 25 Oct 2019 19:22:14 +0200 Subject: Add migartion file for OffensiveMssage.delete_date --- .../apps/api/migrations/0048_auto_20191025_1921.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 pydis_site/apps/api/migrations/0048_auto_20191025_1921.py diff --git a/pydis_site/apps/api/migrations/0048_auto_20191025_1921.py b/pydis_site/apps/api/migrations/0048_auto_20191025_1921.py new file mode 100644 index 00000000..2e5e670a --- /dev/null +++ b/pydis_site/apps/api/migrations/0048_auto_20191025_1921.py @@ -0,0 +1,19 @@ +# Generated by Django 2.2.6 on 2019-10-25 17:21 + +from django.db import migrations, models +import pydis_site.apps.api.models.bot.offensive_message + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0047_merge_20191025_1920'), + ] + + operations = [ + migrations.AlterField( + model_name='offensivemessage', + name='delete_date', + field=models.DateTimeField(help_text='The date on which the message will be auto-deleted.', validators=[pydis_site.apps.api.models.bot.offensive_message.future_date_validator]), + ), + ] -- cgit v1.2.3 From 6334fd1d7e57f39ed61c90d2bace6b367b676d2f Mon Sep 17 00:00:00 2001 From: Akarys42 Date: Fri, 25 Oct 2019 23:36:31 +0200 Subject: Fix type error in the future date validator --- pydis_site/apps/api/models/bot/offensive_message.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydis_site/apps/api/models/bot/offensive_message.py b/pydis_site/apps/api/models/bot/offensive_message.py index cee5b32c..c4080c1f 100644 --- a/pydis_site/apps/api/models/bot/offensive_message.py +++ b/pydis_site/apps/api/models/bot/offensive_message.py @@ -9,7 +9,7 @@ from pydis_site.apps.api.models.utils import ModelReprMixin def future_date_validator(date: datetime.date) -> None: """Raise ValidationError if the date isn't a future date.""" - if date < datetime.datetime.utcnow(): + if date < datetime.datetime.now(datetime.timezone.utc): raise ValidationError("Date must be a future date") -- cgit v1.2.3 From c727d4ce14ae94f0b60402c603e4129a8efe6ef8 Mon Sep 17 00:00:00 2001 From: Akarys42 Date: Sat, 26 Oct 2019 11:14:55 +0200 Subject: Add the offensive message model to the admin panel --- pydis_site/apps/api/admin.py | 2 ++ pydis_site/apps/api/models/bot/offensive_message.py | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/pydis_site/apps/api/admin.py b/pydis_site/apps/api/admin.py index 059f52eb..0333fefc 100644 --- a/pydis_site/apps/api/admin.py +++ b/pydis_site/apps/api/admin.py @@ -12,6 +12,7 @@ from .models import ( MessageDeletionContext, Nomination, OffTopicChannelName, + OffensiveMessage, Role, Tag, User @@ -60,6 +61,7 @@ admin.site.register(Infraction) admin.site.register(LogEntry, LogEntryAdmin) admin.site.register(MessageDeletionContext) admin.site.register(Nomination) +admin.site.register(OffensiveMessage) admin.site.register(OffTopicChannelName) admin.site.register(Role) admin.site.register(Tag) diff --git a/pydis_site/apps/api/models/bot/offensive_message.py b/pydis_site/apps/api/models/bot/offensive_message.py index c4080c1f..b466d9c2 100644 --- a/pydis_site/apps/api/models/bot/offensive_message.py +++ b/pydis_site/apps/api/models/bot/offensive_message.py @@ -42,3 +42,7 @@ class OffensiveMessage(ModelReprMixin, models.Model): help_text="The date on which the message will be auto-deleted.", validators=(future_date_validator,) ) + + def __str__(self): + """Return some info on this message, for display purposes only.""" + return f"Message {self.id}, will be deleted at {self.delete_date}" -- cgit v1.2.3 From e19d310eb03efa5b576b523649c0d6df761f5325 Mon Sep 17 00:00:00 2001 From: Akarys42 Date: Sat, 26 Oct 2019 11:19:15 +0200 Subject: Change docs to use datetime.datetime instead of datetime.date --- pydis_site/apps/api/viewsets/bot/offensive_message.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pydis_site/apps/api/viewsets/bot/offensive_message.py b/pydis_site/apps/api/viewsets/bot/offensive_message.py index cd200efe..380234dd 100644 --- a/pydis_site/apps/api/viewsets/bot/offensive_message.py +++ b/pydis_site/apps/api/viewsets/bot/offensive_message.py @@ -27,7 +27,7 @@ class OffensiveMessageViewSet( ... { ... 'id': '631953598091100200', ... 'channel_id': '291284109232308226', - ... 'delete_date': '2020-01-01' + ... 'delete_date': '2019-11-01T21:51:15.545000Z' ... }, ... ... ... ] @@ -42,7 +42,7 @@ class OffensiveMessageViewSet( >>> { ... 'id': int, ... 'channel_id': int, - ... 'delete_date': datetime.date # ISO-8601-formatted date + ... 'delete_date': datetime.datetime # ISO-8601-formatted date ... } #### Status codes -- cgit v1.2.3 From 981ae74578862ef24d03947eb368d19c9057461e Mon Sep 17 00:00:00 2001 From: Akarys42 Date: Sat, 26 Oct 2019 11:33:14 +0200 Subject: Delete unnecessary search filter --- pydis_site/apps/api/viewsets/bot/offensive_message.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pydis_site/apps/api/viewsets/bot/offensive_message.py b/pydis_site/apps/api/viewsets/bot/offensive_message.py index 380234dd..0ef5666b 100644 --- a/pydis_site/apps/api/viewsets/bot/offensive_message.py +++ b/pydis_site/apps/api/viewsets/bot/offensive_message.py @@ -1,5 +1,3 @@ -from django_filters.rest_framework import DjangoFilterBackend -from rest_framework.filters import SearchFilter from rest_framework.mixins import ( CreateModelMixin, DestroyModelMixin, @@ -62,5 +60,3 @@ class OffensiveMessageViewSet( serializer_class = OffensiveMessageSerializer queryset = OffensiveMessage.objects.all() - filter_backends = (DjangoFilterBackend, SearchFilter) - filter_fields = ('delete_date',) -- cgit v1.2.3 From 57992886c53977fca7b3034d648a94cf4b4d4df1 Mon Sep 17 00:00:00 2001 From: Akarys42 Date: Sat, 26 Oct 2019 17:03:57 +0200 Subject: Write tests for the offensive message model. --- pydis_site/apps/api/tests/test_models.py | 6 +++ .../apps/api/tests/test_offensive_message.py | 61 ++++++++++++++++++++++ pydis_site/apps/api/tests/test_validators.py | 6 +-- 3 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 pydis_site/apps/api/tests/test_offensive_message.py diff --git a/pydis_site/apps/api/tests/test_models.py b/pydis_site/apps/api/tests/test_models.py index b4a766d0..a97d3251 100644 --- a/pydis_site/apps/api/tests/test_models.py +++ b/pydis_site/apps/api/tests/test_models.py @@ -12,6 +12,7 @@ from ..models import ( ModelReprMixin, Nomination, OffTopicChannelName, + OffensiveMessage, Reminder, Role, Tag, @@ -69,6 +70,11 @@ class StringDunderMethodTests(SimpleTestCase): DocumentationLink( 'test', 'http://example.com', 'http://example.com' ), + OffensiveMessage( + id=602951077675139072, + channel_id=291284109232308226, + delete_date=dt(3000, 1, 1) + ), OffTopicChannelName(name='bob-the-builders-playground'), Role( id=5, name='test role', diff --git a/pydis_site/apps/api/tests/test_offensive_message.py b/pydis_site/apps/api/tests/test_offensive_message.py new file mode 100644 index 00000000..4ef9201e --- /dev/null +++ b/pydis_site/apps/api/tests/test_offensive_message.py @@ -0,0 +1,61 @@ +import datetime + +from django_hosts.resolvers import reverse + +from .base import APISubdomainTestCase +from ..models import OffensiveMessage + + +class CreationTests(APISubdomainTestCase): + def test_accept_valid_data(self): + url = reverse('bot:offensivemessage-list', host='api') + delete_at = datetime.datetime.now() + datetime.timedelta(days=1) + data = { + 'id': '602951077675139072', + 'channel_id': '291284109232308226', + 'delete_date': delete_at.isoformat()[:-1] + } + + aware_delete_at = delete_at.replace(tzinfo=datetime.timezone.utc) + + response = self.client.post(url, data=data) + self.assertEqual(response.status_code, 201) + + offensive_message = OffensiveMessage.objects.get(id=response.json()['id']) + self.assertAlmostEqual( + aware_delete_at, + offensive_message.delete_date, + delta=datetime.timedelta(seconds=1) + ) + self.assertEqual(data['id'], str(offensive_message.id)) + self.assertEqual(data['channel_id'], str(offensive_message.channel_id)) + + def test_returns_400_on_non_future_date(self): + url = reverse('bot:offensivemessage-list', host='api') + delete_at = datetime.datetime.now() - datetime.timedelta(days=1) + data = { + 'id': '602951077675139072', + 'channel_id': '291284109232308226', + 'delete_date': delete_at.isoformat()[:-1] + } + response = self.client.post(url, data=data) + self.assertEqual(response.status_code, 400) + + def test_returns_400_on_negative_id_or_channel_id(self): + url = reverse('bot:offensivemessage-list', host='api') + delete_at = datetime.datetime.now() + datetime.timedelta(days=1) + data = { + 'id': '-602951077675139072', + 'channel_id': '291284109232308226', + 'delete_date': delete_at.isoformat()[:-1] + } + response = self.client.post(url, data=data) + self.assertEqual(response.status_code, 400) + + data = { + 'id': '602951077675139072', + 'channel_id': '-291284109232308226', + 'delete_date': delete_at.isoformat()[:-1] + } + response = self.client.post(url, data=data) + self.assertEqual(response.status_code, 400) diff --git a/pydis_site/apps/api/tests/test_validators.py b/pydis_site/apps/api/tests/test_validators.py index 9d993839..241af08c 100644 --- a/pydis_site/apps/api/tests/test_validators.py +++ b/pydis_site/apps/api/tests/test_validators.py @@ -1,4 +1,4 @@ -from datetime import datetime +from datetime import datetime, timezone from django.core.exceptions import ValidationError from django.test import TestCase @@ -252,8 +252,8 @@ class TagEmbedValidatorTests(TestCase): class OffensiveMessageValidatorsTests(TestCase): def test_accepts_future_date(self): - future_date_validator(datetime(3000, 1, 1)) + future_date_validator(datetime(3000, 1, 1, tzinfo=timezone.utc)) def test_rejects_non_future_date(self): with self.assertRaises(ValidationError): - future_date_validator(datetime(1000, 1, 1)) + future_date_validator(datetime(1000, 1, 1, tzinfo=timezone.utc)) -- cgit v1.2.3 From ec1c0f26bfbd7f2b3769ab37e02c3d31b3f16b4c Mon Sep 17 00:00:00 2001 From: Akarys42 Date: Thu, 7 Nov 2019 18:55:59 +0100 Subject: Squash down migration files --- .../apps/api/migrations/0046_offensivemessage.py | 25 ---------------------- .../api/migrations/0047_merge_20191025_1920.py | 14 ------------ .../apps/api/migrations/0047_offensivemessage.py | 25 ++++++++++++++++++++++ .../apps/api/migrations/0048_auto_20191025_1921.py | 19 ---------------- 4 files changed, 25 insertions(+), 58 deletions(-) delete mode 100644 pydis_site/apps/api/migrations/0046_offensivemessage.py delete mode 100644 pydis_site/apps/api/migrations/0047_merge_20191025_1920.py create mode 100644 pydis_site/apps/api/migrations/0047_offensivemessage.py delete mode 100644 pydis_site/apps/api/migrations/0048_auto_20191025_1921.py diff --git a/pydis_site/apps/api/migrations/0046_offensivemessage.py b/pydis_site/apps/api/migrations/0046_offensivemessage.py deleted file mode 100644 index 0ce65946..00000000 --- a/pydis_site/apps/api/migrations/0046_offensivemessage.py +++ /dev/null @@ -1,25 +0,0 @@ -# Generated by Django 2.2.6 on 2019-10-24 17:57 - -import django.core.validators -from django.db import migrations, models -import pydis_site.apps.api.models.bot.offensive_message -import pydis_site.apps.api.models.utils - - -class Migration(migrations.Migration): - - dependencies = [ - ('api', '0045_add_plural_name_for_log_entry'), - ] - - operations = [ - migrations.CreateModel( - name='OffensiveMessage', - fields=[ - ('id', models.BigIntegerField(help_text='The message ID as taken from Discord.', primary_key=True, serialize=False, validators=[django.core.validators.MinValueValidator(limit_value=0, message='Message IDs cannot be negative.')])), - ('channel_id', models.BigIntegerField(help_text='The channel ID that the message was sent in, taken from Discord.', validators=[django.core.validators.MinValueValidator(limit_value=0, message='Channel IDs cannot be negative.')])), - ('delete_date', models.DateField(help_text='The date on which the message will be auto-deleted.', validators=[pydis_site.apps.api.models.bot.offensive_message.future_date_validator])), - ], - bases=(pydis_site.apps.api.models.utils.ModelReprMixin, models.Model), - ), - ] diff --git a/pydis_site/apps/api/migrations/0047_merge_20191025_1920.py b/pydis_site/apps/api/migrations/0047_merge_20191025_1920.py deleted file mode 100644 index f70fe24f..00000000 --- a/pydis_site/apps/api/migrations/0047_merge_20191025_1920.py +++ /dev/null @@ -1,14 +0,0 @@ -# Generated by Django 2.2.6 on 2019-10-25 17:20 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('api', '0046_reminder_jump_url'), - ('api', '0046_offensivemessage'), - ] - - operations = [ - ] diff --git a/pydis_site/apps/api/migrations/0047_offensivemessage.py b/pydis_site/apps/api/migrations/0047_offensivemessage.py new file mode 100644 index 00000000..f2068c1b --- /dev/null +++ b/pydis_site/apps/api/migrations/0047_offensivemessage.py @@ -0,0 +1,25 @@ +# Generated by Django 2.2.6 on 2019-11-07 17:55 + +import django.core.validators +from django.db import migrations, models +import pydis_site.apps.api.models.bot.offensive_message +import pydis_site.apps.api.models.utils + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0046_reminder_jump_url'), + ] + + operations = [ + migrations.CreateModel( + name='OffensiveMessage', + fields=[ + ('id', models.BigIntegerField(help_text='The message ID as taken from Discord.', primary_key=True, serialize=False, validators=[django.core.validators.MinValueValidator(limit_value=0, message='Message IDs cannot be negative.')])), + ('channel_id', models.BigIntegerField(help_text='The channel ID that the message was sent in, taken from Discord.', validators=[django.core.validators.MinValueValidator(limit_value=0, message='Channel IDs cannot be negative.')])), + ('delete_date', models.DateTimeField(help_text='The date on which the message will be auto-deleted.', validators=[pydis_site.apps.api.models.bot.offensive_message.future_date_validator])), + ], + bases=(pydis_site.apps.api.models.utils.ModelReprMixin, models.Model), + ), + ] diff --git a/pydis_site/apps/api/migrations/0048_auto_20191025_1921.py b/pydis_site/apps/api/migrations/0048_auto_20191025_1921.py deleted file mode 100644 index 2e5e670a..00000000 --- a/pydis_site/apps/api/migrations/0048_auto_20191025_1921.py +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by Django 2.2.6 on 2019-10-25 17:21 - -from django.db import migrations, models -import pydis_site.apps.api.models.bot.offensive_message - - -class Migration(migrations.Migration): - - dependencies = [ - ('api', '0047_merge_20191025_1920'), - ] - - operations = [ - migrations.AlterField( - model_name='offensivemessage', - name='delete_date', - field=models.DateTimeField(help_text='The date on which the message will be auto-deleted.', validators=[pydis_site.apps.api.models.bot.offensive_message.future_date_validator]), - ), - ] -- cgit v1.2.3 From a33af9d6d356fa416863e487f71aae4ba0977a0f Mon Sep 17 00:00:00 2001 From: Akarys42 Date: Thu, 7 Nov 2019 18:59:47 +0100 Subject: Fix copy pasting mistake --- pydis_site/apps/api/viewsets/bot/offensive_message.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydis_site/apps/api/viewsets/bot/offensive_message.py b/pydis_site/apps/api/viewsets/bot/offensive_message.py index 0ef5666b..371bd8e7 100644 --- a/pydis_site/apps/api/viewsets/bot/offensive_message.py +++ b/pydis_site/apps/api/viewsets/bot/offensive_message.py @@ -14,7 +14,7 @@ class OffensiveMessageViewSet( CreateModelMixin, ListModelMixin, DestroyModelMixin, UpdateModelMixin, GenericViewSet ): """ - View providing CRUD access to reminders. + View providing CRUD access to offensive messages. ## Routes ### GET /bot/offensive-message -- cgit v1.2.3 From edaf17636ac9ccf832136ed54d00f0a5038d9d7b Mon Sep 17 00:00:00 2001 From: Akarys42 Date: Thu, 7 Nov 2019 19:02:19 +0100 Subject: Block PATCH and PUT methods --- pydis_site/apps/api/viewsets/bot/offensive_message.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pydis_site/apps/api/viewsets/bot/offensive_message.py b/pydis_site/apps/api/viewsets/bot/offensive_message.py index 371bd8e7..f25c14b4 100644 --- a/pydis_site/apps/api/viewsets/bot/offensive_message.py +++ b/pydis_site/apps/api/viewsets/bot/offensive_message.py @@ -1,8 +1,7 @@ from rest_framework.mixins import ( CreateModelMixin, DestroyModelMixin, - ListModelMixin, - UpdateModelMixin + ListModelMixin ) from rest_framework.viewsets import GenericViewSet @@ -11,7 +10,7 @@ from pydis_site.apps.api.serializers import OffensiveMessageSerializer class OffensiveMessageViewSet( - CreateModelMixin, ListModelMixin, DestroyModelMixin, UpdateModelMixin, GenericViewSet + CreateModelMixin, ListModelMixin, DestroyModelMixin, GenericViewSet ): """ View providing CRUD access to offensive messages. -- cgit v1.2.3 From f06148f6efb89e85a8dfad60cce21d5f6b95d505 Mon Sep 17 00:00:00 2001 From: Akarys42 Date: Thu, 7 Nov 2019 19:09:53 +0100 Subject: Merge master migration files --- .../apps/api/migrations/0047_offensivemessage.py | 25 ---------------------- .../apps/api/migrations/0049_offensivemessage.py | 25 ++++++++++++++++++++++ 2 files changed, 25 insertions(+), 25 deletions(-) delete mode 100644 pydis_site/apps/api/migrations/0047_offensivemessage.py create mode 100644 pydis_site/apps/api/migrations/0049_offensivemessage.py diff --git a/pydis_site/apps/api/migrations/0047_offensivemessage.py b/pydis_site/apps/api/migrations/0047_offensivemessage.py deleted file mode 100644 index f2068c1b..00000000 --- a/pydis_site/apps/api/migrations/0047_offensivemessage.py +++ /dev/null @@ -1,25 +0,0 @@ -# Generated by Django 2.2.6 on 2019-11-07 17:55 - -import django.core.validators -from django.db import migrations, models -import pydis_site.apps.api.models.bot.offensive_message -import pydis_site.apps.api.models.utils - - -class Migration(migrations.Migration): - - dependencies = [ - ('api', '0046_reminder_jump_url'), - ] - - operations = [ - migrations.CreateModel( - name='OffensiveMessage', - fields=[ - ('id', models.BigIntegerField(help_text='The message ID as taken from Discord.', primary_key=True, serialize=False, validators=[django.core.validators.MinValueValidator(limit_value=0, message='Message IDs cannot be negative.')])), - ('channel_id', models.BigIntegerField(help_text='The channel ID that the message was sent in, taken from Discord.', validators=[django.core.validators.MinValueValidator(limit_value=0, message='Channel IDs cannot be negative.')])), - ('delete_date', models.DateTimeField(help_text='The date on which the message will be auto-deleted.', validators=[pydis_site.apps.api.models.bot.offensive_message.future_date_validator])), - ], - bases=(pydis_site.apps.api.models.utils.ModelReprMixin, models.Model), - ), - ] diff --git a/pydis_site/apps/api/migrations/0049_offensivemessage.py b/pydis_site/apps/api/migrations/0049_offensivemessage.py new file mode 100644 index 00000000..fe4a1961 --- /dev/null +++ b/pydis_site/apps/api/migrations/0049_offensivemessage.py @@ -0,0 +1,25 @@ +# Generated by Django 2.2.6 on 2019-11-07 18:08 + +import django.core.validators +from django.db import migrations, models +import pydis_site.apps.api.models.bot.offensive_message +import pydis_site.apps.api.models.utils + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0048_add_infractions_unique_constraints_active'), + ] + + operations = [ + migrations.CreateModel( + name='OffensiveMessage', + fields=[ + ('id', models.BigIntegerField(help_text='The message ID as taken from Discord.', primary_key=True, serialize=False, validators=[django.core.validators.MinValueValidator(limit_value=0, message='Message IDs cannot be negative.')])), + ('channel_id', models.BigIntegerField(help_text='The channel ID that the message was sent in, taken from Discord.', validators=[django.core.validators.MinValueValidator(limit_value=0, message='Channel IDs cannot be negative.')])), + ('delete_date', models.DateTimeField(help_text='The date on which the message will be auto-deleted.', validators=[pydis_site.apps.api.models.bot.offensive_message.future_date_validator])), + ], + bases=(pydis_site.apps.api.models.utils.ModelReprMixin, models.Model), + ), + ] -- cgit v1.2.3 From 1acf84b47eda889df5c14caba3ebc38bb13ab542 Mon Sep 17 00:00:00 2001 From: Akarys42 Date: Sun, 10 Nov 2019 18:30:28 +0100 Subject: Make sure the API return the appropriate response. --- pydis_site/apps/api/tests/test_offensive_message.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pydis_site/apps/api/tests/test_offensive_message.py b/pydis_site/apps/api/tests/test_offensive_message.py index 4ef9201e..dd9aaf21 100644 --- a/pydis_site/apps/api/tests/test_offensive_message.py +++ b/pydis_site/apps/api/tests/test_offensive_message.py @@ -40,6 +40,9 @@ class CreationTests(APISubdomainTestCase): } response = self.client.post(url, data=data) self.assertEqual(response.status_code, 400) + self.assertEqual(response.json(), { + 'delete_date': ['Date must be a future date'] + }) def test_returns_400_on_negative_id_or_channel_id(self): url = reverse('bot:offensivemessage-list', host='api') @@ -51,6 +54,9 @@ class CreationTests(APISubdomainTestCase): } response = self.client.post(url, data=data) self.assertEqual(response.status_code, 400) + self.assertEqual(response.json(), { + 'id': ['Ensure this value is greater than or equal to 0.'] + }) data = { 'id': '602951077675139072', @@ -59,3 +65,6 @@ class CreationTests(APISubdomainTestCase): } response = self.client.post(url, data=data) self.assertEqual(response.status_code, 400) + self.assertEqual(response.json(), { + 'channel_id': ['Ensure this value is greater than or equal to 0.'] + }) -- cgit v1.2.3 From 3e01ca7c15aa50683b9d91e427bd8a42a7516ad7 Mon Sep 17 00:00:00 2001 From: Akarys42 Date: Mon, 11 Nov 2019 17:48:42 +0100 Subject: Add tests to make sure the view return 405 for PATCH and PUT requests --- .../apps/api/tests/test_offensive_message.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/pydis_site/apps/api/tests/test_offensive_message.py b/pydis_site/apps/api/tests/test_offensive_message.py index dd9aaf21..0c3ba4f6 100644 --- a/pydis_site/apps/api/tests/test_offensive_message.py +++ b/pydis_site/apps/api/tests/test_offensive_message.py @@ -68,3 +68,25 @@ class CreationTests(APISubdomainTestCase): self.assertEqual(response.json(), { 'channel_id': ['Ensure this value is greater than or equal to 0.'] }) + + +class NotAllowedMethodsTests(APISubdomainTestCase): + @classmethod + def setUpTestData(cls): # noqa + delete_at = datetime.datetime.now() + datetime.timedelta(days=1) + + cls.valid_offensive_message = OffensiveMessage.objects.create( + id=602951077675139072, + channel_id=291284109232308226, + delete_date=delete_at.isoformat()[:-1] + ) + + def test_returns_405_for_patch_and_put_requests(self): + url = reverse( + 'bot:offensivemessage-detail', host='api', args=(self.valid_offensive_message.id,) + ) + + response = self.client.patch(url, {}) + self.assertEqual(response.status_code, 405) + response = self.client.put(url, {}) + self.assertEqual(response.status_code, 405) -- cgit v1.2.3 From 20bfc996404ec9faee8c7105001540724a197dac Mon Sep 17 00:00:00 2001 From: Akarys42 Date: Mon, 11 Nov 2019 18:01:55 +0100 Subject: Add deletion tests --- .../apps/api/tests/test_offensive_message.py | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/pydis_site/apps/api/tests/test_offensive_message.py b/pydis_site/apps/api/tests/test_offensive_message.py index 0c3ba4f6..04da6d26 100644 --- a/pydis_site/apps/api/tests/test_offensive_message.py +++ b/pydis_site/apps/api/tests/test_offensive_message.py @@ -70,6 +70,30 @@ class CreationTests(APISubdomainTestCase): }) +class DeletionTests(APISubdomainTestCase): + @classmethod + def setUpTestData(cls): # noqa + delete_at = datetime.datetime.now(tz=datetime.timezone.utc) + datetime.timedelta(days=1) + + cls.valid_offensive_message = OffensiveMessage.objects.create( + id=602951077675139072, + channel_id=291284109232308226, + delete_date=delete_at.isoformat() + ) + + def test_delete_data(self): + url = reverse( + 'bot:offensivemessage-detail', host='api', args=(self.valid_offensive_message.id,) + ) + + response = self.client.delete(url) + self.assertEqual(response.status_code, 204) + + url = reverse('bot:offensivemessage-list', host='api') + response = self.client.get(url) + self.assertNotIn(self.valid_offensive_message.id, response.json()) + + class NotAllowedMethodsTests(APISubdomainTestCase): @classmethod def setUpTestData(cls): # noqa -- cgit v1.2.3 From 5792c4f43c09430275ce9223704072635de083fc Mon Sep 17 00:00:00 2001 From: Akarys42 Date: Mon, 11 Nov 2019 18:02:41 +0100 Subject: Change setUpTestData to use aware datetime This remove a warning during test run --- pydis_site/apps/api/tests/test_offensive_message.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pydis_site/apps/api/tests/test_offensive_message.py b/pydis_site/apps/api/tests/test_offensive_message.py index 04da6d26..a80b1793 100644 --- a/pydis_site/apps/api/tests/test_offensive_message.py +++ b/pydis_site/apps/api/tests/test_offensive_message.py @@ -97,12 +97,12 @@ class DeletionTests(APISubdomainTestCase): class NotAllowedMethodsTests(APISubdomainTestCase): @classmethod def setUpTestData(cls): # noqa - delete_at = datetime.datetime.now() + datetime.timedelta(days=1) + delete_at = datetime.datetime.now(tz=datetime.timezone.utc) + datetime.timedelta(days=1) cls.valid_offensive_message = OffensiveMessage.objects.create( id=602951077675139072, channel_id=291284109232308226, - delete_date=delete_at.isoformat()[:-1] + delete_date=delete_at.isoformat() ) def test_returns_405_for_patch_and_put_requests(self): -- cgit v1.2.3 From 21961b6d002bac5b35641505bd9f91902da46047 Mon Sep 17 00:00:00 2001 From: Akarys42 Date: Tue, 12 Nov 2019 11:35:42 +0100 Subject: Make use of subtests Co-authored-by: Sebastiaan Zeeff <33516116+SebastiaanZ@users.noreply.github.com> --- .../apps/api/tests/test_offensive_message.py | 40 +++++++++++----------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/pydis_site/apps/api/tests/test_offensive_message.py b/pydis_site/apps/api/tests/test_offensive_message.py index a80b1793..a270074b 100644 --- a/pydis_site/apps/api/tests/test_offensive_message.py +++ b/pydis_site/apps/api/tests/test_offensive_message.py @@ -48,26 +48,25 @@ class CreationTests(APISubdomainTestCase): url = reverse('bot:offensivemessage-list', host='api') delete_at = datetime.datetime.now() + datetime.timedelta(days=1) data = { - 'id': '-602951077675139072', + 'id': '602951077675139072', 'channel_id': '291284109232308226', 'delete_date': delete_at.isoformat()[:-1] } - response = self.client.post(url, data=data) - self.assertEqual(response.status_code, 400) - self.assertEqual(response.json(), { - 'id': ['Ensure this value is greater than or equal to 0.'] - }) + cases = ( + ('id', '-602951077675139072'), + ('channel_id', '-291284109232308226') + ) - data = { - 'id': '602951077675139072', - 'channel_id': '-291284109232308226', - 'delete_date': delete_at.isoformat()[:-1] - } - response = self.client.post(url, data=data) - self.assertEqual(response.status_code, 400) - self.assertEqual(response.json(), { - 'channel_id': ['Ensure this value is greater than or equal to 0.'] - }) + for field, invalid_value in cases: + with self.subTest(fied=field, invalid_value=invalid_value): + test_data = data.copy() + test_data.update({field: invalid_value}) + + response = self.client.post(url, test_data) + self.assertEqual(response.status_code, 400) + self.assertEqual(response.json(), { + field: ['Ensure this value is greater than or equal to 0.'] + }) class DeletionTests(APISubdomainTestCase): @@ -109,8 +108,9 @@ class NotAllowedMethodsTests(APISubdomainTestCase): url = reverse( 'bot:offensivemessage-detail', host='api', args=(self.valid_offensive_message.id,) ) + not_allowed_methods = (self.client.patch, self.client.put) - response = self.client.patch(url, {}) - self.assertEqual(response.status_code, 405) - response = self.client.put(url, {}) - self.assertEqual(response.status_code, 405) + for method in not_allowed_methods: + with self.subTest(method=method): + response = method(url, {}) + self.assertEqual(response.status_code, 405) -- cgit v1.2.3 From c23d1131fff3ba62431eed0750005b3d5cae9a4c Mon Sep 17 00:00:00 2001 From: Akarys42 Date: Sat, 16 Nov 2019 18:43:46 +0100 Subject: Write list test for the offensive message model --- .../apps/api/tests/test_offensive_message.py | 39 ++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/pydis_site/apps/api/tests/test_offensive_message.py b/pydis_site/apps/api/tests/test_offensive_message.py index a270074b..26729c98 100644 --- a/pydis_site/apps/api/tests/test_offensive_message.py +++ b/pydis_site/apps/api/tests/test_offensive_message.py @@ -69,6 +69,45 @@ class CreationTests(APISubdomainTestCase): }) +class ListTests(APISubdomainTestCase): + @classmethod + def setUpTestData(cls): # noqa + delete_at = datetime.datetime.now() + datetime.timedelta(days=1) + aware_delete_at = delete_at.replace(tzinfo=datetime.timezone.utc) + + cls.messages = [ + { + 'id': 602951077675139072, + 'channel_id': 91284109232308226, + }, + { + 'id': 645298201494159401, + 'channel_id': 592000283102674944 + } + ] + + cls.of1 = OffensiveMessage.objects.create( + **cls.messages[0], + delete_date=aware_delete_at.isoformat() + ) + cls.of2 = OffensiveMessage.objects.create( + **cls.messages[1], + delete_date=aware_delete_at.isoformat() + ) + + # Expected API answer : + cls.messages[0]['delete_date'] = delete_at.isoformat() + 'Z' + cls.messages[1]['delete_date'] = delete_at.isoformat() + 'Z' + + def test_get_data(self): + url = reverse('bot:offensivemessage-list', host='api') + + response = self.client.get(url) + self.assertEqual(response.status_code, 200) + + self.assertEqual(response.json(), self.messages) + + class DeletionTests(APISubdomainTestCase): @classmethod def setUpTestData(cls): # noqa -- cgit v1.2.3 From f55d023edb903ce57fd8b209c76e8f918fc9eb65 Mon Sep 17 00:00:00 2001 From: Akarys42 Date: Sat, 16 Nov 2019 18:44:55 +0100 Subject: Use direct database test intead of relying on GET --- pydis_site/apps/api/tests/test_offensive_message.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pydis_site/apps/api/tests/test_offensive_message.py b/pydis_site/apps/api/tests/test_offensive_message.py index 26729c98..d5896714 100644 --- a/pydis_site/apps/api/tests/test_offensive_message.py +++ b/pydis_site/apps/api/tests/test_offensive_message.py @@ -127,9 +127,9 @@ class DeletionTests(APISubdomainTestCase): response = self.client.delete(url) self.assertEqual(response.status_code, 204) - url = reverse('bot:offensivemessage-list', host='api') - response = self.client.get(url) - self.assertNotIn(self.valid_offensive_message.id, response.json()) + self.assertFalse( + OffensiveMessage.objects.filter(id=self.valid_offensive_message.id).exists() + ) class NotAllowedMethodsTests(APISubdomainTestCase): -- cgit v1.2.3 From f3653925b8ddd4ce5d1c81cd9b1dd94cb0b36b53 Mon Sep 17 00:00:00 2001 From: Akarys42 Date: Sat, 14 Dec 2019 11:46:37 +0100 Subject: Rename route /bot/offensive-message to /bot/offensive-messages --- pydis_site/apps/api/urls.py | 2 +- pydis_site/apps/api/viewsets/bot/offensive_message.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pydis_site/apps/api/urls.py b/pydis_site/apps/api/urls.py index b1864ba7..4a0281b4 100644 --- a/pydis_site/apps/api/urls.py +++ b/pydis_site/apps/api/urls.py @@ -35,7 +35,7 @@ bot_router.register( NominationViewSet ) bot_router.register( - 'offensive-message', + 'offensive-messages', OffensiveMessageViewSet ) bot_router.register( diff --git a/pydis_site/apps/api/viewsets/bot/offensive_message.py b/pydis_site/apps/api/viewsets/bot/offensive_message.py index f25c14b4..54cb3a38 100644 --- a/pydis_site/apps/api/viewsets/bot/offensive_message.py +++ b/pydis_site/apps/api/viewsets/bot/offensive_message.py @@ -16,7 +16,7 @@ class OffensiveMessageViewSet( View providing CRUD access to offensive messages. ## Routes - ### GET /bot/offensive-message + ### GET /bot/offensive-messages Returns all offensive messages in the database. #### Response format @@ -32,7 +32,7 @@ class OffensiveMessageViewSet( #### Status codes - 200: returned on success - ### POST /bot/offensive-message + ### POST /bot/offensive-messages Create a new offensive message object. #### Request body @@ -46,7 +46,7 @@ class OffensiveMessageViewSet( - 201: returned on success - 400: if the body format is invalid - ### DELETE /bot/offensive-message/ + ### DELETE /bot/offensive-messages/ Delete the offensive message object with the given `id`. #### Status codes -- cgit v1.2.3