funkwhale/api/tests/common/test_mutations.py

142 wiersze
4.4 KiB
Python

import pytest
from rest_framework import serializers
from funkwhale_api.common import mutations
@pytest.fixture
def mutations_registry():
return mutations.Registry()
def test_apply_mutation(mutations_registry, db):
class Obj:
pass
obj = Obj()
@mutations_registry.connect("foo", Obj)
class S(mutations.MutationSerializer):
foo = serializers.ChoiceField(choices=["bar", "baz"])
def apply(self, obj, validated_data):
setattr(obj, "foo", validated_data["foo"])
with pytest.raises(mutations.ConfNotFound):
mutations_registry.apply("foo", object(), payload={"foo": "nope"})
with pytest.raises(serializers.ValidationError):
mutations_registry.apply("foo", obj, payload={"foo": "nope"})
mutations_registry.apply("foo", obj, payload={"foo": "bar"})
assert obj.foo == "bar"
def test_apply_update_mutation(factories, mutations_registry, mocker):
user = factories["users.User"](email="hello@test.email")
get_update_previous_state = mocker.patch.object(
mutations, "get_update_previous_state"
)
@mutations_registry.connect("update", user.__class__)
class S(mutations.UpdateMutationSerializer):
class Meta:
model = user.__class__
fields = ["username", "email"]
previous_state = mutations_registry.apply(
"update", user, payload={"username": "foo"}
)
assert previous_state == get_update_previous_state.return_value
get_update_previous_state.assert_called_once_with(
user, "username", serialized_relations={}, handlers={}
)
user.refresh_from_db()
assert user.username == "foo"
assert user.email == "hello@test.email"
def test_db_serialize_update_mutation(factories, mutations_registry, mocker):
user = factories["users.User"](email="hello@test.email", with_actor=True)
class S(mutations.UpdateMutationSerializer):
class Meta:
model = user.__class__
fields = ["actor"]
def get_serialized_relations(self):
return {"actor": "full_username"}
expected = {"actor": user.actor.full_username}
assert S().db_serialize({"actor": user.actor}) == expected
def test_is_valid_mutation(factories, mutations_registry):
user = factories["users.User"].build()
@mutations_registry.connect("update", user.__class__)
class S(mutations.UpdateMutationSerializer):
class Meta:
model = user.__class__
fields = ["email"]
with pytest.raises(serializers.ValidationError):
mutations_registry.is_valid("update", user, payload={"email": "foo"})
mutations_registry.is_valid("update", user, payload={"email": "foo@bar.com"})
@pytest.mark.parametrize("perm", ["approve", "suggest"])
def test_permissions(perm, factories, mutations_registry, mocker):
actor = factories["federation.Actor"].build()
user = factories["users.User"].build()
class S(mutations.UpdateMutationSerializer):
class Meta:
model = user.__class__
fields = ["email"]
mutations_registry.connect("update", user.__class__)(S)
assert mutations_registry.has_perm(perm, "update", obj=user, actor=actor) is False
checker = mocker.Mock(return_value=True)
mutations_registry.connect("update", user.__class__, perm_checkers={perm: checker})(
S
)
assert mutations_registry.has_perm(perm, "update", obj=user, actor=actor) is True
checker.assert_called_once_with(obj=user, actor=actor)
def test_model_apply(factories, mocker, now):
target = factories["music.Artist"]()
mutation = factories["common.Mutation"](type="noop", target=target, payload="hello")
apply = mocker.patch.object(
mutations.registry, "apply", return_value={"previous": "state"}
)
mutation.apply()
apply.assert_called_once_with(type="noop", obj=target, payload="hello")
mutation.refresh_from_db()
assert mutation.is_applied is True
assert mutation.previous_state == {"previous": "state"}
assert mutation.applied_date == now
def test_get_previous_state(factories):
obj = factories["music.Track"]()
expected = {
"title": {"value": obj.title},
"album": {"value": obj.album.pk, "repr": str(obj.album)},
}
assert (
mutations.get_update_previous_state(
obj, "title", "album", serialized_relations={"album": "pk"}
)
== expected
)