From 9c812d5c40813b453bf0711538eaebea46e2b16b Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Sat, 10 Oct 2020 19:09:31 +0300 Subject: Add voice ban to infraction types and create migration for it --- .../migrations/0067_add_voice_ban_infraction_type.py | 18 ++++++++++++++++++ pydis_site/apps/api/models/bot/infraction.py | 3 ++- 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 pydis_site/apps/api/migrations/0067_add_voice_ban_infraction_type.py diff --git a/pydis_site/apps/api/migrations/0067_add_voice_ban_infraction_type.py b/pydis_site/apps/api/migrations/0067_add_voice_ban_infraction_type.py new file mode 100644 index 00000000..9a940ff4 --- /dev/null +++ b/pydis_site/apps/api/migrations/0067_add_voice_ban_infraction_type.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.10 on 2020-10-10 16:08 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0066_merge_20201003_0730'), + ] + + operations = [ + migrations.AlterField( + model_name='infraction', + name='type', + field=models.CharField(choices=[('note', 'Note'), ('warning', 'Warning'), ('watch', 'Watch'), ('mute', 'Mute'), ('kick', 'Kick'), ('ban', 'Ban'), ('superstar', 'Superstar'), ('voice_ban', 'Voice Ban')], help_text='The type of the infraction.', max_length=9), + ), + ] diff --git a/pydis_site/apps/api/models/bot/infraction.py b/pydis_site/apps/api/models/bot/infraction.py index 7660cbba..5ef3a4ce 100644 --- a/pydis_site/apps/api/models/bot/infraction.py +++ b/pydis_site/apps/api/models/bot/infraction.py @@ -15,7 +15,8 @@ class Infraction(ModelReprMixin, models.Model): ("mute", "Mute"), ("kick", "Kick"), ("ban", "Ban"), - ("superstar", "Superstar") + ("superstar", "Superstar"), + ("voice_ban", "Voice Ban") ) inserted_at = models.DateTimeField( default=timezone.now, -- cgit v1.2.3 From 511152c0a91ae81949941ff9d8f8129f01338173 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Sat, 10 Oct 2020 19:14:36 +0300 Subject: Don't allow voice ban to be hidden infraction --- pydis_site/apps/api/serializers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydis_site/apps/api/serializers.py b/pydis_site/apps/api/serializers.py index 25c5c82e..10eb3839 100644 --- a/pydis_site/apps/api/serializers.py +++ b/pydis_site/apps/api/serializers.py @@ -167,7 +167,7 @@ class InfractionSerializer(ModelSerializer): raise ValidationError({'expires_at': [f'{infr_type} infractions cannot expire.']}) hidden = attrs.get('hidden') - if hidden and infr_type in ('superstar', 'warning'): + if hidden and infr_type in ('superstar', 'warning', 'voice_ban'): raise ValidationError({'hidden': [f'{infr_type} infractions cannot be hidden.']}) if not hidden and infr_type in ('note', ): -- cgit v1.2.3 From 990d8cfc98ec71a31ea3ef659cb109547f987e31 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Sat, 10 Oct 2020 19:56:54 +0300 Subject: Include voice ban status on metricity data --- pydis_site/apps/api/viewsets/bot/user.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/pydis_site/apps/api/viewsets/bot/user.py b/pydis_site/apps/api/viewsets/bot/user.py index 3ab71186..19f55555 100644 --- a/pydis_site/apps/api/viewsets/bot/user.py +++ b/pydis_site/apps/api/viewsets/bot/user.py @@ -1,6 +1,7 @@ import typing from collections import OrderedDict +from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist from rest_framework import status from rest_framework.decorators import action from rest_framework.pagination import PageNumberPagination @@ -9,6 +10,7 @@ from rest_framework.response import Response from rest_framework.serializers import ModelSerializer from rest_framework.viewsets import ModelViewSet +from pydis_site.apps.api.models.bot.infraction import Infraction from pydis_site.apps.api.models.bot.metricity import Metricity, NotFound from pydis_site.apps.api.models.bot.user import User from pydis_site.apps.api.serializers import UserSerializer @@ -240,10 +242,21 @@ class UserViewSet(ModelViewSet): def metricity_data(self, request: Request, pk: str = None) -> Response: """Request handler for metricity_data endpoint.""" user = self.get_object() + + try: + Infraction.objects.get(user__id=user.id, active=True, type="voice_ban") + except ObjectDoesNotExist: + voice_banned = False + except MultipleObjectReturned: + voice_banned = True + else: + voice_banned = True + with Metricity() as metricity: try: data = metricity.user(user.id) data["total_messages"] = metricity.total_messages(user.id) + data["voice_banned"] = voice_banned return Response(data, status=status.HTTP_200_OK) except NotFound: return Response(dict(detail="User not found in metricity"), -- cgit v1.2.3 From f1bdb525af330f28742638fdaa19cd8c76235906 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Sat, 10 Oct 2020 20:15:01 +0300 Subject: Cover metricity voice ban status with tests --- pydis_site/apps/api/tests/test_users.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/pydis_site/apps/api/tests/test_users.py b/pydis_site/apps/api/tests/test_users.py index d03785ae..01bf208b 100644 --- a/pydis_site/apps/api/tests/test_users.py +++ b/pydis_site/apps/api/tests/test_users.py @@ -1,5 +1,6 @@ from unittest.mock import patch +from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist from django_hosts.resolvers import reverse from .base import APISubdomainTestCase @@ -419,6 +420,7 @@ class UserMetricityTests(APISubdomainTestCase): self.assertEqual(response.json(), { "verified_at": verified_at, "total_messages": total_messages, + "voice_banned": False, }) def test_no_metricity_user(self): @@ -432,6 +434,27 @@ class UserMetricityTests(APISubdomainTestCase): # Then self.assertEqual(response.status_code, 404) + def test_metricity_voice_banned(self): + cases = [ + {'exception': None, 'voice_banned': True}, + {'exception': ObjectDoesNotExist, 'voice_banned': False}, + {'exception': MultipleObjectsReturned, 'voice_banned': True}, + ] + + self.mock_metricity_user("foo", 1) + + for case in cases: + with self.subTest(exception=case['exception'], voice_banned=case['voice_banned']): + with patch("pydis_site.apps.api.viewsets.bot.user.Infraction.objects.get") as p: + p.side_effect = case['exception'] + + url = reverse('bot:user-metricity-data', args=[0], host='api') + response = self.client.get(url) + + self.assertEqual(response.status_code, 200) + self.assertEqual(response.json()["voice_banned"], case["voice_banned"]) + + def mock_metricity_user(self, verified_at, total_messages): patcher = patch("pydis_site.apps.api.viewsets.bot.user.Metricity") self.metricity = patcher.start() -- cgit v1.2.3 From d80c7f18fadd1abc1aa2c080c2de6e7dee395883 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Sat, 10 Oct 2020 20:19:53 +0300 Subject: Fix wrong exception name --- pydis_site/apps/api/viewsets/bot/user.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydis_site/apps/api/viewsets/bot/user.py b/pydis_site/apps/api/viewsets/bot/user.py index 19f55555..367f6b65 100644 --- a/pydis_site/apps/api/viewsets/bot/user.py +++ b/pydis_site/apps/api/viewsets/bot/user.py @@ -247,7 +247,7 @@ class UserViewSet(ModelViewSet): Infraction.objects.get(user__id=user.id, active=True, type="voice_ban") except ObjectDoesNotExist: voice_banned = False - except MultipleObjectReturned: + except MultipleObjectsReturned: voice_banned = True else: voice_banned = True -- cgit v1.2.3 From 8cb18e635920d64734a66be77e849cae3441108b Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Sat, 10 Oct 2020 20:21:42 +0300 Subject: Remove unnecessary newline from user tests --- pydis_site/apps/api/tests/test_users.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pydis_site/apps/api/tests/test_users.py b/pydis_site/apps/api/tests/test_users.py index 01bf208b..e512f506 100644 --- a/pydis_site/apps/api/tests/test_users.py +++ b/pydis_site/apps/api/tests/test_users.py @@ -454,7 +454,6 @@ class UserMetricityTests(APISubdomainTestCase): self.assertEqual(response.status_code, 200) self.assertEqual(response.json()["voice_banned"], case["voice_banned"]) - def mock_metricity_user(self, verified_at, total_messages): patcher = patch("pydis_site.apps.api.viewsets.bot.user.Metricity") self.metricity = patcher.start() -- cgit v1.2.3 From 74f2131d05fdaa27b841e32f6c2fce2926b60f70 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Sat, 10 Oct 2020 20:34:13 +0300 Subject: Add trailing comma to infraction types listing Co-authored-by: Joe Banks --- pydis_site/apps/api/models/bot/infraction.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydis_site/apps/api/models/bot/infraction.py b/pydis_site/apps/api/models/bot/infraction.py index 5ef3a4ce..60c1e8dd 100644 --- a/pydis_site/apps/api/models/bot/infraction.py +++ b/pydis_site/apps/api/models/bot/infraction.py @@ -16,7 +16,7 @@ class Infraction(ModelReprMixin, models.Model): ("kick", "Kick"), ("ban", "Ban"), ("superstar", "Superstar"), - ("voice_ban", "Voice Ban") + ("voice_ban", "Voice Ban"), ) inserted_at = models.DateTimeField( default=timezone.now, -- cgit v1.2.3 From 9c4ed0b98e4f34fe3a589e4e26f2b31e6c5169f9 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Sat, 10 Oct 2020 20:35:32 +0300 Subject: Don't catch multiple object returned exception --- pydis_site/apps/api/viewsets/bot/user.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pydis_site/apps/api/viewsets/bot/user.py b/pydis_site/apps/api/viewsets/bot/user.py index 367f6b65..5205dc97 100644 --- a/pydis_site/apps/api/viewsets/bot/user.py +++ b/pydis_site/apps/api/viewsets/bot/user.py @@ -1,7 +1,7 @@ import typing from collections import OrderedDict -from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist +from django.core.exceptions import ObjectDoesNotExist from rest_framework import status from rest_framework.decorators import action from rest_framework.pagination import PageNumberPagination @@ -247,8 +247,6 @@ class UserViewSet(ModelViewSet): Infraction.objects.get(user__id=user.id, active=True, type="voice_ban") except ObjectDoesNotExist: voice_banned = False - except MultipleObjectsReturned: - voice_banned = True else: voice_banned = True -- cgit v1.2.3 From 42e34e955724eb47a505e24bcd03dc55c8e66419 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Sat, 10 Oct 2020 20:36:18 +0300 Subject: Remove multiple objects returning test case --- pydis_site/apps/api/tests/test_users.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pydis_site/apps/api/tests/test_users.py b/pydis_site/apps/api/tests/test_users.py index e512f506..72ffcb3c 100644 --- a/pydis_site/apps/api/tests/test_users.py +++ b/pydis_site/apps/api/tests/test_users.py @@ -1,6 +1,6 @@ from unittest.mock import patch -from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist +from django.core.exceptions import ObjectDoesNotExist from django_hosts.resolvers import reverse from .base import APISubdomainTestCase @@ -438,7 +438,6 @@ class UserMetricityTests(APISubdomainTestCase): cases = [ {'exception': None, 'voice_banned': True}, {'exception': ObjectDoesNotExist, 'voice_banned': False}, - {'exception': MultipleObjectsReturned, 'voice_banned': True}, ] self.mock_metricity_user("foo", 1) -- cgit v1.2.3