Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion gql/utilities/serialize_variable_values.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
OperationDefinitionNode,
type_from_ast,
)
from graphql.pyutils import inspect
from graphql.pyutils import inspect, is_iterable


def _get_document_operation(
Expand Down Expand Up @@ -76,6 +76,9 @@ def serialize_value(type_: GraphQLType, value: Any) -> Any:
return serialize_value(inner_type, value)

elif isinstance(type_, GraphQLList):
if not is_iterable(value):
# Lists accept a non-list value as a list of one.
return [serialize_value(inner_type, value)]
return [serialize_value(inner_type, v) for v in value]

elif isinstance(type_, (GraphQLScalarType, GraphQLEnumType)):
Expand Down
79 changes: 78 additions & 1 deletion tests/test_graphql_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@
GraphQLObjectType,
GraphQLScalarType,
GraphQLSchema,
GraphQLString,
)
from graphql.utilities import value_from_ast_untyped
from graphql.utilities import build_schema, value_from_ast_untyped

from gql import GraphQLRequest

Expand Down Expand Up @@ -206,6 +207,82 @@ def test_serialize_variables_using_money_example():
assert req.variable_values == {"money": {"amount": 10, "currency": "DM"}}


def test_serialize_variables_single_value_for_list_type():
# A value which is not a list, provided for a list type, should be
# coerced into a list of one instead of being iterated over.
list_schema = build_schema("type Query {f(ids: [String!], ns: [Int]): String}")

req = GraphQLRequest(
"query q($ids: [String!], $ns: [Int]) {f(ids: $ids, ns: $ns)}",
variable_values={"ids": "abc", "ns": 5},
)

req = req.serialize_variable_values(list_schema)

assert req.variable_values == {"ids": ["abc"], "ns": [5]}


def test_serialize_variables_mapping_as_singleton_input_object():
schema = build_schema(
"input ItemInput { name: String } type Query { f(items: [ItemInput]): String }"
)
req = GraphQLRequest(
"query q($items: [ItemInput]) { f(items: $items) }",
variable_values={"items": {"name": "abc"}},
)
req = req.serialize_variable_values(schema)
assert req.variable_values == {"items": [{"name": "abc"}]}


def test_serialize_variables_recursive_list_coercion():
schema = build_schema("type Query { f(values: [[Int]]): String }")

req1 = GraphQLRequest(
"query q($values: [[Int]]) { f(values: $values) }",
variable_values={"values": 1},
)
req1 = req1.serialize_variable_values(schema)
assert req1.variable_values == {"values": [[1]]}

req2 = GraphQLRequest(
"query q($values: [[Int]]) { f(values: $values) }",
variable_values={"values": [1, 2]},
)
req2 = req2.serialize_variable_values(schema)
assert req2.variable_values == {"values": [[1], [2]]}


def test_serialize_variables_collection_behavior():
schema = build_schema("type Query { f(values: [Int]): String }")
req = GraphQLRequest(
"query q($values: [Int]) { f(values: $values) }",
variable_values={"values": (1, 2)},
)
req = req.serialize_variable_values(schema)
assert req.variable_values == {"values": [1, 2]}


def test_serialize_variables_bytes_behavior():
bytes_scalar = GraphQLScalarType(name="Bytes", serialize=lambda v: v)
schema = GraphQLSchema(
query=GraphQLObjectType(
"Query",
fields={
"f": GraphQLField(
GraphQLString,
args={"values": GraphQLArgument(GraphQLList(bytes_scalar))},
)
},
)
)
req = GraphQLRequest(
"query q($values: [Bytes]) { f(values: $values) }",
variable_values={"values": b"abc"},
)
req = req.serialize_variable_values(schema)
assert req.variable_values == {"values": [b"abc"]}


def test_graphql_request_using_string_instead_of_document():
request = GraphQLRequest("{balance}")

Expand Down
Loading