Commit 4feac4bb authored by Vitali Tatarintev's avatar Vitali Tatarintev

Merge branch 'sarnold-issuable-parent-param-refactor' into 'master'

Issuable parent param refactor

See merge request gitlab-org/gitlab!40220
parents ae085beb c69dc778
...@@ -44,6 +44,7 @@ class IssuableFinder ...@@ -44,6 +44,7 @@ class IssuableFinder
NEGATABLE_PARAMS_HELPER_KEYS = %i[project_id scope status include_subgroups].freeze NEGATABLE_PARAMS_HELPER_KEYS = %i[project_id scope status include_subgroups].freeze
attr_accessor :current_user, :params attr_accessor :current_user, :params
attr_writer :parent
delegate(*%i[assignee milestones], to: :params) delegate(*%i[assignee milestones], to: :params)
...@@ -204,8 +205,26 @@ class IssuableFinder ...@@ -204,8 +205,26 @@ class IssuableFinder
end end
end end
def parent_param=(obj)
@parent = obj
params[parent_param] = parent if parent
end
def parent_param
case parent
when Project
:project_id
when Group
:group_id
else
raise "Unexpected parent: #{parent.class}"
end
end
private private
attr_reader :parent
def not_params def not_params
strong_memoize(:not_params) do strong_memoize(:not_params) do
params_class.new(params[:not].dup, current_user, klass).tap do |not_params| params_class.new(params[:not].dup, current_user, klass).tap do |not_params|
......
# frozen_string_literal: true # frozen_string_literal: true
module IssueResolverFields module IssueResolverArguments
extend ActiveSupport::Concern extend ActiveSupport::Concern
prepended do prepended do
......
...@@ -2,26 +2,13 @@ ...@@ -2,26 +2,13 @@
module Resolvers module Resolvers
class IssueStatusCountsResolver < BaseResolver class IssueStatusCountsResolver < BaseResolver
prepend IssueResolverFields prepend IssueResolverArguments
type Types::IssueStatusCountsType, null: true type Types::IssueStatusCountsType, null: true
def continue_issue_resolve(parent, finder, **args) def continue_issue_resolve(parent, finder, **args)
finder.params[parent_param(parent)] = parent if parent finder.parent_param = parent
apply_lookahead(Gitlab::IssuablesCountForState.new(finder, parent)) apply_lookahead(Gitlab::IssuablesCountForState.new(finder, parent))
end end
private
def parent_param(parent)
case parent
when Project
:project_id
when Group
:group_id
else
raise "Unexpected type of parent: #{parent.class}. Must be Project or Group"
end
end
end end
end end
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
module Resolvers module Resolvers
class IssuesResolver < BaseResolver class IssuesResolver < BaseResolver
prepend IssueResolverFields prepend IssueResolverArguments
argument :state, Types::IssuableStateEnum, argument :state, Types::IssuableStateEnum,
required: false, required: false,
......
...@@ -15,6 +15,7 @@ module Gitlab ...@@ -15,6 +15,7 @@ module Gitlab
def batching_find_all(&with_query) def batching_find_all(&with_query)
if issuable_finder.params.keys == ['iids'] if issuable_finder.params.keys == ['iids']
issuable_finder.parent = parent
batch_load_issuables(issuable_finder.params[:iids], with_query) batch_load_issuables(issuable_finder.params[:iids], with_query)
else else
post_process(find_all, with_query) post_process(find_all, with_query)
...@@ -22,24 +23,12 @@ module Gitlab ...@@ -22,24 +23,12 @@ module Gitlab
end end
def find_all def find_all
issuable_finder.params[parent_param] = parent if parent issuable_finder.parent_param = parent if parent
issuable_finder.execute issuable_finder.execute
end end
private private
def parent_param
case parent
when Project
:project_id
when Group
:group_id
else
raise "Unexpected parent: #{parent.class}"
end
end
def post_process(query, with_query) def post_process(query, with_query)
if with_query if with_query
with_query.call(query) with_query.call(query)
...@@ -56,7 +45,7 @@ module Gitlab ...@@ -56,7 +45,7 @@ module Gitlab
return if parent.nil? return if parent.nil?
BatchLoader::GraphQL BatchLoader::GraphQL
.for([parent_param, iid.to_s]) .for([issuable_finder.parent_param, iid.to_s])
.batch(key: batch_key) do |params, loader, args| .batch(key: batch_key) do |params, loader, args|
batch_key = args[:key] batch_key = args[:key]
user = batch_key.current_user user = batch_key.current_user
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe IssuesFinder do RSpec.describe IssuesFinder do
using RSpec::Parameterized::TableSyntax
include_context 'IssuesFinder context' include_context 'IssuesFinder context'
describe '#execute' do describe '#execute' do
...@@ -1022,4 +1023,33 @@ RSpec.describe IssuesFinder do ...@@ -1022,4 +1023,33 @@ RSpec.describe IssuesFinder do
end end
end end
end end
describe '#parent_param=' do
let(:finder) { described_class.new(nil) }
subject { finder.parent_param = obj }
where(:klass, :param) do
:Project | :project_id
:Group | :group_id
end
with_them do
let(:obj) { Object.const_get(klass, false).new }
it 'sets the params' do
subject
expect(finder.params[param]).to eq(obj)
end
end
context 'unexpected parent' do
let(:obj) { MergeRequest.new }
it 'raises an error' do
expect { subject }.to raise_error('Unexpected parent: MergeRequest')
end
end
end
end end
...@@ -41,6 +41,12 @@ RSpec.describe Resolvers::IssueStatusCountsResolver do ...@@ -41,6 +41,12 @@ RSpec.describe Resolvers::IssueStatusCountsResolver do
it_behaves_like 'returns expected results' it_behaves_like 'returns expected results'
context 'project used as parent' do
let(:parent) { project }
it_behaves_like 'returns expected results'
end
context 'group used as parent' do context 'group used as parent' do
let(:parent) { project.group } let(:parent) { project.group }
......
...@@ -6,9 +6,26 @@ RSpec.describe Gitlab::Graphql::Loaders::IssuableLoader do ...@@ -6,9 +6,26 @@ RSpec.describe Gitlab::Graphql::Loaders::IssuableLoader do
subject { described_class.new(parent, finder) } subject { described_class.new(parent, finder) }
let(:params) { HashWithIndifferentAccess.new } let(:params) { HashWithIndifferentAccess.new }
let(:finder_params) { finder.params.to_h.with_indifferent_access }
# Dumb finder class, that only implements what we need, and has
# predictable query counts.
let(:finder_class) do
Class.new(IssuesFinder) do
def execute
params[:project_id].issues.where(iid: params[:iids])
end
private
def params_class
IssuesFinder::Params
end
end
end
describe '#find_all' do describe '#find_all' do
let(:finder) { double(:finder, params: params, execute: %i[x y z]) } let(:finder) { issuable_finder(params: params, result: [:x, :y, :z]) }
where(:factory, :param_name) do where(:factory, :param_name) do
%i[project group].map { |thing| [thing, :"#{thing}_id"] } %i[project group].map { |thing| [thing, :"#{thing}_id"] }
...@@ -19,7 +36,7 @@ RSpec.describe Gitlab::Graphql::Loaders::IssuableLoader do ...@@ -19,7 +36,7 @@ RSpec.describe Gitlab::Graphql::Loaders::IssuableLoader do
it 'assignes the parent parameter, and batching_find_alls the finder' do it 'assignes the parent parameter, and batching_find_alls the finder' do
expect(subject.find_all).to contain_exactly(:x, :y, :z) expect(subject.find_all).to contain_exactly(:x, :y, :z)
expect(params).to include(param_name => parent) expect(finder_params).to include(param_name => parent)
end end
end end
...@@ -34,12 +51,12 @@ RSpec.describe Gitlab::Graphql::Loaders::IssuableLoader do ...@@ -34,12 +51,12 @@ RSpec.describe Gitlab::Graphql::Loaders::IssuableLoader do
describe '#batching_find_all' do describe '#batching_find_all' do
context 'the finder params are anything other than [iids]' do context 'the finder params are anything other than [iids]' do
let(:finder) { double(:finder, params: params, execute: [:foo]) } let(:finder) { issuable_finder(params: params, result: [:foo]) }
let(:parent) { build_stubbed(:project) } let(:parent) { build_stubbed(:project) }
it 'batching_find_alls the finder, setting the correct parent parameter' do it 'batching_find_alls the finder, setting the correct parent parameter' do
expect(subject.batching_find_all).to eq([:foo]) expect(subject.batching_find_all).to eq([:foo])
expect(params[:project_id]).to eq(parent) expect(finder_params[:project_id]).to eq(parent)
end end
it 'allows a post-process block' do it 'allows a post-process block' do
...@@ -48,23 +65,6 @@ RSpec.describe Gitlab::Graphql::Loaders::IssuableLoader do ...@@ -48,23 +65,6 @@ RSpec.describe Gitlab::Graphql::Loaders::IssuableLoader do
end end
context 'the finder params are exactly [iids]' do context 'the finder params are exactly [iids]' do
# Dumb finder class, that only implements what we need, and has
# predictable query counts.
let(:finder_class) do
Class.new do
attr_reader :current_user, :params
def initialize(user, args)
@current_user = user
@params = HashWithIndifferentAccess.new(args.to_h)
end
def execute
params[:project_id].issues.where(iid: params[:iids])
end
end
end
it 'batches requests' do it 'batches requests' do
issue_a = create(:issue) issue_a = create(:issue)
issue_b = create(:issue) issue_b = create(:issue)
...@@ -93,4 +93,13 @@ RSpec.describe Gitlab::Graphql::Loaders::IssuableLoader do ...@@ -93,4 +93,13 @@ RSpec.describe Gitlab::Graphql::Loaders::IssuableLoader do
end end
end end
end end
private
def issuable_finder(user: double(:user), params: {}, result: nil)
new_finder = finder_class.new(user, params)
allow(new_finder).to receive(:execute).and_return(result) if result
new_finder
end
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