1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Resolvers::BoardListIssuesResolver do
include GraphqlHelpers
let_it_be(:user) { create(:user) }
let_it_be(:unauth_user) { create(:user) }
let_it_be(:user_project) { create(:project, creator_id: user.id, namespace: user.namespace ) }
let_it_be(:group) { create(:group, :private) }
shared_examples_for 'group and project board list issues resolver' do
before do
board_parent.add_developer(user)
end
# auth is handled by the parent object
context 'when authorized' do
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, milestone: started_milestone) }
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(:wildcard_started) { 'STARTED' }
let(:filters) { { milestone_title: ["started"], milestone_wildcard_id: wildcard_started } }
it 'raises a mutually exclusive filter error when milestone 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 the issues in the correct order' do
# by relative_position and then ID
result = resolve_board_list_issues
expect(result.map(&:id)).to eq [issue1.id, issue3.id, issue2.id, issue4.id]
end
it 'finds only issues matching filters' do
result = resolve_board_list_issues(args: { filters: { label_name: [label.title], not: { label_name: [label2.title] } } })
expect(result).to match_array([issue1, issue3, issue4])
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
result = resolve_board_list_issues(args: { filters: { search: issue1.title } })
expect(result).to match_array([issue1])
end
it 'filters issues by negated issue type' do
incident = create(:incident, project: project, labels: [label], relative_position: 15)
result = resolve_board_list_issues(args: { filters: { not: { types: ['issue'] } } })
expect(result).to contain_exactly(incident)
end
it 'raises an exception if both assignee_username and assignee_wildcard_id are present' do
expect do
resolve_board_list_issues(args: { filters: { assignee_username: ['username'], assignee_wildcard_id: 'NONE' } })
end.to raise_error(Gitlab::Graphql::Errors::ArgumentError)
end
it 'accepts assignee wildcard id NONE' do
result = resolve_board_list_issues(args: { filters: { assignee_wildcard_id: 'NONE' } })
expect(result).to match_array([issue1, issue2, issue3, issue4])
end
it 'accepts assignee wildcard id ANY' do
result = resolve_board_list_issues(args: { filters: { assignee_wildcard_id: 'ANY' } })
expect(result).to match_array([])
end
context 'when filtering by confidential' do
let(:confidential_issue) { create(:issue, project: project, labels: [label], relative_position: nil, confidential: true) }
it 'returns matching issue' do
result = resolve_board_list_issues(args: { filters: { confidential: true } })
expect(result).to contain_exactly(confidential_issue)
end
end
end
end
describe '#resolve' do
context 'when project boards' do
let_it_be(:label) { create(:label, project: user_project) }
let_it_be(:label2) { create(:label, project: user_project) }
let_it_be(:label3) { create(:label, project: user_project) }
let_it_be(:board) { create(:board, resource_parent: user_project) }
let_it_be(:list) { create(:list, board: board, label: label) }
let(:board_parent) { 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'
end
context 'when group boards' do
let_it_be(:label) { create(:group_label, group: group) }
let_it_be(:label2) { create(:group_label, group: group) }
let_it_be(:label3) { create(:group_label, group: group) }
let_it_be(:board) { create(:board, resource_parent: group) }
let_it_be(:list) { create(:list, board: board, label: label) }
let(:board_parent) { 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'
end
end
def resolve_board_list_issues(args: {}, current_user: user)
resolve(described_class, obj: list, args: args, ctx: { current_user: current_user })
end
end
|