mirror of
				https://github.com/graphql-python/graphene-django.git
				synced 2025-11-04 18:08:01 +03:00 
			
		
		
		
	* Use ruff in pre-commit * Add pyupgrade * Add isort * Add bugbear * Fix B015 Pointless comparison * Fix B026 * B018 false positive * Remove flake8 and isort config from setup.cfg * Remove black and flake8 from dev dependencies * Update black * Show list of fixes applied with autofix on * Fix typo * Add C4 flake8-comprehensions * Add ruff to dev dependencies * Fix up
		
			
				
	
	
		
			334 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			334 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
from django import forms
 | 
						|
from pytest import raises
 | 
						|
 | 
						|
import graphene
 | 
						|
from graphene_django import DjangoObjectType
 | 
						|
 | 
						|
from ...tests.models import CHOICES, Film, Reporter
 | 
						|
from ..types import DjangoFormInputObjectType
 | 
						|
 | 
						|
# Reporter a_choice CHOICES = ((1, "this"), (2, _("that")))
 | 
						|
THIS = CHOICES[0][0]
 | 
						|
THIS_ON_CLIENT_CONVERTED = "A_1"
 | 
						|
 | 
						|
# Film genre choices=[("do", "Documentary"), ("ac", "Action"), ("ot", "Other")],
 | 
						|
DOCUMENTARY = "do"
 | 
						|
DOCUMENTARY_ON_CLIENT_CONVERTED = "DO"
 | 
						|
 | 
						|
 | 
						|
class FilmForm(forms.ModelForm):
 | 
						|
    class Meta:
 | 
						|
        model = Film
 | 
						|
        exclude = ()
 | 
						|
 | 
						|
 | 
						|
class ReporterType(DjangoObjectType):
 | 
						|
    class Meta:
 | 
						|
        model = Reporter
 | 
						|
        fields = "__all__"
 | 
						|
 | 
						|
 | 
						|
class ReporterForm(forms.ModelForm):
 | 
						|
    class Meta:
 | 
						|
        model = Reporter
 | 
						|
        exclude = ("pets", "email", "fans")
 | 
						|
 | 
						|
 | 
						|
class MyForm(forms.Form):
 | 
						|
    text_field = forms.CharField()
 | 
						|
    int_field = forms.IntegerField()
 | 
						|
 | 
						|
 | 
						|
def test_needs_form_class():
 | 
						|
    with raises(Exception) as exc:
 | 
						|
 | 
						|
        class MyInputType(DjangoFormInputObjectType):
 | 
						|
            pass
 | 
						|
 | 
						|
    assert exc.value.args[0] == "form_class is required for DjangoFormInputObjectType"
 | 
						|
 | 
						|
 | 
						|
def test_type_from_modelform_has_input_fields():
 | 
						|
    class ReporterInputType(DjangoFormInputObjectType):
 | 
						|
        class Meta:
 | 
						|
            form_class = ReporterForm
 | 
						|
            only_fields = ("first_name", "last_name", "a_choice")
 | 
						|
 | 
						|
    fields = ["first_name", "last_name", "a_choice", "id"]
 | 
						|
    assert all(f in ReporterInputType._meta.fields for f in fields)
 | 
						|
 | 
						|
 | 
						|
def test_type_from_form_has_input_fields():
 | 
						|
    class MyFormInputType(DjangoFormInputObjectType):
 | 
						|
        class Meta:
 | 
						|
            form_class = MyForm
 | 
						|
 | 
						|
    fields = ["text_field", "int_field", "id"]
 | 
						|
    assert all(f in MyFormInputType._meta.fields for f in fields)
 | 
						|
 | 
						|
 | 
						|
def test_type_custom_id_field():
 | 
						|
    class MyFormInputType(DjangoFormInputObjectType):
 | 
						|
        class Meta:
 | 
						|
            form_class = MyForm
 | 
						|
            add_id_field_name = "pk"
 | 
						|
 | 
						|
    fields = ["text_field", "int_field", "pk"]
 | 
						|
    assert all(f in MyFormInputType._meta.fields for f in fields)
 | 
						|
    assert MyFormInputType._meta.fields["pk"].type is graphene.ID
 | 
						|
 | 
						|
 | 
						|
