Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Daily email notification to admins about new FD statuses #2718

Merged
merged 1 commit into from
Dec 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion app/interactions/domains/force_delete/post_set_process.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ def execute
# Allow deletion
statuses.delete(DomainStatus::CLIENT_DELETE_PROHIBITED)

puts "Try to save domain: #{domain.name} with statuses: #{statuses}"
domain.save(validate: false)
end
end
Expand Down
41 changes: 41 additions & 0 deletions app/jobs/force_delete_daily_admin_notifier_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
class ForceDeleteDailyAdminNotifierJob < ApplicationJob
queue_as :default

def perform
domains = Domain.where("'#{DomainStatus::FORCE_DELETE}' = ANY (statuses)")
.where("force_delete_start = ?", Time.zone.now)

return if domains.empty?

notify_admins(domains)
end

private

def notify_admins(domains)
summary = generate_summary(domains)
AdminMailer.force_delete_daily_summary(summary).deliver_now
end

def generate_summary(domains)
domains.map do |domain|
{
name: domain.name,
reason: determine_reason(domain),
force_delete_type: domain.force_delete_type,
force_delete_start: domain.force_delete_start,
force_delete_date: domain.force_delete_date
}
end
end

def determine_reason(domain)
if domain.template_name.present?
domain.template_name
elsif domain.status_notes[DomainStatus::FORCE_DELETE].present?
"Manual force delete: #{domain.status_notes[DomainStatus::FORCE_DELETE]}"
else
'Unknown reason'
end
end
end
9 changes: 9 additions & 0 deletions app/mailers/admin_mailer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class AdminMailer < ApplicationMailer
def force_delete_daily_summary(domains_summary)
@domains = domains_summary
mail(
to: ENV['admin_notification_email'] || '[email protected]',
subject: "Force Delete Daily Summary - #{Date.current}"
)
end
end
24 changes: 24 additions & 0 deletions app/views/admin_mailer/force_delete_daily_summary.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<h1>Force Delete Daily Summary - <%= Date.current %></h1>

<table>
<thead>
<tr>
<th>Domain</th>
<th>Reason</th>
<th>Type</th>
<th>Start Date</th>
<th>Delete Date</th>
</tr>
</thead>
<tbody>
<% @domains.each do |domain| %>
<tr>
<td><%= domain[:name] %></td>
<td><%= domain[:reason] %></td>
<td><%= domain[:force_delete_type] %></td>
<td><%= domain[:force_delete_start]&.to_date %></td>
<td><%= domain[:force_delete_date]&.to_date %></td>
</tr>
<% end %>
</tbody>
</table>
81 changes: 81 additions & 0 deletions test/jobs/force_delete_daily_admin_notifier_job_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
require 'test_helper'

class ForceDeleteDailyAdminNotifierJobTest < ActiveSupport::TestCase
include ActionMailer::TestHelper

setup do
@domain = domains(:shop)
travel_to Time.zone.parse('2010-07-05')
ActionMailer::Base.deliveries.clear
end

def test_sends_notification_for_domains_with_force_delete_today
@domain.schedule_force_delete(type: :soft)
@domain.update!(force_delete_start: Time.zone.now.to_date)
@domain.reload

assert_emails 1 do
ForceDeleteDailyAdminNotifierJob.perform_now
end

email = ActionMailer::Base.deliveries.last
assert_includes email.body.to_s, @domain.name
assert_includes email.body.to_s, @domain.force_delete_type
end

def test_does_not_send_notification_when_no_force_delete_domains_today
travel_to Time.zone.parse('2010-07-06')
@domain.schedule_force_delete(type: :soft)
@domain.reload

assert_no_emails do
ForceDeleteDailyAdminNotifierJob.perform_now
end
end

def test_includes_multiple_domains_in_notification
@domain.schedule_force_delete(type: :soft)
@domain.update!(force_delete_start: Time.zone.now.to_date)

domain2 = domains(:airport)
domain2.schedule_force_delete(type: :fast_track)
domain2.update!(force_delete_start: Time.zone.now.to_date)

assert_emails 1 do
ForceDeleteDailyAdminNotifierJob.perform_now
end

email = ActionMailer::Base.deliveries.last
assert_includes email.body.to_s, @domain.name
assert_includes email.body.to_s, domain2.name
end

def test_includes_correct_reason_for_invalid_email_template
@domain.update!(template_name: 'invalid_email')
@domain.schedule_force_delete(type: :soft)
@domain.update!(force_delete_start: Time.zone.now.to_date)
@domain.reload

assert_emails 1 do
ForceDeleteDailyAdminNotifierJob.perform_now
end

email = ActionMailer::Base.deliveries.last
assert_includes email.body.to_s, 'invalid_email'
end

def test_includes_correct_reason_for_manual_force_delete
manual_reason = "Manual deletion requested"
@domain.status_notes = { DomainStatus::FORCE_DELETE => manual_reason }
@domain.schedule_force_delete(type: :fast_track)
@domain.update!(force_delete_start: Time.zone.now.to_date)
@domain.reload

assert_emails 1 do
ForceDeleteDailyAdminNotifierJob.perform_now
end

email = ActionMailer::Base.deliveries.last
assert_includes email.body.to_s, "Manual force delete: #{manual_reason}"
end
end
Loading