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
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
......
......@@ -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
# 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)
......
......@@ -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
......
---
title: Add field mergeRequests for project in GraphQL
merge_request: 24805
author:
type: added
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
......
......@@ -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
......
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