def test_type_custom_id_field_type():
 | 
						|
    class MyFormInputType(DjangoFormInputObjectType):
 | 
						|
        class Meta:
 | 
						|
            form_class = MyForm
 | 
						|
            add_id_field_name = "pk"
 | 
						|
            add_id_field_type = graphene.String(required=False)
 | 
						|
 | 
						|
    fields = ["text_field", "int_field", "pk"]
 | 
						|
    assert all(f in MyFormInputType._meta.fields for f in fields)
 | 
						|
    assert MyFormInputType._meta.fields["pk"].type is graphene.String
 | 
						|
 | 
						|
 | 
						|
class MockQuery(graphene.ObjectType):
 | 
						|
    a = graphene.String()
 | 
						|
 | 
						|
 | 
						|
def test_mutation_with_form_djangoforminputtype():
 | 
						|
    class MyFormInputType(DjangoFormInputObjectType):
 | 
						|
        class Meta:
 | 
						|
            form_class = MyForm
 | 
						|
 | 
						|
    class MyFormMutation(graphene.Mutation):
 | 
						|
        class Arguments:
 | 
						|
            form_data = MyFormInputType(required=True)
 | 
						|
 | 
						|
        result = graphene.Boolean()
 | 
						|
 | 
						|
        def mutate(_root, _info, form_data):
 | 
						|
            form = MyForm(data=form_data)
 | 
						|
            if form.is_valid():
 | 
						|
                result = form.cleaned_data == {
 | 
						|
                    "text_field": "text",
 | 
						|
                    "int_field": 777,
 | 
						|
                }
 | 
						|
                return MyFormMutation(result=result)
 | 
						|
            return MyFormMutation(result=False)
 | 
						|
 | 
						|
    class Mutation(graphene.ObjectType):
 | 
						|
        myForm_mutation = MyFormMutation.Field()
 | 
						|
 | 
						|
    schema = graphene.Schema(query=MockQuery, mutation=Mutation)
 | 
						|
 | 
						|
    result = schema.execute(
 | 
						|
        """ mutation MyFormMutation($formData: MyFormInputType!) {
 | 
						|
            myFormMutation(formData: $formData) {
 | 
						|
                result
 | 
						|
            }
 | 
						|
        }
 | 
						|
        """,
 | 
						|
        variable_values={"formData": {"textField": "text", "intField": 777}},
 | 
						|
    )
 | 
						|
    assert result.errors is None
 | 
						|
    assert result.data == {"myFormMutation": {"result": True}}
 | 
						|
 | 
						|
 | 
						|
def test_mutation_with_modelform_djangoforminputtype():
 | 
						|
    class ReporterInputType(DjangoFormInputObjectType):
 | 
						|
        class Meta:
 | 
						|
            form_class = ReporterForm
 | 
						|
            object_type = ReporterType
 | 
						|
            only_fields = ("first_name", "last_name", "a_choice")
 | 
						|
 | 
						|
    class ReporterMutation(graphene.Mutation):
 | 
						|
        class Arguments:
 | 
						|
            reporter_data = ReporterInputType(required=True)
 | 
						|
 | 
						|
        result = graphene.Field(ReporterType)
 | 
						|
 | 
						|
        def mutate(_root, _info, reporter_data):
 | 
						|
            reporter = Reporter.objects.get(pk=reporter_data.id)
 | 
						|
            form = ReporterForm(data=reporter_data, instance=reporter)
 | 
						|
            if form.is_valid():
 | 
						|
                reporter = form.save()
 | 
						|
                return ReporterMutation(result=reporter)
 | 
						|
 | 
						|
            return ReporterMutation(result=None)
 | 
						|
 | 
						|
    class Mutation(graphene.ObjectType):
 | 
						|
        report_mutation = ReporterMutation.Field()
 | 
						|
 | 
						|
    schema = graphene.Schema(query=MockQuery, mutation=Mutation)
 | 
						|
 | 
						|
    reporter = Reporter.objects.create(
 | 
						|
        first_name="Bob", last_name="Roberts", a_choice=THIS
 | 
						|
    )
 | 
						|
 | 
						|
    result = schema.execute(
 | 
						|
        """ mutation ReportMutation($reporterData: ReporterInputType!) {
 | 
						|
            reportMutation(reporterData: $reporterData) {
 | 
						|
                result {
 | 
						|
                    id,
 | 
						|
                    firstName,
 | 
						|
                    lastName,
 | 
						|
                    aChoice
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
        """,
 | 
						|
        variable_values={
 | 
						|
            "reporterData": {
 | 
						|
                "id": reporter.pk,
 | 
						|
                "firstName": "Dave",
 | 
						|
                "lastName": "Smith",
 | 
						|
                "aChoice": THIS_ON_CLIENT_CONVERTED,
 | 
						|
            }
 | 
						|
        },
 | 
						|
    )
 | 
						|
    assert result.errors is None
 | 
						|
    assert result.data["reportMutation"]["result"] == {
 | 
						|
        "id": "1",
 | 
						|
        "firstName": "Dave",
 | 
						|
        "lastName": "Smith",
 | 
						|
        "aChoice": THIS_ON_CLIENT_CONVERTED,
 | 
						|
    }
 | 
						|
    assert Reporter.objects.count() == 1
 | 
						|
    reporter.refresh_from_db()
 | 
						|
    assert reporter.first_name == "Dave"
 | 
						|
 | 
						|
 | 
						|
