Skip to content

Commit 6ccd54e

Browse files
author
Mathieu Asselin
committed
fixed issue graphql-dotnet#286 - UTC Dates in Mutation Input fields are broken
1 parent df11b63 commit 6ccd54e

File tree

2 files changed

+208
-3
lines changed

2 files changed

+208
-3
lines changed

src/GraphQL.Tests/Execution/MutationTests.cs

Lines changed: 202 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,21 @@ public class NumberHolder
1212
public int TheNumber { get; set; }
1313
}
1414

15+
public class DateTimeHolder
16+
{
17+
public DateTime TheDateTime { get; set; }
18+
}
19+
1520
public class Root
1621
{
17-
public Root(int number)
22+
public Root(int number, DateTime dateTime)
1823
{
1924
NumberHolder = new NumberHolder {TheNumber = number};
25+
DateTimeHolder = new DateTimeHolder { TheDateTime = dateTime };
2026
}
2127

2228
public NumberHolder NumberHolder { get; private set; }
29+
public DateTimeHolder DateTimeHolder { get; private set; }
2330

2431
public NumberHolder ImmediatelyChangeTheNumber(int number)
2532
{
@@ -43,6 +50,29 @@ public async Task<NumberHolder> PromiseAndFailToChangeTheNumberAsync(int number)
4350
await Task.Delay(100).ConfigureAwait(false);
4451
throw new InvalidOperationException("Cannot change the number");
4552
}
53+
54+
public DateTimeHolder ImmediatelyChangeTheDateTime(DateTime dateTime)
55+
{
56+
DateTimeHolder.TheDateTime = dateTime;
57+
return DateTimeHolder;
58+
}
59+
60+
public Task<DateTimeHolder> PromiseToChangeTheDateTimeAsync(DateTime dateTime)
61+
{
62+
DateTimeHolder.TheDateTime = dateTime;
63+
return Task.FromResult(DateTimeHolder);
64+
}
65+
66+
public DateTimeHolder FailToChangeTheDateTime(DateTime dateTime)
67+
{
68+
throw new InvalidOperationException("Cannot change the datetime");
69+
}
70+
71+
public async Task<DateTimeHolder> PromiseAndFailToChangeTheDateTimeAsync(DateTime dateTime)
72+
{
73+
await Task.Delay(100).ConfigureAwait(false);
74+
throw new InvalidOperationException("Cannot change the datetime");
75+
}
4676
}
4777

4878
public class MutationSchema : Schema
@@ -63,12 +93,22 @@ public NumberHolderType()
6393
}
6494
}
6595

96+
public class DateTimeHolderType : ObjectGraphType
97+
{
98+
public DateTimeHolderType()
99+
{
100+
Name = "DateTimeHolder";
101+
Field<DateGraphType>("theDateTime");
102+
}
103+
}
104+
66105
public class MutationQuery : ObjectGraphType
67106
{
68107
public MutationQuery()
69108
{
70109
Name = "Query";
71110
Field<NumberHolderType>("numberHolder");
111+
Field<DateTimeHolderType>("dateTimeHolder");
72112
}
73113
}
74114

@@ -145,6 +185,70 @@ public MutationChange()
145185
return root.PromiseAndFailToChangeTheNumberAsync(change);
146186
}
147187
);
188+
189+
Field<DateTimeHolderType>(
190+
"immediatelyChangeTheDateTime",
191+
arguments: new QueryArguments(
192+
new QueryArgument<DateGraphType>
193+
{
194+
Name = "newDateTime"
195+
}
196+
),
197+
resolve: context =>
198+
{
199+
var root = context.Source as Root;
200+
var change = context.GetArgument<DateTime>("newDateTime");
201+
return root.ImmediatelyChangeTheDateTime(change);
202+
}
203+
);
204+
205+
Field<DateTimeHolderType>(
206+
"promiseToChangeTheDateTime",
207+
arguments: new QueryArguments(
208+
new QueryArgument<DateGraphType>
209+
{
210+
Name = "newDateTime"
211+
}
212+
),
213+
resolve: context =>
214+
{
215+
var root = context.Source as Root;
216+
var change = context.GetArgument<DateTime>("newDateTime");
217+
return root.PromiseToChangeTheDateTimeAsync(change);
218+
}
219+
);
220+
221+
Field<DateTimeHolderType>(
222+
"failToChangeTheDateTime",
223+
arguments: new QueryArguments(
224+
new QueryArgument<DateGraphType>
225+
{
226+
Name = "newDateTime"
227+
}
228+
),
229+
resolve: context =>
230+
{
231+
var root = context.Source as Root;
232+
var change = context.GetArgument<DateTime>("newDateTime");
233+
return root.FailToChangeTheDateTime(change);
234+
}
235+
);
236+
237+
Field<DateTimeHolderType>(
238+
"promiseAndFailToChangeTheDateTime",
239+
arguments: new QueryArguments(
240+
new QueryArgument<DateGraphType>
241+
{
242+
Name = "newDateTime"
243+
}
244+
),
245+
resolve: context =>
246+
{
247+
var root = context.Source as Root;
248+
var change = context.GetArgument<DateTime>("newDateTime");
249+
return root.PromiseAndFailToChangeTheDateTimeAsync(change);
250+
}
251+
);
148252
}
149253
}
150254

