142 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			142 lines
		
	
	
		
			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
 | |
|     )
 |