From 1ce5a97bd522475155cb401c15bc0d147d547498 Mon Sep 17 00:00:00 2001 From: Jonathan Kim Date: Thu, 25 Jun 2020 11:40:16 +0100 Subject: [PATCH] Add some tests for the middleware --- graphene/compat/middleware.py | 43 ++++-- graphene/types/tests/test_enum.py | 2 +- graphene/types/tests/test_mutation.py | 188 ++++++++++++++++++++++++++ 3 files changed, 220 insertions(+), 13 deletions(-) diff --git a/graphene/compat/middleware.py b/graphene/compat/middleware.py index d5b1f682..7796e978 100644 --- a/graphene/compat/middleware.py +++ b/graphene/compat/middleware.py @@ -1,10 +1,37 @@ from graphql import OperationType from ..utils.str_converters import to_snake_case -from ..types.definitions import GrapheneEnumType +from ..types.definitions import GrapheneEnumType, GrapheneInputObjectType from ..types.utils import get_underlying_type +def convert_enum_args(args, input_arguments): + new_args = {} + + for arg_name, arg in input_arguments.items(): + _type = get_underlying_type(arg.type) + + arg_name = to_snake_case(arg_name) + input_value = args.get(arg_name, None) + + if isinstance(_type, GrapheneEnumType): + # Convert inputs to value + if input_value and isinstance(input_value, _type.graphene_type._meta.enum): + new_args[arg_name] = input_value.value + else: + new_args[arg_name] = input_value + elif isinstance(_type, GrapheneInputObjectType): + _input_arguments = get_underlying_type(arg.type).fields + input_type = input_value.get_type() + new_args[arg_name] = input_type( + **convert_enum_args(input_value, _input_arguments) + ) + else: + new_args[arg_name] = input_value + + return new_args + + def enum_value_convertor_middleware(next, root, info, **args): """ Compatibility middleware for upgrading to v3: @@ -14,15 +41,7 @@ def enum_value_convertor_middleware(next, root, info, **args): operation = info.operation.operation if operation == OperationType.MUTATION: input_arguments = info.parent_type.fields[info.field_name].args - for arg_name, arg in input_arguments.items(): - _type = get_underlying_type(arg.type) - if isinstance(_type, GrapheneEnumType): - # Convert inputs to value - arg_name = to_snake_case(arg_name) - input_value = args.get(arg_name, None) - if input_value and isinstance( - input_value, _type.graphene_type._meta.enum - ): - args[arg_name] = args[arg_name].value - return next(root, info, **args) + new_args = convert_enum_args(args, input_arguments) + + return next(root, info, **new_args) diff --git a/graphene/types/tests/test_enum.py b/graphene/types/tests/test_enum.py index 57d3cfee..1e8f3e51 100644 --- a/graphene/types/tests/test_enum.py +++ b/graphene/types/tests/test_enum.py @@ -246,7 +246,7 @@ def test_enum_types(): color = GColor(required=True) def resolve_color(_, info): - return Color.RED.value + return Color.RED schema = Schema(query=Query) diff --git a/graphene/types/tests/test_mutation.py b/graphene/types/tests/test_mutation.py index 4a7ad3c7..b5cc64b7 100644 --- a/graphene/types/tests/test_mutation.py +++ b/graphene/types/tests/test_mutation.py @@ -8,6 +8,9 @@ from ..scalars import String from ..schema import Schema from ..structures import NonNull from ..interface import Interface +from ..enum import Enum +from ..inputobjecttype import InputObjectType +from graphene.compat.middleware import enum_value_convertor_middleware class MyType(Interface): @@ -218,3 +221,188 @@ def test_mutation_as_subclass(): ) assert not result.errors assert result.data == {"createUserWithPlanet": {"name": "Peter", "planet": "earth"}} + + +def test_mutation_enum_input(): + class RGB(Enum): + """Available colors""" + + RED = 1 + GREEN = 2 + BLUE = 3 + + color_input = None + + class CreatePaint(Mutation): + class Arguments: + color = RGB(required=True) + + color = RGB(required=True) + + def mutate(_, info, color): + nonlocal color_input + color_input = color + return CreatePaint(color=color) + + class MyMutation(ObjectType): + create_paint = CreatePaint.Field() + + class Query(ObjectType): + a = String() + + schema = Schema(query=Query, mutation=MyMutation) + result = schema.execute( + """ mutation MyMutation { + createPaint(color: RED) { + color + } + } + """ + ) + assert not result.errors + assert result.data == {"createPaint": {"color": "RED"}} + + assert color_input == RGB.RED + + +def test_mutation_enum_input_type(): + class RGB(Enum): + """Available colors""" + + RED = 1 + GREEN = 2 + BLUE = 3 + + class ColorInput(InputObjectType): + color = RGB(required=True) + + color_input_value = None + + class CreatePaint(Mutation): + class Arguments: + color_input = ColorInput(required=True) + + color = RGB(required=True) + + def mutate(_, info, color_input): + nonlocal color_input_value + color_input_value = color_input.color + return CreatePaint(color=color_input.color) + + class MyMutation(ObjectType): + create_paint = CreatePaint.Field() + + class Query(ObjectType): + a = String() + + schema = Schema(query=Query, mutation=MyMutation) + result = schema.execute( + """ mutation MyMutation { + createPaint(colorInput: { color: RED }) { + color + } + } + """, + ) + assert not result.errors + assert result.data == {"createPaint": {"color": "RED"}} + + assert color_input_value == RGB.RED + + +def test_mutation_enum_input_compatability_middleware(): + """Test the `enum_value_convertor_middleware`""" + + class RGB(Enum): + """Available colors""" + + RED = 1 + GREEN = 2 + BLUE = 3 + + color_input = None + + class CreatePaint(Mutation): + class Arguments: + color = RGB(required=True) + + color = RGB(required=True) + + def mutate(_, info, color): + nonlocal color_input + color_input = color + return CreatePaint(color=color) + + class MyMutation(ObjectType): + create_paint = CreatePaint.Field() + + class Query(ObjectType): + a = String() + + schema = Schema(query=Query, mutation=MyMutation) + result = schema.execute( + """ mutation MyMutation { + createPaint(color: RED) { + color + } + } + """, + middleware=[enum_value_convertor_middleware], + ) + assert not result.errors + assert result.data == {"createPaint": {"color": "RED"}} + + assert color_input == 1 + assert type(color_input) == int + + +def test_mutation_enum_input_compatability_middleware_input_type(): + """Test the `enum_value_convertor_middleware`""" + + class RGB(Enum): + """Available colors""" + + RED = 1 + GREEN = 2 + BLUE = 3 + + class SecondColorInput(InputObjectType): + color = RGB(required=True) + + class ColorInput(InputObjectType): + color_input = SecondColorInput(required=True) + + color_input_value = None + + class CreatePaint(Mutation): + class Arguments: + color_input = ColorInput(required=True) + + color = RGB(required=True) + + def mutate(_, info, color_input): + nonlocal color_input_value + color_input_value = color_input.color_input.color + return CreatePaint(color=color_input_value) + + class MyMutation(ObjectType): + create_paint = CreatePaint.Field() + + class Query(ObjectType): + a = String() + + schema = Schema(query=Query, mutation=MyMutation) + result = schema.execute( + """ mutation MyMutation { + createPaint(colorInput: { colorInput: { color: RED } }) { + color + } + } + """, + middleware=[enum_value_convertor_middleware], + ) + assert not result.errors + assert result.data == {"createPaint": {"color": "RED"}} + + assert color_input_value == 1 + assert type(color_input_value) == int