Commit 70121424 authored by Rémy Coutable's avatar Rémy Coutable

Add the `draft` argument to GraphQL MergeRequestsResolver

Changelog: added
Signed-off-by: default avatarRémy Coutable <remy@rymai.me>
parent 356491bd
......@@ -140,14 +140,13 @@ class MergeRequestsFinder < IssuableFinder
# rubocop: disable CodeReuse/ActiveRecord
def by_draft(items)
draft_param = params[:draft] || params[:wip]
draft_param = Gitlab::Utils.to_boolean(params.fetch(:draft) { params.fetch(:wip, nil) })
return items if draft_param.nil?
if draft_param == 'yes'
if draft_param
items.where(wip_match(items.arel_table))
elsif draft_param == 'no'
items.where.not(wip_match(items.arel_table))
else
items
items.where.not(wip_match(items.arel_table))
end
end
# rubocop: enable CodeReuse/ActiveRecord
......
......@@ -51,6 +51,10 @@ module Resolvers
required: false,
description: 'Merge request state. If provided, all resolved merge requests will have this state.'
argument :draft, GraphQL::Types::Boolean,
required: false,
description: 'Limit result to draft merge requests.'
argument :labels, [GraphQL::Types::String],
required: false,
as: :label_name,
......
......@@ -11073,6 +11073,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="groupmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
| <a id="groupmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
| <a id="groupmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
| <a id="groupmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
| <a id="groupmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
| <a id="groupmergerequestsincludesubgroups"></a>`includeSubgroups` | [`Boolean`](#boolean) | Include merge requests belonging to subgroups. |
| <a id="groupmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
......@@ -12008,6 +12009,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="mergerequestassigneeassignedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
| <a id="mergerequestassigneeassignedmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
| <a id="mergerequestassigneeassignedmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
| <a id="mergerequestassigneeassignedmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
| <a id="mergerequestassigneeassignedmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
| <a id="mergerequestassigneeassignedmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
| <a id="mergerequestassigneeassignedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. |
......@@ -12039,6 +12041,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="mergerequestassigneeauthoredmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. |
| <a id="mergerequestassigneeauthoredmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
| <a id="mergerequestassigneeauthoredmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
| <a id="mergerequestassigneeauthoredmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
| <a id="mergerequestassigneeauthoredmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
| <a id="mergerequestassigneeauthoredmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
| <a id="mergerequestassigneeauthoredmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. |
......@@ -12088,6 +12091,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="mergerequestassigneereviewrequestedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
| <a id="mergerequestassigneereviewrequestedmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
| <a id="mergerequestassigneereviewrequestedmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
| <a id="mergerequestassigneereviewrequestedmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
| <a id="mergerequestassigneereviewrequestedmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
| <a id="mergerequestassigneereviewrequestedmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
| <a id="mergerequestassigneereviewrequestedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. |
......@@ -12260,6 +12264,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="mergerequestreviewerassignedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
| <a id="mergerequestreviewerassignedmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
| <a id="mergerequestreviewerassignedmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
| <a id="mergerequestreviewerassignedmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
| <a id="mergerequestreviewerassignedmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
| <a id="mergerequestreviewerassignedmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
| <a id="mergerequestreviewerassignedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. |
......@@ -12291,6 +12296,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="mergerequestreviewerauthoredmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. |
| <a id="mergerequestreviewerauthoredmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
| <a id="mergerequestreviewerauthoredmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
| <a id="mergerequestreviewerauthoredmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
| <a id="mergerequestreviewerauthoredmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
| <a id="mergerequestreviewerauthoredmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
| <a id="mergerequestreviewerauthoredmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. |
......@@ -12340,6 +12346,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="mergerequestreviewerreviewrequestedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
| <a id="mergerequestreviewerreviewrequestedmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
| <a id="mergerequestreviewerreviewrequestedmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
| <a id="mergerequestreviewerreviewrequestedmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
| <a id="mergerequestreviewerreviewrequestedmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
| <a id="mergerequestreviewerreviewrequestedmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
| <a id="mergerequestreviewerreviewrequestedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. |
......@@ -13775,6 +13782,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="projectmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
| <a id="projectmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
| <a id="projectmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
| <a id="projectmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
| <a id="projectmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
| <a id="projectmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
| <a id="projectmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. |
......@@ -15438,6 +15446,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="usercoreassignedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
| <a id="usercoreassignedmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
| <a id="usercoreassignedmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
| <a id="usercoreassignedmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
| <a id="usercoreassignedmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
| <a id="usercoreassignedmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
| <a id="usercoreassignedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. |
......@@ -15469,6 +15478,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="usercoreauthoredmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. |
| <a id="usercoreauthoredmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
| <a id="usercoreauthoredmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
| <a id="usercoreauthoredmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
| <a id="usercoreauthoredmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
| <a id="usercoreauthoredmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
| <a id="usercoreauthoredmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. |
......@@ -15518,6 +15528,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="usercorereviewrequestedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
| <a id="usercorereviewrequestedmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
| <a id="usercorereviewrequestedmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
| <a id="usercorereviewrequestedmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
| <a id="usercorereviewrequestedmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
| <a id="usercorereviewrequestedmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
| <a id="usercorereviewrequestedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. |
......@@ -18659,6 +18670,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="userassignedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
| <a id="userassignedmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
| <a id="userassignedmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
| <a id="userassignedmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
| <a id="userassignedmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
| <a id="userassignedmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
| <a id="userassignedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. |
......@@ -18690,6 +18702,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="userauthoredmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. |
| <a id="userauthoredmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
| <a id="userauthoredmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
| <a id="userauthoredmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
| <a id="userauthoredmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
| <a id="userauthoredmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
| <a id="userauthoredmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. |
......@@ -18739,6 +18752,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="userreviewrequestedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
| <a id="userreviewrequestedmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
| <a id="userreviewrequestedmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
| <a id="userreviewrequestedmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
| <a id="userreviewrequestedmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
| <a id="userreviewrequestedmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
| <a id="userreviewrequestedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. |
......@@ -278,33 +278,38 @@ RSpec.describe MergeRequestsFinder do
end
describe 'draft state' do
let!(:wip_merge_request1) { create(:merge_request, :simple, author: user, source_project: project5, target_project: project5, title: 'WIP: thing') }
let!(:wip_merge_request2) { create(:merge_request, :simple, author: user, source_project: project6, target_project: project6, title: 'wip thing') }
let!(:wip_merge_request3) { create(:merge_request, :simple, author: user, source_project: project1, target_project: project1, title: '[wip] thing') }
let!(:wip_merge_request4) { create(:merge_request, :simple, author: user, source_project: project1, target_project: project2, title: 'wip: thing') }
let!(:draft_merge_request1) { create(:merge_request, :simple, author: user, source_branch: 'draft1', source_project: project5, target_project: project5, title: 'Draft: thing') }
let!(:draft_merge_request2) { create(:merge_request, :simple, author: user, source_branch: 'draft2', source_project: project6, target_project: project6, title: '[draft] thing') }
let!(:draft_merge_request3) { create(:merge_request, :simple, author: user, source_branch: 'draft3', source_project: project1, target_project: project1, title: '(draft) thing') }
let!(:draft_merge_request4) { create(:merge_request, :simple, author: user, source_branch: 'draft4', source_project: project1, target_project: project2, title: 'Draft - thing') }
[:wip, :draft].each do |draft_param_key|
it "filters by #{draft_param_key}" do
params = { draft_param_key => 'yes' }
shared_examples 'draft MRs filtering' do |draft_param_key, draft_param_value, title_prefix, draft_only|
it "filters by #{draft_param_key} => #{draft_param_value}" do
merge_request1.reload.update!(title: "#{title_prefix} #{merge_request1.title}")
params = { draft_param_key => draft_param_value }
merge_requests = described_class.new(user, params).execute
expect(merge_requests).to contain_exactly(
merge_request4, merge_request5, wip_merge_request1, wip_merge_request2, wip_merge_request3, wip_merge_request4,
draft_merge_request1, draft_merge_request2, draft_merge_request3, draft_merge_request4
)
if draft_only
expect(merge_requests).to contain_exactly(merge_request1, merge_request4, merge_request5)
else
expect(merge_requests).to contain_exactly(merge_request2, merge_request3)
end
end
end
it "filters by not #{draft_param_key}" do
params = { draft_param_key => 'no' }
merge_requests = described_class.new(user, params).execute
{
wip: ["WIP:", "wip", "[wip]"],
draft: ["Draft:", "Draft -", "[Draft]", "(Draft)"]
}.each do |draft_param_key, title_prefixes|
title_prefixes.each do |title_prefix|
it_behaves_like 'draft MRs filtering', draft_param_key, 1, title_prefix, true
it_behaves_like 'draft MRs filtering', draft_param_key, '1', title_prefix, true
it_behaves_like 'draft MRs filtering', draft_param_key, true, title_prefix, true
it_behaves_like 'draft MRs filtering', draft_param_key, 'true', title_prefix, true
it_behaves_like 'draft MRs filtering', draft_param_key, 'yes', title_prefix, true
expect(merge_requests).to contain_exactly(merge_request1, merge_request2, merge_request3)
it_behaves_like 'draft MRs filtering', draft_param_key, 0, title_prefix, false
it_behaves_like 'draft MRs filtering', draft_param_key, '0', title_prefix, false
it_behaves_like 'draft MRs filtering', draft_param_key, false, title_prefix, false
it_behaves_like 'draft MRs filtering', draft_param_key, 'false', title_prefix, false
it_behaves_like 'draft MRs filtering', draft_param_key, 'no', title_prefix, false
end
it "returns all items if no valid #{draft_param_key} param exists" do
......@@ -313,43 +318,41 @@ RSpec.describe MergeRequestsFinder do
merge_requests = described_class.new(user, params).execute
expect(merge_requests).to contain_exactly(
merge_request1, merge_request2, merge_request3, merge_request4,
merge_request5, wip_merge_request1, wip_merge_request2, wip_merge_request3, wip_merge_request4,
draft_merge_request1, draft_merge_request2, draft_merge_request3, draft_merge_request4
merge_request1, merge_request2, merge_request3, merge_request4, merge_request5
)
end
end
end
context 'filter by deployment' do
let_it_be(:project_with_repo) { create(:project, :repository) }
context 'filter by deployment' do
let_it_be(:project_with_repo) { create(:project, :repository) }
it 'returns the relevant merge requests' do
deployment1 = create(
:deployment,
project: project_with_repo,
sha: project_with_repo.commit.id
)
deployment2 = create(
:deployment,
project: project_with_repo,
sha: project_with_repo.commit.id
)
deployment1.link_merge_requests(MergeRequest.where(id: [merge_request1.id, merge_request2.id]))
deployment2.link_merge_requests(MergeRequest.where(id: merge_request3.id))
it 'returns the relevant merge requests' do
deployment1 = create(
:deployment,
project: project_with_repo,
sha: project_with_repo.commit.id
)
deployment2 = create(
:deployment,
project: project_with_repo,
sha: project_with_repo.commit.id
)
deployment1.link_merge_requests(MergeRequest.where(id: [merge_request1.id, merge_request2.id]))
deployment2.link_merge_requests(MergeRequest.where(id: merge_request3.id))
params = { deployment_id: deployment1.id }
merge_requests = described_class.new(user, params).execute
params = { deployment_id: deployment1.id }
merge_requests = described_class.new(user, params).execute
expect(merge_requests).to contain_exactly(merge_request1, merge_request2)
end
expect(merge_requests).to contain_exactly(merge_request1, merge_request2)
end
context 'when a deployment does not contain any merge requests' do
it 'returns an empty result' do
params = { deployment_id: create(:deployment, project: project_with_repo, sha: project_with_repo.commit.sha).id }
merge_requests = described_class.new(user, params).execute
context 'when a deployment does not contain any merge requests' do
it 'returns an empty result' do
params = { deployment_id: create(:deployment, project: project_with_repo, sha: project_with_repo.commit.sha).id }
merge_requests = described_class.new(user, params).execute
expect(merge_requests).to be_empty
end
expect(merge_requests).to be_empty
end
end
end
......
......@@ -172,6 +172,28 @@ RSpec.describe Resolvers::MergeRequestsResolver do
end
end
context 'with draft argument' do
before do
merge_request_4.update!(title: MergeRequest.wip_title(merge_request_4.title))
end
context 'with draft: true argument' do
it 'takes one argument' do
result = resolve_mr(project, draft: true)
expect(result).to contain_exactly(merge_request_4)
end
end
context 'with draft: false argument' do
it 'takes one argument' do
result = resolve_mr(project, draft: false)
expect(result).not_to contain_exactly(merge_request_1, merge_request_2, merge_request_3, merge_request_5, merge_request_6)
end
end
end
context 'with label argument' do
let_it_be(:label) { merge_request_6.labels.first }
let_it_be(:with_label) { create(:labeled_merge_request, :closed, labels: [label], **common_attrs) }
......
......@@ -289,6 +289,7 @@ RSpec.describe GitlabSchema.types['Project'] do
:source_branches,
:target_branches,
:state,
:draft,
:labels,
:before,
:after,
......
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