import copy import graphene from django.db import models from graphene import InputObjectType from pytest import raises from rest_framework import serializers from ..serializer_converter import convert_serializer_field from ..types import DictType def _get_type( rest_framework_field, is_input=True, convert_choices_to_enum=True, **kwargs ): # prevents the following error: # AssertionError: The `source` argument is not meaningful when applied to a `child=` field. # Remove `source=` from the field declaration. # since we are reusing the same child in when testing the required attribute if "child" in kwargs: kwargs["child"] = copy.deepcopy(kwargs["child"]) field = rest_framework_field(**kwargs) return convert_serializer_field( field, is_input=is_input, convert_choices_to_enum=convert_choices_to_enum ) def assert_conversion(rest_framework_field, graphene_field, **kwargs): graphene_type = _get_type( rest_framework_field, help_text="Custom Help Text", **kwargs ) assert isinstance(graphene_type, graphene_field) graphene_type_required = _get_type( rest_framework_field, help_text="Custom Help Text", required=True, **kwargs ) assert isinstance(graphene_type_required, graphene_field) return graphene_type def test_should_unknown_rest_framework_field_raise_exception(): with raises(Exception) as excinfo: convert_serializer_field(None) assert "Don't know how to convert the serializer field" in str(excinfo.value) def test_should_char_convert_string(): assert_conversion(serializers.CharField, graphene.String) def test_should_email_convert_string(): assert_conversion(serializers.EmailField, graphene.String) def test_should_slug_convert_string(): assert_conversion(serializers.SlugField, graphene.String) def test_should_url_convert_string(): assert_conversion(serializers.URLField, graphene.String) def test_should_choice_convert_enum(): field = assert_conversion( serializers.ChoiceField, graphene.Enum, choices=[("h", "Hello"), ("w", "World")], source="word", ) assert field._meta.enum.__members__["H"].value == "h" assert field._meta.enum.__members__["H"].description == "Hello" assert field._meta.enum.__members__["W"].value == "w" assert field._meta.enum.__members__["W"].description == "World" def test_should_choice_convert_string_if_enum_disabled(): assert_conversion( serializers.ChoiceField, graphene.String, choices=[("h", "Hello"), ("w", "World")], source="word", convert_choices_to_enum=False, ) def test_should_base_field_convert_string(): assert_conversion(serializers.Field, graphene.String) def test_should_regex_convert_string(): assert_conversion(serializers.RegexField, graphene.String, regex="[0-9]+") def test_should_uuid_convert_string(): if hasattr(serializers, "UUIDField"): assert_conversion(serializers.UUIDField, graphene.String) def test_should_model_convert_field(): class MyModelSerializer(serializers.ModelSerializer): class Meta: model = None fields = "__all__" assert_conversion(MyModelSerializer, graphene.Field, is_input=False) def test_should_date_time_convert_datetime(): assert_conversion(serializers.DateTimeField, graphene.types.datetime.DateTime) def test_should_date_convert_date(): assert_conversion(serializers.DateField, graphene.types.datetime.Date) def test_should_time_convert_time(): assert_conversion(serializers.TimeField, graphene.types.datetime.Time) def test_should_integer_convert_int(): assert_conversion(serializers.IntegerField, graphene.Int) def test_should_boolean_convert_boolean(): assert_conversion(serializers.BooleanField, graphene.Boolean) def test_should_float_convert_float(): assert_conversion(serializers.FloatField, graphene.Float) def test_should_decimal_convert_decimal(): assert_conversion( serializers.DecimalField, graphene.Decimal, max_digits=4, decimal_places=2 ) def test_should_list_convert_to_list(): class StringListField(serializers.ListField): child = serializers.CharField() field_a = assert_conversion( serializers.ListField, graphene.List, child=serializers.IntegerField(min_value=0, max_value=100), ) assert field_a.of_type == graphene.Int field_b = assert_conversion(StringListField, graphene.List) assert field_b.of_type == graphene.String def test_should_list_serializer_convert_to_list(): class FooModel(models.Model): pass class ChildSerializer(serializers.ModelSerializer): class Meta: model = FooModel fields = "__all__" class ParentSerializer(serializers.ModelSerializer): child = ChildSerializer(many=True) class Meta: model = FooModel fields = "__all__" converted_type = convert_serializer_field( ParentSerializer().get_fields()["child"], is_input=True ) assert isinstance(converted_type, graphene.List) converted_type = convert_serializer_field( ParentSerializer().get_fields()["child"], is_input=False ) assert isinstance(converted_type, graphene.List) assert converted_type.of_type is None def test_should_dict_convert_dict(): assert_conversion(serializers.DictField, DictType) def test_should_duration_convert_string(): assert_conversion(serializers.DurationField, graphene.String) def test_should_file_convert_string(): assert_conversion(serializers.FileField, graphene.String) def test_should_filepath_convert_string(): assert_conversion(serializers.FilePathField, graphene.Enum, path="/") def test_should_ip_convert_string(): assert_conversion(serializers.IPAddressField, graphene.String) def test_should_image_convert_string(): assert_conversion(serializers.ImageField, graphene.String) def test_should_json_convert_jsonstring(): assert_conversion(serializers.JSONField, graphene.types.json.JSONString) def test_should_multiplechoicefield_convert_to_list_of_enum(): field = assert_conversion( serializers.MultipleChoiceField, graphene.List, choices=[1, 2, 3] ) assert issubclass(field.of_type, graphene.Enum)