From c813ed1f2fbf6d65179079cc8a86bcde8d52c326 Mon Sep 17 00:00:00 2001
From: syasonik <syasonik@gitlab.com>
Date: Thu, 3 Feb 2022 20:57:17 -0500
Subject: [PATCH] Create issue which is already associated with the alert

This change is not user-facing and ensures that issues are
created while associated with the alert to support the correct
behavior for the :incident_escalations feature flag.
---
 .../create_alert_issue_service.rb             | 13 ++-----------
 .../incidents/create_service.rb               | 16 +++++++++++-----
 .../create_alert_issue_service_spec.rb        |  4 ++--
 .../incidents/create_service_spec.rb          | 19 +++++++++++++++++++
 4 files changed, 34 insertions(+), 18 deletions(-)

diff --git a/app/services/alert_management/create_alert_issue_service.rb b/app/services/alert_management/create_alert_issue_service.rb
index a81c2380dad..ab8d1176b9e 100644
--- a/app/services/alert_management/create_alert_issue_service.rb
+++ b/app/services/alert_management/create_alert_issue_service.rb
@@ -22,8 +22,6 @@ module AlertManagement
       return result unless result.success?
 
       issue = result.payload[:issue]
-      return error(object_errors(alert), issue) unless associate_alert_with_issue(issue)
-
       update_title_for(issue)
 
       SystemNoteService.new_alert_issue(alert, issue, user)
@@ -47,14 +45,11 @@ module AlertManagement
         user,
         title: alert_presenter.title,
         description: alert_presenter.issue_description,
-        severity: alert.severity
+        severity: alert.severity,
+        alert: alert
       ).execute
     end
 
-    def associate_alert_with_issue(issue)
-      alert.update(issue_id: issue.id)
-    end
-
     def update_title_for(issue)
       return unless issue.title == DEFAULT_ALERT_TITLE
 
@@ -78,9 +73,5 @@ module AlertManagement
         alert.present
       end
     end
-
-    def object_errors(object)
-      object.errors.full_messages.to_sentence
-    end
   end
 end
diff --git a/app/services/incident_management/incidents/create_service.rb b/app/services/incident_management/incidents/create_service.rb
index f8437290d9b..ef66325fdcc 100644
--- a/app/services/incident_management/incidents/create_service.rb
+++ b/app/services/incident_management/incidents/create_service.rb
@@ -2,15 +2,16 @@
 
 module IncidentManagement
   module Incidents
-    class CreateService < BaseService
+    class CreateService < ::BaseProjectService
       ISSUE_TYPE = 'incident'
 
-      def initialize(project, current_user, title:, description:, severity: IssuableSeverity::DEFAULT)
-        super(project, current_user)
+      def initialize(project, current_user, title:, description:, severity: IssuableSeverity::DEFAULT, alert: nil)
+        super(project: project, current_user: current_user)
 
         @title = title
         @description = description
         @severity = severity
+        @alert = alert
       end
 
       def execute
@@ -21,11 +22,16 @@ module IncidentManagement
             title: title,
             description: description,
             issue_type: ISSUE_TYPE,
-            severity: severity
+            severity: severity,
+            alert_management_alert: alert
           },
           spam_params: nil
         ).execute
 
+        if alert
+          return error(alert.errors.full_messages.to_sentence, issue) unless alert.valid?
+        end
+
         return error(issue.errors.full_messages.to_sentence, issue) unless issue.valid?
 
         success(issue)
@@ -33,7 +39,7 @@ module IncidentManagement
 
       private
 
-      attr_reader :title, :description, :severity
+      attr_reader :title, :description, :severity, :alert
 
       def success(issue)
         ServiceResponse.success(payload: { issue: issue })
diff --git a/spec/services/alert_management/create_alert_issue_service_spec.rb b/spec/services/alert_management/create_alert_issue_service_spec.rb
index 55f8e47717c..083e5b8c6f1 100644
--- a/spec/services/alert_management/create_alert_issue_service_spec.rb
+++ b/spec/services/alert_management/create_alert_issue_service_spec.rb
@@ -43,10 +43,10 @@ RSpec.describe AlertManagement::CreateAlertIssueService do
         expect(execute).to be_success
       end
 
-      it 'updates alert.issue_id' do
+      it 'sets alert.issue_id in the same ActiveRecord query execution' do
         execute
 
-        expect(alert.reload.issue_id).to eq(created_issue.id)
+        expect(alert.issue_id).to eq(created_issue.id)
       end
 
       it 'creates a system note' do
diff --git a/spec/services/incident_management/incidents/create_service_spec.rb b/spec/services/incident_management/incidents/create_service_spec.rb
index 862b7de4ec8..ac44bc4608c 100644
--- a/spec/services/incident_management/incidents/create_service_spec.rb
+++ b/spec/services/incident_management/incidents/create_service_spec.rb
@@ -83,6 +83,25 @@ RSpec.describe IncidentManagement::Incidents::CreateService do
       it 'result payload contains an Issue object' do
         expect(create_incident.payload[:issue]).to be_kind_of(Issue)
       end
+
+      context 'with alert' do
+        let(:alert) { create(:alert_management_alert, project: project) }
+
+        subject(:create_incident) { described_class.new(project, user, title: title, description: description, alert: alert).execute }
+
+        it 'associates the alert with the incident' do
+          expect(create_incident[:issue].alert_management_alert).to eq(alert)
+        end
+
+        context 'the alert prevents the issue from saving' do
+          let(:alert) { create(:alert_management_alert, :with_validation_errors, project: project) }
+
+          it 'responds with errors' do
+            expect(create_incident).to be_error
+            expect(create_incident.message).to eq('Hosts hosts array is over 255 chars')
+          end
+        end
+      end
     end
   end
 end
-- 
GitLab