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
|
# frozen_string_literal: true
RSpec.shared_examples 'a Note mutation that does not create a Note' do
it do
expect do
post_graphql_mutation(mutation, current_user: current_user)
end.not_to change { Note.count }
end
end
RSpec.shared_examples 'a Note mutation that creates a Note' do
it do
expect do
post_graphql_mutation(mutation, current_user: current_user)
end.to change { Note.count }.by(1)
end
end
RSpec.shared_examples 'a Note mutation when the user does not have permission' do
it_behaves_like 'a Note mutation that does not create a Note'
it_behaves_like 'a mutation that returns top-level errors',
errors: ['The resource that you are attempting to access does not exist or you don\'t have permission to perform this action']
end
RSpec.shared_examples 'a Note mutation when there are active record validation errors' do |model: Note|
before do
expect_next_instance_of(model) do |note|
allow(note).to receive_message_chain(:errors, :empty?).and_return(true)
expect(note).to receive(:valid?).at_least(:once).and_return(false)
expect(note).to receive_message_chain(
:errors,
:full_messages
).and_return(['Error 1', 'Error 2'])
end
end
it_behaves_like 'a Note mutation that does not create a Note'
it_behaves_like 'a mutation that returns errors in the response', errors: ['Error 1', 'Error 2']
it 'returns an empty Note' do
post_graphql_mutation(mutation, current_user: current_user)
expect(mutation_response).to have_key('note')
expect(mutation_response['note']).to be_nil
end
end
RSpec.shared_examples 'a Note mutation when the given resource id is not for a Noteable' do
let(:noteable) { create(:label, project: project) }
it_behaves_like 'a Note mutation that does not create a Note'
it_behaves_like 'a mutation that returns top-level errors' do
let(:match_errors) { include(/ does not represent an instance of Noteable/) }
end
end
RSpec.shared_examples 'a Note mutation when the given resource id is not for a Note' do
let(:note) { create(:issue) }
it_behaves_like 'a mutation that returns top-level errors' do
let(:match_errors) { include(/does not represent an instance of Note/) }
end
end
RSpec.shared_examples 'a Note mutation when there are rate limit validation errors' do
context 'with rate limiter', :freeze_time, :clean_gitlab_redis_rate_limiting do
before do
stub_application_setting(notes_create_limit: 3)
3.times { post_graphql_mutation(mutation, current_user: current_user) }
end
it_behaves_like 'a Note mutation that does not create a Note'
it_behaves_like 'a mutation that returns top-level errors',
errors: ['This endpoint has been requested too many times. Try again later.']
context 'when the user is in the allowlist' do
before do
stub_application_setting(notes_create_limit_allowlist: [current_user.username.to_s])
end
it_behaves_like 'a Note mutation that creates a Note'
end
end
end
RSpec.shared_examples 'a Note mutation with confidential notes' do
it_behaves_like 'a Note mutation that creates a Note'
it 'returns a Note with confidentiality enabled' do
post_graphql_mutation(mutation, current_user: current_user)
expect(mutation_response).to have_key('note')
expect(mutation_response['note']['confidential']).to eq(true)
expect(mutation_response['note']['internal']).to eq(true)
end
end
RSpec.shared_examples 'a Note mutation updates a note successfully' do
it 'updates the Note' do
post_graphql_mutation(mutation, current_user: current_user)
expect(note.reload.note).to eq(updated_body)
end
it 'returns the updated Note' do
post_graphql_mutation(mutation, current_user: current_user)
expect(mutation_response['note']['body']).to eq(updated_body)
end
end
RSpec.shared_examples 'a Note mutation update with errors' do
context 'when there are ActiveRecord validation errors' do
let(:params) { { body: '', confidential: true } }
it_behaves_like 'a mutation that returns errors in the response',
errors: ["Note can't be blank", 'Confidential can not be changed for existing notes']
it 'does not update the Note' do
post_graphql_mutation(mutation, current_user: current_user)
expect(note.reload.note).to eq(original_body)
expect(note.confidential).to be_falsey
end
it 'returns the original Note' do
post_graphql_mutation(mutation, current_user: current_user)
expect(mutation_response['note']['body']).to eq(original_body)
expect(mutation_response['note']['confidential']).to be_falsey
end
end
end
RSpec.shared_examples 'a Note mutation update only with quick actions' do
context 'when body only contains quick actions' do
let(:updated_body) { '/close' }
it 'returns a nil note and empty errors' do
post_graphql_mutation(mutation, current_user: current_user)
expect(mutation_response).to include(
'errors' => [],
'note' => nil
)
end
end
end
|