summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLin Jen-Shin <godfat@godfat.org>2019-01-31 03:00:30 +0800
committerLin Jen-Shin <godfat@godfat.org>2019-02-14 15:52:17 +0800
commit91e9e50a1153021257abaa528498d7a82cc3350f (patch)
tree654dd11658da179f0bd4bd0eea5e4d63718c99b1
parent1322146bbf5c76403db10969f1af6540717b1cdf (diff)
downloadgitlab-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.rb3
-rw-r--r--app/graphql/resolvers/base_resolver.rb7
-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.rb9
-rw-r--r--changelogs/unreleased/56485-implement-graphql-mergerequestsresolver.yml5
-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.rb13
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