From 581c531fca973a2112c8856c52d9ea4d05bb83b3 Mon Sep 17 00:00:00 2001 From: Eliot Berriot Date: Fri, 14 Feb 2020 11:56:53 +0100 Subject: [PATCH] See #170: proper error handling for username uniqueness in channels --- api/funkwhale_api/audio/serializers.py | 9 +++++++++ api/tests/audio/test_serializers.py | 18 +++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/api/funkwhale_api/audio/serializers.py b/api/funkwhale_api/audio/serializers.py index 70c51587e..aaf8a1e68 100644 --- a/api/funkwhale_api/audio/serializers.py +++ b/api/funkwhale_api/audio/serializers.py @@ -6,6 +6,7 @@ from funkwhale_api.common import serializers as common_serializers from funkwhale_api.common import utils as common_utils from funkwhale_api.common import locales from funkwhale_api.common import preferences +from funkwhale_api.federation import models as federation_models from funkwhale_api.federation import serializers as federation_serializers from funkwhale_api.federation import utils as federation_utils from funkwhale_api.music import models as music_models @@ -74,6 +75,14 @@ class ChannelCreateSerializer(serializers.Serializer): validated_data["metadata"] = metadata return validated_data + def validate_username(self, value): + matching = federation_models.Actor.objects.local().filter( + preferred_username__iexact=value + ) + if matching.exists(): + raise serializers.ValidationError("This username is already taken") + return value + @transaction.atomic def create(self, validated_data): from . import views diff --git a/api/tests/audio/test_serializers.py b/api/tests/audio/test_serializers.py index 2ada89653..ee5a9c1b9 100644 --- a/api/tests/audio/test_serializers.py +++ b/api/tests/audio/test_serializers.py @@ -56,7 +56,6 @@ def test_channel_serializer_create_honor_max_channels_setting(factories, prefere attributed_to = factories["federation.Actor"](local=True) factories["audio.Channel"](attributed_to=attributed_to) data = { - # TODO: cover "name": "My channel", "username": "mychannel", "description": {"text": "This is my channel", "content_type": "text/markdown"}, @@ -71,6 +70,23 @@ def test_channel_serializer_create_honor_max_channels_setting(factories, prefere assert serializer.is_valid(raise_exception=True) +def test_channel_serializer_create_validates_username(factories): + attributed_to = factories["federation.Actor"](local=True) + data = { + "name": "My channel", + "username": attributed_to.preferred_username.upper(), + "description": {"text": "This is my channel", "content_type": "text/markdown"}, + "tags": ["hello", "world"], + "content_category": "other", + } + + serializer = serializers.ChannelCreateSerializer( + data=data, context={"actor": attributed_to} + ) + with pytest.raises(serializers.serializers.ValidationError, match=r".*username.*"): + assert serializer.is_valid(raise_exception=True) + + def test_channel_serializer_create_podcast(factories): attributed_to = factories["federation.Actor"](local=True)