mirror of
				https://github.com/graphql-python/graphene-django.git
				synced 2025-10-30 23:47:30 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			291 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			291 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| import datetime
 | |
| 
 | |
| from py.test import mark, raises
 | |
| from rest_framework import serializers
 | |
| 
 | |
| from graphene import Field, ResolveInfo
 | |
| from graphene.types.inputobjecttype import InputObjectType
 | |
| 
 | |
| from ...settings import graphene_settings
 | |
| from ...types import DjangoObjectType
 | |
| from ..models import MyFakeModel, MyFakeModelWithPassword, MyFakeModelWithDate
 | |
| from ..mutation import SerializerMutation
 | |
| 
 | |
| 
 | |
| def mock_info():
 | |
|     return ResolveInfo(
 | |
|         None,
 | |
|         None,
 | |
|         None,
 | |
|         None,
 | |
|         schema=None,
 | |
|         fragments=None,
 | |
|         root_value=None,
 | |
|         operation=None,
 | |
|         variable_values=None,
 | |
|         context=None,
 | |
|     )
 | |
| 
 | |
| 
 | |
| class MyModelSerializer(serializers.ModelSerializer):
 | |
|     class Meta:
 | |
|         model = MyFakeModel
 | |
|         fields = "__all__"
 | |
| 
 | |
| 
 | |
| class MyModelSerializerWithMethod(serializers.ModelSerializer):
 | |
|     days_since_last_edit = serializers.SerializerMethodField()
 | |
| 
 | |
|     class Meta:
 | |
|         model = MyFakeModelWithDate
 | |
|         fields = "__all__"
 | |
| 
 | |
|     def get_days_since_last_edit(self, obj):
 | |
|         now = datetime.date(2020, 1, 8)
 | |
|         return (now - obj.last_edited).days
 | |
| 
 | |
| 
 | |
| class MyModelMutation(SerializerMutation):
 | |
|     class Meta:
 | |
|         serializer_class = MyModelSerializer
 | |
| 
 | |
| 
 | |
| class MySerializer(serializers.Serializer):
 | |
|     text = serializers.CharField()
 | |
|     model = MyModelSerializer()
 | |
| 
 | |
|     def create(self, validated_data):
 | |
|         return validated_data
 | |
| 
 | |
| 
 | |
| def test_needs_serializer_class():
 | |
|     with raises(Exception) as exc:
 | |
| 
 | |
|         class MyMutation(SerializerMutation):
 | |
|             pass
 | |
| 
 | |
|     assert str(exc.value) == "serializer_class is required for the SerializerMutation"
 | |
| 
 | |
| 
 | |
| def test_has_fields():
 | |
|     class MyMutation(SerializerMutation):
 | |
|         class Meta:
 | |
|             serializer_class = MySerializer
 | |
| 
 | |
|     assert "text" in MyMutation._meta.fields
 | |
|     assert "model" in MyMutation._meta.fields
 | |
|     assert "errors" in MyMutation._meta.fields
 | |
| 
 | |
| 
 | |
| def test_has_input_fields():
 | |
|     class MyMutation(SerializerMutation):
 | |
|         class Meta:
 | |
|             serializer_class = MySerializer
 | |
| 
 | |
|     assert "text" in MyMutation.Input._meta.fields
 | |
|     assert "model" in MyMutation.Input._meta.fields
 | |
| 
 | |
| 
 | |
| def test_exclude_fields():
 | |
|     class MyMutation(SerializerMutation):
 | |
|         class Meta:
 | |
|             serializer_class = MyModelSerializer
 | |
|             exclude_fields = ["created"]
 | |
| 
 | |
|     assert "cool_name" in MyMutation._meta.fields
 | |
|     assert "created" not in MyMutation._meta.fields
 | |
|     assert "errors" in MyMutation._meta.fields
 | |
|     assert "cool_name" in MyMutation.Input._meta.fields
 | |
|     assert "created" not in MyMutation.Input._meta.fields
 | |
| 
 | |
| 
 | |
| @mark.django_db
 | |
| def test_write_only_field():
 | |
|     class WriteOnlyFieldModelSerializer(serializers.ModelSerializer):
 | |
