162 lines
5.4 KiB
Python
162 lines
5.4 KiB
Python
import pytest
|
|
from django.contrib.auth.models import AnonymousUser
|
|
from django.db.models import Q
|
|
|
|
from funkwhale_api.common import fields
|
|
from funkwhale_api.favorites import models as favorite_models
|
|
from funkwhale_api.history import models
|
|
|
|
|
|
def test_privacy_level_query(factories):
|
|
user = factories["users.User"](with_actor=True)
|
|
user_query = (
|
|
Q(privacy_level__in=["instance", "everyone"])
|
|
| Q(privacy_level="me", user=user)
|
|
| Q(
|
|
privacy_level="followers",
|
|
user__actor__in=user.actor.get_approved_followings(),
|
|
)
|
|
| Q(user__isnull=True)
|
|
)
|
|
|
|
query = fields.privacy_level_query(user)
|
|
assert str(query) == str(user_query)
|
|
|
|
user = AnonymousUser()
|
|
user_query = Q(privacy_level="everyone")
|
|
query = fields.privacy_level_query(user)
|
|
assert str(query) == str(user_query)
|
|
|
|
|
|
def test_privacy_level_query_followers(factories):
|
|
user = factories["users.User"](with_actor=True)
|
|
target = factories["users.User"](with_actor=True, privacy_level="followers")
|
|
userfollow = factories["federation.Follow"](
|
|
actor=user.actor, target=target.actor, approved=True
|
|
)
|
|
assert user.actor.get_approved_followings()[0] == target.actor
|
|
|
|
listening = factories["history.Listening"](actor=userfollow.target)
|
|
favorite = factories["favorites.TrackFavorite"](actor=userfollow.target)
|
|
factories["history.Listening"]()
|
|
factories["favorites.TrackFavorite"]()
|
|
factories["favorites.TrackFavorite"]()
|
|
queryset = models.Listening.objects.all().filter(
|
|
fields.privacy_level_query(user, "actor__user__privacy_level", "actor__user")
|
|
)
|
|
fav_qs = favorite_models.TrackFavorite.objects.all().filter(
|
|
fields.privacy_level_query(user, "actor__user__privacy_level", "actor__user")
|
|
)
|
|
|
|
assert listening in queryset
|
|
assert favorite in fav_qs
|
|
|
|
|
|
def test_privacy_level_query_not_followers(factories):
|
|
user = factories["users.User"](with_actor=True)
|
|
target = factories["users.User"](privacy_level="followers")
|
|
target.create_actor()
|
|
target.refresh_from_db()
|
|
|
|
userfollow = factories["federation.Follow"](target=target.actor, approved=True)
|
|
listening = factories["history.Listening"](actor=userfollow.target)
|
|
favorite = factories["favorites.TrackFavorite"](actor=userfollow.target)
|
|
|
|
factories["history.Listening"]()
|
|
factories["history.Listening"]()
|
|
factories["favorites.TrackFavorite"]()
|
|
factories["favorites.TrackFavorite"]()
|
|
|
|
queryset = models.Listening.objects.all().filter(
|
|
fields.privacy_level_query(user, "actor__user__privacy_level", "actor__user")
|
|
)
|
|
fav_qs = favorite_models.TrackFavorite.objects.all().filter(
|
|
fields.privacy_level_query(user, "actor__user__privacy_level", "actor__user")
|
|
)
|
|
|
|
assert listening not in queryset
|
|
assert favorite not in fav_qs
|
|
|
|
|
|
def test_generic_relation_field(factories):
|
|
obj = factories["users.User"]()
|
|
f = fields.GenericRelation(
|
|
{
|
|
"user": {
|
|
"queryset": obj.__class__.objects.all(),
|
|
"id_attr": "username",
|
|
"id_field": fields.serializers.CharField(),
|
|
}
|
|
}
|
|
)
|
|
|
|
data = {"type": "user", "username": obj.username}
|
|
|
|
assert f.to_internal_value(data) == obj
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"payload, expected_error",
|
|
[
|
|
({}, r".*Invalid data.*"),
|
|
(1, r".*Invalid data.*"),
|
|
(False, r".*Invalid data.*"),
|
|
("test", r".*Invalid data.*"),
|
|
({"missing": "type"}, r".*Invalid type.*"),
|
|
({"type": "noop"}, r".*Invalid type.*"),
|
|
({"type": "user"}, r".*Invalid username.*"),
|
|
({"type": "user", "username": {}}, r".*Invalid username.*"),
|
|
({"type": "user", "username": "not_found"}, r".*Object not found.*"),
|
|
],
|
|
)
|
|
def test_generic_relation_field_validation_error(payload, expected_error, factories):
|
|
obj = factories["users.User"]()
|
|
f = fields.GenericRelation(
|
|
{
|
|
"user": {
|
|
"queryset": obj.__class__.objects.all(),
|
|
"id_attr": "username",
|
|
"id_field": fields.serializers.CharField(),
|
|
}
|
|
}
|
|
)
|
|
|
|
with pytest.raises(fields.serializers.ValidationError, match=expected_error):
|
|
f.to_internal_value(payload)
|
|
|
|
|
|
def test_generic_relation_filter_target_type(factories):
|
|
user = factories["users.User"]()
|
|
note = factories["moderation.Note"](target=user)
|
|
factories["moderation.Note"](target=factories["music.Artist"]())
|
|
f = fields.GenericRelationFilter(
|
|
"target",
|
|
{
|
|
"user": {
|
|
"queryset": user.__class__.objects.all(),
|
|
"id_attr": "username",
|
|
"id_field": fields.serializers.CharField(),
|
|
}
|
|
},
|
|
)
|
|
qs = f.filter(note.__class__.objects.all(), "user")
|
|
assert list(qs) == [note]
|
|
|
|
|
|
def test_generic_relation_filter_target_type_and_id(factories):
|
|
user = factories["users.User"]()
|
|
note = factories["moderation.Note"](target=user)
|
|
factories["moderation.Note"](target=factories["users.User"]())
|
|
f = fields.GenericRelationFilter(
|
|
"target",
|
|
{
|
|
"user": {
|
|
"queryset": user.__class__.objects.all(),
|
|
"id_attr": "username",
|
|
"id_field": fields.serializers.CharField(),
|
|
}
|
|
},
|
|
)
|
|
qs = f.filter(note.__class__.objects.all(), f"user:{user.username}")
|
|
assert list(qs) == [note]
|