Skip to content

Commit 6aedea6

Browse files
committed
Fix inheriting visibility with preload: true
1 parent 0e092de commit 6aedea6

File tree

4 files changed

+25
-15
lines changed

4 files changed

+25
-15
lines changed

lib/graphql/schema/visibility.rb

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@ def self.use(schema, dynamic: false, profiles: EmptyObjects::EMPTY_HASH, preload
1818
ctx.freeze
1919
}
2020
schema.visibility = self.new(schema, dynamic: dynamic, preload: preload, profiles: profiles, migration_errors: migration_errors)
21-
if preload
22-
schema.visibility.preload
23-
end
2421
end
2522

2623
def initialize(schema, dynamic:, preload:, profiles:, migration_errors:)
@@ -43,6 +40,9 @@ def initialize(schema, dynamic:, preload:, profiles:, migration_errors:)
4340
@types = nil
4441
@all_references = nil
4542
@loaded_all = false
43+
if preload
44+
self.preload
45+
end
4646
end
4747

4848
def all_directives
@@ -153,12 +153,12 @@ def profile_for(context)
153153
visibility_profile = context[:visibility_profile]
154154
if @profiles.include?(visibility_profile)
155155
profile_ctx = @profiles[visibility_profile]
156-
@cached_profiles[visibility_profile] ||= @schema.visibility_profile_class.new(name: visibility_profile, context: profile_ctx, schema: @schema)
156+
@cached_profiles[visibility_profile] ||= @schema.visibility_profile_class.new(name: visibility_profile, context: profile_ctx, schema: @schema, visibility: self)
157157
elsif @dynamic
158158
if context.is_a?(Query::NullContext)
159159
top_level_profile
160160
else
161-
@schema.visibility_profile_class.new(context: context, schema: @schema)
161+
@schema.visibility_profile_class.new(context: context, schema: @schema, visibility: self)
162162
end
163163
elsif !context.key?(:visibility_profile)
164164
raise ArgumentError, "#{@schema} expects a visibility profile, but `visibility_profile:` wasn't passed. Provide a `visibility_profile:` value or add `dynamic: true` to your visibility configuration."
@@ -168,7 +168,7 @@ def profile_for(context)
168168
elsif context.is_a?(Query::NullContext)
169169
top_level_profile
170170
else
171-
@schema.visibility_profile_class.new(context: context, schema: @schema)
171+
@schema.visibility_profile_class.new(context: context, schema: @schema, visibility: self)
172172
end
173173
end
174174

@@ -181,7 +181,7 @@ def top_level_profile(refresh: false)
181181
if refresh
182182
@top_level_profile = nil
183183
end
184-
@top_level_profile ||= @schema.visibility_profile_class.new(context: Query::NullContext.instance, schema: @schema)
184+
@top_level_profile ||= @schema.visibility_profile_class.new(context: Query::NullContext.instance, schema: @schema, visibility: self)
185185
end
186186

187187
private

lib/graphql/schema/visibility/migration.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,10 @@ def humanize(val)
7676
end
7777
end
7878

79-
def initialize(context:, schema:, name: nil)
79+
def initialize(context:, schema:, name: nil, visibility:)
8080
@name = name
8181
@skip_error = context[:skip_visibility_migration_error] || context.is_a?(Query::NullContext) || context.is_a?(Hash)
82-
@profile_types = GraphQL::Schema::Visibility::Profile.new(context: context, schema: schema)
82+
@profile_types = GraphQL::Schema::Visibility::Profile.new(context: context, schema: schema, visibility: visibility)
8383
if !@skip_error
8484
context[:visibility_migration_running] = true
8585
warden_ctx_vals = context.to_h.dup

lib/graphql/schema/visibility/profile.rb

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,11 @@ def self.null_profile(context:, schema:)
3131
# @return [Symbol, nil]
3232
attr_reader :name
3333

34-
def initialize(name: nil, context:, schema:)
34+
def initialize(name: nil, context:, schema:, visibility:)
3535
@name = name
3636
@context = context
3737
@schema = schema
38+
@visibility = visibility
3839
@all_types = {}
3940
@all_types_loaded = false
4041
@unvisited_types = []
@@ -122,7 +123,7 @@ def field_on_visible_interface?(field, owner)
122123
end
123124

124125
def type(type_name)
125-
t = @schema.visibility.get_type(type_name) # rubocop:disable Development/ContextIsPassedCop
126+
t = @visibility.get_type(type_name) # rubocop:disable Development/ContextIsPassedCop
126127
if t
127128
if t.is_a?(Array)
128129
vis_t = nil
@@ -250,8 +251,8 @@ def directive_exists?(dir_name)
250251
end
251252

252253
def directives
253-
@all_directives ||= @schema.visibility.all_directives.select { |dir|
254-
@cached_visible[dir] && @schema.visibility.all_references[dir].any? { |ref| ref == true || (@cached_visible[ref] && referenced?(ref)) }
254+
@all_directives ||= @visibility.all_directives.select { |dir|
255+
@cached_visible[dir] && @visibility.all_references[dir].any? { |ref| ref == true || (@cached_visible[ref] && referenced?(ref)) }
255256
}
256257
end
257258

@@ -322,7 +323,7 @@ def load_all_types
322323
end
323324

324325
def referenced?(type_defn)
325-
@schema.visibility.all_references[type_defn].any? do |ref|
326+
@visibility.all_references[type_defn].any? do |ref|
326327
case ref
327328
when GraphQL::Schema::Argument
328329
@cached_visible_arguments[ref.owner][ref]
@@ -340,7 +341,7 @@ def possible_types_for(type)
340341
case type.kind.name
341342
when "INTERFACE"
342343
pts = []
343-
@schema.visibility.all_interface_type_memberships[type].each do |(itm, impl_type)|
344+
@visibility.all_interface_type_memberships[type].each do |(itm, impl_type)|
344345
if @cached_visible[itm] && @cached_visible[impl_type] && referenced?(impl_type)
345346
pts << impl_type
346347
end

spec/graphql/schema/visibility_spec.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,15 @@ def exec_query(...)
121121
res = exec_query("{ products { name costOfGoodsSold } }", visibility_profile: :admin)
122122
assert_equal [{ "name" => "Pool Noodle", "costOfGoodsSold" => 5}], res["data"]["products"]
123123
end
124+
125+
it "works with subclasses" do
126+
child_schema = Class.new(VisSchema) do
127+
query(VisSchema::Query)
128+
end
129+
res = child_schema.execute("{ products { name } }", visibility_profile: :public)
130+
assert_equal ["Pool Noodle"], res["data"]["products"].map { |p| p["name"] }
131+
assert_equal :public, res.context.types.name
132+
end
124133
end
125134

126135
describe "preloading profiles" do

0 commit comments

Comments
 (0)