Fix mailer previews with attachments

Use the mail gem's own API to locate the correct part.

Fixes #14435.
This commit is contained in:
Andrew White 2015-05-04 08:02:36 +01:00
parent 4261aa575a
commit 350d272d6c
4 changed files with 206 additions and 7 deletions

View File

@ -1,3 +1,10 @@
* Fix mailer previews with attachments by using the mail gem's own API to
locate the first part of the correct mime type.
Fixes #14435.
*Andrew White*
* Remove sqlite support from `rails dbconsole`.
*Andrew White*

View File

@ -54,18 +54,20 @@ class Rails::MailersController < Rails::ApplicationController # :nodoc:
end
def find_preferred_part(*formats)
if @email.multipart?
formats.each do |format|
return find_part(format) if @email.parts.any?{ |p| p.mime_type == format }
formats.each do |format|
if part = @email.find_first_mime_type(format)
return part
end
else
end
if formats.any?{ |f| @email.mime_type == f }
@email
end
end
def find_part(format)
if @email.multipart?
@email.parts.find{ |p| p.mime_type == format }
if part = @email.find_first_mime_type(format)
part
elsif @email.mime_type == format
@email
end

View File

@ -103,7 +103,7 @@
</dl>
</header>
<% if @part.mime_type %>
<% if @part && @part.mime_type %>
<iframe seamless name="messageBody" src="?part=<%= Rack::Utils.escape(@part.mime_type) %>"></iframe>
<% else %>
<p>

View File

@ -1,5 +1,7 @@
require 'isolation/abstract_unit'
require 'rack/test'
require 'base64'
module ApplicationTests
class MailerPreviewsTest < ActiveSupport::TestCase
include ActiveSupport::Testing::Isolation
@ -484,6 +486,190 @@ module ApplicationTests
assert_match '<li><a href="/my_app/rails/mailers/notifier/foo">foo</a></li>', last_response.body
end
test "plain text mailer preview with attachment" do
image_file "pixel.png", "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEWzIioc\na/JlAAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg=="
mailer 'notifier', <<-RUBY
class Notifier < ActionMailer::Base
default from: "from@example.com"
def foo
mail to: "to@example.org"
end
end
RUBY
text_template 'notifier/foo', <<-RUBY
Hello, World!
RUBY
mailer_preview 'notifier', <<-RUBY
class NotifierPreview < ActionMailer::Preview
def foo
Notifier.foo
end
end
RUBY
app('development')
get "/rails/mailers/notifier/foo"
assert_equal 200, last_response.status
assert_match %r[<iframe seamless name="messageBody"], last_response.body
get "/rails/mailers/notifier/foo?part=text/plain"
assert_equal 200, last_response.status
assert_match %r[Hello, World!], last_response.body
end
test "multipart mailer preview with attachment" do
image_file "pixel.png", "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEWzIioc\na/JlAAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg=="
mailer 'notifier', <<-RUBY
class Notifier < ActionMailer::Base
default from: "from@example.com"
def foo
attachments['pixel.png'] = File.read("#{app_path}/public/images/pixel.png")
mail to: "to@example.org"
end
end
RUBY
text_template 'notifier/foo', <<-RUBY
Hello, World!
RUBY
html_template 'notifier/foo', <<-RUBY
<p>Hello, World!</p>
RUBY
mailer_preview 'notifier', <<-RUBY
class NotifierPreview < ActionMailer::Preview
def foo
Notifier.foo
end
end
RUBY
app('development')
get "/rails/mailers/notifier/foo"
assert_equal 200, last_response.status
assert_match %r[<iframe seamless name="messageBody"], last_response.body
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/notifier/foo?part=text/html"
assert_equal 200, last_response.status
assert_match %r[<p>Hello, World!</p>], last_response.body
end
test "multipart mailer preview with inline attachment" do
image_file "pixel.png", "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEWzIioc\na/JlAAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg=="
mailer 'notifier', <<-RUBY
class Notifier < ActionMailer::Base
default from: "from@example.com"
def foo
attachments['pixel.png'] = File.read("#{app_path}/public/images/pixel.png")
mail to: "to@example.org"
end
end
RUBY
text_template 'notifier/foo', <<-RUBY
Hello, World!
RUBY
html_template 'notifier/foo', <<-RUBY
<p>Hello, World!</p>
<%= image_tag attachments['pixel.png'].url %>
RUBY
mailer_preview 'notifier', <<-RUBY
class NotifierPreview < ActionMailer::Preview
def foo
Notifier.foo
end
end
RUBY
app('development')
get "/rails/mailers/notifier/foo"
assert_equal 200, last_response.status
assert_match %r[<iframe seamless name="messageBody"], last_response.body
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/notifier/foo?part=text/html"
assert_equal 200, last_response.status
assert_match %r[<p>Hello, World!</p>], last_response.body
end
test "multipart mailer preview with attached email" do
mailer 'notifier', <<-RUBY
class Notifier < ActionMailer::Base
default from: "from@example.com"
def foo
message = ::Mail.new do
from 'foo@example.com'
to 'bar@example.com'
subject 'Important Message'
text_part do
body 'Goodbye, World!'
end
html_part do
body '<p>Goodbye, World!</p>'
end
end
attachments['message.eml'] = message.to_s
mail to: "to@example.org"
end
end
RUBY
text_template 'notifier/foo', <<-RUBY
Hello, World!
RUBY
html_template 'notifier/foo', <<-RUBY
<p>Hello, World!</p>
RUBY
mailer_preview 'notifier', <<-RUBY
class NotifierPreview < ActionMailer::Preview
def foo
Notifier.foo
end
end
RUBY
app('development')
get "/rails/mailers/notifier/foo"
assert_equal 200, last_response.status
assert_match %r[<iframe seamless name="messageBody"], last_response.body
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/notifier/foo?part=text/html"
assert_equal 200, last_response.status
assert_match %r[<p>Hello, World!</p>], last_response.body
end
private
def build_app
super
@ -505,5 +691,9 @@ module ApplicationTests
def text_template(name, contents)
app_file("app/views/#{name}.text.erb", contents)
end
def image_file(name, contents)
app_file("public/images/#{name}", Base64.decode64(contents))
end
end
end