diff --git a/graphene/types/datetime.py b/graphene/types/datetime.py index d45030b9..ca96547f 100644 --- a/graphene/types/datetime.py +++ b/graphene/types/datetime.py @@ -34,8 +34,8 @@ class Date(Scalar): try: if isinstance(value, datetime.date): return value - - return parse_date(value) + elif isinstance(value, str): + return parse_date(value) except ValueError: return None @@ -64,8 +64,8 @@ class DateTime(Scalar): try: if isinstance(value, datetime.datetime): return value - - return parse_datetime(value) + elif isinstance(value, str): + return parse_datetime(value) except ValueError: return None @@ -94,7 +94,7 @@ class Time(Scalar): try: if isinstance(value, datetime.time): return value - - return parse_time(value) + elif isinstance(value, str): + return parse_time(value) except ValueError: return None diff --git a/graphene/types/tests/test_datetime.py b/graphene/types/tests/test_datetime.py index 98e5e7ab..47841760 100644 --- a/graphene/types/tests/test_datetime.py +++ b/graphene/types/tests/test_datetime.py @@ -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,46 @@ 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: %s){ %s(in: $input) }""" % (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)