2019-12-21 20:55:43 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2018-11-08 19:23:39 +05:30
|
|
|
require 'spec_helper'
|
|
|
|
|
2020-07-28 23:09:34 +05:30
|
|
|
RSpec.describe Resolvers::MergeRequestsResolver do
|
2018-11-08 19:23:39 +05:30
|
|
|
include GraphqlHelpers
|
|
|
|
|
2020-04-08 14:13:33 +05:30
|
|
|
let_it_be(:project) { create(:project, :repository) }
|
2020-11-24 15:15:51 +05:30
|
|
|
let_it_be(:milestone) { create(:milestone, project: project) }
|
2020-06-23 00:09:42 +05:30
|
|
|
let_it_be(:current_user) { create(:user) }
|
2020-11-24 15:15:51 +05:30
|
|
|
let_it_be(:other_user) { create(:user) }
|
2020-06-23 00:09:42 +05:30
|
|
|
let_it_be(:common_attrs) { { author: current_user, source_project: project, target_project: project } }
|
|
|
|
let_it_be(:merge_request_1) { create(:merge_request, :simple, **common_attrs) }
|
|
|
|
let_it_be(:merge_request_2) { create(:merge_request, :rebased, **common_attrs) }
|
|
|
|
let_it_be(:merge_request_3) { create(:merge_request, :unique_branches, **common_attrs) }
|
|
|
|
let_it_be(:merge_request_4) { create(:merge_request, :unique_branches, :locked, **common_attrs) }
|
|
|
|
let_it_be(:merge_request_5) { create(:merge_request, :simple, :locked, **common_attrs) }
|
2020-11-24 15:15:51 +05:30
|
|
|
let_it_be(:merge_request_6) { create(:labeled_merge_request, :unique_branches, labels: create_list(:label, 2, project: project), **common_attrs) }
|
|
|
|
let_it_be(:merge_request_with_milestone) { create(:merge_request, :unique_branches, **common_attrs, milestone: milestone) }
|
2020-04-08 14:13:33 +05:30
|
|
|
let_it_be(:other_project) { create(:project, :repository) }
|
|
|
|
let_it_be(:other_merge_request) { create(:merge_request, source_project: other_project, target_project: other_project) }
|
2020-11-24 15:15:51 +05:30
|
|
|
|
2018-11-08 19:23:39 +05:30
|
|
|
let(:iid_1) { merge_request_1.iid }
|
|
|
|
let(:iid_2) { merge_request_2.iid }
|
|
|
|
let(:other_iid) { other_merge_request.iid }
|
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
before do
|
|
|
|
project.add_developer(current_user)
|
2020-07-28 23:09:34 +05:30
|
|
|
other_project.add_developer(current_user)
|
2020-06-23 00:09:42 +05:30
|
|
|
end
|
|
|
|
|
2018-11-08 19:23:39 +05:30
|
|
|
describe '#resolve' do
|
2020-07-28 23:09:34 +05:30
|
|
|
let(:queries_per_project) { 3 }
|
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
context 'no arguments' do
|
|
|
|
it 'returns all merge requests' do
|
|
|
|
result = resolve_mr(project, {})
|
|
|
|
|
2020-11-24 15:15:51 +05:30
|
|
|
expect(result).to contain_exactly(merge_request_1, merge_request_2, merge_request_3, merge_request_4, merge_request_5, merge_request_6, merge_request_with_milestone)
|
2019-07-07 11:18:12 +05:30
|
|
|
end
|
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
it 'returns only merge requests that the current user can see' do
|
|
|
|
result = resolve_mr(project, {}, user: build(:user))
|
|
|
|
|
|
|
|
expect(result).to be_empty
|
|
|
|
end
|
2019-07-07 11:18:12 +05:30
|
|
|
end
|
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
context 'by iid alone' do
|
2020-07-28 23:09:34 +05:30
|
|
|
it 'batch-resolves by target project full path and individual IID', :request_store do
|
|
|
|
# 1 query for project_authorizations, and 1 for merge_requests
|
|
|
|
result = batch_sync(max_queries: queries_per_project) do
|
2020-06-23 00:09:42 +05:30
|
|
|
[iid_1, iid_2].map { |iid| resolve_mr_single(project, iid) }
|
|
|
|
end
|
|
|
|
|
|
|
|
expect(result).to contain_exactly(merge_request_1, merge_request_2)
|
|
|
|
end
|
|
|
|
|
2020-07-28 23:09:34 +05:30
|
|
|
it 'batch-resolves by target project full path and IIDS', :request_store do
|
|
|
|
result = batch_sync(max_queries: queries_per_project) do
|
2020-06-23 00:09:42 +05:30
|
|
|
resolve_mr(project, iids: [iid_1, iid_2])
|
|
|
|
end
|
|
|
|
|
|
|
|
expect(result).to contain_exactly(merge_request_1, merge_request_2)
|
|
|
|
end
|
|
|
|
|
2020-07-28 23:09:34 +05:30
|
|
|
it 'batch-resolves by target project full path and IIDS, single or plural', :request_store do
|
|
|
|
result = batch_sync(max_queries: queries_per_project) do
|
|
|
|
[resolve_mr_single(project, merge_request_3.iid), *resolve_mr(project, iids: [iid_1, iid_2])]
|
|
|
|
end
|
|
|
|
|
|
|
|
expect(result).to contain_exactly(merge_request_1, merge_request_2, merge_request_3)
|
|
|
|
end
|
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
it 'can batch-resolve merge requests from different projects' do
|
2020-07-28 23:09:34 +05:30
|
|
|
# 2 queries for project_authorizations, and 2 for merge_requests
|
|
|
|
result = batch_sync(max_queries: queries_per_project * 2) do
|
2020-06-23 00:09:42 +05:30
|
|
|
resolve_mr(project, iids: iid_1) +
|
|
|
|
resolve_mr(project, iids: iid_2) +
|
|
|
|
resolve_mr(other_project, iids: other_iid)
|
|
|
|
end
|
|
|
|
|
|
|
|
expect(result).to contain_exactly(merge_request_1, merge_request_2, other_merge_request)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'resolves an unknown iid to be empty' do
|
|
|
|
result = batch_sync { resolve_mr_single(project, -1) }
|
|
|
|
|
|
|
|
expect(result).to be_nil
|
2018-11-08 19:23:39 +05:30
|
|
|
end
|
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
it 'resolves empty iids to be empty' do
|
|
|
|
result = batch_sync { resolve_mr(project, iids: []) }
|
|
|
|
|
|
|
|
expect(result).to be_empty
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'resolves an unknown project to be nil when single' do
|
|
|
|
result = batch_sync { resolve_mr_single(nil, iid_1) }
|
|
|
|
|
|
|
|
expect(result).to be_nil
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'resolves an unknown project to be empty' do
|
|
|
|
result = batch_sync { resolve_mr(nil, iids: [iid_1]) }
|
|
|
|
|
|
|
|
expect(result).to be_empty
|
|
|
|
end
|
2018-11-08 19:23:39 +05:30
|
|
|
end
|
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
context 'by source branches' do
|
|
|
|
it 'takes one argument' do
|
|
|
|
result = resolve_mr(project, source_branch: [merge_request_3.source_branch])
|
|
|
|
|
|
|
|
expect(result).to contain_exactly(merge_request_3)
|
2018-11-08 19:23:39 +05:30
|
|
|
end
|
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
it 'takes more than one argument' do
|
|
|
|
mrs = [merge_request_3, merge_request_4]
|
|
|
|
branches = mrs.map(&:source_branch)
|
|
|
|
result = resolve_mr(project, source_branch: branches )
|
|
|
|
|
|
|
|
expect(result).to match_array(mrs)
|
|
|
|
end
|
2018-11-08 19:23:39 +05:30
|
|
|
end
|
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
context 'by target branches' do
|
|
|
|
it 'takes one argument' do
|
|
|
|
result = resolve_mr(project, target_branch: [merge_request_3.target_branch])
|
|
|
|
|
|
|
|
expect(result).to contain_exactly(merge_request_3)
|
|
|
|
end
|
2019-07-07 11:18:12 +05:30
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
it 'takes more than one argument' do
|
|
|
|
mrs = [merge_request_3, merge_request_4]
|
|
|
|
branches = mrs.map(&:target_branch)
|
|
|
|
result = resolve_mr(project, target_branch: branches )
|
|
|
|
|
|
|
|
expect(result.compact).to match_array(mrs)
|
|
|
|
end
|
2019-07-07 11:18:12 +05:30
|
|
|
end
|
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
context 'by state' do
|
|
|
|
it 'takes one argument' do
|
|
|
|
result = resolve_mr(project, state: 'locked')
|
2018-11-08 19:23:39 +05:30
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
expect(result).to contain_exactly(merge_request_4, merge_request_5)
|
|
|
|
end
|
2018-11-08 19:23:39 +05:30
|
|
|
end
|
2020-04-22 19:07:51 +05:30
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
context 'by label' do
|
|
|
|
let_it_be(:label) { merge_request_6.labels.first }
|
|
|
|
let_it_be(:with_label) { create(:labeled_merge_request, :closed, labels: [label], **common_attrs) }
|
2020-04-22 19:07:51 +05:30
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
it 'takes one argument' do
|
|
|
|
result = resolve_mr(project, label_name: [label.title])
|
|
|
|
|
|
|
|
expect(result).to contain_exactly(merge_request_6, with_label)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'takes multiple arguments, with semantics of ALL MUST MATCH' do
|
|
|
|
result = resolve_mr(project, label_name: merge_request_6.labels.map(&:title))
|
|
|
|
|
|
|
|
expect(result).to contain_exactly(merge_request_6)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-10-24 23:57:45 +05:30
|
|
|
context 'by merged_after and merged_before' do
|
|
|
|
before do
|
|
|
|
merge_request_1.metrics.update!(merged_at: 10.days.ago)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns merge requests merged between the given period' do
|
|
|
|
result = resolve_mr(project, merged_after: 20.days.ago, merged_before: 5.days.ago)
|
|
|
|
|
|
|
|
expect(result).to eq([merge_request_1])
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not return anything' do
|
|
|
|
result = resolve_mr(project, merged_after: 2.days.ago)
|
|
|
|
|
|
|
|
expect(result).to be_empty
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-11-24 15:15:51 +05:30
|
|
|
context 'by milestone' do
|
|
|
|
it 'filters merge requests by milestone title' do
|
|
|
|
result = resolve_mr(project, milestone_title: milestone.title)
|
|
|
|
|
|
|
|
expect(result).to eq([merge_request_with_milestone])
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not find anything' do
|
|
|
|
result = resolve_mr(project, milestone_title: 'unknown-milestone')
|
|
|
|
|
|
|
|
expect(result).to be_empty
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
describe 'combinations' do
|
|
|
|
it 'requires all filters' do
|
|
|
|
create(:merge_request, :closed, source_project: project, target_project: project, source_branch: merge_request_4.source_branch)
|
|
|
|
|
|
|
|
result = resolve_mr(project, source_branch: [merge_request_4.source_branch], state: 'locked')
|
|
|
|
|
|
|
|
expect(result.compact).to contain_exactly(merge_request_4)
|
|
|
|
end
|
2020-04-22 19:07:51 +05:30
|
|
|
end
|
2020-11-24 15:15:51 +05:30
|
|
|
|
|
|
|
describe 'sorting' do
|
|
|
|
context 'when sorting by created' do
|
|
|
|
it 'sorts merge requests ascending' do
|
|
|
|
expect(resolve_mr(project, sort: 'created_asc')).to eq [merge_request_1, merge_request_2, merge_request_3, merge_request_4, merge_request_5, merge_request_6, merge_request_with_milestone]
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'sorts merge requests descending' do
|
|
|
|
expect(resolve_mr(project, sort: 'created_desc')).to eq [merge_request_with_milestone, merge_request_6, merge_request_5, merge_request_4, merge_request_3, merge_request_2, merge_request_1]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when sorting by merged at' do
|
|
|
|
before do
|
|
|
|
merge_request_1.metrics.update!(merged_at: 10.days.ago)
|
|
|
|
merge_request_3.metrics.update!(merged_at: 5.days.ago)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'sorts merge requests ascending' do
|
|
|
|
expect(resolve_mr(project, sort: :merged_at_asc)).to eq [merge_request_1, merge_request_3, merge_request_with_milestone, merge_request_6, merge_request_5, merge_request_4, merge_request_2]
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'sorts merge requests descending' do
|
|
|
|
expect(resolve_mr(project, sort: :merged_at_desc)).to eq [merge_request_3, merge_request_1, merge_request_with_milestone, merge_request_6, merge_request_5, merge_request_4, merge_request_2]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2018-11-08 19:23:39 +05:30
|
|
|
end
|
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
def resolve_mr_single(project, iid)
|
|
|
|
resolve_mr(project, { iids: iid }, resolver: described_class.single)
|
|
|
|
end
|
|
|
|
|
|
|
|
def resolve_mr(project, args, resolver: described_class, user: current_user)
|
|
|
|
resolve(resolver, obj: project, args: args, ctx: { current_user: user })
|
2018-11-08 19:23:39 +05:30
|
|
|
end
|
|
|
|
end
|