Skip to content

Commit dbe2113

Browse files
committed
dedupe interfaces from superclass
1 parent 0f6aead commit dbe2113

File tree

2 files changed

+46
-21
lines changed

2 files changed

+46
-21
lines changed

lib/graphql/schema/member/has_interfaces.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,10 @@ def interfaces(context = GraphQL::Query::NullContext)
8282
end
8383

8484
if self.is_a?(Class) && superclass <= GraphQL::Schema::Object
85-
visible_interfaces.concat(superclass.interfaces(context))
85+
# add interfaces from superclass if not already present
86+
superclass.interfaces(context).each do |sc_int|
87+
visible_interfaces << sc_int unless visible_interfaces.include?(sc_int)
88+
end
8689
end
8790

8891
visible_interfaces

spec/graphql/schema/interface_spec.rb

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -249,37 +249,55 @@ module Timestamped
249249
def timestamp; "ts"; end
250250
end
251251

252-
class Query < GraphQL::Schema::Object
252+
class BaseObject < GraphQL::Schema::Object
253+
implements Named
254+
implements Timestamped
255+
end
256+
257+
class Thing < BaseObject
253258
implements Named
254259
implements Timestamped
255260
end
256261

262+
class Query < GraphQL::Schema::Object
263+
field :thing, Thing
264+
def thing
265+
{}
266+
end
267+
end
268+
257269
query(Query)
258270
end
259271

260272
it "allows running queries on transitive interfaces" do
261-
result = TransitiveInterfaceSchema.execute("{ id name timestamp }")
262-
263-
assert_equal "id", result["data"]["id"]
264-
assert_equal "name", result["data"]["name"]
265-
assert_equal "ts", result["data"]["timestamp"]
273+
result = TransitiveInterfaceSchema.execute("{ thing { id name timestamp } }")
274+
275+
thing = result.dig("data", "thing")
276+
277+
assert_equal "id", thing["id"]
278+
assert_equal "name", thing["name"]
279+
assert_equal "ts", thing["timestamp"]
266280

267281
result2 = TransitiveInterfaceSchema.execute(<<-GRAPHQL)
268282
{
269-
...on Node { id }
270-
...on Named {
271-
nid: id name
272-
...on Node { nnid: id }
283+
thing {
284+
...on Node { id }
285+
...on Named {
286+
nid: id name
287+
...on Node { nnid: id }
288+
}
289+
... on Timestamped { tid: id timestamp }
273290
}
274-
... on Timestamped { tid: id timestamp }
275291
}
276292
GRAPHQL
293+
294+
thing2 = result2.dig("data", "thing")
277295

278-
assert_equal "id", result2["data"]["id"]
279-
assert_equal "id", result2["data"]["nid"]
280-
assert_equal "id", result2["data"]["tid"]
281-
assert_equal "name", result2["data"]["name"]
282-
assert_equal "ts", result2["data"]["timestamp"]
296+
assert_equal "id", thing2["id"]
297+
assert_equal "id", thing2["nid"]
298+
assert_equal "id", thing2["tid"]
299+
assert_equal "name", thing2["name"]
300+
assert_equal "ts", thing2["timestamp"]
283301
end
284302

285303
it "has the right structure" do
@@ -293,7 +311,11 @@ class Query < GraphQL::Schema::Object
293311
id: ID
294312
}
295313
296-
type Query implements Named & Node & Timestamped {
314+
type Query {
315+
thing: Thing
316+
}
317+
318+
type Thing implements Named & Node & Timestamped {
297319
id: ID
298320
name: String
299321
timestamp: String
@@ -309,10 +331,10 @@ class Query < GraphQL::Schema::Object
309331

310332
it "only lists each implemented interface once when introspecting" do
311333
introspection = TransitiveInterfaceSchema.as_json
312-
query_type = introspection.dig("data", "__schema", "types").find do |type|
313-
type["name"] == "Query"
334+
thing_type = introspection.dig("data", "__schema", "types").find do |type|
335+
type["name"] == "Thing"
314336
end
315-
interfaces_names = query_type["interfaces"].map { |i| i["name"] }.sort
337+
interfaces_names = thing_type["interfaces"].map { |i| i["name"] }.sort
316338

317339
assert_equal interfaces_names, ["Named", "Node", "Timestamped"]
318340
end

0 commit comments

Comments
 (0)