Commit 91e9e50a authored by Lin Jen-Shin's avatar Lin Jen-Shin

Add field mergeRequests for project in GraphQL

And fix the tests so that it won't run into circular paths.
parent 1322146b
...@@ -25,7 +25,8 @@ module Mutations ...@@ -25,7 +25,8 @@ module Mutations
def find_object(project_path:, iid:) def find_object(project_path:, iid:)
project = resolve_project(full_path: project_path) 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) resolver.resolve(iid: iid)
end end
......
...@@ -2,5 +2,12 @@ ...@@ -2,5 +2,12 @@
module Resolvers module Resolvers
class BaseResolver < GraphQL::Schema::Resolver class BaseResolver < GraphQL::Schema::Resolver
def self.single
@single ||= Class.new(self) do
def resolve(**args)
super.first
end
end
end
end end
end end
# frozen_string_literal: true # frozen_string_literal: true
module Resolvers module Resolvers
class MergeRequestResolver < BaseResolver class MergeRequestsResolver < BaseResolver
argument :iid, GraphQL::ID_TYPE, argument :iid, GraphQL::ID_TYPE,
required: true, required: false,
description: 'The IID of the merge request, e.g., "1"' 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 type Types::MergeRequestType, null: true
alias_method :project, :object alias_method :project, :object
# rubocop: disable CodeReuse/ActiveRecord def resolve(**args)
def resolve(iid:)
return unless project.present? 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| BatchLoader.for(iid.to_s).batch(key: project) do |iids, loader, args|
args[:key].merge_requests.where(iid: iids).each do |mr| args[:key].merge_requests.where(iid: iids).each do |mr|
loader.call(mr.iid.to_s, mr) loader.call(mr.iid.to_s, mr)
......
...@@ -66,10 +66,17 @@ module Types ...@@ -66,10 +66,17 @@ module Types
field :only_allow_merge_if_all_discussions_are_resolved, GraphQL::BOOLEAN_TYPE, null: true 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 :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, field :merge_request,
Types::MergeRequestType, Types::MergeRequestType,
null: true, null: true,
resolver: Resolvers::MergeRequestResolver do resolver: Resolvers::MergeRequestsResolver.single do
authorize :read_merge_request authorize :read_merge_request
end end
......
---
title: Add field mergeRequests for project in GraphQL
merge_request: 24805
author:
type: added
require 'spec_helper' require 'spec_helper'
describe Resolvers::MergeRequestResolver do describe Resolvers::MergeRequestsResolver do
include GraphqlHelpers include GraphqlHelpers
set(:project) { create(:project, :repository) } set(:project) { create(:project, :repository) }
...@@ -18,7 +18,7 @@ describe Resolvers::MergeRequestResolver do ...@@ -18,7 +18,7 @@ describe Resolvers::MergeRequestResolver do
describe '#resolve' do describe '#resolve' do
it 'batch-resolves merge requests by target project full path and IID' do it 'batch-resolves merge requests by target project full path and IID' do
result = batch(max_queries: 2) 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 end
expect(result).to contain_exactly(merge_request_1, merge_request_2) expect(result).to contain_exactly(merge_request_1, merge_request_2)
...@@ -26,7 +26,9 @@ describe Resolvers::MergeRequestResolver do ...@@ -26,7 +26,9 @@ describe Resolvers::MergeRequestResolver do
it 'can batch-resolve merge requests from different projects' do it 'can batch-resolve merge requests from different projects' do
result = batch(max_queries: 3) 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 end
expect(result).to contain_exactly(merge_request_1, merge_request_2, other_merge_request) expect(result).to contain_exactly(merge_request_1, merge_request_2, other_merge_request)
...@@ -35,7 +37,7 @@ describe Resolvers::MergeRequestResolver do ...@@ -35,7 +37,7 @@ describe Resolvers::MergeRequestResolver do
it 'resolves an unknown iid to nil' do it 'resolves an unknown iid to nil' do
result = batch { resolve_mr(project, -1) } result = batch { resolve_mr(project, -1) }
expect(result).to be_nil expect(result).to be_empty
end end
end end
......
...@@ -84,7 +84,7 @@ module GraphqlHelpers ...@@ -84,7 +84,7 @@ module GraphqlHelpers
QUERY QUERY
end 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] type = GitlabSchema.types[class_name.to_s]
return "" unless type return "" unless type
...@@ -92,8 +92,17 @@ module GraphqlHelpers ...@@ -92,8 +92,17 @@ module GraphqlHelpers
# We can't guess arguments, so skip fields that require them # We can't guess arguments, so skip fields that require them
next if required_arguments?(field) 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) 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 else
name name
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment