diff options
Diffstat (limited to 'pydis_site/apps')
| -rw-r--r-- | pydis_site/apps/api/migrations/0049_deletedmessage_attachments.py | 20 | ||||
| -rw-r--r-- | pydis_site/apps/api/models/bot/message.py | 7 | ||||
| -rw-r--r-- | pydis_site/apps/api/serializers.py | 3 | ||||
| -rw-r--r-- | pydis_site/apps/api/tests/test_deleted_messages.py | 9 | ||||
| -rw-r--r-- | pydis_site/apps/api/tests/test_reminders.py | 196 | ||||
| -rw-r--r-- | pydis_site/apps/staff/tests/test_logs_view.py | 17 | 
6 files changed, 248 insertions, 4 deletions
diff --git a/pydis_site/apps/api/migrations/0049_deletedmessage_attachments.py b/pydis_site/apps/api/migrations/0049_deletedmessage_attachments.py new file mode 100644 index 00000000..31ac239a --- /dev/null +++ b/pydis_site/apps/api/migrations/0049_deletedmessage_attachments.py @@ -0,0 +1,20 @@ +# Generated by Django 2.2.6 on 2019-10-28 17:12 + +import django.contrib.postgres.fields +from django.db import migrations, models + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('api', '0049_offensivemessage'), +    ] + +    operations = [ +        migrations.AddField( +            model_name='deletedmessage', +            name='attachments', +            field=django.contrib.postgres.fields.ArrayField(base_field=models.URLField(max_length=512), default=[], blank=True, help_text='Attachments attached to this message.', size=None), +            preserve_default=False, +        ), +    ] diff --git a/pydis_site/apps/api/models/bot/message.py b/pydis_site/apps/api/models/bot/message.py index 31316a01..8b18fc9f 100644 --- a/pydis_site/apps/api/models/bot/message.py +++ b/pydis_site/apps/api/models/bot/message.py @@ -51,6 +51,13 @@ class Message(ModelReprMixin, models.Model):          ),          help_text="Embeds attached to this message."      ) +    attachments = pgfields.ArrayField( +        models.URLField( +            max_length=512 +        ), +        blank=True, +        help_text="Attachments attached to this message." +    )      @property      def timestamp(self) -> datetime: diff --git a/pydis_site/apps/api/serializers.py b/pydis_site/apps/api/serializers.py index e538a012..e11c4af2 100644 --- a/pydis_site/apps/api/serializers.py +++ b/pydis_site/apps/api/serializers.py @@ -50,7 +50,8 @@ class DeletedMessageSerializer(ModelSerializer):          fields = (              'id', 'author',              'channel_id', 'content', -            'embeds', 'deletion_context' +            'embeds', 'deletion_context', +            'attachments'          ) diff --git a/pydis_site/apps/api/tests/test_deleted_messages.py b/pydis_site/apps/api/tests/test_deleted_messages.py index d1e9f2f5..b3a8197b 100644 --- a/pydis_site/apps/api/tests/test_deleted_messages.py +++ b/pydis_site/apps/api/tests/test_deleted_messages.py @@ -25,14 +25,16 @@ class DeletedMessagesWithoutActorTests(APISubdomainTestCase):                      'id': 55,                      'channel_id': 5555,                      'content': "Terror Billy is a meanie", -                    'embeds': [] +                    'embeds': [], +                    'attachments': []                  },                  {                      'author': cls.author.id,                      'id': 56,                      'channel_id': 5555,                      'content': "If you purge this, you're evil", -                    'embeds': [] +                    'embeds': [], +                    'attachments': []                  }              ]          } @@ -64,7 +66,8 @@ class DeletedMessagesWithActorTests(APISubdomainTestCase):                      'id': 12903,                      'channel_id': 1824,                      'content': "I hate trailing commas", -                    'embeds': [] +                    'embeds': [], +                    'attachments': []                  },              ]          } diff --git a/pydis_site/apps/api/tests/test_reminders.py b/pydis_site/apps/api/tests/test_reminders.py new file mode 100644 index 00000000..3441e0cc --- /dev/null +++ b/pydis_site/apps/api/tests/test_reminders.py @@ -0,0 +1,196 @@ +from datetime import datetime + +from django.forms.models import model_to_dict +from django_hosts.resolvers import reverse + +from .base import APISubdomainTestCase +from ..models import Reminder, User + + +class UnauthedReminderAPITests(APISubdomainTestCase): +    def setUp(self): +        super().setUp() +        self.client.force_authenticate(user=None) + +    def test_list_returns_401(self): +        url = reverse('bot:reminder-list', host='api') +        response = self.client.get(url) + +        self.assertEqual(response.status_code, 401) + +    def test_create_returns_401(self): +        url = reverse('bot:reminder-list', host='api') +        response = self.client.post(url, data={'not': 'important'}) + +        self.assertEqual(response.status_code, 401) + +    def test_delete_returns_401(self): +        url = reverse('bot:reminder-detail', args=('1234',), host='api') +        response = self.client.delete(url) + +        self.assertEqual(response.status_code, 401) + + +class EmptyDatabaseReminderAPITests(APISubdomainTestCase): +    def test_list_all_returns_empty_list(self): +        url = reverse('bot:reminder-list', host='api') +        response = self.client.get(url) + +        self.assertEqual(response.status_code, 200) +        self.assertEqual(response.json(), []) + +    def test_delete_returns_404(self): +        url = reverse('bot:reminder-detail', args=('1234',), host='api') +        response = self.client.delete(url) + +        self.assertEqual(response.status_code, 404) + + +class ReminderCreationTests(APISubdomainTestCase): +    @classmethod +    def setUpTestData(cls): +        cls.author = User.objects.create( +            id=1234, +            name='Mermaid Man', +            discriminator=1234, +            avatar_hash=None, +        ) + +    def test_accepts_valid_data(self): +        data = { +            'author': self.author.id, +            'content': 'Remember to...wait what was it again?', +            'expiration': datetime.utcnow().isoformat(), +            'jump_url': "https://www.google.com", +            'channel_id': 123, +        } +        url = reverse('bot:reminder-list', host='api') +        response = self.client.post(url, data=data) +        self.assertEqual(response.status_code, 201) +        self.assertIsNotNone(Reminder.objects.filter(id=1).first()) + +    def test_rejects_invalid_data(self): +        data = { +            'author': self.author.id,  # Missing multiple required fields +        } +        url = reverse('bot:reminder-list', host='api') +        response = self.client.post(url, data=data) +        self.assertEqual(response.status_code, 400) +        self.assertRaises(Reminder.DoesNotExist, Reminder.objects.get, id=1) + + +class ReminderDeletionTests(APISubdomainTestCase): +    @classmethod +    def setUpTestData(cls): +        cls.author = User.objects.create( +            id=6789, +            name='Barnacle Boy', +            discriminator=6789, +            avatar_hash=None, +        ) + +        cls.reminder = Reminder.objects.create( +            author=cls.author, +            content="Don't forget to set yourself a reminder", +            expiration=datetime.utcnow().isoformat(), +            jump_url="https://www.decliningmentalfaculties.com", +            channel_id=123 +        ) + +    def test_delete_unknown_reminder_returns_404(self): +        url = reverse('bot:reminder-detail', args=('something',), host='api') +        response = self.client.delete(url) + +        self.assertEqual(response.status_code, 404) + +    def test_delete_known_reminder_returns_204(self): +        url = reverse('bot:reminder-detail', args=(self.reminder.id,), host='api') +        response = self.client.delete(url) + +        self.assertEqual(response.status_code, 204) +        self.assertRaises(Reminder.DoesNotExist, Reminder.objects.get, id=self.reminder.id) + + +class ReminderListTests(APISubdomainTestCase): +    @classmethod +    def setUpTestData(cls): +        cls.author = User.objects.create( +            id=6789, +            name='Patrick Star', +            discriminator=6789, +            avatar_hash=None, +        ) + +        cls.reminder_one = Reminder.objects.create( +            author=cls.author, +            content="We should take Bikini Bottom, and push it somewhere else!", +            expiration=datetime.utcnow().isoformat(), +            jump_url="https://www.icantseemyforehead.com", +            channel_id=123 +        ) + +        cls.reminder_two = Reminder.objects.create( +            author=cls.author, +            content="Gahhh-I love being purple!", +            expiration=datetime.utcnow().isoformat(), +            jump_url="https://www.goofygoobersicecreampartyboat.com", +            channel_id=123, +            active=False +        ) + +        cls.rem_dict_one = model_to_dict(cls.reminder_one) +        cls.rem_dict_one['expiration'] += 'Z'  # Massaging a quirk of the response time format +        cls.rem_dict_two = model_to_dict(cls.reminder_two) +        cls.rem_dict_two['expiration'] += 'Z'  # Massaging a quirk of the response time format + +    def test_reminders_in_full_list(self): +        url = reverse('bot:reminder-list', host='api') +        response = self.client.get(url) + +        self.assertEqual(response.status_code, 200) +        self.assertCountEqual(response.json(), [self.rem_dict_one, self.rem_dict_two]) + +    def test_filter_search(self): +        url = reverse('bot:reminder-list', host='api') +        response = self.client.get(f'{url}?search={self.author.name}') + +        self.assertEqual(response.status_code, 200) +        self.assertCountEqual(response.json(), [self.rem_dict_one, self.rem_dict_two]) + +    def test_filter_field(self): +        url = reverse('bot:reminder-list', host='api') +        response = self.client.get(f'{url}?active=true') + +        self.assertEqual(response.status_code, 200) +        self.assertEqual(response.json(), [self.rem_dict_one]) + + +class ReminderUpdateTests(APISubdomainTestCase): +    @classmethod +    def setUpTestData(cls): +        cls.author = User.objects.create( +            id=666, +            name='Man Ray', +            discriminator=666, +            avatar_hash=None, +        ) + +        cls.reminder = Reminder.objects.create( +            author=cls.author, +            content="Squash those do-gooders", +            expiration=datetime.utcnow().isoformat(), +            jump_url="https://www.decliningmentalfaculties.com", +            channel_id=123 +        ) + +        cls.data = {'content': 'Oops I forgot'} + +    def test_patch_updates_record(self): +        url = reverse('bot:reminder-detail', args=(self.reminder.id,), host='api') +        response = self.client.patch(url, data=self.data) + +        self.assertEqual(response.status_code, 200) +        self.assertEqual( +            Reminder.objects.filter(id=self.reminder.id).first().content, +            self.data['content'] +        ) diff --git a/pydis_site/apps/staff/tests/test_logs_view.py b/pydis_site/apps/staff/tests/test_logs_view.py index 32cb6bbf..1415c558 100644 --- a/pydis_site/apps/staff/tests/test_logs_view.py +++ b/pydis_site/apps/staff/tests/test_logs_view.py @@ -37,6 +37,7 @@ class TestLogsView(TestCase):              channel_id=1984,              content='<em>I think my tape has run out...</em>',              embeds=[], +            attachments=[],              deletion_context=cls.deletion_context,          ) @@ -101,6 +102,7 @@ class TestLogsView(TestCase):              channel_id=1984,              content='Does that mean this thing will halt?',              embeds=[cls.embed_one, cls.embed_two], +            attachments=['https://http.cat/100', 'https://http.cat/402'],              deletion_context=cls.deletion_context,          ) @@ -149,6 +151,21 @@ class TestLogsView(TestCase):          self.assertInHTML(embed_colour_needle.format(colour=embed_one_colour), html_response)          self.assertInHTML(embed_colour_needle.format(colour=embed_two_colour), html_response) +    def test_if_both_attachments_are_included_html_response(self): +        url = reverse('logs', host="staff", args=(self.deletion_context.id,)) +        response = self.client.get(url) + +        html_response = response.content.decode() +        attachment_needle = '<img alt="Attachment" class="discord-attachment" src="{url}">' +        self.assertInHTML( +            attachment_needle.format(url=self.deleted_message_two.attachments[0]), +            html_response +        ) +        self.assertInHTML( +            attachment_needle.format(url=self.deleted_message_two.attachments[1]), +            html_response +        ) +      def test_if_html_in_content_is_properly_escaped(self):          url = reverse('logs', host="staff", args=(self.deletion_context.id,))          response = self.client.get(url)  |