def reporter_enum_convert_mutation_result(
 | 
						|
    ReporterInputType, choice_val_on_client=THIS_ON_CLIENT_CONVERTED
 | 
						|
):
 | 
						|
    class ReporterMutation(graphene.Mutation):
 | 
						|
        class Arguments:
 | 
						|
            reporter = ReporterInputType(required=True)
 | 
						|
 | 
						|
        result_str = graphene.String()
 | 
						|
        result_int = graphene.Int()
 | 
						|
 | 
						|
        def mutate(_root, _info, reporter):
 | 
						|
            if isinstance(reporter.a_choice, int) or reporter.a_choice.isdigit():
 | 
						|
                return ReporterMutation(result_int=reporter.a_choice, result_str=None)
 | 
						|
            return ReporterMutation(result_int=None, result_str=reporter.a_choice)
 | 
						|
 | 
						|
    class Mutation(graphene.ObjectType):
 | 
						|
        report_mutation = ReporterMutation.Field()
 | 
						|
 | 
						|
    schema = graphene.Schema(query=MockQuery, mutation=Mutation)
 | 
						|
 | 
						|
    return schema.execute(
 | 
						|
        """ mutation ReportMutation($reporter: ReporterInputType!) {
 | 
						|
            reportMutation(reporter: $reporter) {
 | 
						|
                resultStr,
 | 
						|
                resultInt
 | 
						|
            }
 | 
						|
        }
 | 
						|
        """,
 | 
						|
        variable_values={"reporter": {"aChoice": choice_val_on_client}},
 | 
						|
    )
 | 
						|
 | 
						|
 | 
						|
def test_enum_not_converted():
 | 
						|
    class ReporterInputType(DjangoFormInputObjectType):
 | 
						|
        class Meta:
 | 
						|
            form_class = ReporterForm
 | 
						|
            only_fields = ("a_choice",)
 | 
						|
 | 
						|
    result = reporter_enum_convert_mutation_result(ReporterInputType)
 | 
						|
    assert result.errors is None
 | 
						|
    assert result.data["reportMutation"]["resultStr"] == THIS_ON_CLIENT_CONVERTED
 | 
						|
    assert result.data["reportMutation"]["resultInt"] is None
 | 
						|
    assert ReporterInputType._meta.fields["a_choice"].type is graphene.String
 | 
						|
 | 
						|
 | 
						|
