diff --git a/api/funkwhale_api/federation/serializers.py b/api/funkwhale_api/federation/serializers.py index 17541c50fa348d0f28cc6752b4a50b94b6ca1890..d8e5ddb2d5a663dd104080519bc104be5c320a33 100644 --- a/api/funkwhale_api/federation/serializers.py +++ b/api/funkwhale_api/federation/serializers.py @@ -21,6 +21,7 @@ AP_CONTEXT = [ {}, ] + class ActorSerializer(serializers.ModelSerializer): # left maps to activitypub fields, right to our internal models id = serializers.URLField(source='url') @@ -206,6 +207,11 @@ OBJECT_SERIALIZERS = { class PaginatedCollectionSerializer(serializers.Serializer): + type = serializers.ChoiceField(choices=['Collection']) + totalItems = serializers.IntegerField(min_value=0) + items = serializers.ListField() + actor = serializers.URLField() + id = serializers.URLField() def to_representation(self, conf): paginator = Paginator( @@ -230,6 +236,14 @@ class PaginatedCollectionSerializer(serializers.Serializer): class CollectionPageSerializer(serializers.Serializer): + type = serializers.ChoiceField(choices=['CollectionPage']) + totalItems = serializers.IntegerField(min_value=0) + items = serializers.ListField() + actor = serializers.URLField() + id = serializers.URLField() + prev = serializers.URLField(required=False) + next = serializers.URLField(required=False) + partOf = serializers.URLField() def to_representation(self, conf): page = conf['page'] diff --git a/api/tests/federation/test_serializers.py b/api/tests/federation/test_serializers.py index 71407dc43f1cb9c3c84001fbf9b6ab5096aeb6c5..8c76bb443ad1f24287eec76dc8d4385b39f3fc69 100644 --- a/api/tests/federation/test_serializers.py +++ b/api/tests/federation/test_serializers.py @@ -34,7 +34,7 @@ def test_actor_serializer_from_ap(db): } serializer = serializers.ActorSerializer(data=payload) - assert serializer.is_valid() + assert serializer.is_valid(raise_exception=True) actor = serializer.build() @@ -65,7 +65,7 @@ def test_actor_serializer_only_mandatory_field_from_ap(db): } serializer = serializers.ActorSerializer(data=payload) - assert serializer.is_valid() + assert serializer.is_valid(raise_exception=True) actor = serializer.build() @@ -201,6 +201,53 @@ def test_paginated_collection_serializer(factories): assert serializer.data == expected +def test_paginated_collection_serializer_validation(): + data = { + 'type': 'Collection', + 'id': 'https://test.federation/test', + 'totalItems': 5, + 'actor': 'http://test.actor', + 'items': [] + } + + serializer = serializers.PaginatedCollectionSerializer( + data=data + ) + + assert serializer.is_valid(raise_exception=True) is True + assert serializer.validated_data['totalItems'] == 5 + assert serializer.validated_data['id'] == data['id'] + assert serializer.validated_data['actor'] == data['actor'] + assert serializer.validated_data['items'] == [] + + +def test_collection_page_serializer_validdation(): + base = 'https://test.federation/test' + data = { + 'type': 'CollectionPage', + 'id': base + '?page=2', + 'totalItems': 5, + 'actor': 'https://test.actor', + 'items': [], + 'prev': base + '?page=1', + 'next': base + '?page=3', + 'partOf': base, + } + + serializer = serializers.CollectionPageSerializer( + data=data + ) + + assert serializer.is_valid(raise_exception=True) is True + assert serializer.validated_data['totalItems'] == 5 + assert serializer.validated_data['id'] == data['id'] + assert serializer.validated_data['actor'] == data['actor'] + assert serializer.validated_data['items'] == [] + assert serializer.validated_data['prev'] == data['prev'] + assert serializer.validated_data['next'] == data['next'] + assert serializer.validated_data['partOf'] == data['partOf'] + + def test_collection_page_serializer(factories): tfs = factories['music.TrackFile'].create_batch(size=5) actor = factories['federation.Actor'](local=True) diff --git a/api/tests/federation/test_views.py b/api/tests/federation/test_views.py index c5d651dce2ec634b4004ad6fa4e9b45e2caefaca..b3fd85910040bb2e045f3517afcb938685e49eec 100644 --- a/api/tests/federation/test_views.py +++ b/api/tests/federation/test_views.py @@ -116,6 +116,7 @@ def test_audio_file_list_actor_page( assert response.status_code == 200 assert response.data == expected + def test_audio_file_list_actor_page_exclude_federated_files( db, settings, api_client, factories): settings.FEDERATION_MUSIC_NEEDS_APPROVAL = False