diff --git a/lib/graphql/query.rb b/lib/graphql/query.rb index 8aa1d75d90..3f55f5f5d7 100644 --- a/lib/graphql/query.rb +++ b/lib/graphql/query.rb @@ -96,23 +96,23 @@ def selected_operation_name # @param max_depth [Numeric] the maximum number of nested selections allowed for this query (falls back to schema-level value) # @param max_complexity [Numeric] the maximum field complexity for this query (falls back to schema-level value) # @param visibility_profile [Symbol] - def initialize(schema, query_string = nil, query: nil, document: nil, context: nil, variables: nil, validate: true, static_validator: nil, visibility_profile: nil, subscription_topic: nil, operation_name: nil, root_value: nil, max_depth: schema.max_depth, max_complexity: schema.max_complexity, warden: nil, use_schema_subset: nil) + def initialize(schema, query_string = nil, query: nil, document: nil, context: nil, variables: nil, validate: true, static_validator: nil, visibility_profile: nil, subscription_topic: nil, operation_name: nil, root_value: nil, max_depth: schema.max_depth, max_complexity: schema.max_complexity, warden: nil, use_visibility_profile: nil) # Even if `variables: nil` is passed, use an empty hash for simpler logic variables ||= {} @schema = schema @context = schema.context_class.new(query: self, values: context) - if use_schema_subset.nil? - use_schema_subset = warden ? false : schema.use_schema_visibility? + if use_visibility_profile.nil? + use_visibility_profile = warden ? false : schema.use_visibility_profile? end @visibility_profile = visibility_profile - if use_schema_subset - @schema_subset = @schema.visibility.profile_for(@context, visibility_profile) + if use_visibility_profile + @visibility_profile = @schema.visibility.profile_for(@context, visibility_profile) @warden = Schema::Warden::NullWarden.new(context: @context, schema: @schema) else - @schema_subset = nil + @visibility_profile = nil @warden = warden end @@ -375,7 +375,7 @@ def root_type_for_operation(op_type) end def types - @schema_subset || warden.schema_subset + @visibility_profile || warden.visibility_profile end # @param abstract_type [GraphQL::UnionType, GraphQL::InterfaceType] diff --git a/lib/graphql/query/null_context.rb b/lib/graphql/query/null_context.rb index 814d981bd2..96d270c73b 100644 --- a/lib/graphql/query/null_context.rb +++ b/lib/graphql/query/null_context.rb @@ -28,7 +28,7 @@ def initialize end def types - @types ||= GraphQL::Schema::Warden::SchemaSubset.new(@warden) + @types ||= Schema::Warden::VisibilityProfile.new(@warden) end end end diff --git a/lib/graphql/schema.rb b/lib/graphql/schema.rb index 484f4cf452..ed64a330af 100644 --- a/lib/graphql/schema.rb +++ b/lib/graphql/schema.rb @@ -336,8 +336,8 @@ def plugins # @return [Hash Class>] A dictionary of type classes by their GraphQL name # @see get_type Which is more efficient for finding _one type_ by name, because it doesn't merge hashes. def types(context = GraphQL::Query::NullContext.instance) - if use_schema_visibility? - types = Visibility::Subset.from_context(context, self) + if use_visibility_profile? + types = Visibility::Profile.from_context(context, self) return types.all_types_h end all_types = non_introspection_types.merge(introspection_system.types) @@ -366,18 +366,18 @@ def types(context = GraphQL::Query::NullContext.instance) # @param type_name [String] # @param context [GraphQL::Query::Context] Used for filtering definitions at query-time - # @param use_schema_visibility Private, for migration to {Schema::Visibility} + # @param use_visibility_profile Private, for migration to {Schema::Visibility} # @return [Module, nil] A type, or nil if there's no type called `type_name` - def get_type(type_name, context = GraphQL::Query::NullContext.instance, use_schema_visibility = use_schema_visibility?) - if use_schema_visibility - return Visibility::Subset.from_context(context, self).type(type_name) + def get_type(type_name, context = GraphQL::Query::NullContext.instance, use_visibility_profile = use_visibility_profile?) + if use_visibility_profile + return Visibility::Profile.from_context(context, self).type(type_name) end local_entry = own_types[type_name] type_defn = case local_entry when nil nil when Array - if context.respond_to?(:types) && context.types.is_a?(GraphQL::Schema::Visibility::Subset) + if context.respond_to?(:types) && context.types.is_a?(GraphQL::Schema::Visibility::Profile) local_entry else visible_t = nil @@ -403,7 +403,7 @@ def get_type(type_name, context = GraphQL::Query::NullContext.instance, use_sche type_defn || introspection_system.types[type_name] || # todo context-specific introspection? - (superclass.respond_to?(:get_type) ? superclass.get_type(type_name, context, use_schema_visibility) : nil) + (superclass.respond_to?(:get_type) ? superclass.get_type(type_name, context, use_visibility_profile) : nil) end # @return [Boolean] Does this schema have _any_ definition for a type named `type_name`, regardless of visibility? @@ -435,7 +435,7 @@ def query(new_query_object = nil, &lazy_load_block) if @query_object dup_defn = new_query_object || yield raise GraphQL::Error, "Second definition of `query(...)` (#{dup_defn.inspect}) is invalid, already configured with #{@query_object.inspect}" - elsif use_schema_visibility? + elsif use_visibility_profile? @query_object = block_given? ? lazy_load_block : new_query_object else @query_object = new_query_object || lazy_load_block.call @@ -454,7 +454,7 @@ def mutation(new_mutation_object = nil, &lazy_load_block) if @mutation_object dup_defn = new_mutation_object || yield raise GraphQL::Error, "Second definition of `mutation(...)` (#{dup_defn.inspect}) is invalid, already configured with #{@mutation_object.inspect}" - elsif use_schema_visibility? + elsif use_visibility_profile? @mutation_object = block_given? ? lazy_load_block : new_mutation_object else @mutation_object = new_mutation_object || lazy_load_block.call @@ -473,7 +473,7 @@ def subscription(new_subscription_object = nil, &lazy_load_block) if @subscription_object dup_defn = new_subscription_object || yield raise GraphQL::Error, "Second definition of `subscription(...)` (#{dup_defn.inspect}) is invalid, already configured with #{@subscription_object.inspect}" - elsif use_schema_visibility? + elsif use_visibility_profile? @subscription_object = block_given? ? lazy_load_block : new_subscription_object add_subscription_extension_if_necessary else @@ -507,7 +507,7 @@ def root_type_for_operation(operation) end def root_types - if use_schema_visibility? + if use_visibility_profile? [query, mutation, subscription].compact else @root_types @@ -526,24 +526,27 @@ def warden_class attr_writer :warden_class - def subset_class - if defined?(@subset_class) - @subset_class - elsif superclass.respond_to?(:subset_class) - superclass.subset_class + # @api private + def visibility_profile_class + if defined?(@visibility_profile_class) + @visibility_profile_class + elsif superclass.respond_to?(:visibility_profile_class) + superclass.visibility_profile_class else - GraphQL::Schema::Visibility::Subset + GraphQL::Schema::Visibility::Profile end end - attr_writer :subset_class, :use_schema_visibility + # @api private + attr_writer :visibility_profile_class, :use_visibility_profile + # @api private attr_accessor :visibility - - def use_schema_visibility? - if defined?(@use_schema_visibility) - @use_schema_visibility - elsif superclass.respond_to?(:use_schema_visibility?) - superclass.use_schema_visibility? + # @api private + def use_visibility_profile? + if defined?(@use_visibility_profile) + @use_visibility_profile + elsif superclass.respond_to?(:use_visibility_profile?) + superclass.use_visibility_profile? else false end @@ -551,15 +554,15 @@ def use_schema_visibility? # @param type [Module] The type definition whose possible types you want to see # @param context [GraphQL::Query::Context] used for filtering visible possible types at runtime - # @param use_schema_visibility Private, for migration to {Schema::Visibility} + # @param use_visibility_profile Private, for migration to {Schema::Visibility} # @return [Hash] All possible types, if no `type` is given. # @return [Array] Possible types for `type`, if it's given. - def possible_types(type = nil, context = GraphQL::Query::NullContext.instance, use_schema_visibility = use_schema_visibility?) - if use_schema_visibility + def possible_types(type = nil, context = GraphQL::Query::NullContext.instance, use_visibility_profile = use_visibility_profile?) + if use_visibility_profile if type - return Visibility::Subset.from_context(context, self).possible_types(type) + return Visibility::Profile.from_context(context, self).possible_types(type) else - raise "Schema.possible_types is not implemented for `use_schema_visibility?`" + raise "Schema.possible_types is not implemented for `use_visibility_profile?`" end end if type @@ -579,7 +582,7 @@ def possible_types(type = nil, context = GraphQL::Query::NullContext.instance, u introspection_system.possible_types[type] || ( superclass.respond_to?(:possible_types) ? - superclass.possible_types(type, context, use_schema_visibility) : + superclass.possible_types(type, context, use_visibility_profile) : EMPTY_ARRAY ) end @@ -935,7 +938,7 @@ def orphan_types(*new_orphan_types) To add other types to your schema, you might want `extra_types`: https://graphql-ruby.org/schema/definition.html#extra-types ERR end - add_type_and_traverse(new_orphan_types, root: false) unless use_schema_visibility? + add_type_and_traverse(new_orphan_types, root: false) unless use_visibility_profile? own_orphan_types.concat(new_orphan_types.flatten) end @@ -1078,7 +1081,7 @@ def inherited(child_class) end child_class.singleton_class.prepend(ResolveTypeWithType) - if use_schema_visibility? + if use_visibility_profile? vis = self.visibility child_class.visibility = vis.dup_for(child_class) end @@ -1199,7 +1202,7 @@ def directives(*new_directives) # @param new_directive [Class] # @return void def directive(new_directive) - if use_schema_visibility? + if use_visibility_profile? own_directives[new_directive.graphql_name] = new_directive else add_type_and_traverse(new_directive, root: false) diff --git a/lib/graphql/schema/member/has_arguments.rb b/lib/graphql/schema/member/has_arguments.rb index 8548166fa9..126c406ab8 100644 --- a/lib/graphql/schema/member/has_arguments.rb +++ b/lib/graphql/schema/member/has_arguments.rb @@ -135,7 +135,7 @@ def all_argument_definitions def get_argument(argument_name, context = GraphQL::Query::NullContext.instance) warden = Warden.from_context(context) - skip_visible = context.respond_to?(:types) && context.types.is_a?(GraphQL::Schema::Visibility::Subset) + skip_visible = context.respond_to?(:types) && context.types.is_a?(GraphQL::Schema::Visibility::Profile) for ancestor in ancestors if ancestor.respond_to?(:own_arguments) && (a = ancestor.own_arguments[argument_name]) && @@ -210,7 +210,7 @@ def all_argument_definitions # @return [GraphQL::Schema::Argument, nil] Argument defined on this thing, fetched by name. def get_argument(argument_name, context = GraphQL::Query::NullContext.instance) warden = Warden.from_context(context) - if (arg_config = own_arguments[argument_name]) && ((context.respond_to?(:types) && context.types.is_a?(GraphQL::Schema::Visibility::Subset)) || (visible_arg = Warden.visible_entry?(:visible_argument?, arg_config, context, warden))) + if (arg_config = own_arguments[argument_name]) && ((context.respond_to?(:types) && context.types.is_a?(GraphQL::Schema::Visibility::Profile)) || (visible_arg = Warden.visible_entry?(:visible_argument?, arg_config, context, warden))) visible_arg || arg_config elsif defined?(@resolver_class) && @resolver_class @resolver_class.get_field_argument(argument_name, context) diff --git a/lib/graphql/schema/member/has_fields.rb b/lib/graphql/schema/member/has_fields.rb index da7dcd16d5..3a5065500f 100644 --- a/lib/graphql/schema/member/has_fields.rb +++ b/lib/graphql/schema/member/has_fields.rb @@ -99,7 +99,7 @@ def all_field_definitions module InterfaceMethods def get_field(field_name, context = GraphQL::Query::NullContext.instance) warden = Warden.from_context(context) - skip_visible = context.respond_to?(:types) && context.types.is_a?(GraphQL::Schema::Visibility::Subset) + skip_visible = context.respond_to?(:types) && context.types.is_a?(GraphQL::Schema::Visibility::Profile) for ancestor in ancestors if ancestor.respond_to?(:own_fields) && (f_entry = ancestor.own_fields[field_name]) && @@ -135,7 +135,7 @@ def get_field(field_name, context = GraphQL::Query::NullContext.instance) # Objects need to check that the interface implementation is visible, too warden = Warden.from_context(context) ancs = ancestors - skip_visible = context.respond_to?(:types) && context.types.is_a?(GraphQL::Schema::Visibility::Subset) + skip_visible = context.respond_to?(:types) && context.types.is_a?(GraphQL::Schema::Visibility::Profile) i = 0 while (ancestor = ancs[i]) if ancestor.respond_to?(:own_fields) && diff --git a/lib/graphql/schema/visibility.rb b/lib/graphql/schema/visibility.rb index 6d4c6c7b2c..972c2d0ed7 100644 --- a/lib/graphql/schema/visibility.rb +++ b/lib/graphql/schema/visibility.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true -require "graphql/schema/visibility/subset" +require "graphql/schema/visibility/profile" require "graphql/schema/visibility/migration" module GraphQL @@ -17,9 +17,9 @@ def self.use(schema, dynamic: false, profiles: EmptyObjects::EMPTY_ARRAY, preloa def initialize(schema, dynamic:, preload:, profiles:, migration_errors:) @schema = schema - schema.use_schema_visibility = true + schema.use_visibility_profile = true if migration_errors - schema.subset_class = Migration + schema.visibility_profile_class = Migration end @profiles = profiles @cached_profiles = {} @@ -57,17 +57,17 @@ def profile_for(context, visibility_profile) if @profiles.any? if visibility_profile.nil? if @dynamic - @schema.subset_class.new(context: context, schema: @schema) + @schema.visibility_profile_class.new(context: context, schema: @schema) elsif @profiles.any? 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." end elsif !@profiles.include?(visibility_profile) raise ArgumentError, "`#{visibility_profile.inspect}` isn't allowed for `visibility_profile:` (must be one of #{@profiles.keys.map(&:inspect).join(", ")}). Or, add `#{visibility_profile.inspect}` to the list of profiles in the schema definition." else - @cached_profiles[visibility_profile] ||= @schema.subset_class.new(name: visibility_profile, context: context, schema: @schema) + @cached_profiles[visibility_profile] ||= @schema.visibility_profile_class.new(name: visibility_profile, context: context, schema: @schema) end else - @schema.subset_class.new(context: context, schema: @schema) + @schema.visibility_profile_class.new(context: context, schema: @schema) end end end diff --git a/lib/graphql/schema/visibility/migration.rb b/lib/graphql/schema/visibility/migration.rb index 1c055126b4..7a9afe8493 100644 --- a/lib/graphql/schema/visibility/migration.rb +++ b/lib/graphql/schema/visibility/migration.rb @@ -2,7 +2,7 @@ module GraphQL class Schema class Visibility - # You can use this to see how {GraphQL::Schema::Warden} and {GraphQL::Schema::Visibility::Subset} + # You can use this to see how {GraphQL::Schema::Warden} and {GraphQL::Schema::Visibility::Profile} # handle `.visible?` differently in your schema. # # It runs the same method on both implementations and raises an error when the results diverge. @@ -15,28 +15,28 @@ class Visibility # This plugin adds two keys to `context` when running: # # - `visibility_migration_running: true` - # - For the {Warden} which it instantiates, it adds `visibility_migration_warden_running: true`. + # - For the {Schema::Warden} which it instantiates, it adds `visibility_migration_warden_running: true`. # # Use those keys to modify your `visible?` behavior as needed. # # Also, in a pinch, you can set `skip_visibility_migration_error: true` in context to turn off this behavior per-query. - # (In that case, it uses {Subset} directly.) + # (In that case, it uses {Profile} directly.) # # @example Adding this plugin # # use GraphQL::Schema::Visibility::Migration # - class Migration < GraphQL::Schema::Visibility::Subset + class Migration < GraphQL::Schema::Visibility::Profile def self.use(schema) - schema.subset_class = self + schema.visibility_profile_class = self end class RuntimeTypesMismatchError < GraphQL::Error - def initialize(method_called, warden_result, subset_result, method_args) + def initialize(method_called, warden_result, profile_result, method_args) super(<<~ERR) Mismatch in types for `##{method_called}(#{method_args.map(&:inspect).join(", ")})`: - #{compare_results(warden_result, subset_result)} + #{compare_results(warden_result, profile_result)} Update your `.visible?` implementation to make these implementations return the same value. @@ -45,9 +45,9 @@ def initialize(method_called, warden_result, subset_result, method_args) end private - def compare_results(warden_result, subset_result) - if warden_result.is_a?(Array) && subset_result.is_a?(Array) - all_results = warden_result | subset_result + def compare_results(warden_result, profile_result) + if warden_result.is_a?(Array) && profile_result.is_a?(Array) + all_results = warden_result | profile_result all_results.sort_by!(&:graphql_name) entries_text = all_results.map { |entry| "#{entry.graphql_name} (#{entry})"} @@ -55,13 +55,13 @@ def compare_results(warden_result, subset_result) yes = " ✔ " no = " " res = "".dup - res << "#{"Result".center(width)} Warden Subset \n" + res << "#{"Result".center(width)} Warden Profile \n" all_results.each_with_index do |entry, idx| - res << "#{entries_text[idx].ljust(width)}#{warden_result.include?(entry) ? yes : no}#{subset_result.include?(entry) ? yes : no}\n" + res << "#{entries_text[idx].ljust(width)}#{warden_result.include?(entry) ? yes : no}#{profile_result.include?(entry) ? yes : no}\n" end res << "\n" else - "- Warden returned: #{humanize(warden_result)}\n\n- Subset returned: #{humanize(subset_result)}" + "- Warden returned: #{humanize(warden_result)}\n\n- Visibility::Profile returned: #{humanize(profile_result)}" end end def humanize(val) @@ -83,7 +83,7 @@ def humanize(val) def initialize(context:, schema:, name: nil) @name = name @skip_error = context[:skip_visibility_migration_error] || context.is_a?(Query::NullContext) || context.is_a?(Hash) - @subset_types = GraphQL::Schema::Visibility::Subset.new(context: context, schema: schema) + @profile_types = GraphQL::Schema::Visibility::Profile.new(context: context, schema: schema) if !@skip_error context[:visibility_migration_running] = true warden_ctx_vals = context.to_h.dup @@ -92,7 +92,7 @@ def initialize(context:, schema:, name: nil) warden_schema = schema.const_get(:WardenCompatSchema, false) else warden_schema = Class.new(schema) - warden_schema.use_schema_visibility = false + warden_schema.use_visibility_profile = false # TODO public API warden_schema.send(:add_type_and_traverse, [warden_schema.query, warden_schema.mutation, warden_schema.subscription].compact, root: true) warden_schema.send(:add_type_and_traverse, warden_schema.directives.values + warden_schema.orphan_types, root: false) @@ -100,15 +100,15 @@ def initialize(context:, schema:, name: nil) end warden_ctx = GraphQL::Query::Context.new(query: context.query, values: warden_ctx_vals) warden_ctx.warden = GraphQL::Schema::Warden.new(schema: warden_schema, context: warden_ctx) - warden_ctx.types = @warden_types = warden_ctx.warden.schema_subset + warden_ctx.types = @warden_types = warden_ctx.warden.visibility_profile end end def loaded_types - @subset_types.loaded_types + @profile_types.loaded_types end - PUBLIC_SUBSET_METHODS = [ + PUBLIC_PROFILE_METHODS = [ :enum_values, :interfaces, :all_types, @@ -128,14 +128,14 @@ def loaded_types :reachable_type? ] - PUBLIC_SUBSET_METHODS.each do |subset_method| - define_method(subset_method) do |*args| - call_method_and_compare(subset_method, args) + PUBLIC_PROFILE_METHODS.each do |profile_method| + define_method(profile_method) do |*args| + call_method_and_compare(profile_method, args) end end def call_method_and_compare(method, args) - res_1 = @subset_types.public_send(method, *args) + res_1 = @profile_types.public_send(method, *args) if @skip_error return res_1 end diff --git a/lib/graphql/schema/visibility/subset.rb b/lib/graphql/schema/visibility/profile.rb similarity index 97% rename from lib/graphql/schema/visibility/subset.rb rename to lib/graphql/schema/visibility/profile.rb index dc94dbfab1..85ccba2b9e 100644 --- a/lib/graphql/schema/visibility/subset.rb +++ b/lib/graphql/schema/visibility/profile.rb @@ -11,11 +11,9 @@ class Visibility # - It doesn't use {Schema}'s top-level caches (eg {Schema.references_to}, {Schema.possible_types}, {Schema.types}) # - It doesn't hide Interface or Union types when all their possible types are hidden. (Instead, those types should implement `.visible?` to hide in that case.) # - It checks `.visible?` on root introspection types - # - # In the future, {Subset} will support lazy-loading types as needed during execution and multi-request caching of subsets. - # TODO rename to Profile? - class Subset - # @return [Schema::Visibility::Subset] + # - It can be used to cache profiles by name for re-use across queries + class Profile + # @return [Schema::Visibility::Profile] def self.from_context(ctx, schema) if ctx.respond_to?(:types) && (types = ctx.types).is_a?(self) types @@ -25,9 +23,9 @@ def self.from_context(ctx, schema) end def self.pass_thru(context:, schema:) - subset = self.new(context: context, schema: schema) - subset.instance_variable_set(:@cached_visible, Hash.new { |h,k| h[k] = true }) - subset + profile = self.new(context: context, schema: schema) + profile.instance_variable_set(:@cached_visible, Hash.new { |h,k| h[k] = true }) + profile end # @return [Symbol, nil] diff --git a/lib/graphql/schema/warden.rb b/lib/graphql/schema/warden.rb index a229305233..b905ddef55 100644 --- a/lib/graphql/schema/warden.rb +++ b/lib/graphql/schema/warden.rb @@ -61,8 +61,8 @@ def visible_type_membership?(tm, ctx); tm.visible?(ctx); end def interface_type_memberships(obj_t, ctx); obj_t.interface_type_memberships; end def arguments(owner, ctx); owner.arguments(ctx); end def loadable?(type, ctx); type.visible?(ctx); end - def schema_subset - @schema_subset ||= Warden::SchemaSubset.new(self) + def visibility_profile + @visibility_profile ||= Warden::VisibilityProfile.new(self) end end end @@ -70,17 +70,17 @@ def schema_subset class NullWarden def initialize(_filter = nil, context:, schema:) @schema = schema - @schema_subset = Warden::SchemaSubset.new(self) + @visibility_profile = Warden::VisibilityProfile.new(self) end # @api private - module NullSubset + module NullVisibilityProfile def self.new(context:, schema:) - NullWarden.new(context: context, schema: schema).schema_subset + NullWarden.new(context: context, schema: schema).visibility_profile end end - attr_reader :schema_subset + attr_reader :visibility_profile def visible_field?(field_defn, _ctx = nil, owner = nil); true; end def visible_argument?(arg_defn, _ctx = nil); true; end @@ -104,11 +104,11 @@ def possible_types(type_defn); @schema.possible_types(type_defn, Query::NullCont def interfaces(obj_type); obj_type.interfaces; end end - def schema_subset - @schema_subset ||= SchemaSubset.new(self) + def visibility_profile + @visibility_profile ||= VisibilityProfile.new(self) end - class SchemaSubset + class VisibilityProfile def initialize(warden) @warden = warden end @@ -193,7 +193,7 @@ def initialize(context:, schema:) @visible_possible_types = @visible_fields = @visible_arguments = @visible_enum_arrays = @visible_enum_values = @visible_interfaces = @type_visibility = @type_memberships = @visible_and_reachable_type = @unions = @unfiltered_interfaces = - @reachable_type_set = @schema_subset = + @reachable_type_set = @visibility_profile = nil end diff --git a/lib/graphql/testing/helpers.rb b/lib/graphql/testing/helpers.rb index 42be0279f0..f15832e0f9 100644 --- a/lib/graphql/testing/helpers.rb +++ b/lib/graphql/testing/helpers.rb @@ -92,7 +92,7 @@ def run_graphql_field(schema, field_path, object, arguments: {}, context: {}, as end graphql_result else - unfiltered_type = Schema::Visibility::Subset.pass_thru(schema: schema, context: context).type(type_name) + unfiltered_type = Schema::Visibility::Profile.pass_thru(schema: schema, context: context).type(type_name) if unfiltered_type raise TypeNotVisibleError.new(type_name: type_name) else diff --git a/spec/graphql/authorization_spec.rb b/spec/graphql/authorization_spec.rb index 0620a0f48e..3df00a305c 100644 --- a/spec/graphql/authorization_spec.rb +++ b/spec/graphql/authorization_spec.rb @@ -88,7 +88,7 @@ def resolve_type(obj, ctx) end module HiddenDefaultInterface - if GraphQL::Schema.use_schema_visibility? + if GraphQL::Schema.use_visibility_profile? include HiddenInterface else # Warden will detect no possible types diff --git a/spec/graphql/execution/instrumentation_spec.rb b/spec/graphql/execution/instrumentation_spec.rb index 52170e6320..1044d0da47 100644 --- a/spec/graphql/execution/instrumentation_spec.rb +++ b/spec/graphql/execution/instrumentation_spec.rb @@ -166,7 +166,7 @@ def int(value:) assert multiplex_ctx[:second_instrumenter_did_begin] refute multiplex_ctx[:second_instrumenter_did_end] # No query instrumentation was run at all - expected_ctx_size = GraphQL::Schema.use_schema_visibility? ? 1 : 0 + expected_ctx_size = GraphQL::Schema.use_visibility_profile? ? 1 : 0 assert_equal expected_ctx_size, query_1_ctx.size assert_equal expected_ctx_size, query_2_ctx.size end diff --git a/spec/graphql/logger_spec.rb b/spec/graphql/logger_spec.rb index 7df5cf9729..c811067685 100644 --- a/spec/graphql/logger_spec.rb +++ b/spec/graphql/logger_spec.rb @@ -96,8 +96,8 @@ class CustomLoggerSchema < DefaultLoggerSchema it "logs about hidden interfaces with no implementations" do res = LoggerTest::CustomLoggerSchema.execute("{ node(id: \"5\") { id } }", context: { skip_visibility_migration_error: true }) - if GraphQL::Schema.use_schema_visibility? - assert_nil res["data"]["node"], "Schema::Visibility::Subset doesn't warn in this case -- it doesn't check possible types because it doesn't have to" + if GraphQL::Schema.use_visibility_profile? + assert_nil res["data"]["node"], "Schema::Visibility::Profile doesn't warn in this case -- it doesn't check possible types because it doesn't have to" else assert_equal ["Field 'node' doesn't exist on type 'Query'"], res["errors"].map { |err| err["message"] } assert_includes LoggerTest::CustomLoggerSchema::LOG_STRING.string, "Interface `Node` hidden because it has no visible implementers" @@ -110,8 +110,8 @@ class CustomLoggerSchema < DefaultLoggerSchema res = LoggerTest::DefaultLoggerSchema.execute("{ node(id: \"5\") { id } }", context: { skip_visibility_migration_error: true }) end - if GraphQL::Schema.use_schema_visibility? - assert_nil res["data"]["node"], "Schema::Visibility::Subset doesn't warn in this case -- it doesn't check possible types because it doesn't have to" + if GraphQL::Schema.use_visibility_profile? + assert_nil res["data"]["node"], "Schema::Visibility::Profile doesn't warn in this case -- it doesn't check possible types because it doesn't have to" else assert_equal ["Field 'node' doesn't exist on type 'Query'"], res["errors"].map { |err| err["message"] } end diff --git a/spec/graphql/query/result_spec.rb b/spec/graphql/query/result_spec.rb index 5c8126485a..c725c29915 100644 --- a/spec/graphql/query/result_spec.rb +++ b/spec/graphql/query/result_spec.rb @@ -24,7 +24,7 @@ it "exposes the context" do assert_instance_of GraphQL::Query::Context, result.context - expected_ctx = if GraphQL::Schema.use_schema_visibility? && result.context.schema.visibility.migration_errors? + expected_ctx = if GraphQL::Schema.use_visibility_profile? && result.context.schema.visibility.migration_errors? {a: :b, visibility_migration_running: true} else {a: :b} diff --git a/spec/graphql/schema/addition_spec.rb b/spec/graphql/schema/addition_spec.rb index 17cfbdcb99..0819509c83 100644 --- a/spec/graphql/schema/addition_spec.rb +++ b/spec/graphql/schema/addition_spec.rb @@ -4,7 +4,7 @@ describe GraphQL::Schema::Addition do it "handles duplicate types with cycles" do duplicate_types_schema = Class.new(GraphQL::Schema) - duplicate_types_schema.use_schema_visibility = false + duplicate_types_schema.use_visibility_profile = false duplicate_types = 2.times.map { Class.new(GraphQL::Schema::Object) do graphql_name "Thing" diff --git a/spec/graphql/schema/directive/flagged_spec.rb b/spec/graphql/schema/directive/flagged_spec.rb index 8bb9582009..17836aae69 100644 --- a/spec/graphql/schema/directive/flagged_spec.rb +++ b/spec/graphql/schema/directive/flagged_spec.rb @@ -5,7 +5,7 @@ class FlaggedSchema < GraphQL::Schema module Animal include GraphQL::Schema::Interface - if GraphQL::Schema.use_schema_visibility? + if GraphQL::Schema.use_visibility_profile? # It won't check possible types, so it needs this directly directive GraphQL::Schema::Directive::Flagged, by: ["northPole", "southPole"] end diff --git a/spec/graphql/schema/dynamic_members_spec.rb b/spec/graphql/schema/dynamic_members_spec.rb index 6d30713fc9..c868935a1c 100644 --- a/spec/graphql/schema/dynamic_members_spec.rb +++ b/spec/graphql/schema/dynamic_members_spec.rb @@ -200,8 +200,8 @@ class Country < BaseObject class Locale < BaseUnion possible_types Country, future_schema: true - if GraphQL::Schema.use_schema_visibility? - # Subset won't check possible_types, this must be flagged + if GraphQL::Schema.use_visibility_profile? + # Profile won't check possible_types, this must be flagged self.future_schema = true end end @@ -595,7 +595,7 @@ def legacy_schema_sdl assert_includes MultifieldSchema::Country.interfaces({ future_schema: true }), MultifieldSchema::HasCapital assert_includes MultifieldSchema.possible_types(MultifieldSchema::HasCapital, { future_schema: true }), MultifieldSchema::Country assert_includes MultifieldSchema::Country.interfaces, MultifieldSchema::HasCapital - if GraphQL::Schema.use_schema_visibility? + if GraphQL::Schema.use_visibility_profile? # filtered with `future_schema: nil` refute_includes MultifieldSchema.possible_types(MultifieldSchema::HasCapital), MultifieldSchema::Country else @@ -605,17 +605,17 @@ def legacy_schema_sdl it "hides hidden union memberships" do assert MultifieldSchema::Locale.visible?({ future_schema: true }) - if GraphQL::Schema.use_schema_visibility? + if GraphQL::Schema.use_visibility_profile? refute MultifieldSchema::Locale.visible?({ future_schema: false }) else - # Warden will check possible types -- but Subset doesn't + # Warden will check possible types -- but Profile doesn't assert MultifieldSchema::Locale.visible?({ future_schema: false }) end # and the possible types relationship is sometimes hidden: refute_includes MultifieldSchema.possible_types(MultifieldSchema::Locale, { future_schema: false }), MultifieldSchema::Country assert_includes MultifieldSchema.possible_types(MultifieldSchema::Locale, { future_schema: true }), MultifieldSchema::Country - if GraphQL::Schema.use_schema_visibility? + if GraphQL::Schema.use_visibility_profile? # This type is hidden in this case assert_equal [], MultifieldSchema.possible_types(MultifieldSchema::Locale) else @@ -631,7 +631,7 @@ def legacy_schema_sdl # and the possible types relationship is sometimes hidden: assert_equal [], MultifieldSchema.possible_types(MultifieldSchema::Region, { future_schema: false }) assert_equal [MultifieldSchema::Country, MultifieldSchema::Place], MultifieldSchema.possible_types(MultifieldSchema::Region, { future_schema: true }) - if GraphQL::Schema.use_schema_visibility? + if GraphQL::Schema.use_visibility_profile? # Filtered like `future_schema: false` assert_equal [MultifieldSchema::Country, MultifieldSchema::LegacyPlace], MultifieldSchema.possible_types(MultifieldSchema::Region) else @@ -694,7 +694,7 @@ def legacy_schema_sdl assert_equal MultifieldSchema::MoneyScalar, MultifieldSchema.get_type("Money", { future_schema: nil }) assert_equal MultifieldSchema::MoneyScalar, MultifieldSchema.get_type("Money", { future_schema: false }) assert_equal MultifieldSchema::Money, MultifieldSchema.get_type("Money", { future_schema: true }) - if GraphQL::Schema.use_schema_visibility? + if GraphQL::Schema.use_visibility_profile? # Filtered like `future_schema: nil` assert_equal MultifieldSchema::MoneyScalar, MultifieldSchema.get_type("Money") else @@ -874,7 +874,7 @@ class OtherObject < GraphQL::Schema::Object field :f, Int, null: false end - if GraphQL::Schema.use_schema_visibility? + if GraphQL::Schema.use_visibility_profile? ThingInterface.orphan_types(OtherObject) end diff --git a/spec/graphql/schema/visibility/subset_spec.rb b/spec/graphql/schema/visibility/subset_spec.rb index 1262c72f07..c54b1ca4af 100644 --- a/spec/graphql/schema/visibility/subset_spec.rb +++ b/spec/graphql/schema/visibility/subset_spec.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true require "spec_helper" -describe GraphQL::Schema::Visibility::Subset do - class SubsetSchema < GraphQL::Schema +describe GraphQL::Schema::Visibility::Profile do + class ProfileSchema < GraphQL::Schema class Thing < GraphQL::Schema::Object field :name, String, method: :to_s end @@ -17,7 +17,7 @@ class Query < GraphQL::Schema::Object use GraphQL::Schema::Visibility end it "only loads the types it needs" do - query = GraphQL::Query.new(SubsetSchema, "{ thing { name } }", use_schema_subset: true) + query = GraphQL::Query.new(ProfileSchema, "{ thing { name } }", use_visibility_profile: true) assert_equal [], query.types.loaded_types res = query.result diff --git a/spec/graphql/schema/warden_spec.rb b/spec/graphql/schema/warden_spec.rb index f0646ea487..08ae4e6405 100644 --- a/spec/graphql/schema/warden_spec.rb +++ b/spec/graphql/schema/warden_spec.rb @@ -226,7 +226,7 @@ class QueryType < BaseObject field :public_type, PublicType, null: false # Warden would exclude this when it was only referenced as a possible_type of LanguageMemberType. - # But Subset always included it. This makes them behave the + # But Profile always included it. This makes them behave the same field :example_character, Character do metadata :hidden_abstract_type, true end @@ -535,7 +535,7 @@ class C < A; end class BagOfThings < GraphQL::Schema::Union possible_types A, B, C - if GraphQL::Schema.use_schema_visibility? + if GraphQL::Schema.use_visibility_profile? def self.visible?(ctx) ( possible_types.any? { |pt| ctx.schema.visible?(pt, ctx) } || @@ -636,7 +636,7 @@ def self.visible?(member, context) res = schema.execute(query_string, context: { skip_visibility_migration_error: true, except: ->(m, _) { ["A", "B", "C"].include?(m.graphql_name) } }) - if GraphQL::Schema.use_schema_visibility? + if GraphQL::Schema.use_visibility_profile? # Node is still visible even though it has no possible types assert res["data"]["Node"] assert_equal [{ "name" => "node" }], res["data"]["Query"]["fields"] @@ -1079,7 +1079,7 @@ def account result = schema.execute(query_str, context: { skip_visibility_migration_error: true }) - if GraphQL::Schema.use_schema_visibility? + if GraphQL::Schema.use_visibility_profile? assert_equal "1", result["data"]["account"]["id"] else assert_equal ["Field 'id' doesn't exist on type 'NewAccount'"], result["errors"].map { |e| e["message"] } diff --git a/spec/graphql/schema_spec.rb b/spec/graphql/schema_spec.rb index 34298251c2..2e2d9279c5 100644 --- a/spec/graphql/schema_spec.rb +++ b/spec/graphql/schema_spec.rb @@ -75,7 +75,7 @@ class CustomSubscriptions < GraphQL::Subscriptions::ActionCableSubscriptions assert_equal base_schema.multiplex_analyzers, schema.multiplex_analyzers assert_equal base_schema.disable_introspection_entry_points?, schema.disable_introspection_entry_points? expected_plugins = [ - (GraphQL::Schema.use_schema_visibility? ? GraphQL::Schema::Visibility : nil), + (GraphQL::Schema.use_visibility_profile? ? GraphQL::Schema::Visibility : nil), GraphQL::Backtrace, GraphQL::Subscriptions::ActionCableSubscriptions ].compact @@ -149,7 +149,7 @@ class CustomSubscriptions < GraphQL::Subscriptions::ActionCableSubscriptions assert_equal base_schema.query_analyzers + [query_analyzer], schema.query_analyzers assert_equal base_schema.multiplex_analyzers + [multiplex_analyzer], schema.multiplex_analyzers expected_plugins = [GraphQL::Backtrace, GraphQL::Subscriptions::ActionCableSubscriptions, CustomSubscriptions] - if GraphQL::Schema.use_schema_visibility? + if GraphQL::Schema.use_visibility_profile? expected_plugins.unshift(GraphQL::Schema::Visibility) end assert_equal expected_plugins, schema.plugins.map(&:first) diff --git a/spec/integration/rails/graphql/schema_spec.rb b/spec/integration/rails/graphql/schema_spec.rb index acaa69a49a..731d9c0ef3 100644 --- a/spec/integration/rails/graphql/schema_spec.rb +++ b/spec/integration/rails/graphql/schema_spec.rb @@ -16,7 +16,7 @@ describe "#union_memberships" do it "returns a list of unions that include the type" do - skip("Not implemented for Subset") if GraphQL::Schema.use_schema_visibility? + skip("Not implemented for Visibility::Profile") if GraphQL::Schema.use_visibility_profile? assert_equal [schema.types["Animal"], schema.types["AnimalAsCow"]], schema.union_memberships(schema.types["Cow"]) end end @@ -43,7 +43,7 @@ describe "#references_to" do it "returns a list of Field and Arguments of that type" do - skip "Not implemented when using Subset" if GraphQL::Schema.use_schema_visibility? + skip "Not implemented when using Visibility::Profile" if GraphQL::Schema.use_visibility_profile? cow_field = schema.get_field("Query", "cow") cow_t = schema.get_type("Cow") assert_equal [cow_field], schema.references_to(cow_t) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 08882b0263..6b1f9d016d 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -19,7 +19,7 @@ if ENV["GRAPHQL_REJECT_NUMBERS_FOLLOWED_BY_NAMES"] puts "Opting into GraphQL.reject_numbers_followed_by_names" GraphQL.reject_numbers_followed_by_names = true - puts "Opting into GraphQL::Schema::Visibility::Subset" + puts "Opting into GraphQL::Schema::Visibility::Profile" GraphQL::Schema.use(GraphQL::Schema::Visibility, migration_errors: true) end