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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'Reposition and move issue within board lists', feature_category: :team_planning do
include GraphqlHelpers
let_it_be(:group) { create(:group, :private) }
let_it_be(:project) { create(:project, group: group) }
let_it_be(:board) { create(:board, group: group) }
let_it_be(:user) { create(:user) }
let_it_be(:development) { create(:label, project: project, name: 'Development') }
let_it_be(:testing) { create(:label, project: project, name: 'Testing') }
let_it_be(:list1) { create(:list, board: board, label: development, position: 0) }
let_it_be(:list2) { create(:list, board: board, label: testing, position: 1) }
let_it_be(:existing_issue1) { create(:labeled_issue, project: project, labels: [testing], relative_position: 10) }
let_it_be(:existing_issue2) { create(:labeled_issue, project: project, labels: [testing], relative_position: 50) }
let_it_be(:issue1) { create(:labeled_issue, project: project, labels: [development]) }
let(:mutation_class) { Mutations::Boards::Issues::IssueMoveList }
let(:mutation_name) { mutation_class.graphql_name }
let(:mutation_result_identifier) { mutation_name.camelize(:lower) }
let(:current_user) { user }
let(:board_id) { global_id_of(board) }
let(:params) { { board_id: board_id, project_path: project.full_path, iid: issue1.iid.to_s } }
let(:issue_move_params) do
{
from_list_id: list1.id,
to_list_id: list2.id
}
end
before_all do
group.add_maintainer(user)
end
shared_examples 'returns an error' do
let(:message) do
"The resource that you are attempting to access does not exist or you don't have " \
"permission to perform this action"
end
it 'fails with error' do
post_graphql_mutation(mutation(params), current_user: current_user)
expect(graphql_errors).to include(a_hash_including('message' => message))
end
end
context 'when the board_id is not a board' do
let(:board_id) { global_id_of(project) }
let(:issue_move_params) do
{ move_after_id: existing_issue1.id, move_before_id: existing_issue2.id }
end
it_behaves_like 'returns an error' do
let(:message) { include('does not represent an instance of') }
end
end
# This test aims to distinguish between the failures to authorize
# :read_issue_board and :update_issue
context 'when the user cannot read the issue board' do
let(:issue_move_params) do
{ move_after_id: existing_issue1.id, move_before_id: existing_issue2.id }
end
before do
allow(Ability).to receive(:allowed?).with(any_args).and_return(true)
allow(Ability).to receive(:allowed?).with(current_user, :read_issue_board, board).and_return(false)
end
it_behaves_like 'returns an error'
end
context 'when user has access to resources' do
context 'when repositioning an issue' do
let(:issue_move_params) { { move_after_id: existing_issue1.id, move_before_id: existing_issue2.id } }
it 'repositions an issue' do
post_graphql_mutation(mutation(params), current_user: current_user)
expect(response).to have_gitlab_http_status(:success)
response_issue = json_response['data'][mutation_result_identifier]['issue']
expect(response_issue['iid']).to eq(issue1.iid.to_s)
expect(response_issue['relativePosition']).to be > existing_issue1.relative_position
expect(response_issue['relativePosition']).to be < existing_issue2.relative_position
end
end
context 'when moving an issue to a different list' do
let(:issue_move_params) { { from_list_id: list1.id, to_list_id: list2.id } }
it 'moves issue to a different list' do
post_graphql_mutation(mutation(params), current_user: current_user)
expect(response).to have_gitlab_http_status(:success)
response_issue = json_response['data'][mutation_result_identifier]['issue']
expect(response_issue['iid']).to eq(issue1.iid.to_s)
expect(response_issue['labels']['edges'][0]['node']['title']).to eq(testing.title)
end
end
context 'when moving an issue using position_in_list' do
let(:issue_move_params) { { from_list_id: list1.id, to_list_id: list2.id, position_in_list: 0 } }
it 'repositions an issue' do
post_graphql_mutation(mutation(params), current_user: current_user)
expect(response).to have_gitlab_http_status(:success)
response_issue = json_response['data'][mutation_result_identifier]['issue']
expect(response_issue['iid']).to eq(issue1.iid.to_s)
expect(response_issue['labels']['edges'][0]['node']['title']).to eq(testing.title)
expect(response_issue['relativePosition']).to be < existing_issue1.relative_position
end
end
end
context 'when user has no access to resources' do
context 'the user is not allowed to update the issue' do
let(:current_user) { create(:user) }
it_behaves_like 'returns an error'
end
context 'when the user can not read board' do
let(:board) { create(:board, group: create(:group, :private)) }
it_behaves_like 'returns an error'
end
end
def mutation(additional_params = {})
graphql_mutation(mutation_name, issue_move_params.merge(additional_params),
<<-QL.strip_heredoc
clientMutationId
issue {
iid,
relativePosition
labels {
edges {
node{
title
}
}
}
}
errors
QL
)
end
end
|