mirror of
https://github.com/graphql-python/graphene.git
synced 2024-11-25 19:13:57 +03:00
[863] DateTime, Date, and Time now accept datetime.datetime, datetime.date,… (#864)
* DateTime, Date, and Time now accept datetime.datetime, datetime.date, and datetime.time resp. inputs when used as variables * Added tests and improved resilience against bad DateTime, Date, and Time inputs. * Fixed string type checks too narrow for py2.7 * fixed some of pre-commit's complaints
This commit is contained in:
parent
c5b2281e22
commit
7b6dae7fa3
|
@ -4,6 +4,7 @@ import datetime
|
|||
|
||||
from aniso8601 import parse_date, parse_datetime, parse_time
|
||||
from graphql.language import ast
|
||||
from six import string_types
|
||||
|
||||
from .scalars import Scalar
|
||||
|
||||
|
@ -32,6 +33,9 @@ class Date(Scalar):
|
|||
@staticmethod
|
||||
def parse_value(value):
|
||||
try:
|
||||
if isinstance(value, datetime.date):
|
||||
return value
|
||||
elif isinstance(value, string_types):
|
||||
return parse_date(value)
|
||||
except ValueError:
|
||||
return None
|
||||
|
@ -59,6 +63,9 @@ class DateTime(Scalar):
|
|||
@staticmethod
|
||||
def parse_value(value):
|
||||
try:
|
||||
if isinstance(value, datetime.datetime):
|
||||
return value
|
||||
elif isinstance(value, string_types):
|
||||
return parse_datetime(value)
|
||||
except ValueError:
|
||||
return None
|
||||
|
@ -86,6 +93,9 @@ class Time(Scalar):
|
|||
@classmethod
|
||||
def parse_value(cls, value):
|
||||
try:
|
||||
if isinstance(value, datetime.time):
|
||||
return value
|
||||
elif isinstance(value, string_types):
|
||||
return parse_time(value)
|
||||
except ValueError:
|
||||
return None
|
||||
|
|
|
@ -2,6 +2,7 @@ import datetime
|
|||
|
||||
import pytz
|
||||
from graphql import GraphQLError
|
||||
import pytest
|
||||
|
||||
from ..datetime import Date, DateTime, Time
|
||||
from ..objecttype import ObjectType
|
||||
|
@ -88,6 +89,15 @@ def test_datetime_query_variable():
|
|||
now = datetime.datetime.now().replace(tzinfo=pytz.utc)
|
||||
isoformat = now.isoformat()
|
||||
|
||||
# test datetime variable provided as Python datetime
|
||||
result = schema.execute(
|
||||
"""query Test($date: DateTime){ datetime(in: $date) }""",
|
||||
variables={"date": now},
|
||||
)
|
||||
assert not result.errors
|
||||
assert result.data == {"datetime": isoformat}
|
||||
|
||||
# test datetime variable in string representation
|
||||
result = schema.execute(
|
||||
"""query Test($date: DateTime){ datetime(in: $date) }""",
|
||||
variables={"date": isoformat},
|
||||
|
@ -100,6 +110,14 @@ def test_date_query_variable():
|
|||
now = datetime.datetime.now().replace(tzinfo=pytz.utc).date()
|
||||
isoformat = now.isoformat()
|
||||
|
||||
# test date variable provided as Python date
|
||||
result = schema.execute(
|
||||
"""query Test($date: Date){ date(in: $date) }""", variables={"date": now}
|
||||
)
|
||||
assert not result.errors
|
||||
assert result.data == {"date": isoformat}
|
||||
|
||||
# test date variable in string representation
|
||||
result = schema.execute(
|
||||
"""query Test($date: Date){ date(in: $date) }""", variables={"date": isoformat}
|
||||
)
|
||||
|
@ -112,8 +130,57 @@ def test_time_query_variable():
|
|||
time = datetime.time(now.hour, now.minute, now.second, now.microsecond, now.tzinfo)
|
||||
isoformat = time.isoformat()
|
||||
|
||||
# test time variable provided as Python time
|
||||
result = schema.execute(
|
||||
"""query Test($time: Time){ time(at: $time) }""", variables={"time": time}
|
||||
)
|
||||
assert not result.errors
|
||||
assert result.data == {"time": isoformat}
|
||||
|
||||
# test time variable in string representation
|
||||
result = schema.execute(
|
||||
"""query Test($time: Time){ time(at: $time) }""", variables={"time": isoformat}
|
||||
)
|
||||
assert not result.errors
|
||||
assert result.data == {"time": isoformat}
|
||||
|
||||
|
||||
@pytest.mark.xfail(
|
||||
reason="creating the error message fails when un-parsable object is not JSON serializable."
|
||||
)
|
||||
def test_bad_variables():
|
||||
def _test_bad_variables(type, input):
|
||||
result = schema.execute(
|
||||
"""query Test($input: {}){{ {}(in: $input) }}""".format(type, type.lower()),
|
||||
variables={"input": input},
|
||||
)
|
||||
assert len(result.errors) == 1
|
||||
# when `input` is not JSON serializable formatting the error message in
|
||||
# `graphql.utils.is_valid_value` line 79 fails with a TypeError
|
||||
assert isinstance(result.errors[0], GraphQLError)
|
||||
print(result.errors[0])
|
||||
assert result.data is None
|
||||
|
||||
not_a_date = dict()
|
||||
not_a_date_str = "Some string that's not a date"
|
||||
today = datetime.date.today()
|
||||
now = datetime.datetime.now().replace(tzinfo=pytz.utc)
|
||||
time = datetime.time(now.hour, now.minute, now.second, now.microsecond, now.tzinfo)
|
||||
|
||||
bad_pairs = [
|
||||
("DateTime", not_a_date),
|
||||
("DateTime", not_a_date_str),
|
||||
("DateTime", today),
|
||||
("DateTime", time),
|
||||
("Date", not_a_date),
|
||||
("Date", not_a_date_str),
|
||||
("Date", now),
|
||||
("Date", time),
|
||||
("Time", not_a_date),
|
||||
("Time", not_a_date_str),
|
||||
("Time", now),
|
||||
("Time", today),
|
||||
]
|
||||
|
||||
for type, input in bad_pairs:
|
||||
_test_bad_variables(type, input)
|
||||
|
|
Loading…
Reference in New Issue
Block a user