diff --git a/app/jobs/report_job.rb b/app/jobs/report_job.rb index f3ac9b8f6b..390ab18f9c 100644 --- a/app/jobs/report_job.rb +++ b/app/jobs/report_job.rb @@ -13,10 +13,13 @@ class ReportJob < ApplicationJob execution_time = Time.zone.now - start_time - email_result if execution_time > NOTIFICATION_TIME + email_result(user, blob) if execution_time > NOTIFICATION_TIME end - def email_result - ReportMailer.report_ready.deliver_later + def email_result(user, blob) + ReportMailer.with( + to: user.email, + blob: blob, + ).report_ready.deliver_later end end diff --git a/app/mailers/report_mailer.rb b/app/mailers/report_mailer.rb index a0de628308..08dee47d81 100644 --- a/app/mailers/report_mailer.rb +++ b/app/mailers/report_mailer.rb @@ -2,6 +2,11 @@ class ReportMailer < ApplicationMailer def report_ready - mail + # When we are in a background job then we don't have an HTTP request object + # and we need to tell ActiveStorage the hostname to generate URLs. + ActiveStorage::Current.url_options ||= url_options + + @blob = params[:blob] + mail(params) end end diff --git a/app/views/report_mailer/report_ready.html.haml b/app/views/report_mailer/report_ready.html.haml index a210462891..604e265150 100644 --- a/app/views/report_mailer/report_ready.html.haml +++ b/app/views/report_mailer/report_ready.html.haml @@ -1 +1,5 @@ -%h3 TBC +%h3= t(".heading") +%p + = t(".intro") +%ul + %li= link_to(t(".link_label", name: @blob.filename), @blob.url) diff --git a/config/locales/en.yml b/config/locales/en.yml index c8a9ab96fc..84e3ec6c68 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -319,6 +319,13 @@ en: order_cycle: subject: "Order cycle report for %{producer}" provider_settings: "Provider settings" + report_mailer: + report_ready: + subject: "Report ready" + heading: "Report ready for download" + intro: | + The link below will expire after one month. + link_label: "%{name}" shipment_mailer: shipped_email: dear_customer: "Dear Customer," diff --git a/spec/jobs/report_job_spec.rb b/spec/jobs/report_job_spec.rb index 45b527d8f5..5c748b5609 100644 --- a/spec/jobs/report_job_spec.rb +++ b/spec/jobs/report_job_spec.rb @@ -40,7 +40,13 @@ describe ReportJob do # rspec-rails: https://github.com/rspec/rspec-rails/issues/2668 ReportJob.perform_later(*report_args) perform_enqueued_jobs(only: ReportJob) - }.to enqueue_mail(ReportMailer, :report_ready) + }.to enqueue_mail(ReportMailer, :report_ready).with( + params: { + to: user.email, + blob: blob, + }, + args: [], + ) end it "triggers no email when the report is done quickly" do diff --git a/spec/mailers/report_mailer_spec.rb b/spec/mailers/report_mailer_spec.rb new file mode 100644 index 0000000000..ad66d03b54 --- /dev/null +++ b/spec/mailers/report_mailer_spec.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe ReportMailer do + describe "#report_ready" do + subject(:email) { + ReportMailer.with( + to: "current_user@example.net", + blob: blob, + ).report_ready + } + let(:blob) { ReportBlob.create_for_upload_later!("customers.csv") } + + it "notifies about a report" do + expect(email.subject).to eq "Report ready" + expect(email.body).to have_content "Report ready for download" + end + + it "notifies the user" do + expect(email.to).to eq ["current_user@example.net"] + end + + it "contains a download link" do + expect(email.body).to have_link( + "customers.csv", + href: %r"^http://test\.host/rails/active_storage/disk/.*/customers\.csv$" + ) + end + end +end diff --git a/spec/system/admin/reports_spec.rb b/spec/system/admin/reports_spec.rb index 0020d5bfbe..3c1f604342 100644 --- a/spec/system/admin/reports_spec.rb +++ b/spec/system/admin/reports_spec.rb @@ -77,8 +77,10 @@ describe ' visit admin_report_path( report_type: :customers, report_subtype: :mailing_list ) + allow(ENV).to receive(:fetch).and_call_original expect(ENV).to receive(:fetch).with("RACK_TIMEOUT_SERVICE_TIMEOUT", "15") .and_return("-1") # Negative values time out immediately. + stub_const("ReportJob::NOTIFICATION_TIME", 0) click_button "Go" @@ -92,6 +94,12 @@ describe ' content = File.read(downloaded_filename) expect(content).to match "\nFirst Name\n" + + # We also get an email. + perform_enqueued_jobs(only: ActionMailer::MailDeliveryJob) + email = ActionMailer::Base.deliveries.last + expect(email.body).to have_link "customers", + href: %r"^http://test\.host/rails/active_storage/disk/.*/customers_[0-9]+\.html$" end end