|         password = serializers.CharField(write_only=True)
 | |
| 
 | |
|         class Meta:
 | |
|             model = MyFakeModelWithPassword
 | |
|             fields = ["cool_name", "password"]
 | |
| 
 | |
|     class MyMutation(SerializerMutation):
 | |
|         class Meta:
 | |
|             serializer_class = WriteOnlyFieldModelSerializer
 | |
| 
 | |
|     result = MyMutation.mutate_and_get_payload(
 | |
|         None, mock_info(), **{"cool_name": "New Narf", "password": "admin"}
 | |
|     )
 | |
| 
 | |
|     assert hasattr(result, "cool_name")
 | |
|     assert not hasattr(
 | |
|         result, "password"
 | |
|     ), "'password' is write_only field and shouldn't be visible"
 | |
| 
 | |
| 
 | |
| @mark.django_db
 | |
| def test_write_only_field_using_extra_kwargs():
 | |
|     class WriteOnlyFieldModelSerializer(serializers.ModelSerializer):
 | |
|         class Meta:
 | |
|             model = MyFakeModelWithPassword
 | |
|             fields = ["cool_name", "password"]
 | |
|             extra_kwargs = {"password": {"write_only": True}}
 | |
| 
 | |
|     class MyMutation(SerializerMutation):
 | |
|         class Meta:
 | |
|             serializer_class = WriteOnlyFieldModelSerializer
 | |
| 
 | |
|     result = MyMutation.mutate_and_get_payload(
 | |
|         None, mock_info(), **{"cool_name": "New Narf", "password": "admin"}
 | |
|     )
 | |
| 
 | |
|     assert hasattr(result, "cool_name")
 | |
|     assert not hasattr(
 | |
|         result, "password"
 | |
|     ), "'password' is write_only field and shouldn't be visible"
 | |
| 
 | |
| 
 | |
| @mark.django_db
 | |
| def test_read_only_fields():
 | |
|     class ReadOnlyFieldModelSerializer(serializers.ModelSerializer):
 | |
|         cool_name = serializers.CharField(read_only=True)
 | |
| 
 | |
|         class Meta:
 | |
|             model = MyFakeModelWithPassword
 | |
|             fields = ["cool_name", "password"]
 | |
| 
 | |
|     class MyMutation(SerializerMutation):
 | |
|         class Meta:
 | |
|             serializer_class = ReadOnlyFieldModelSerializer
 | |
| 
 | |
|     assert "password" in MyMutation.Input._meta.fields
 | |
|     assert (
 | |
|         "cool_name" not in MyMutation.Input._meta.fields
 | |
|     ), "'cool_name' is read_only field and shouldn't be on arguments"
 | |
| 
 | |
| 
 | |
| def test_nested_model():
 | |
|     class MyFakeModelGrapheneType(DjangoObjectType):
 | |
|         class Meta:
 | |
|             model = MyFakeModel
 | |
| 
 | |
|     class MyMutation(SerializerMutation):
 | |
|         class Meta:
 | |
|             serializer_class = MySerializer
 | |
| 
 | |
|     model_field = MyMutation._meta.fields["model"]
 | |
|     assert isinstance(model_field, Field)
 | |
|     assert model_field.type == MyFakeModelGrapheneType
 | |
| 
 | |
|     model_input = MyMutation.Input._meta.fields["model"]
 | |
|     model_input_type = model_input._type.of_type
 | |
|     assert issubclass(model_input_type, InputObjectType)
 | |
|     assert "cool_name" in model_input_type._meta.fields
 | |
|     assert "created" in model_input_type._meta.fields
 | |
| 
 | |
| 
 | |
| def test_mutate_and_get_payload_success():
 | |
|     class MyMutation(SerializerMutation):
 | |
|         class Meta:
 | |
|             serializer_class = MySerializer
 | |
| 
 | |
|     result = MyMutation.mutate_and_get_payload(
 | |
|         None, mock_info(), **{"text": "value", "model": {"cool_name": "other_value"}}
 | |
|     )
 | |
|     assert result.errors is None
 | |
| 
 | |
| 
 | |
| @mark.django_db
 | |
