From e94a628948fefa439d9592fd30a30d0dd0165830 Mon Sep 17 00:00:00 2001
From: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com>
Date: Thu, 15 Aug 2024 15:58:28 +0100
Subject: [PATCH] CLDC-2101 Add begin merge (#2575)
* Calculate merge request status
* Add start merge and merge request job
* Update merge request when it gets processed
* Refactor and display a banner for failed requests
* update test
* Update change links
---
app/controllers/merge_requests_controller.rb | 9 +++
app/helpers/merge_requests_helper.rb | 14 +++--
app/jobs/process_merge_request_job.rb | 14 +++++
app/models/merge_request.rb | 31 ++++++++++
app/models/merge_request_organisation.rb | 7 +++
.../_notification_banners.html.erb | 21 +++++++
app/views/merge_requests/show.html.erb | 25 ++-------
config/routes.rb | 1 +
.../20240814083017_add_last_failed_attempt.rb | 5 ++
db/schema.rb | 3 +-
.../{merge_requests.rb => merge_request.rb} | 0
spec/factories/merge_request_organisation.rb | 6 ++
spec/jobs/process_merge_request_job_spec.rb | 47 ++++++++++++++++
spec/models/merge_request_spec.rb | 47 ++++++++++++++++
.../merge_requests_controller_spec.rb | 56 +++++++++++++++++++
.../merge_requests/show.html.erb_spec.rb | 2 +-
16 files changed, 263 insertions(+), 25 deletions(-)
create mode 100644 app/jobs/process_merge_request_job.rb
create mode 100644 app/views/merge_requests/_notification_banners.html.erb
create mode 100644 db/migrate/20240814083017_add_last_failed_attempt.rb
rename spec/factories/{merge_requests.rb => merge_request.rb} (100%)
create mode 100644 spec/factories/merge_request_organisation.rb
create mode 100644 spec/jobs/process_merge_request_job_spec.rb
diff --git a/app/controllers/merge_requests_controller.rb b/app/controllers/merge_requests_controller.rb
index 95be8d875..f19224a92 100644
--- a/app/controllers/merge_requests_controller.rb
+++ b/app/controllers/merge_requests_controller.rb
@@ -61,6 +61,15 @@ class MergeRequestsController < ApplicationController
@new_merging_org_ids = []
end
+ def start_merge
+ if @merge_request.status == "ready_to_merge"
+ @merge_request.update!(status: :processing)
+ ProcessMergeRequestJob.perform_later(merge_request: @merge_request)
+ end
+
+ redirect_to merge_request_path(@merge_request)
+ end
+
private
def page
diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb
index 8318b533a..4d7408349 100644
--- a/app/helpers/merge_requests_helper.rb
+++ b/app/helpers/merge_requests_helper.rb
@@ -6,16 +6,16 @@ module MergeRequestsHelper
def request_details(merge_request)
[
{ label: "Requester", value: display_value_or_placeholder(merge_request.requester&.name) },
- { label: "Helpdesk ticket", value: merge_request.helpdesk_ticket.present? ? link_to("#{merge_request.helpdesk_ticket} (opens in a new tab)", "https://dluhcdigital.atlassian.net/browse/#{merge_request.helpdesk_ticket}", target: "_blank", rel: "noopener noreferrer") : display_value_or_placeholder(nil), action: merge_request.status == "request_merged" ? nil : { text: "Change", href: helpdesk_ticket_merge_request_path(merge_request, referrer: "check_answers"), visually_hidden_text: "helpdesk ticket" } },
+ { label: "Helpdesk ticket", value: merge_request.helpdesk_ticket.present? ? link_to("#{merge_request.helpdesk_ticket} (opens in a new tab)", "https://dluhcdigital.atlassian.net/browse/#{merge_request.helpdesk_ticket}", target: "_blank", rel: "noopener noreferrer") : display_value_or_placeholder(nil), action: merge_request_action(merge_request, "helpdesk_ticket") },
{ label: "Status", value: status_tag(merge_request.status) },
]
end
def merge_details(merge_request)
[
- { label: "Absorbing organisation", value: display_value_or_placeholder(merge_request.absorbing_organisation_name), action: merge_request.status == "request_merged" ? nil : { text: "Change", href: absorbing_organisation_merge_request_path(merge_request, referrer: "check_answers"), visually_hidden_text: "absorbing organisation" } },
- { label: "Merging organisations", value: merge_request.merge_request_organisations.any? ? merge_request.merge_request_organisations.map(&:merging_organisation_name).join("
").html_safe : display_value_or_placeholder(nil), action: merge_request.status == "request_merged" ? nil : { text: "Change", href: merging_organisations_merge_request_path(merge_request, referrer: "check_answers"), visually_hidden_text: "merging organisations" } },
- { label: "Merge date", value: display_value_or_placeholder(merge_request.merge_date), action: merge_request.status == "request_merged" ? nil : { text: "Change", href: merge_date_merge_request_path(merge_request, referrer: "check_answers"), visually_hidden_text: "merge date" } },
+ { label: "Absorbing organisation", value: display_value_or_placeholder(merge_request.absorbing_organisation_name), action: merge_request_action(merge_request, "absorbing_organisation") },
+ { label: "Merging organisations", value: merge_request.merge_request_organisations.any? ? merge_request.merge_request_organisations.map(&:merging_organisation_name).join("
").html_safe : display_value_or_placeholder(nil), action: merge_request_action(merge_request, "merging_organisations") },
+ { label: "Merge date", value: display_value_or_placeholder(merge_request.merge_date), action: merge_request_action(merge_request, "merge_date") },
]
end
@@ -68,4 +68,10 @@ module MergeRequestsHelper
merge_date_merge_request_path(merge_request)
end
end
+
+ def merge_request_action(merge_request, page)
+ unless merge_request.status == "request_merged" || merge_request.status == "processing"
+ { text: "Change", href: send("#{page}_merge_request_path", merge_request, referrer: "check_answers"), visually_hidden_text: page.humanize }
+ end
+ end
end
diff --git a/app/jobs/process_merge_request_job.rb b/app/jobs/process_merge_request_job.rb
new file mode 100644
index 000000000..b706d9a81
--- /dev/null
+++ b/app/jobs/process_merge_request_job.rb
@@ -0,0 +1,14 @@
+class ProcessMergeRequestJob < ApplicationJob
+ queue_as :default
+
+ def perform(merge_request:)
+ absorbing_organisation_id = merge_request.absorbing_organisation_id
+ merging_organisation_ids = merge_request.merging_organisations.pluck(:id)
+ merge_date = merge_request.merge_date
+
+ Merge::MergeOrganisationsService.new(absorbing_organisation_id:, merging_organisation_ids:, merge_date:).call
+ merge_request.update!(status: "request_merged", last_failed_attempt: nil)
+ rescue StandardError
+ merge_request.update!(last_failed_attempt: Time.zone.now)
+ end
+end
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 7c95e199c..078399c2a 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -4,6 +4,7 @@ class MergeRequest < ApplicationRecord
belongs_to :absorbing_organisation, class_name: "Organisation", optional: true
has_many :merging_organisations, through: :merge_request_organisations, source: :merging_organisation
belongs_to :requester, class_name: "User", optional: true
+ before_save :update_status!
STATUS = {
"merge_issues" => 0,
@@ -11,6 +12,7 @@ class MergeRequest < ApplicationRecord
"ready_to_merge" => 2,
"processing" => 3,
"request_merged" => 4,
+ "deleted" => 5,
}.freeze
enum status: STATUS
@@ -21,6 +23,8 @@ class MergeRequest < ApplicationRecord
merged.where("merge_requests.merge_date >= ?", open_collection_period_start_date).or(not_merged).where(discarded_at: nil)
}
+ attr_accessor :skip_update_status
+
def absorbing_organisation_name
absorbing_organisation&.name || ""
end
@@ -32,4 +36,31 @@ class MergeRequest < ApplicationRecord
def discard!
update!(discarded_at: Time.zone.now)
end
+
+ def update_status!
+ return if skip_update_status
+
+ self.status = calculate_status
+ end
+
+ def calculate_status
+ return "deleted" if discarded_at.present?
+ return "request_merged" if status == "request_merged"
+ return "processing" if status == "processing"
+ return "incomplete" unless required_questions_answered?
+ return "ready_to_merge" if absorbing_organisation_signed_dsa?
+
+ "merge_issues"
+ end
+
+ def required_questions_answered?
+ absorbing_organisation_id.present? &&
+ merge_date.present? &&
+ merging_organisations.count.positive? &&
+ errors.empty?
+ end
+
+ def absorbing_organisation_signed_dsa?
+ absorbing_organisation&.data_protection_confirmed?
+ end
end
diff --git a/app/models/merge_request_organisation.rb b/app/models/merge_request_organisation.rb
index e181ca304..18a77d93a 100644
--- a/app/models/merge_request_organisation.rb
+++ b/app/models/merge_request_organisation.rb
@@ -8,12 +8,19 @@ class MergeRequestOrganisation < ApplicationRecord
scope :merged, -> { joins(:merge_request).where(merge_requests: { status: "request_merged" }) }
scope :with_merging_organisation, ->(merging_organisation) { where(merging_organisation:) }
+ after_save :update_merge_request_status
+
has_paper_trail
def merging_organisation_name
merging_organisation.name || ""
end
+ def update_merge_request_status
+ merge_request.update_status!
+ merge_request.save!
+ end
+
private
def validate_merging_organisations
diff --git a/app/views/merge_requests/_notification_banners.html.erb b/app/views/merge_requests/_notification_banners.html.erb
new file mode 100644
index 000000000..7674773ab
--- /dev/null
+++ b/app/views/merge_requests/_notification_banners.html.erb
@@ -0,0 +1,21 @@
+<% unless @merge_request.absorbing_organisation_signed_dsa? || @merge_request.absorbing_organisation_id.blank? %>
+ <%= govuk_notification_banner(title_text: "Important") do %>
+
+ <% if @merge_request.dpo_user %> + Contact the Data Protection Officer: <%= link_to @merge_request.dpo_user.name, user_path(@merge_request.dpo_user.id) %> + <% else %> + <%= @merge_request.absorbing_organisation_name %> does not have a Data Protection Officer. You can assign one on the <%= link_to "users page", "#{organisation_path(@merge_request.absorbing_organisation_id)}/users" %>. + <% end %> + <% end %> +<% end %> + +<% if @merge_request.last_failed_attempt.present? %> + <%= govuk_notification_banner(title_text: "Important") do %> +
+ No changes have been made. Try beginning the merge again. + <% end %> +<% end %> diff --git a/app/views/merge_requests/show.html.erb b/app/views/merge_requests/show.html.erb index ce4fbb38d..c93e99738 100644 --- a/app/views/merge_requests/show.html.erb +++ b/app/views/merge_requests/show.html.erb @@ -3,31 +3,18 @@ <% content_for :title, title %> <%= govuk_back_link href: organisations_path(anchor: "merge-requests") %> <% end %> -<% unless @merge_request.signed_dsa || @merge_request.absorbing_organisation_id.blank? %> -
-<% end %> + +<%= render partial: "notification_banners" %> +