From 9f0a064fde3c053c1436fe6c88279b287fe01cad Mon Sep 17 00:00:00 2001 From: Igor Kasyanchuk Date: Sat, 10 Sep 2022 00:01:06 +0300 Subject: [PATCH] Added ability to download `.eml` file for the email preview. --- actionmailer/CHANGELOG.md | 4 ++++ actionmailer/lib/action_mailer/railtie.rb | 3 ++- railties/lib/rails/mailers_controller.rb | 14 ++++++++++++-- .../templates/rails/mailers/email.html.erb | 2 ++ .../test/application/mailer_previews_test.rb | 18 ++++++++++++++++++ 5 files changed, 38 insertions(+), 3 deletions(-) diff --git a/actionmailer/CHANGELOG.md b/actionmailer/CHANGELOG.md index 5aa00c275e..ebfe64abfa 100644 --- a/actionmailer/CHANGELOG.md +++ b/actionmailer/CHANGELOG.md @@ -1,3 +1,7 @@ +* Added ability to download `.eml` file for the email preview. + + *Igor Kasyanchuk* + * Support multiple preview paths for mailers. Option `config.action_mailer.preview_path` is deprecated in favor of diff --git a/actionmailer/lib/action_mailer/railtie.rb b/actionmailer/lib/action_mailer/railtie.rb index 55e44f7d3e..dcf4129dc9 100644 --- a/actionmailer/lib/action_mailer/railtie.rb +++ b/actionmailer/lib/action_mailer/railtie.rb @@ -80,7 +80,8 @@ module ActionMailer if options.show_previews app.routes.prepend do - get "/rails/mailers" => "rails/mailers#index", internal: true + get "/rails/mailers" => "rails/mailers#index", internal: true + get "/rails/mailers/download/*path" => "rails/mailers#download", internal: true get "/rails/mailers/*path" => "rails/mailers#preview", internal: true end end diff --git a/railties/lib/rails/mailers_controller.rb b/railties/lib/rails/mailers_controller.rb index 29586a0f9d..2c139fa927 100644 --- a/railties/lib/rails/mailers_controller.rb +++ b/railties/lib/rails/mailers_controller.rb @@ -5,8 +5,8 @@ require "rails/application_controller" class Rails::MailersController < Rails::ApplicationController # :nodoc: prepend_view_path ActionDispatch::DebugView::RESCUES_TEMPLATE_PATH - around_action :set_locale, only: :preview - before_action :find_preview, only: :preview + around_action :set_locale, only: [:preview, :download] + before_action :find_preview, only: [:preview, :download] before_action :require_local!, unless: :show_previews? helper_method :part_query, :locale_query @@ -18,6 +18,16 @@ class Rails::MailersController < Rails::ApplicationController # :nodoc: @page_title = "Mailer Previews" end + def download + @email_action = File.basename(params[:path]) + if @preview.email_exists?(@email_action) + @email = @preview.call(@email_action, params) + send_data @email.to_s, filename: "#{@email_action}.eml" + else + raise AbstractController::ActionNotFound, "Email '#{@email_action}' not found in #{@preview.name}" + end + end + def preview if params[:path] == @preview.preview_name @page_title = "Mailer Previews for #{@preview.preview_name}" diff --git a/railties/lib/rails/templates/rails/mailers/email.html.erb b/railties/lib/rails/templates/rails/mailers/email.html.erb index 0c5ff765d4..5a41c757cf 100644 --- a/railties/lib/rails/templates/rails/mailers/email.html.erb +++ b/railties/lib/rails/templates/rails/mailers/email.html.erb @@ -125,6 +125,8 @@ <% end %> +
EML File:
+
<%= link_to "Download", action: :download %>
diff --git a/railties/test/application/mailer_previews_test.rb b/railties/test/application/mailer_previews_test.rb index 354bf91182..0d5779f1bc 100644 --- a/railties/test/application/mailer_previews_test.rb +++ b/railties/test/application/mailer_previews_test.rb @@ -355,6 +355,10 @@ module ApplicationTests get "/rails/mailers/notifier/bar" assert_predicate last_response, :not_found? assert_match "Email 'bar' not found in NotifierPreview", h(last_response.body) + + get "/rails/mailers/download/notifier/bar" + assert_predicate last_response, :not_found? + assert_match "Email 'bar' not found in NotifierPreview", h(last_response.body) end test "mailer preview NullMail" do @@ -444,6 +448,13 @@ module ApplicationTests assert_match "Ruby on Rails <core@rubyonrails.org>", last_response.body assert_match "Andrew White <andyw@pixeltrix.co.uk>", last_response.body assert_match "David Heinemeier Hansson <david@heinemeierhansson.com>", last_response.body + + get "/rails/mailers/download/notifier/foo" + email = Mail.read_from_string(last_response.body) + assert_equal "attachment; filename=\"foo.eml\"; filename*=UTF-8''foo.eml", last_response.headers["Content-Disposition"] + assert_equal 200, last_response.status + assert_equal ["andyw@pixeltrix.co.uk"], email.to + assert_equal ["david@heinemeierhansson.com"], email.cc end test "part menu selects correct option" do @@ -663,6 +674,13 @@ module ApplicationTests get "/rails/mailers/notifier/foo?part=text/plain" assert_equal 200, last_response.status assert_match %r[Hello, World!], last_response.body + + get "/rails/mailers/download/notifier/foo" + assert_equal 200, last_response.status + email = Mail.read_from_string(last_response.body) + assert_equal 2, email.parts.size + assert_equal "text/plain; charset=UTF-8", email.parts[0].content_type + assert_equal "image/png; filename=pixel.png", email.parts[1].content_type end test "multipart mailer preview with attachment" do