Skip to content

Commit 484c33a

Browse files
authored
Merge pull request rmosolgo#4413 from rmosolgo/2.0.17-resolve-type-fix
[2.0.17] Fix returning [Type, false] from resolve_type
2 parents 96ae99b + 7e077be commit 484c33a

File tree

3 files changed

+109
-34
lines changed

3 files changed

+109
-34
lines changed

lib/graphql/schema.rb

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -785,11 +785,7 @@ def resolve_type(type, obj, ctx)
785785
end
786786

787787
if resolved_type.nil? || (resolved_type.is_a?(Module) && resolved_type.respond_to?(:kind))
788-
if resolved_value
789-
[resolved_type, resolved_value]
790-
else
791-
resolved_type
792-
end
788+
[resolved_type, resolved_value]
793789
else
794790
raise ".resolve_type should return a type definition, but got #{resolved_type.inspect} (#{resolved_type.class}) from `resolve_type(#{type}, #{obj}, #{ctx})`"
795791
end

spec/graphql/schema/union_spec.rb

Lines changed: 107 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
assert_equal "Fragment on Ensemble can't be spread inside PerformingAct", res.to_h["errors"].first["message"]
6868
end
6969

70-
describe "two-value type resolution" do
70+
describe "type resolution" do
7171
Box = Struct.new(:value)
7272

7373
class Schema < GraphQL::Schema
@@ -79,60 +79,139 @@ class B < GraphQL::Schema::Object
7979
field :b, String, method: :itself
8080
end
8181

82-
class MyUnion < GraphQL::Schema::Union
83-
possible_types A, B
82+
class C < GraphQL::Schema::Object
83+
field :c, Boolean, method: :itself
84+
end
85+
86+
class UnboxedUnion < GraphQL::Schema::Union
87+
possible_types A, C
8488

8589
def self.resolve_type(object, ctx)
86-
if object.value == "return-nil"
90+
case object
91+
when FalseClass
92+
C
93+
else
94+
A
95+
end
96+
end
97+
end
98+
99+
class BoxedUnion < GraphQL::Schema::Union
100+
possible_types A, B, C
101+
102+
def self.resolve_type(object, ctx)
103+
case object.value
104+
when "return-nil"
87105
[B, nil]
106+
when FalseClass
107+
[C, object.value]
88108
else
89109
[A, object.value]
90110
end
91111
end
92112
end
93113

94114
class Query < GraphQL::Schema::Object
95-
field :my_union, MyUnion
115+
field :boxed_union, BoxedUnion
96116

97-
def my_union
117+
def boxed_union
98118
Box.new(context[:value])
99119
end
120+
121+
field :unboxed_union, UnboxedUnion
122+
123+
def unboxed_union
124+
context[:value]
125+
end
100126
end
101127

102128
query(Query)
103129
end
104130

105-
it "can cast the object after resolving the type" do
131+
describe "two-value resolution" do
132+
it "can cast the object after resolving the type" do
106133

107-
query_str = <<-GRAPHQL
108-
{
109-
myUnion {
110-
... on A { a }
134+
query_str = <<-GRAPHQL
135+
{
136+
boxedUnion {
137+
... on A { a }
138+
}
111139
}
112-
}
113-
GRAPHQL
140+
GRAPHQL
141+
142+
res = Schema.execute(query_str, context: { value: "unwrapped" })
143+
144+
assert_equal({
145+
'data' => { 'boxedUnion' => { 'a' => 'unwrapped' } }
146+
}, res.to_h)
147+
end
148+
149+
it "uses `false` when returned from resolve_type" do
150+
query_str = <<-GRAPHQL
151+
{
152+
boxedUnion {
153+
... on C { c }
154+
}
155+
}
156+
GRAPHQL
157+
158+
res = Schema.execute(query_str, context: { value: false })
114159

115-
res = Schema.execute(query_str, context: { value: "unwrapped" })
160+
assert_equal({
161+
'data' => { 'boxedUnion' => { 'c' => false } }
162+
}, res.to_h)
163+
end
116164

117-
assert_equal({
118-
'data' => { 'myUnion' => { 'a' => 'unwrapped' } }
119-
}, res.to_h)
165+
it "uses `nil` when returned from resolve_type" do
166+
query_str = <<-GRAPHQL
167+
{
168+
boxedUnion {
169+
... on B { b }
170+
}
171+
}
172+
GRAPHQL
173+
174+
res = Schema.execute(query_str, context: { value: "return-nil" })
175+
176+
assert_equal({
177+
'data' => { 'boxedUnion' => { 'b' => nil } }
178+
}, res.to_h)
179+
end
120180
end
121181

122-
it "uses `nil` when returned from resolve_type" do
123-
query_str = <<-GRAPHQL
124-
{
125-
myUnion {
126-
... on B { b }
182+
describe "single-value resolution" do
183+
it "can cast the object after resolving the type" do
184+
185+
query_str = <<-GRAPHQL
186+
{
187+
unboxedUnion {
188+
... on A { a }
189+
}
127190
}
128-
}
129-
GRAPHQL
191+
GRAPHQL
130192

131-
res = Schema.execute(query_str, context: { value: "return-nil" })
193+
res = Schema.execute(query_str, context: { value: "string" })
132194

133-
assert_equal({
134-
'data' => { 'myUnion' => { 'b' => nil } }
135-
}, res.to_h)
195+
assert_equal({
196+
'data' => { 'unboxedUnion' => { 'a' => 'string' } }
197+
}, res.to_h)
198+
end
199+
200+
it "works with literal false values" do
201+
query_str = <<-GRAPHQL
202+
{
203+
unboxedUnion {
204+
... on C { c }
205+
}
206+
}
207+
GRAPHQL
208+
209+
res = Schema.execute(query_str, context: { value: false })
210+
211+
assert_equal({
212+
'data' => { 'unboxedUnion' => { 'c' => false } }
213+
}, res.to_h)
214+
end
136215
end
137216
end
138217
end

spec/integration/rails/graphql/schema_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
describe "when the return value is nil" do
6262
it "returns nil" do
6363
result = relay_schema.resolve_type(123, nil, GraphQL::Query::NullContext)
64-
assert_equal(nil, result)
64+
assert_equal([nil, nil], result)
6565
end
6666
end
6767

0 commit comments

Comments
 (0)