2020-05-24 23:13:21 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
require 'spec_helper'
|
|
|
|
|
|
|
|
RSpec.describe AlertManagement::CreateAlertIssueService do
|
|
|
|
let_it_be(:user) { create(:user) }
|
2020-07-28 23:09:34 +05:30
|
|
|
let_it_be(:group) { create(:group) }
|
|
|
|
let_it_be(:project) { create(:project, group: group) }
|
2020-05-24 23:13:21 +05:30
|
|
|
let_it_be(:payload) do
|
|
|
|
{
|
|
|
|
'startsAt' => '2020-04-27T10:10:22.265949279Z',
|
|
|
|
'generatorURL' => 'http://8d467bd4607a:9090/graph?g0.expr=vector%281%29&g0.tab=1'
|
|
|
|
}
|
|
|
|
end
|
2021-01-29 00:20:46 +05:30
|
|
|
|
2020-05-24 23:13:21 +05:30
|
|
|
let_it_be(:generic_alert, reload: true) { create(:alert_management_alert, :triggered, project: project, payload: payload) }
|
2020-07-28 23:09:34 +05:30
|
|
|
let_it_be(:prometheus_alert, reload: true) { create(:alert_management_alert, :triggered, :prometheus, project: project, payload: payload) }
|
2021-09-30 23:02:18 +05:30
|
|
|
|
2020-05-24 23:13:21 +05:30
|
|
|
let(:alert) { generic_alert }
|
2020-07-28 23:09:34 +05:30
|
|
|
let(:alert_presenter) { alert.present }
|
2020-05-24 23:13:21 +05:30
|
|
|
let(:created_issue) { Issue.last! }
|
|
|
|
|
|
|
|
describe '#execute' do
|
|
|
|
subject(:execute) { described_class.new(alert, user).execute }
|
|
|
|
|
|
|
|
before do
|
|
|
|
allow(user).to receive(:can?).and_call_original
|
|
|
|
allow(user).to receive(:can?)
|
|
|
|
.with(:create_issue, project)
|
|
|
|
.and_return(can_create)
|
|
|
|
end
|
|
|
|
|
2020-07-28 23:09:34 +05:30
|
|
|
shared_examples 'creating an alert issue' do
|
2020-05-24 23:13:21 +05:30
|
|
|
it 'creates an issue' do
|
|
|
|
expect { execute }.to change { project.issues.count }.by(1)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns a created issue' do
|
|
|
|
expect(execute.payload).to eq(issue: created_issue)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'has a successful status' do
|
|
|
|
expect(execute).to be_success
|
|
|
|
end
|
|
|
|
|
2022-04-04 11:22:00 +05:30
|
|
|
it 'sets alert.issue_id in the same ActiveRecord query execution' do
|
2020-05-24 23:13:21 +05:30
|
|
|
execute
|
|
|
|
|
2022-04-04 11:22:00 +05:30
|
|
|
expect(alert.issue_id).to eq(created_issue.id)
|
2020-05-24 23:13:21 +05:30
|
|
|
end
|
|
|
|
|
2020-07-28 23:09:34 +05:30
|
|
|
it 'creates a system note' do
|
|
|
|
expect { execute }.to change { alert.reload.notes.count }.by(1)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
shared_examples 'setting an issue attributes' do
|
|
|
|
before do
|
2020-05-24 23:13:21 +05:30
|
|
|
execute
|
2020-07-28 23:09:34 +05:30
|
|
|
end
|
2020-05-24 23:13:21 +05:30
|
|
|
|
2020-07-28 23:09:34 +05:30
|
|
|
it 'sets issue author to the current user' do
|
2020-05-24 23:13:21 +05:30
|
|
|
expect(created_issue.author).to eq(user)
|
|
|
|
end
|
2020-07-28 23:09:34 +05:30
|
|
|
|
|
|
|
it 'sets the issue title' do
|
|
|
|
expect(created_issue.title).to eq(alert.title)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'sets the issue description' do
|
2020-11-24 15:15:51 +05:30
|
|
|
expect(created_issue.description).to include(alert_presenter.send(:issue_summary_markdown).strip)
|
2020-07-28 23:09:34 +05:30
|
|
|
end
|
2020-05-24 23:13:21 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
context 'when a user is allowed to create an issue' do
|
|
|
|
let(:can_create) { true }
|
|
|
|
|
|
|
|
before do
|
|
|
|
project.add_developer(user)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'checks permissions' do
|
|
|
|
execute
|
2022-11-25 23:54:43 +05:30
|
|
|
expect(user).to have_received(:can?).with(:create_issue, project).exactly(2).times
|
2020-05-24 23:13:21 +05:30
|
|
|
end
|
|
|
|
|
2020-11-24 15:15:51 +05:30
|
|
|
context 'with alert severity' do
|
|
|
|
using RSpec::Parameterized::TableSyntax
|
|
|
|
|
|
|
|
where(:alert_severity, :incident_severity) do
|
|
|
|
'critical' | 'critical'
|
|
|
|
'high' | 'high'
|
|
|
|
'medium' | 'medium'
|
|
|
|
'low' | 'low'
|
|
|
|
'info' | 'unknown'
|
|
|
|
'unknown' | 'unknown'
|
|
|
|
end
|
|
|
|
|
|
|
|
with_them do
|
|
|
|
before do
|
|
|
|
alert.update!(severity: alert_severity)
|
|
|
|
execute
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'sets the correct severity level' do
|
|
|
|
expect(created_issue.severity).to eq(incident_severity)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-05-24 23:13:21 +05:30
|
|
|
context 'when the alert is prometheus alert' do
|
|
|
|
let(:alert) { prometheus_alert }
|
2020-07-28 23:09:34 +05:30
|
|
|
let(:issue) { subject.payload[:issue] }
|
2020-05-24 23:13:21 +05:30
|
|
|
|
2020-07-28 23:09:34 +05:30
|
|
|
it_behaves_like 'creating an alert issue'
|
|
|
|
it_behaves_like 'setting an issue attributes'
|
2020-05-24 23:13:21 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
context 'when the alert is generic' do
|
|
|
|
let(:alert) { generic_alert }
|
2020-07-28 23:09:34 +05:30
|
|
|
let(:issue) { subject.payload[:issue] }
|
2021-04-17 20:07:23 +05:30
|
|
|
let(:default_alert_title) { described_class::DEFAULT_ALERT_TITLE }
|
2020-05-24 23:13:21 +05:30
|
|
|
|
2020-07-28 23:09:34 +05:30
|
|
|
it_behaves_like 'creating an alert issue'
|
|
|
|
it_behaves_like 'setting an issue attributes'
|
2021-04-17 20:07:23 +05:30
|
|
|
|
|
|
|
context 'when alert title matches the default title exactly' do
|
|
|
|
before do
|
|
|
|
generic_alert.update!(title: default_alert_title)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'updates issue title with the IID' do
|
|
|
|
execute
|
|
|
|
|
|
|
|
expect(created_issue.title).to eq("New: Incident #{created_issue.iid}")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when the alert title contains the default title' do
|
|
|
|
let(:non_default_alert_title) { "Not #{default_alert_title}" }
|
|
|
|
|
|
|
|
before do
|
|
|
|
generic_alert.update!(title: non_default_alert_title)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not change issue title' do
|
|
|
|
execute
|
|
|
|
|
|
|
|
expect(created_issue.title).to eq(non_default_alert_title)
|
|
|
|
end
|
|
|
|
end
|
2020-05-24 23:13:21 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
context 'when issue cannot be created' do
|
2020-07-28 23:09:34 +05:30
|
|
|
let(:alert) { generic_alert }
|
2020-05-24 23:13:21 +05:30
|
|
|
|
|
|
|
before do
|
2020-07-28 23:09:34 +05:30
|
|
|
# Invalid alert
|
|
|
|
alert.update_columns(title: '')
|
2020-05-24 23:13:21 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
it 'has an unsuccessful status' do
|
|
|
|
expect(execute).to be_error
|
2022-11-25 23:54:43 +05:30
|
|
|
expect(execute.errors).to contain_exactly("Title can't be blank")
|
2020-05-24 23:13:21 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when alert cannot be updated' do
|
2020-06-23 00:09:42 +05:30
|
|
|
let(:alert) { create(:alert_management_alert, :with_validation_errors, :triggered, project: project, payload: payload) }
|
2020-05-24 23:13:21 +05:30
|
|
|
|
|
|
|
it 'responds with error' do
|
|
|
|
expect(execute).to be_error
|
2022-11-25 23:54:43 +05:30
|
|
|
expect(execute.errors).to contain_exactly('Hosts hosts array is over 255 chars')
|
2020-05-24 23:13:21 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when alert already has an attached issue' do
|
|
|
|
let!(:issue) { create(:issue, project: project) }
|
|
|
|
|
|
|
|
before do
|
|
|
|
alert.update!(issue_id: issue.id)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not create yet another issue' do
|
|
|
|
expect { execute }.not_to change(Issue, :count)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'responds with error' do
|
|
|
|
expect(execute).to be_error
|
|
|
|
expect(execute.message).to eq(_('An issue already exists'))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when a user is not allowed to create an issue' do
|
|
|
|
let(:can_create) { false }
|
|
|
|
|
|
|
|
it 'checks permissions' do
|
|
|
|
execute
|
|
|
|
expect(user).to have_received(:can?).with(:create_issue, project)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'responds with error' do
|
|
|
|
expect(execute).to be_error
|
|
|
|
expect(execute.message).to eq(_('You have no permissions'))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|