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
|
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe ErrorTracking::IssueUpdateService, feature_category: :error_tracking do
include_context 'sentry error tracking context'
let(:arguments) { { issue_id: non_existing_record_id, status: 'resolved' } }
subject(:update_service) { described_class.new(project, user, arguments) }
shared_examples 'does not perform close issue flow' do
it 'does not call the close issue service' do
update_service.execute
expect(issue_close_service).not_to have_received(:execute)
end
it 'does not create system note' do
expect(SystemNoteService).not_to receive(:close_after_error_tracking_resolve)
update_service.execute
end
end
describe '#execute' do
context 'with authorized user' do
context 'when update_issue returns success' do
let(:update_issue_response) { { updated: true } }
before do
allow(error_tracking_setting).to receive(:update_issue).and_return(update_issue_response)
end
it 'returns the response' do
expect(update_service.execute).to eq(update_issue_response.merge(status: :success, closed_issue_iid: nil))
end
it 'updates any related issue' do
expect(update_service).to receive(:update_related_issue)
update_service.execute
end
it 'clears the reactive cache' do
expect(error_tracking_setting).to receive(:expire_issues_cache)
result
end
context 'with related issue and resolving' do
let(:issue) { create(:issue, project: project) }
let(:sentry_issue) { create(:sentry_issue, issue: issue) }
let(:arguments) { { issue_id: sentry_issue.sentry_issue_identifier, status: 'resolved' } }
let(:issue_close_service) { instance_double('Issues::CloseService') }
before do
allow_next_instance_of(SentryIssueFinder) do |finder|
allow(finder).to receive(:execute).and_return(sentry_issue)
end
allow(Issues::CloseService)
.to receive(:new)
.and_return(issue_close_service)
allow(issue_close_service)
.to receive(:execute)
.and_return(issue)
end
it 'closes the issue' do
update_service.execute
expect(issue_close_service)
.to have_received(:execute)
.with(issue, system_note: false)
end
context 'when issue gets closed' do
let(:closed_issue) { create(:issue, :closed, project: project) }
before do
allow(issue_close_service)
.to receive(:execute)
.with(issue, system_note: false)
.and_return(closed_issue)
end
it 'creates a system note' do
expect(SystemNoteService).to receive(:close_after_error_tracking_resolve)
update_service.execute
end
it 'returns a response with closed issue' do
expect(update_service.execute).to eq(status: :success, updated: true, closed_issue_iid: closed_issue.iid)
end
end
context 'when issue is already closed' do
let(:issue) { create(:issue, :closed, project: project) }
include_examples 'does not perform close issue flow'
end
context 'when status is not resolving' do
let(:arguments) { { issue_id: sentry_issue.sentry_issue_identifier, status: 'ignored' } }
include_examples 'does not perform close issue flow'
end
end
end
include_examples 'error tracking service sentry error handling', :update_issue
context 'with integrated error tracking' do
let(:error) { create(:error_tracking_error, project: project) }
let(:arguments) { { issue_id: error.id, status: 'resolved' } }
let(:update_issue_response) { { updated: true, status: :success, closed_issue_iid: nil } }
before do
error_tracking_setting.update!(integrated: true)
end
it 'resolves the error and responds with expected format' do
expect(update_service.execute).to eq(update_issue_response)
expect(error.reload.status).to eq('resolved')
end
end
end
include_examples 'error tracking service unauthorized user'
include_examples 'error tracking service disabled'
end
end
|