def test_enum_is_converted_to_original():
 | 
						|
    class ReporterInputType(DjangoFormInputObjectType):
 | 
						|
        class Meta:
 | 
						|
            form_class = ReporterForm
 | 
						|
            object_type = ReporterType
 | 
						|
            only_fields = ("a_choice",)
 | 
						|
 | 
						|
    result = reporter_enum_convert_mutation_result(ReporterInputType)
 | 
						|
    assert result.errors is None
 | 
						|
    assert result.data["reportMutation"]["resultInt"] == THIS
 | 
						|
    assert result.data["reportMutation"]["resultStr"] is None
 | 
						|
    assert (
 | 
						|
        ReporterInputType._meta.fields["a_choice"].type.__name__
 | 
						|
        == "AChoiceEnumBackConvString"
 | 
						|
    )
 | 
						|
 | 
						|
 | 
						|
def test_convert_choices_to_enum_is_false_and_field_type_as_in_model():
 | 
						|
    class ReporterTypeNotConvertChoices(DjangoObjectType):
 | 
						|
        class Meta:
 | 
						|
            model = Reporter
 | 
						|
            convert_choices_to_enum = False
 | 
						|
            fields = "__all__"
 | 
						|
 | 
						|
    class ReporterInputType(DjangoFormInputObjectType):
 | 
						|
        class Meta:
 | 
						|
            form_class = ReporterForm
 | 
						|
            object_type = ReporterTypeNotConvertChoices
 | 
						|
            only_fields = ("a_choice",)
 | 
						|
 | 
						|
    result = reporter_enum_convert_mutation_result(ReporterInputType, THIS)
 | 
						|
    assert result.errors is None
 | 
						|
    assert result.data["reportMutation"]["resultInt"] == THIS
 | 
						|
    assert result.data["reportMutation"]["resultStr"] is None
 | 
						|
    assert ReporterInputType._meta.fields["a_choice"].type is graphene.Int
 | 
						|
 | 
						|
 | 
						|
def enum_convert_mutation_result_film(FilmInputType):
 | 
						|
    class FilmMutation(graphene.Mutation):
 | 
						|
        class Arguments:
 | 
						|
            film = FilmInputType(required=True)
 | 
						|
 | 
						|
        result = graphene.String()
 | 
						|
 | 
						|
        def mutate(_root, _info, film):
 | 
						|
            return FilmMutation(result=film.genre)
 | 
						|
 | 
						|
    class Mutation(graphene.ObjectType):
 | 
						|
        film_mutation = FilmMutation.Field()
 | 
						|
 | 
						|
    schema = graphene.Schema(query=MockQuery, mutation=Mutation)
 | 
						|
 | 
						|
    return schema.execute(
 | 
						|
        """ mutation FilmMutation($film: FilmInputType!) {
 | 
						|
            filmMutation(film: $film) {
 | 
						|
                result
 | 
						|
            }
 | 
						|
        }
 | 
						|
        """,
 | 
						|
        variable_values={"film": {"genre": DOCUMENTARY_ON_CLIENT_CONVERTED}},
 | 
						|
    )
 | 
						|
 | 
						|
 | 
						|
def test_enum_not_converted_required_non_number():
 | 
						|
    class FilmInputType(DjangoFormInputObjectType):
 | 
						|
        class Meta:
 | 
						|
            form_class = FilmForm
 | 
						|
            only_fields = ("genre",)
 | 
						|
 | 
						|
    result = enum_convert_mutation_result_film(FilmInputType)
 | 
						|
    assert result.errors is None
 | 
						|
    assert result.data["filmMutation"]["result"] == DOCUMENTARY_ON_CLIENT_CONVERTED
 | 
						|
 | 
						|
 | 
						|
def test_enum_is_converted_to_original_required_non_number():
 | 
						|
    class FilmType(DjangoObjectType):
 | 
						|
        class Meta:
 | 
						|
            model = Film
 | 
						|
            fields = "__all__"
 | 
						|
 | 
						|
    class FilmInputType(DjangoFormInputObjectType):
 | 
						|
        class Meta:
 | 
						|
            form_class = FilmForm
 | 
						|
            object_type = FilmType
 | 
						|
            only_fields = ("genre",)
 | 
						|
 | 
						|
    result = enum_convert_mutation_result_film(FilmInputType)
 | 
						|
    assert result.errors is None
 | 
						|
    assert result.data["filmMutation"]["result"] == DOCUMENTARY
 |