@@ -192,7 +296,7 @@ mutation M {
192296
}
193297
}";
194298

195-
AssertQuerySuccess(query, expected, root: new Root(6));
299+
AssertQuerySuccess(query, expected, root: new Root(6, DateTime.Now));
196300
}
197301

198302
[Fact]
@@ -239,10 +343,105 @@ mutation M {
239343
'sixth': null
240344
}";
241345

242-
var result = AssertQueryWithErrors(query, expected, root: new Root(6), expectedErrorCount: 2);
346+
var result = AssertQueryWithErrors(query, expected, root: new Root(6, DateTime.Now), expectedErrorCount: 2);
243347
result.Errors.First().InnerException.Message.ShouldBe("Cannot change the number");
244348
var last = result.Errors.Last();
245349
last.InnerException.GetBaseException().Message.ShouldBe("Cannot change the number");
246350
}
351+
352+
[Fact]
353+
public void evaluates_datetime_mutations_serially()
354+
{
355+
var query = @"
356+
mutation M {
357+
first: immediatelyChangeTheDateTime(newDateTime: ""2017-01-27T15:19:53.123Z"") {
358+
theDateTime
359+
}
360+
second: immediatelyChangeTheDateTime(newDateTime: ""2017-02-27T15:19:53.123Z"") {
361+
theDateTime
362+
}
363+
third: immediatelyChangeTheDateTime(newDateTime: ""2017-03-27T15:19:53.123Z"") {
364+
theDateTime
365+
}
366+
fourth: immediatelyChangeTheDateTime(newDateTime: ""2017-04-27T15:19:53.123-5:00"") {
367+
theDateTime
368+
}
369+
fifth: immediatelyChangeTheDateTime(newDateTime: ""2017-05-27T15:19:53.123+2:00"") {
370+
theDateTime
371+
}
372+
}
373+
";
374+
375+
var expected = @"
376+
{
377+
'first': {
378+
'theDateTime': ""2017-01-27T15:19:53.123Z""
379+
},
380+
'second': {
381+
'theDateTime': ""2017-02-27T15:19:53.123Z""
382+
},
383+
'third': {
384+
'theDateTime': ""2017-03-27T15:19:53.123Z""
385+
},
386+
'fourth': {
387+
'theDateTime': ""2017-04-27T20:19:53.123Z""
388+
},
389+
'fifth': {
390+
'theDateTime': ""2017-05-27T13:19:53.123Z""
391+
}
392+
}";
393+
394+
AssertQuerySuccess(query, expected, root: new Root(6, DateTime.Now));
395+
}
396+
397+
[Fact]
398+
public void evaluates_datetime_mutations_correctly_in_the_presense_of_a_failed_mutation()
399+
{
400+
var query = @"
401+
mutation M {
402+
first: immediatelyChangeTheDateTime(newDateTime: ""2017-01-27T15:19:53.123Z"") {
403+
theDateTime
404+
}
405+
second: promiseToChangeTheDateTime(newDateTime: ""2017-02-27T15:19:53.123Z"") {
406+
theDateTime
407+
}
408+
third: failToChangeTheDateTime(newDateTime: ""2017-03-27T15:19:53.123Z"") {
409+
theDateTime
410+
}
411+
fourth: promiseToChangeTheDateTime(newDateTime: ""2017-04-27T15:19:53.123-5:00"") {
412+
theDateTime
413+
}
414+
fifth: immediatelyChangeTheDateTime(newDateTime: ""2017-05-27T15:19:53.123+2:00"") {
415+
theDateTime
416+
}
417+
sixth: promiseAndFailToChangeTheDateTime(newDateTime: ""2017-06-27T15:19:53.123Z"") {
418+
theDateTime
419+
}
420+
}
421+
";
422+
423+
var expected = @"
424+
{
425+
'first': {
426+
'theDateTime': ""2017-01-27T15:19:53.123Z""
427+
},
428+
'second': {
429+
'theDateTime': ""2017-02-27T15:19:53.123Z""
430+
},
431+
'third': null,
432+
'fourth': {
433+
'theDateTime': ""2017-04-27T20:19:53.123""
434+
},
435+
'fifth': {
436+
'theDateTime': ""2017-05-27T13:19:53.123""
437+
},
438+
'sixth': null
439+
}";
440+
441+
var result = AssertQueryWithErrors(query, expected, root: new Root(6, DateTime.Now), expectedErrorCount: 2);
442+
result.Errors.First().InnerException.Message.ShouldBe("Cannot change the datetime");
443+
var last = result.Errors.Last();
444+
last.InnerException.GetBaseException().Message.ShouldBe("Cannot change the datetime");
445+
}
247446
}
248447
}

src/GraphQL/ObjectExtensions.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections;
33
using System.Collections.Generic;
4+
using System.Globalization;
45
using System.Linq;
56
using System.Reflection;
67
using GraphQL.Conversion;
@@ -124,6 +125,11 @@ public static object ConvertValue(object value, Type fieldType)
124125
{
125126
if (value == null) return null;
126127

128+
if (fieldType == typeof(DateTime) && value is DateTime)
129+
{
130+
return value;
131+
}
132+
127133
var text = value.ToString();
128134
return _conversions.Value.Convert(fieldType, text);
129135
}

0 commit comments

Comments
 (0)