Skip to content

Issue #1413 fix invalid input type #1414

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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
2 changes: 1 addition & 1 deletion docs/types/scalars.rst
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ The following is an example for creating a DateTime scalar:
return dt.isoformat()

@staticmethod
def parse_literal(node):
def parse_literal(node, _variables=None):
if isinstance(node, ast.StringValue):
return datetime.datetime.strptime(
node.value, "%Y-%m-%dT%H:%M:%S.%f")
Expand Down
4 changes: 2 additions & 2 deletions graphene/tests/issues/test_1419.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
(ID, "1"),
(DateTime, '"2022-02-02T11:11:11"'),
(UUID, '"cbebbc62-758e-4f75-a890-bc73b5017d81"'),
(Decimal, "1.1"),
(JSONString, '{key:"foo",value:"bar"}'),
(Decimal, '"1.1"'),
(JSONString, '"{\\"key\\":\\"foo\\",\\"value\\":\\"bar\\"}"'),
(Base64, '"Q2hlbG8gd29ycmxkCg=="'),
],
)
Expand Down
6 changes: 4 additions & 2 deletions graphene/types/decimal.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from decimal import Decimal as _Decimal

from graphql import Undefined
from graphql.language.ast import StringValueNode, IntValueNode

from .scalars import Scalar
Expand All @@ -25,10 +26,11 @@ def serialize(dec):
def parse_literal(cls, node, _variables=None):
if isinstance(node, (StringValueNode, IntValueNode)):
return cls.parse_value(node.value)
return Undefined

@staticmethod
def parse_value(value):
try:
return _Decimal(value)
except ValueError:
return None
except Exception:
return Undefined
7 changes: 6 additions & 1 deletion graphene/types/json.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import json

from graphql import Undefined
from graphql.language.ast import StringValueNode

from .scalars import Scalar
Expand All @@ -22,7 +23,11 @@ def serialize(dt):
@staticmethod
def parse_literal(node, _variables=None):
if isinstance(node, StringValueNode):
return json.loads(node.value)
try:
return json.loads(node.value)
except Exception as error:
raise ValueError(f"Badly formed JSONString: {str(error)}")
return Undefined

@staticmethod
def parse_value(value):
Expand Down
14 changes: 11 additions & 3 deletions graphene/types/scalars.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from typing import Any

from graphql import Undefined
from graphql.language.ast import (
BooleanValueNode,
FloatValueNode,
Expand Down Expand Up @@ -67,9 +68,10 @@ def coerce_int(value):
try:
num = int(float(value))
except ValueError:
return None
return Undefined
if MIN_INT <= num <= MAX_INT:
return num
return Undefined

serialize = coerce_int
parse_value = coerce_int
Expand All @@ -80,6 +82,7 @@ def parse_literal(ast, _variables=None):
num = int(ast.value)
if MIN_INT <= num <= MAX_INT:
return num
return Undefined


class BigInt(Scalar):
Expand All @@ -97,7 +100,7 @@ def coerce_int(value):
try:
num = int(float(value))
except ValueError:
return None
return Undefined
return num

serialize = coerce_int
Expand All @@ -107,6 +110,7 @@ def coerce_int(value):
def parse_literal(ast, _variables=None):
if isinstance(ast, IntValueNode):
return int(ast.value)
return Undefined


class Float(Scalar):
Expand All @@ -122,7 +126,7 @@ def coerce_float(value):
try:
return float(value)
except ValueError:
return None
return Undefined

serialize = coerce_float
parse_value = coerce_float
Expand All @@ -131,6 +135,7 @@ def coerce_float(value):
def parse_literal(ast, _variables=None):
if isinstance(ast, (FloatValueNode, IntValueNode)):
return float(ast.value)
return Undefined


class String(Scalar):
Expand All @@ -153,6 +158,7 @@ def coerce_string(value):
def parse_literal(ast, _variables=None):
if isinstance(ast, StringValueNode):
return ast.value
return Undefined


class Boolean(Scalar):
Expand All @@ -167,6 +173,7 @@ class Boolean(Scalar):
def parse_literal(ast, _variables=None):
if isinstance(ast, BooleanValueNode):
return ast.value
return Undefined


class ID(Scalar):
Expand All @@ -185,3 +192,4 @@ class ID(Scalar):
def parse_literal(ast, _variables=None):
if isinstance(ast, (StringValueNode, IntValueNode)):
return ast.value
return Undefined
17 changes: 17 additions & 0 deletions graphene/types/tests/test_decimal.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,25 @@ def test_bad_decimal_query():
not_a_decimal = "Nobody expects the Spanish Inquisition!"

result = schema.execute("""{ decimal(input: "%s") }""" % not_a_decimal)
assert result.errors
assert len(result.errors) == 1
assert result.data is None
assert (
result.errors[0].message
== "Expected value of type 'Decimal', found \"Nobody expects the Spanish Inquisition!\"."
)

result = schema.execute("{ decimal(input: true) }")
assert result.errors
assert len(result.errors) == 1
assert result.data is None
assert result.errors[0].message == "Expected value of type 'Decimal', found true."

result = schema.execute("{ decimal(input: 1.2) }")
assert result.errors
assert len(result.errors) == 1
assert result.data is None
assert result.errors[0].message == "Expected value of type 'Decimal', found 1.2."


def test_decimal_string_query_integer():
Expand Down
52 changes: 52 additions & 0 deletions graphene/types/tests/test_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ def test_jsonstring_query():
assert not result.errors
assert result.data == {"json": json_value}

result = schema.execute("""{ json(input: "{}") }""")
assert not result.errors
assert result.data == {"json": "{}"}


def test_jsonstring_query_variable():
json_value = '{"key": "value"}'
Expand All @@ -31,3 +35,51 @@ def test_jsonstring_query_variable():
)
assert not result.errors
assert result.data == {"json": json_value}


def test_jsonstring_optional_uuid_input():
"""
Test that we can provide a null value to an optional input
"""
result = schema.execute("{ json(input: null) }")
assert not result.errors
assert result.data == {"json": None}


def test_jsonstring_invalid_query():
"""
Test that if an invalid type is provided we get an error
"""
result = schema.execute("{ json(input: 1) }")
assert result.errors
assert len(result.errors) == 1
assert result.errors[0].message == "Expected value of type 'JSONString', found 1."

result = schema.execute("{ json(input: {}) }")
assert result.errors
assert len(result.errors) == 1
assert result.errors[0].message == "Expected value of type 'JSONString', found {}."

result = schema.execute('{ json(input: "a") }')
assert result.errors
assert len(result.errors) == 1
assert result.errors[0].message == (
"Expected value of type 'JSONString', found \"a\"; "
"Badly formed JSONString: Expecting value: line 1 column 1 (char 0)"
)

result = schema.execute("""{ json(input: "{\\'key\\': 0}") }""")
assert result.errors
assert len(result.errors) == 1
assert (
result.errors[0].message
== "Syntax Error: Invalid character escape sequence: '\\''."
)

result = schema.execute("""{ json(input: "{\\"key\\": 0,}") }""")
assert result.errors
assert len(result.errors) == 1
assert result.errors[0].message == (
'Expected value of type \'JSONString\', found "{\\"key\\": 0,}"; '
"Badly formed JSONString: Expecting property name enclosed in double quotes: line 1 column 11 (char 10)"
)
Loading