diff options
author | Lin Jen-Shin <godfat@godfat.org> | 2019-01-31 03:00:30 +0800 |
---|---|---|
committer | Lin Jen-Shin <godfat@godfat.org> | 2019-02-14 15:52:17 +0800 |
commit | 91e9e50a1153021257abaa528498d7a82cc3350f (patch) | |
tree | 654dd11658da179f0bd4bd0eea5e4d63718c99b1 | |
parent | 1322146bbf5c76403db10969f1af6540717b1cdf (diff) | |
download | gitlab-ce-91e9e50a1153021257abaa528498d7a82cc3350f.tar.gz |
Add field mergeRequests for project in GraphQL
And fix the tests so that it won't run into circular paths.
-rw-r--r-- | app/graphql/mutations/merge_requests/base.rb | 3 | ||||
-rw-r--r-- | app/graphql/resolvers/base_resolver.rb | 7 | ||||
-rw-r--r-- | app/graphql/resolvers/merge_requests_resolver.rb (renamed from app/graphql/resolvers/merge_request_resolver.rb) | 19 | ||||
-rw-r--r-- | app/graphql/types/project_type.rb | 9 | ||||
-rw-r--r-- | changelogs/unreleased/56485-implement-graphql-mergerequestsresolver.yml | 5 | ||||
-rw-r--r-- | spec/graphql/resolvers/merge_requests_resolver_spec.rb (renamed from spec/graphql/resolvers/merge_request_resolver_spec.rb) | 10 | ||||
-rw-r--r-- | spec/support/helpers/graphql_helpers.rb | 13 |
7 files changed, 54 insertions, 12 deletions
diff --git a/app/graphql/mutations/merge_requests/base.rb b/app/graphql/mutations/merge_requests/base.rb index 54f01c99d78..7d0cb777ad1 100644 --- a/app/graphql/mutations/merge_requests/base.rb +++ b/app/graphql/mutations/merge_requests/base.rb @@ -25,7 +25,8 @@ module Mutations def find_object(project_path:, iid:) project = resolve_project(full_path: project_path) - resolver = Resolvers::MergeRequestResolver.new(object: project, context: context) + resolver = Resolvers::MergeRequestsResolver + .single.new(object: project, context: context) resolver.resolve(iid: iid) end diff --git a/app/graphql/resolvers/base_resolver.rb b/app/graphql/resolvers/base_resolver.rb index 459933af9d3..063def75d38 100644 --- a/app/graphql/resolvers/base_resolver.rb +++ b/app/graphql/resolvers/base_resolver.rb @@ -2,5 +2,12 @@ module Resolvers class BaseResolver < GraphQL::Schema::Resolver + def self.single + @single ||= Class.new(self) do + def resolve(**args) + super.first + end + end + end end end diff --git a/app/graphql/resolvers/merge_request_resolver.rb b/app/graphql/resolvers/merge_requests_resolver.rb index d047ce9e3a1..15055db633a 100644 --- a/app/graphql/resolvers/merge_request_resolver.rb +++ b/app/graphql/resolvers/merge_requests_resolver.rb @@ -1,19 +1,30 @@ # frozen_string_literal: true module Resolvers - class MergeRequestResolver < BaseResolver + class MergeRequestsResolver < BaseResolver argument :iid, GraphQL::ID_TYPE, - required: true, + required: false, description: 'The IID of the merge request, e.g., "1"' + argument :iids, [GraphQL::ID_TYPE], + required: false, + description: 'The list of IIDs of issues, e.g., [1, 2]' + type Types::MergeRequestType, null: true alias_method :project, :object - # rubocop: disable CodeReuse/ActiveRecord - def resolve(iid:) + def resolve(**args) return unless project.present? + args[:iids] ||= [args[:iid]] + + args[:iids].map(&method(:batch_load)) + .select(&:itself) # .compact doesn't work on BatchLoader + end + + # rubocop: disable CodeReuse/ActiveRecord + def batch_load(iid) BatchLoader.for(iid.to_s).batch(key: project) do |iids, loader, args| args[:key].merge_requests.where(iid: iids).each do |mr| loader.call(mr.iid.to_s, mr) diff --git a/app/graphql/types/project_type.rb b/app/graphql/types/project_type.rb index 050706f97be..daced8af1c2 100644 --- a/app/graphql/types/project_type.rb +++ b/app/graphql/types/project_type.rb @@ -66,10 +66,17 @@ module Types field :only_allow_merge_if_all_discussions_are_resolved, GraphQL::BOOLEAN_TYPE, null: true field :printing_merge_request_link_enabled, GraphQL::BOOLEAN_TYPE, null: true + field :merge_requests, + Types::MergeRequestType.connection_type, + null: true, + resolver: Resolvers::MergeRequestsResolver do + # authorize :read_merge_request + end + field :merge_request, Types::MergeRequestType, null: true, - resolver: Resolvers::MergeRequestResolver do + resolver: Resolvers::MergeRequestsResolver.single do authorize :read_merge_request end diff --git a/changelogs/unreleased/56485-implement-graphql-mergerequestsresolver.yml b/changelogs/unreleased/56485-implement-graphql-mergerequestsresolver.yml new file mode 100644 index 00000000000..5362ac65038 --- /dev/null +++ b/changelogs/unreleased/56485-implement-graphql-mergerequestsresolver.yml @@ -0,0 +1,5 @@ +--- +title: Add field mergeRequests for project in GraphQL +merge_request: 24805 +author: +type: added diff --git a/spec/graphql/resolvers/merge_request_resolver_spec.rb b/spec/graphql/resolvers/merge_requests_resolver_spec.rb index 73993b3a039..782a530e6f7 100644 --- a/spec/graphql/resolvers/merge_request_resolver_spec.rb +++ b/spec/graphql/resolvers/merge_requests_resolver_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Resolvers::MergeRequestResolver do +describe Resolvers::MergeRequestsResolver do include GraphqlHelpers set(:project) { create(:project, :repository) } @@ -18,7 +18,7 @@ describe Resolvers::MergeRequestResolver do describe '#resolve' do it 'batch-resolves merge requests by target project full path and IID' do result = batch(max_queries: 2) do - [resolve_mr(project, iid_1), resolve_mr(project, iid_2)] + resolve_mr(project, iid_1) + resolve_mr(project, iid_2) end expect(result).to contain_exactly(merge_request_1, merge_request_2) @@ -26,7 +26,9 @@ describe Resolvers::MergeRequestResolver do it 'can batch-resolve merge requests from different projects' do result = batch(max_queries: 3) do - [resolve_mr(project, iid_1), resolve_mr(project, iid_2), resolve_mr(other_project, other_iid)] + resolve_mr(project, iid_1) + + resolve_mr(project, iid_2) + + resolve_mr(other_project, other_iid) end expect(result).to contain_exactly(merge_request_1, merge_request_2, other_merge_request) @@ -35,7 +37,7 @@ describe Resolvers::MergeRequestResolver do it 'resolves an unknown iid to nil' do result = batch { resolve_mr(project, -1) } - expect(result).to be_nil + expect(result).to be_empty end end diff --git a/spec/support/helpers/graphql_helpers.rb b/spec/support/helpers/graphql_helpers.rb index ea3a03879c5..e468ee4676d 100644 --- a/spec/support/helpers/graphql_helpers.rb +++ b/spec/support/helpers/graphql_helpers.rb @@ -84,7 +84,7 @@ module GraphqlHelpers QUERY end - def all_graphql_fields_for(class_name) + def all_graphql_fields_for(class_name, parent_types = Set.new) type = GitlabSchema.types[class_name.to_s] return "" unless type @@ -92,8 +92,17 @@ module GraphqlHelpers # We can't guess arguments, so skip fields that require them next if required_arguments?(field) + singular_field_type = field_type(field) + + # If field type is the same as parent type, then we're hitting into + # mutual dependency. Break it from infinite recursion + next if parent_types.include?(singular_field_type) + if nested_fields?(field) - "#{name} { #{all_graphql_fields_for(field_type(field))} }" + fields = + all_graphql_fields_for(singular_field_type, parent_types | [type]) + + "#{name} { #{fields} }" else name end |