@@ -271,6 +271,36 @@ def resolve
271
271
end
272
272
end
273
273
274
+ class MutationWithNullableLoadsArgument < GraphQL ::Schema ::Mutation
275
+ argument :label_id , ID , required : false , loads : HasValue
276
+ argument :label_ids , [ ID ] , required : false , loads : HasValue
277
+
278
+ field :inputs , String , null : false
279
+
280
+ def resolve ( **inputs )
281
+ {
282
+ inputs : JSON . dump ( inputs )
283
+ }
284
+ end
285
+ end
286
+
287
+ class MutationWithRequiredLoadsArgument < GraphQL ::Schema ::Mutation
288
+ argument :label_id , ID , required : true , loads : HasValue
289
+
290
+ field :inputs , String , null : false
291
+
292
+ def resolve ( **inputs )
293
+ {
294
+ inputs : JSON . dump ( inputs )
295
+ }
296
+ end
297
+ end
298
+
299
+ class Mutation < GraphQL ::Schema ::Object
300
+ field :mutation_with_nullable_loads_argument , mutation : MutationWithNullableLoadsArgument
301
+ field :mutation_with_required_loads_argument , mutation : MutationWithRequiredLoadsArgument
302
+ end
303
+
274
304
class Query < GraphQL ::Schema ::Object
275
305
class CustomField < GraphQL ::Schema ::Field
276
306
def resolve_field ( *args )
@@ -312,8 +342,17 @@ def resolve_field(*args)
312
342
313
343
class Schema < GraphQL ::Schema
314
344
query ( Query )
345
+ mutation ( Mutation )
315
346
lazy_resolve LazyBlock , :value
316
347
orphan_types IntegerWrapper
348
+
349
+ def object_from_id ( id , ctx )
350
+ if id == "invalid"
351
+ nil
352
+ else
353
+ 1
354
+ end
355
+ end
317
356
end
318
357
end
319
358
@@ -535,6 +574,41 @@ def add_error_assertions(field_name, description)
535
574
# (100 + 8) * 3
536
575
assert_equal [ 27 , 54 , 324 ] , res [ "data" ] [ "prepResolver9Array" ] . map { |v | v [ "value" ] }
537
576
end
577
+
578
+ it "preserves `nil` when nullable argument is provided `null`" do
579
+ res = exec_query ( "mutation { mutationWithNullableLoadsArgument(labelId: null) { inputs } }" )
580
+
581
+ assert_equal nil , res [ "errors" ]
582
+ assert_equal '{"label":null}' , res [ "data" ] [ "mutationWithNullableLoadsArgument" ] [ "inputs" ]
583
+ end
584
+
585
+ it "preserves `nil` when nullable list argument is provided `null`" do
586
+ res = exec_query ( "mutation { mutationWithNullableLoadsArgument(labelIds: null) { inputs } }" )
587
+
588
+ assert_equal nil , res [ "errors" ]
589
+ assert_equal '{"labels":null}' , res [ "data" ] [ "mutationWithNullableLoadsArgument" ] [ "inputs" ]
590
+ end
591
+
592
+ it "omits omitted nullable argument" do
593
+ res = exec_query ( "mutation { mutationWithNullableLoadsArgument { inputs } }" )
594
+
595
+ assert_equal nil , res [ "errors" ]
596
+ assert_equal "{}" , res [ "data" ] [ "mutationWithNullableLoadsArgument" ] [ "inputs" ]
597
+ end
598
+
599
+ it "returns an error when nullable argument is provided an invalid value" do
600
+ res = exec_query ( 'mutation { mutationWithNullableLoadsArgument(labelId: "invalid") { inputs } }' )
601
+
602
+ assert res [ "errors" ]
603
+ assert_equal 'No object found for `labelId: "invalid"`' , res [ "errors" ] [ 0 ] [ "message" ]
604
+ end
605
+
606
+ it "returns an error when a non-nullable argument is provided an invalid value" do
607
+ res = exec_query ( 'mutation { mutationWithRequiredLoadsArgument(labelId: "invalid") { inputs } }' )
608
+
609
+ assert res [ "errors" ]
610
+ assert_equal 'No object found for `labelId: "invalid"`' , res [ "errors" ] [ 0 ] [ "message" ]
611
+ end
538
612
end
539
613
end
540
614
end
0 commit comments