FIX: Notification emails with attachments are incorrectly structured
Two behaviors in the mail gem collide: 1. Attachments are added as extra parts at the top level, 2. When there are both text and html parts, the content type is set to 'multipart/alternative'. Since attachments aren't alternative renderings, for emails that contain attachments and both html and text parts, some coercing is necessary.
This commit is contained in:
parent
1b8793e7a4
commit
59578dfc5b
|
@ -270,6 +270,50 @@ module Email
|
|||
)
|
||||
end
|
||||
end
|
||||
|
||||
fix_parts_after_attachments!
|
||||
end
|
||||
|
||||
#
|
||||
# Two behaviors in the mail gem collide:
|
||||
#
|
||||
# 1. Attachments are added as extra parts at the top level,
|
||||
# 2. When there are both text and html parts, the content type is set
|
||||
# to 'multipart/alternative'.
|
||||
#
|
||||
# Since attachments aren't alternative renderings, for emails that contain
|
||||
# attachments and both html and text parts, some coercing is necessary.
|
||||
#
|
||||
# When there are alternative rendering and attachments, this method causes
|
||||
# the top level to be 'multipart/mixed' and puts the html and text parts
|
||||
# into a nested 'multipart/alternative' part.
|
||||
#
|
||||
# Due to mail gem magic, @message.text_part and @message.html_part still
|
||||
# refer to the same objects.
|
||||
#
|
||||
def fix_parts_after_attachments!
|
||||
has_attachments = @message.attachments.present?
|
||||
has_alternative_renderings =
|
||||
@message.html_part.present? && @message.text_part.present?
|
||||
|
||||
if has_attachments && has_alternative_renderings
|
||||
@message.content_type = "multipart/mixed"
|
||||
|
||||
html_part = @message.html_part
|
||||
@message.html_part = nil
|
||||
|
||||
text_part = @message.text_part
|
||||
@message.text_part = nil
|
||||
|
||||
content = Mail::Part.new do
|
||||
content_type "multipart/alternative"
|
||||
|
||||
part html_part
|
||||
part text_part
|
||||
end
|
||||
|
||||
@message.parts.unshift(content)
|
||||
end
|
||||
end
|
||||
|
||||
def header_value(name)
|
||||
|
|
|
@ -412,6 +412,16 @@ describe Email::Sender do
|
|||
expect(message.attachments.map(&:filename))
|
||||
.to contain_exactly(*[small_pdf, csv_file].map(&:original_filename))
|
||||
end
|
||||
|
||||
it "structures the email as a multipart/mixed with a multipart/alternative first part" do
|
||||
SiteSetting.email_total_attachment_size_limit_kb = 10_000
|
||||
Email::Sender.new(message, :valid_type).send
|
||||
|
||||
expect(message.content_type).to start_with("multipart/mixed")
|
||||
expect(message.parts.size).to eq(4)
|
||||
expect(message.parts[0].content_type).to start_with("multipart/alternative")
|
||||
expect(message.parts[0].parts.size).to eq(2)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a deleted post' do
|
||||
|
|
Loading…
Reference in New Issue