Skip to content

Commit ba16226

Browse files
author
Robert Mosolgo
authored
Merge pull request rmosolgo#978 from rmosolgo/fix-dynamic-field-traversal
fix(Traversal) don't apply instrumentation to Query.__type
2 parents 185b08a + 6f032d7 commit ba16226

File tree

2 files changed

+45
-4
lines changed

2 files changed

+45
-4
lines changed

lib/graphql/schema/traversal.rb

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,13 @@ def visit_fields(type_defn)
104104
end
105105

106106
def visit_field_on_type(type_defn, field_defn, dynamic_field: false)
107-
instrumented_field_defn = @field_instrumenters.reduce(field_defn) do |defn, inst|
108-
inst.instrument(type_defn, defn)
109-
end
110-
if !dynamic_field
107+
if dynamic_field
108+
# Don't apply instrumentation to dynamic fields since they're shared constants
109+
instrumented_field_defn = field_defn
110+
else
111+
instrumented_field_defn = @field_instrumenters.reduce(field_defn) do |defn, inst|
112+
inst.instrument(type_defn, defn)
113+
end
111114
@instrumented_field_map[type_defn.name][instrumented_field_defn.name] = instrumented_field_defn
112115
end
113116
@type_reference_map[instrumented_field_defn.type.unwrap.name] << instrumented_field_defn
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# frozen_string_literal: true
2+
require "spec_helper"
3+
4+
describe GraphQL::Introspection::TypeByNameField do
5+
describe "after instrumentation" do
6+
# Just make sure it returns a new object, not the original field
7+
class DupInstrumenter
8+
def self.instrument(t, f)
9+
f.redefine {
10+
resolve ->(o, a, c) { :no_op }
11+
}
12+
end
13+
end
14+
15+
class ArgAnalyzer
16+
def call(_, _, node)
17+
if node.ast_node.is_a?(GraphQL::Language::Nodes::Field)
18+
node.arguments
19+
end
20+
end
21+
end
22+
23+
let(:instrumented_schema) {
24+
# This was probably assigned earlier in the test suite, but to simulate an application, clear it.
25+
GraphQL::Introspection::TypeByNameField.arguments_class = nil
26+
27+
Dummy::Schema.redefine {
28+
instrument(:field, DupInstrumenter)
29+
query_analyzer(ArgAnalyzer.new)
30+
}
31+
}
32+
33+
it "still works with __type" do
34+
res = instrumented_schema.execute("{ __type(name: \"X\") { name } }")
35+
assert_equal({"data"=>{"__type"=>nil}}, res)
36+
end
37+
end
38+
end

0 commit comments

Comments
 (0)