Commit 75fd1f06 authored by Jarka Košanová's avatar Jarka Košanová

Add milestoneWildcardId to board issues graphQL endpoint

Changelog: added
parent 4a3a6d93
...@@ -13,7 +13,10 @@ module Resolvers ...@@ -13,7 +13,10 @@ module Resolvers
alias_method :list, :object alias_method :list, :object
def resolve(**args) def resolve(**args)
filter_params = item_filters(args[:filters]).merge(board_id: list.board.id, id: list.id) filters = item_filters(args[:filters])
mutually_exclusive_milestone_args!(filters)
filter_params = filters.merge(board_id: list.board.id, id: list.id)
service = ::Boards::Issues::ListService.new(list.board.resource_parent, context[:current_user], filter_params) service = ::Boards::Issues::ListService.new(list.board.resource_parent, context[:current_user], filter_params)
pagination_connections = Gitlab::Graphql::Pagination::Keyset::Connection.new(service.execute) pagination_connections = Gitlab::Graphql::Pagination::Keyset::Connection.new(service.execute)
...@@ -26,5 +29,13 @@ module Resolvers ...@@ -26,5 +29,13 @@ module Resolvers
def self.complexity_multiplier(args) def self.complexity_multiplier(args)
0.005 0.005
end end
private
def mutually_exclusive_milestone_args!(filters)
if filters[:milestone_title] && filters[:milestone_wildcard_id]
raise ::Gitlab::Graphql::Errors::ArgumentError, 'Incompatible arguments: milestoneTitle, milestoneWildcardId.'
end
end
end end
end end
...@@ -24,6 +24,10 @@ module Types ...@@ -24,6 +24,10 @@ module Types
as: :issue_types, as: :issue_types,
description: 'Filter by the given issue types.', description: 'Filter by the given issue types.',
required: false required: false
argument :milestone_wildcard_id, ::Types::MilestoneWildcardIdEnum,
required: false,
description: 'Filter by milestone ID wildcard.'
end end
end end
end end
......
...@@ -17414,6 +17414,7 @@ Field that are available while modifying the custom mapping attributes for an HT ...@@ -17414,6 +17414,7 @@ Field that are available while modifying the custom mapping attributes for an HT
| <a id="boardissueinputiterationwildcardid"></a>`iterationWildcardId` | [`IterationWildcardId`](#iterationwildcardid) | Filter by iteration ID wildcard. | | <a id="boardissueinputiterationwildcardid"></a>`iterationWildcardId` | [`IterationWildcardId`](#iterationwildcardid) | Filter by iteration ID wildcard. |
| <a id="boardissueinputlabelname"></a>`labelName` | [`[String]`](#string) | Filter by label name. | | <a id="boardissueinputlabelname"></a>`labelName` | [`[String]`](#string) | Filter by label name. |
| <a id="boardissueinputmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter by milestone title. | | <a id="boardissueinputmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter by milestone title. |
| <a id="boardissueinputmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter by milestone ID wildcard. |
| <a id="boardissueinputmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. Wildcard values "NONE" and "ANY" are supported. | | <a id="boardissueinputmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. Wildcard values "NONE" and "ANY" are supported. |
| <a id="boardissueinputnot"></a>`not` | [`NegatedBoardIssueInput`](#negatedboardissueinput) | List of negated arguments. | | <a id="boardissueinputnot"></a>`not` | [`NegatedBoardIssueInput`](#negatedboardissueinput) | List of negated arguments. |
| <a id="boardissueinputreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. | | <a id="boardissueinputreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
...@@ -17594,6 +17595,7 @@ Represents an escalation rule. ...@@ -17594,6 +17595,7 @@ Represents an escalation rule.
| <a id="negatedboardissueinputiterationwildcardid"></a>`iterationWildcardId` | [`NegatedIterationWildcardId`](#negatediterationwildcardid) | Filter by iteration ID wildcard. | | <a id="negatedboardissueinputiterationwildcardid"></a>`iterationWildcardId` | [`NegatedIterationWildcardId`](#negatediterationwildcardid) | Filter by iteration ID wildcard. |
| <a id="negatedboardissueinputlabelname"></a>`labelName` | [`[String]`](#string) | Filter by label name. | | <a id="negatedboardissueinputlabelname"></a>`labelName` | [`[String]`](#string) | Filter by label name. |
| <a id="negatedboardissueinputmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter by milestone title. | | <a id="negatedboardissueinputmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter by milestone title. |
| <a id="negatedboardissueinputmilestonewildcardid"></a>`milestoneWildcardId` | [`MilestoneWildcardId`](#milestonewildcardid) | Filter by milestone ID wildcard. |
| <a id="negatedboardissueinputmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. Wildcard values "NONE" and "ANY" are supported. | | <a id="negatedboardissueinputmyreactionemoji"></a>`myReactionEmoji` | [`String`](#string) | Filter by reaction emoji applied by the current user. Wildcard values "NONE" and "ANY" are supported. |
| <a id="negatedboardissueinputreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. | | <a id="negatedboardissueinputreleasetag"></a>`releaseTag` | [`String`](#string) | Filter by release tag. |
| <a id="negatedboardissueinputtypes"></a>`types` | [`[IssueType!]`](#issuetype) | Filter by the given issue types. | | <a id="negatedboardissueinputtypes"></a>`types` | [`[IssueType!]`](#issuetype) | Filter by the given issue types. |
......
...@@ -17,11 +17,20 @@ RSpec.describe Resolvers::BoardListIssuesResolver do ...@@ -17,11 +17,20 @@ RSpec.describe Resolvers::BoardListIssuesResolver do
# auth is handled by the parent object # auth is handled by the parent object
context 'when authorized' do context 'when authorized' do
let!(:issue1) { create(:issue, project: project, labels: [label], relative_position: 10) } let!(:issue1) { create(:issue, project: project, labels: [label], relative_position: 10, milestone: started_milestone) }
let!(:issue2) { create(:issue, project: project, labels: [label, label2], relative_position: 12) } let!(:issue2) { create(:issue, project: project, labels: [label, label2], relative_position: 12, milestone: started_milestone) }
let!(:issue3) { create(:issue, project: project, labels: [label, label3], relative_position: 10) } let!(:issue3) { create(:issue, project: project, labels: [label, label3], relative_position: 10, milestone: future_milestone) }
let!(:issue4) { create(:issue, project: project, labels: [label], relative_position: nil) } let!(:issue4) { create(:issue, project: project, labels: [label], relative_position: nil) }
let(:wildcard_started) { 'STARTED' }
let(:filters) { { milestone_title: ["started"], milestone_wildcard_id: wildcard_started } }
it 'raises a mutually exclusive filter error when milstone wildcard and title are provided' do
expect do
resolve_board_list_issues(args: { filters: filters })
end.to raise_error(Gitlab::Graphql::Errors::ArgumentError)
end
it 'returns issues in the correct order with non-nil relative positions', :aggregate_failures do it 'returns issues in the correct order with non-nil relative positions', :aggregate_failures do
# by relative_position and then ID # by relative_position and then ID
result = resolve_board_list_issues result = resolve_board_list_issues
...@@ -36,6 +45,12 @@ RSpec.describe Resolvers::BoardListIssuesResolver do ...@@ -36,6 +45,12 @@ RSpec.describe Resolvers::BoardListIssuesResolver do
expect(result).to match_array([issue1, issue3, issue4]) expect(result).to match_array([issue1, issue3, issue4])
end end
it 'finds only issues filtered by milestone wildcard' do
result = resolve_board_list_issues(args: { filters: { milestone_wildcard_id: wildcard_started } })
expect(result).to match_array([issue1, issue2])
end
it 'finds only issues matching search param' do it 'finds only issues matching search param' do
result = resolve_board_list_issues(args: { filters: { search: issue1.title } }) result = resolve_board_list_issues(args: { filters: { search: issue1.title } })
...@@ -73,6 +88,9 @@ RSpec.describe Resolvers::BoardListIssuesResolver do ...@@ -73,6 +88,9 @@ RSpec.describe Resolvers::BoardListIssuesResolver do
let(:board_parent) { user_project } let(:board_parent) { user_project }
let(:project) { user_project } let(:project) { user_project }
let_it_be(:started_milestone) { create(:milestone, project: user_project, title: 'started milestone', start_date: 1.day.ago, due_date: 1.day.from_now) }
let_it_be(:future_milestone) { create(:milestone, project: user_project, title: 'future milestone', start_date: 1.day.from_now) }
it_behaves_like 'group and project board list issues resolver' it_behaves_like 'group and project board list issues resolver'
end end
...@@ -86,6 +104,9 @@ RSpec.describe Resolvers::BoardListIssuesResolver do ...@@ -86,6 +104,9 @@ RSpec.describe Resolvers::BoardListIssuesResolver do
let(:board_parent) { group } let(:board_parent) { group }
let!(:project) { create(:project, :private, group: group) } let!(:project) { create(:project, :private, group: group) }
let_it_be(:started_milestone) { create(:milestone, group: group, title: 'started milestone', start_date: 1.day.ago, due_date: 1.day.from_now) }
let_it_be(:future_milestone) { create(:milestone, group: group, title: 'future milestone', start_date: 1.day.from_now) }
it_behaves_like 'group and project board list issues resolver' it_behaves_like 'group and project board list issues resolver'
end 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