diff --git a/app/registries/foreman/plugin.rb b/app/registries/foreman/plugin.rb index 5a5e5bc52e4..7ad92d38f98 100644 --- a/app/registries/foreman/plugin.rb +++ b/app/registries/foreman/plugin.rb @@ -619,8 +619,8 @@ def extend_graphql_type(type:, with_module: nil, &block) graphql_types_registry.register_extension(type: type, with_module: with_module, &block) end - def register_graphql_query_field(field_name, type, field_type) - graphql_types_registry.register_plugin_query_field(field_name, type, field_type) + def register_graphql_query_field(field_name, type, field_type, options = nil) + graphql_types_registry.register_plugin_query_field(field_name, type, field_type, options) end def register_graphql_mutation_field(field_name, mutation_class) diff --git a/app/registries/foreman/plugin/graphql_plugin_fields.rb b/app/registries/foreman/plugin/graphql_plugin_fields.rb index 424be188a10..e3eb192b236 100644 --- a/app/registries/foreman/plugin/graphql_plugin_fields.rb +++ b/app/registries/foreman/plugin/graphql_plugin_fields.rb @@ -6,7 +6,11 @@ module GraphqlPluginFields module ClassMethods def realize_plugin_query_extensions(source = Foreman::Plugin.graphql_types_registry.plugin_query_fields) source.map do |plugin_type| - send plugin_type[:field_type], plugin_type[:field_name], Foreman::Module.resolve(plugin_type[:type]) + if plugin_type[:options].empty? + send plugin_type[:field_type], plugin_type[:field_name], Foreman::Module.resolve(plugin_type[:type]) + else + send plugin_type[:field_type], plugin_type[:field_name], Foreman::Module.resolve(plugin_type[:type]), plugin_type[:options] + end end end diff --git a/app/registries/foreman/plugin/graphql_types_registry.rb b/app/registries/foreman/plugin/graphql_types_registry.rb index d8e2bcdb00b..89a724704f7 100644 --- a/app/registries/foreman/plugin/graphql_types_registry.rb +++ b/app/registries/foreman/plugin/graphql_types_registry.rb @@ -11,11 +11,14 @@ def initialize @plugin_mutation_fields = [] end - def register_plugin_query_field(field_name, type, field_type) - unless [:record_field, :collection_field].any? { |field| field == field_type } - raise "expected :record_field or :collection_field as a field_type, got #{field_type}" + def register_plugin_query_field(field_name, type, field_type, options = {}) + unless [:record_field, :collection_field, :field].any? { |field| field == field_type } + raise "expected :record_field, :collection_field or :field as a field_type, got #{field_type}" end - @plugin_query_fields << { :field_type => field_type, :field_name => field_name, :type => type } + if [:record_field, :collection_field].any? { |field| field == field_type && !options.empty? } + raise "options are allowed only for :field" + end + @plugin_query_fields << { :field_type => field_type, :field_name => field_name, :type => type, :options => options } end def register_plugin_mutation_field(field_name, mutation) diff --git a/test/unit/foreman/plugin/graphql_plugin_fields_test.rb b/test/unit/foreman/plugin/graphql_plugin_fields_test.rb index 724af30526e..66633c3325f 100644 --- a/test/unit/foreman/plugin/graphql_plugin_fields_test.rb +++ b/test/unit/foreman/plugin/graphql_plugin_fields_test.rb @@ -5,25 +5,29 @@ class GraphqlType include ::Foreman::Plugin::GraphqlPluginFields class << self - attr_accessor :record_fields, :collection_fields, :mutation_fields + attr_accessor :record_fields, :collection_fields, :mutation_fields, :fields def record_field(name, type) - push_item :record_fields, name, type + push_item :record_fields, name, type, {} end def collection_field(name, type) - push_item :collection_fields, name, type + push_item :collection_fields, name, type, {} end - def field(name, mutation) - item = { :name => name, :mutation => mutation } - @mutation_fields ? @mutation_fields << item : @mutation_fields = [item] + def field(name, type_or_opts, opts = {}) + if type_or_opts.is_a?(Hash) && type_or_opts[:mutation] + item = { :name => name, :mutation => type_or_opts[:mutation] } + @mutation_fields ? @mutation_fields << item : @mutation_fields = [item] + else + push_item :fields, name, type_or_opts, opts + end end private - def push_item(place, name, type) - item = { :name => name, :type => type } + def push_item(place, name, type, opts) + item = { :name => name, :type => type }.merge(opts) instance_var = instance_variable_get("@#{place}") instance_var ? instance_var << item : instance_variable_set("@#{place}", [item]) end @@ -62,6 +66,28 @@ def push_item(place, name, type) assert_equal 1, klass.collection_fields.size assert_equal :woof, klass.collection_fields.first[:name] end + + it 'adds a field with custom resolver' do + registry = Foreman::Plugin::GraphqlTypesRegistry.new.tap do |reg| + reg.register_plugin_query_field :quack, -> { [String] }, :field, :resolver => Object + end + + klass = Class.new(GraphqlType) + + assert_nil klass.record_fields + assert_nil klass.collection_fields + assert_nil klass.mutation_fields + assert_nil klass.fields + klass.realize_plugin_query_extensions registry.plugin_query_fields + + assert_nil klass.record_fields + assert_nil klass.collection_fields + assert_nil klass.mutation_fields + + assert_equal 1, klass.fields.size + assert_equal :quack, klass.fields.first[:name] + assert klass.fields.first[:resolver] + end end describe 'graphql plugin mutation fields' do diff --git a/test/unit/foreman/plugin/graphql_types_registry_test.rb b/test/unit/foreman/plugin/graphql_types_registry_test.rb index 094274c4ac2..5dcd987be13 100644 --- a/test/unit/foreman/plugin/graphql_types_registry_test.rb +++ b/test/unit/foreman/plugin/graphql_types_registry_test.rb @@ -70,7 +70,7 @@ def foo err = assert_raises RuntimeError do registry.register_plugin_query_field :woof, 'TestType', :custom_field end - assert_equal err.message, "expected :record_field or :collection_field as a field_type, got custom_field" + assert_equal err.message, "expected :record_field, :collection_field or :field as a field_type, got custom_field" end it 'registeres plugin mutation fields' do