2019-01-05 17:21:35 +00:00
|
|
|
import pytest
|
|
|
|
|
2018-05-28 22:07:20 +00:00
|
|
|
from funkwhale_api.manage import serializers
|
2019-01-09 13:18:32 +00:00
|
|
|
from funkwhale_api.federation import tasks as federation_tasks
|
2018-05-28 22:07:20 +00:00
|
|
|
|
|
|
|
|
2018-09-22 12:29:30 +00:00
|
|
|
def test_manage_upload_action_delete(factories):
|
|
|
|
uploads = factories["music.Upload"](size=5)
|
|
|
|
s = serializers.ManageUploadActionSerializer(queryset=None)
|
2018-05-28 22:07:20 +00:00
|
|
|
|
2018-09-22 12:29:30 +00:00
|
|
|
s.handle_delete(uploads.__class__.objects.all())
|
2018-05-28 22:07:20 +00:00
|
|
|
|
2018-09-22 12:29:30 +00:00
|
|
|
assert uploads.__class__.objects.count() == 0
|
2018-06-19 18:11:40 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_user_update_permission(factories):
|
|
|
|
user = factories["users.User"](
|
|
|
|
permission_library=False,
|
2018-12-06 10:18:09 +00:00
|
|
|
permission_moderation=False,
|
2018-06-19 18:11:40 +00:00
|
|
|
permission_settings=True,
|
|
|
|
is_active=True,
|
|
|
|
)
|
|
|
|
s = serializers.ManageUserSerializer(
|
|
|
|
user,
|
2018-09-28 19:05:43 +00:00
|
|
|
data={
|
|
|
|
"is_active": False,
|
2018-12-26 22:03:27 +00:00
|
|
|
"permissions": {"moderation": True, "settings": False},
|
2018-09-28 19:05:43 +00:00
|
|
|
"upload_quota": 12,
|
|
|
|
},
|
2018-06-19 18:11:40 +00:00
|
|
|
)
|
|
|
|
s.is_valid(raise_exception=True)
|
|
|
|
s.save()
|
|
|
|
user.refresh_from_db()
|
|
|
|
|
|
|
|
assert user.is_active is False
|
2018-09-28 19:05:43 +00:00
|
|
|
assert user.upload_quota == 12
|
2018-12-06 10:18:09 +00:00
|
|
|
assert user.permission_moderation is True
|
2018-06-19 18:11:40 +00:00
|
|
|
assert user.permission_library is False
|
2018-12-26 22:03:27 +00:00
|
|
|
assert user.permission_settings is False
|
|
|
|
|
|
|
|
|
|
|
|
def test_manage_domain_serializer(factories, now):
|
2019-01-30 10:54:43 +00:00
|
|
|
domain = factories["federation.Domain"](nodeinfo_fetch_date=None)
|
2018-12-26 22:03:27 +00:00
|
|
|
setattr(domain, "actors_count", 42)
|
|
|
|
setattr(domain, "outbox_activities_count", 23)
|
|
|
|
expected = {
|
|
|
|
"name": domain.name,
|
|
|
|
"creation_date": domain.creation_date.isoformat().split("+")[0] + "Z",
|
|
|
|
"actors_count": 42,
|
|
|
|
"outbox_activities_count": 23,
|
2018-12-27 16:42:43 +00:00
|
|
|
"nodeinfo": {},
|
|
|
|
"nodeinfo_fetch_date": None,
|
2019-01-07 08:45:53 +00:00
|
|
|
"instance_policy": None,
|
2018-12-26 22:03:27 +00:00
|
|
|
}
|
|
|
|
s = serializers.ManageDomainSerializer(domain)
|
|
|
|
|
|
|
|
assert s.data == expected
|
2019-01-03 10:47:29 +00:00
|
|
|
|
|
|
|
|
2019-01-05 17:21:35 +00:00
|
|
|
def test_manage_domain_serializer_validates_hostname(db):
|
|
|
|
s = serializers.ManageDomainSerializer(data={"name": "hello world"})
|
|
|
|
|
|
|
|
with pytest.raises(serializers.serializers.ValidationError):
|
|
|
|
s.is_valid(raise_exception=True)
|
|
|
|
|
|
|
|
|
2019-01-03 10:47:29 +00:00
|
|
|
def test_manage_actor_serializer(factories, now):
|
|
|
|
actor = factories["federation.Actor"]()
|
|
|
|
setattr(actor, "uploads_count", 66)
|
|
|
|
expected = {
|
|
|
|
"id": actor.id,
|
|
|
|
"name": actor.name,
|
|
|
|
"creation_date": actor.creation_date.isoformat().split("+")[0] + "Z",
|
|
|
|
"last_fetch_date": actor.last_fetch_date.isoformat().split("+")[0] + "Z",
|
|
|
|
"uploads_count": 66,
|
|
|
|
"fid": actor.fid,
|
|
|
|
"url": actor.url,
|
|
|
|
"outbox_url": actor.outbox_url,
|
|
|
|
"shared_inbox_url": actor.shared_inbox_url,
|
|
|
|
"inbox_url": actor.inbox_url,
|
|
|
|
"domain": actor.domain_id,
|
|
|
|
"type": actor.type,
|
|
|
|
"summary": actor.summary,
|
|
|
|
"preferred_username": actor.preferred_username,
|
|
|
|
"manually_approves_followers": actor.manually_approves_followers,
|
2019-01-03 16:10:02 +00:00
|
|
|
"full_username": actor.full_username,
|
|
|
|
"user": None,
|
2019-01-07 08:45:53 +00:00
|
|
|
"instance_policy": None,
|
2019-01-03 10:47:29 +00:00
|
|
|
}
|
|
|
|
s = serializers.ManageActorSerializer(actor)
|
|
|
|
|
|
|
|
assert s.data == expected
|
2019-01-07 08:45:53 +00:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"factory_kwargs,expected",
|
|
|
|
[
|
|
|
|
(
|
|
|
|
{"for_domain": True, "target_domain__name": "test.federation"},
|
|
|
|
{"target": {"type": "domain", "id": "test.federation"}},
|
|
|
|
),
|
|
|
|
(
|
|
|
|
{
|
|
|
|
"for_actor": True,
|
|
|
|
"target_actor__domain__name": "test.federation",
|
|
|
|
"target_actor__preferred_username": "hello",
|
|
|
|
},
|
|
|
|
{"target": {"type": "actor", "id": "hello@test.federation"}},
|
|
|
|
),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
def test_instance_policy_serializer_repr(factories, factory_kwargs, expected):
|
|
|
|
policy = factories["moderation.InstancePolicy"](block_all=True, **factory_kwargs)
|
|
|
|
|
|
|
|
e = {
|
|
|
|
"id": policy.id,
|
|
|
|
"uuid": str(policy.uuid),
|
|
|
|
"creation_date": policy.creation_date.isoformat().split("+")[0] + "Z",
|
|
|
|
"actor": policy.actor.full_username,
|
|
|
|
"block_all": True,
|
|
|
|
"silence_activity": False,
|
|
|
|
"silence_notifications": False,
|
|
|
|
"reject_media": False,
|
|
|
|
"is_active": policy.is_active,
|
|
|
|
"summary": policy.summary,
|
|
|
|
}
|
|
|
|
e.update(expected)
|
|
|
|
|
|
|
|
assert serializers.ManageInstancePolicySerializer(policy).data == e
|
|
|
|
|
|
|
|
|
|
|
|
def test_instance_policy_serializer_save_domain(factories):
|
|
|
|
domain = factories["federation.Domain"]()
|
|
|
|
|
|
|
|
data = {"target": {"id": domain.name, "type": "domain"}, "block_all": True}
|
|
|
|
|
|
|
|
serializer = serializers.ManageInstancePolicySerializer(data=data)
|
|
|
|
serializer.is_valid(raise_exception=True)
|
|
|
|
policy = serializer.save()
|
|
|
|
|
|
|
|
assert policy.target_domain == domain
|
2019-01-09 13:18:32 +00:00
|
|
|
|
|
|
|
|
2019-01-09 16:52:14 +00:00
|
|
|
def test_instance_policy_serializer_save_actor(factories):
|
|
|
|
actor = factories["federation.Actor"]()
|
|
|
|
|
|
|
|
data = {"target": {"id": actor.full_username, "type": "actor"}, "block_all": True}
|
|
|
|
|
|
|
|
serializer = serializers.ManageInstancePolicySerializer(data=data)
|
|
|
|
serializer.is_valid(raise_exception=True)
|
|
|
|
policy = serializer.save()
|
|
|
|
|
|
|
|
assert policy.target_actor == actor
|
|
|
|
|
|
|
|
|
2019-01-09 13:18:32 +00:00
|
|
|
def test_manage_actor_action_purge(factories, mocker):
|
|
|
|
actors = factories["federation.Actor"].create_batch(size=3)
|
|
|
|
s = serializers.ManageActorActionSerializer(queryset=None)
|
|
|
|
on_commit = mocker.patch("funkwhale_api.common.utils.on_commit")
|
|
|
|
|
|
|
|
s.handle_purge(actors[0].__class__.objects.all())
|
|
|
|
on_commit.assert_called_once_with(
|
|
|
|
federation_tasks.purge_actors.delay, ids=[a.pk for a in actors]
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def test_manage_domain_action_purge(factories, mocker):
|
|
|
|
domains = factories["federation.Domain"].create_batch(size=3)
|
|
|
|
s = serializers.ManageDomainActionSerializer(queryset=None)
|
|
|
|
on_commit = mocker.patch("funkwhale_api.common.utils.on_commit")
|
|
|
|
|
|
|
|
s.handle_purge(domains[0].__class__.objects.all())
|
|
|
|
on_commit.assert_called_once_with(
|
|
|
|
federation_tasks.purge_actors.delay, domains=[d.pk for d in domains]
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2019-01-10 10:02:09 +00:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"param,expected_only", [("block_all", []), ("reject_media", ["media"])]
|
|
|
|
)
|
|
|
|
def test_instance_policy_serializer_purges_target_domain(
|
|
|
|
factories, mocker, param, expected_only
|
|
|
|
):
|
|
|
|
params = {param: False}
|
|
|
|
if param != "block_all":
|
|
|
|
params["block_all"] = False
|
|
|
|
policy = factories["moderation.InstancePolicy"](for_domain=True, **params)
|
2019-01-09 13:18:32 +00:00
|
|
|
on_commit = mocker.patch("funkwhale_api.common.utils.on_commit")
|
|
|
|
|
|
|
|
serializer = serializers.ManageInstancePolicySerializer(
|
2019-01-10 10:02:09 +00:00
|
|
|
policy, data={param: True}, partial=True
|
2019-01-09 13:18:32 +00:00
|
|
|
)
|
|
|
|
serializer.is_valid(raise_exception=True)
|
|
|
|
serializer.save()
|
|
|
|
|
|
|
|
policy.refresh_from_db()
|
|
|
|
|
2019-01-10 10:02:09 +00:00
|
|
|
assert getattr(policy, param) is True
|
2019-01-09 13:18:32 +00:00
|
|
|
on_commit.assert_called_once_with(
|
2019-01-10 10:02:09 +00:00
|
|
|
federation_tasks.purge_actors.delay,
|
|
|
|
domains=[policy.target_domain_id],
|
|
|
|
only=expected_only,
|
2019-01-09 13:18:32 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
on_commit.reset_mock()
|
|
|
|
|
|
|
|
# setting to false should have no effect
|
|
|
|
serializer = serializers.ManageInstancePolicySerializer(
|
2019-01-10 10:02:09 +00:00
|
|
|
policy, data={param: False}, partial=True
|
2019-01-09 13:18:32 +00:00
|
|
|
)
|
|
|
|
serializer.is_valid(raise_exception=True)
|
|
|
|
serializer.save()
|
|
|
|
|
|
|
|
policy.refresh_from_db()
|
|
|
|
|
2019-01-10 10:02:09 +00:00
|
|
|
assert getattr(policy, param) is False
|
2019-01-09 13:18:32 +00:00
|
|
|
assert on_commit.call_count == 0
|
|
|
|
|
|
|
|
|
2019-01-10 10:02:09 +00:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"param,expected_only", [("block_all", []), ("reject_media", ["media"])]
|
|
|
|
)
|
|
|
|
def test_instance_policy_serializer_purges_target_actor(
|
|
|
|
factories, mocker, param, expected_only
|
|
|
|
):
|
|
|
|
params = {param: False}
|
|
|
|
if param != "block_all":
|
|
|
|
params["block_all"] = False
|
|
|
|
policy = factories["moderation.InstancePolicy"](for_actor=True, **params)
|
2019-01-09 13:18:32 +00:00
|
|
|
on_commit = mocker.patch("funkwhale_api.common.utils.on_commit")
|
|
|
|
|
|
|
|
serializer = serializers.ManageInstancePolicySerializer(
|
2019-01-10 10:02:09 +00:00
|
|
|
policy, data={param: True}, partial=True
|
2019-01-09 13:18:32 +00:00
|
|
|
)
|
|
|
|
serializer.is_valid(raise_exception=True)
|
|
|
|
serializer.save()
|
|
|
|
|
|
|
|
policy.refresh_from_db()
|
|
|
|
|
2019-01-10 10:02:09 +00:00
|
|
|
assert getattr(policy, param) is True
|
2019-01-09 13:18:32 +00:00
|
|
|
on_commit.assert_called_once_with(
|
2019-01-10 10:02:09 +00:00
|
|
|
federation_tasks.purge_actors.delay,
|
|
|
|
ids=[policy.target_actor_id],
|
|
|
|
only=expected_only,
|
2019-01-09 13:18:32 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
on_commit.reset_mock()
|
|
|
|
|
|
|
|
# setting to false should have no effect
|
|
|
|
serializer = serializers.ManageInstancePolicySerializer(
|
2019-01-10 10:02:09 +00:00
|
|
|
policy, data={param: False}, partial=True
|
2019-01-09 13:18:32 +00:00
|
|
|
)
|
|
|
|
serializer.is_valid(raise_exception=True)
|
|
|
|
serializer.save()
|
|
|
|
|
|
|
|
policy.refresh_from_db()
|
|
|
|
|
2019-01-10 10:02:09 +00:00
|
|
|
assert getattr(policy, param) is False
|
2019-01-09 13:18:32 +00:00
|
|
|
assert on_commit.call_count == 0
|
2019-04-17 12:17:59 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_manage_artist_serializer(factories, now):
|
|
|
|
artist = factories["music.Artist"](attributed=True)
|
|
|
|
track = factories["music.Track"](artist=artist)
|
|
|
|
album = factories["music.Album"](artist=artist)
|
|
|
|
expected = {
|
|
|
|
"id": artist.id,
|
|
|
|
"domain": artist.domain_name,
|
|
|
|
"is_local": artist.is_local,
|
|
|
|
"fid": artist.fid,
|
|
|
|
"name": artist.name,
|
|
|
|
"mbid": artist.mbid,
|
|
|
|
"creation_date": artist.creation_date.isoformat().split("+")[0] + "Z",
|
|
|
|
"albums": [serializers.ManageNestedAlbumSerializer(album).data],
|
|
|
|
"tracks": [serializers.ManageNestedTrackSerializer(track).data],
|
|
|
|
"attributed_to": serializers.ManageBaseActorSerializer(
|
|
|
|
artist.attributed_to
|
|
|
|
).data,
|
|
|
|
}
|
|
|
|
s = serializers.ManageArtistSerializer(artist)
|
|
|
|
|
|
|
|
assert s.data == expected
|
|
|
|
|
|
|
|
|
|
|
|
def test_manage_nested_track_serializer(factories, now):
|
|
|
|
track = factories["music.Track"]()
|
|
|
|
expected = {
|
|
|
|
"id": track.id,
|
|
|
|
"domain": track.domain_name,
|
|
|
|
"is_local": track.is_local,
|
|
|
|
"fid": track.fid,
|
|
|
|
"title": track.title,
|
|
|
|
"mbid": track.mbid,
|
|
|
|
"creation_date": track.creation_date.isoformat().split("+")[0] + "Z",
|
|
|
|
"position": track.position,
|
|
|
|
"disc_number": track.disc_number,
|
|
|
|
"copyright": track.copyright,
|
|
|
|
"license": track.license,
|
|
|
|
}
|
|
|
|
s = serializers.ManageNestedTrackSerializer(track)
|
|
|
|
|
|
|
|
assert s.data == expected
|
|
|
|
|
|
|
|
|
|
|
|
def test_manage_nested_album_serializer(factories, now):
|
|
|
|
album = factories["music.Album"]()
|
|
|
|
setattr(album, "tracks_count", 44)
|
|
|
|
expected = {
|
|
|
|
"id": album.id,
|
|
|
|
"domain": album.domain_name,
|
|
|
|
"is_local": album.is_local,
|
|
|
|
"fid": album.fid,
|
|
|
|
"title": album.title,
|
|
|
|
"mbid": album.mbid,
|
|
|
|
"creation_date": album.creation_date.isoformat().split("+")[0] + "Z",
|
|
|
|
"release_date": album.release_date.isoformat(),
|
|
|
|
"cover": {
|
|
|
|
"original": album.cover.url,
|
|
|
|
"square_crop": album.cover.crop["400x400"].url,
|
|
|
|
"medium_square_crop": album.cover.crop["200x200"].url,
|
|
|
|
"small_square_crop": album.cover.crop["50x50"].url,
|
|
|
|
},
|
|
|
|
"tracks_count": 44,
|
|
|
|
}
|
|
|
|
s = serializers.ManageNestedAlbumSerializer(album)
|
|
|
|
|
|
|
|
assert s.data == expected
|
|
|
|
|
|
|
|
|
|
|
|
def test_manage_nested_artist_serializer(factories, now):
|
|
|
|
artist = factories["music.Artist"]()
|
|
|
|
expected = {
|
|
|
|
"id": artist.id,
|
|
|
|
"domain": artist.domain_name,
|
|
|
|
"is_local": artist.is_local,
|
|
|
|
"fid": artist.fid,
|
|
|
|
"name": artist.name,
|
|
|
|
"mbid": artist.mbid,
|
|
|
|
"creation_date": artist.creation_date.isoformat().split("+")[0] + "Z",
|
|
|
|
}
|
|
|
|
s = serializers.ManageNestedArtistSerializer(artist)
|
|
|
|
|
|
|
|
assert s.data == expected
|
|
|
|
|
|
|
|
|
|
|
|
def test_manage_album_serializer(factories, now):
|
|
|
|
album = factories["music.Album"](attributed=True)
|
|
|
|
track = factories["music.Track"](album=album)
|
|
|
|
expected = {
|
|
|
|
"id": album.id,
|
|
|
|
"domain": album.domain_name,
|
|
|
|
"is_local": album.is_local,
|
|
|
|
"fid": album.fid,
|
|
|
|
"title": album.title,
|
|
|
|
"mbid": album.mbid,
|
|
|
|
"creation_date": album.creation_date.isoformat().split("+")[0] + "Z",
|
|
|
|
"release_date": album.release_date.isoformat(),
|
|
|
|
"cover": {
|
|
|
|
"original": album.cover.url,
|
|
|
|
"square_crop": album.cover.crop["400x400"].url,
|
|
|
|
"medium_square_crop": album.cover.crop["200x200"].url,
|
|
|
|
"small_square_crop": album.cover.crop["50x50"].url,
|
|
|
|
},
|
|
|
|
"artist": serializers.ManageNestedArtistSerializer(album.artist).data,
|
|
|
|
"tracks": [serializers.ManageNestedTrackSerializer(track).data],
|
|
|
|
"attributed_to": serializers.ManageBaseActorSerializer(
|
|
|
|
album.attributed_to
|
|
|
|
).data,
|
|
|
|
}
|
|
|
|
s = serializers.ManageAlbumSerializer(album)
|
|
|
|
|
|
|
|
assert s.data == expected
|
|
|
|
|
|
|
|
|
|
|
|
def test_manage_track_serializer(factories, now):
|
|
|
|
track = factories["music.Track"](attributed=True)
|
|
|
|
setattr(track, "uploads_count", 44)
|
|
|
|
expected = {
|
|
|
|
"id": track.id,
|
|
|
|
"domain": track.domain_name,
|
|
|
|
"is_local": track.is_local,
|
|
|
|
"fid": track.fid,
|
|
|
|
"title": track.title,
|
|
|
|
"mbid": track.mbid,
|
|
|
|
"disc_number": track.disc_number,
|
|
|
|
"position": track.position,
|
|
|
|
"copyright": track.copyright,
|
|
|
|
"license": track.license,
|
|
|
|
"creation_date": track.creation_date.isoformat().split("+")[0] + "Z",
|
|
|
|
"artist": serializers.ManageNestedArtistSerializer(track.artist).data,
|
|
|
|
"album": serializers.ManageTrackAlbumSerializer(track.album).data,
|
|
|
|
"attributed_to": serializers.ManageBaseActorSerializer(
|
|
|
|
track.attributed_to
|
|
|
|
).data,
|
|
|
|
"uploads_count": 44,
|
|
|
|
}
|
|
|
|
s = serializers.ManageTrackSerializer(track)
|
|
|
|
|
|
|
|
assert s.data == expected
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"factory, serializer_class",
|
|
|
|
[
|
|
|
|
("music.Track", serializers.ManageTrackActionSerializer),
|
|
|
|
("music.Album", serializers.ManageAlbumActionSerializer),
|
|
|
|
("music.Artist", serializers.ManageArtistActionSerializer),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
def test_action_serializer_delete(factory, serializer_class, factories):
|
|
|
|
objects = factories[factory].create_batch(size=5)
|
|
|
|
s = serializer_class(queryset=None)
|
|
|
|
|
|
|
|
s.handle_delete(objects[0].__class__.objects.all())
|
|
|
|
|
|
|
|
assert objects[0].__class__.objects.count() == 0
|