| def test_model_add_mutate_and_get_payload_success():
 | |
|     result = MyModelMutation.mutate_and_get_payload(
 | |
|         None, mock_info(), **{"cool_name": "Narf"}
 | |
|     )
 | |
|     assert result.errors is None
 | |
|     assert result.cool_name == "Narf"
 | |
|     assert isinstance(result.created, datetime.datetime)
 | |
| 
 | |
| 
 | |
| @mark.django_db
 | |
| def test_model_update_mutate_and_get_payload_success():
 | |
|     instance = MyFakeModel.objects.create(cool_name="Narf")
 | |
|     result = MyModelMutation.mutate_and_get_payload(
 | |
|         None, mock_info(), **{"id": instance.id, "cool_name": "New Narf"}
 | |
|     )
 | |
|     assert result.errors is None
 | |
|     assert result.cool_name == "New Narf"
 | |
| 
 | |
| 
 | |
| @mark.django_db
 | |
| def test_model_partial_update_mutate_and_get_payload_success():
 | |
|     instance = MyFakeModel.objects.create(cool_name="Narf")
 | |
|     result = MyModelMutation.mutate_and_get_payload(
 | |
|         None, mock_info(), **{"id": instance.id}
 | |
|     )
 | |
|     assert result.errors is None
 | |
|     assert result.cool_name == "Narf"
 | |
| 
 | |
| 
 | |
| @mark.django_db
 | |
| def test_model_invalid_update_mutate_and_get_payload_success():
 | |
|     class InvalidModelMutation(SerializerMutation):
 | |
|         class Meta:
 | |
|             serializer_class = MyModelSerializer
 | |
|             model_operations = ["update"]
 | |
| 
 | |
|     with raises(Exception) as exc:
 | |
|         result = InvalidModelMutation.mutate_and_get_payload(
 | |
|             None, mock_info(), **{"cool_name": "Narf"}
 | |
|         )
 | |
| 
 | |
|     assert '"id" required' in str(exc.value)
 | |
| 
 | |
| 
 | |
| @mark.django_db
 | |
| def test_perform_mutate_success():
 | |
|     class MyMethodMutation(SerializerMutation):
 | |
|         class Meta:
 | |
|             serializer_class = MyModelSerializerWithMethod
 | |
| 
 | |
|     result = MyMethodMutation.mutate_and_get_payload(
 | |
|         None,
 | |
|         mock_info(),
 | |
|         **{"cool_name": "Narf", "last_edited": datetime.date(2020, 1, 4)}
 | |
|     )
 | |
| 
 | |
|     assert result.errors is None
 | |
|     assert result.cool_name == "Narf"
 | |
|     assert result.days_since_last_edit == 4
 | |
| 
 | |
| 
 | |
| def test_mutate_and_get_payload_error():
 | |
|     class MyMutation(SerializerMutation):
 | |
|         class Meta:
 | |
|             serializer_class = MySerializer
 | |
| 
 | |
|     # missing required fields
 | |
|     result = MyMutation.mutate_and_get_payload(None, mock_info(), **{})
 | |
|     assert len(result.errors) > 0
 | |
| 
 | |
| 
 | |
| def test_model_mutate_and_get_payload_error():
 | |
|     # missing required fields
 | |
|     result = MyModelMutation.mutate_and_get_payload(None, mock_info(), **{})
 | |
|     assert len(result.errors) > 0
 | |
| 
 | |
| 
 | |
| def test_mutation_error_camelcased():
 | |
|     graphene_settings.CAMELCASE_ERRORS = True
 | |
|     result = MyModelMutation.mutate_and_get_payload(None, mock_info(), **{})
 | |
|     assert result.errors[0].field == "coolName"
 | |
|     graphene_settings.CAMELCASE_ERRORS = False
 | |
| 
 | |
| 
 | |
| def test_invalid_serializer_operations():
 | |
|     with raises(Exception) as exc:
 | |
| 
 | |
|         class MyModelMutation(SerializerMutation):
 | |
|             class Meta:
 | |
|                 serializer_class = MyModelSerializer
 | |
|                 model_operations = ["Add"]
 | |
| 
 | |
|     assert "model_operations" in str(exc.value)
 |