From 0ac90cf3c55ed41f1a292b4ff4f32881de81d0c4 Mon Sep 17 00:00:00 2001 From: Philipe Fatio Date: Wed, 6 Jul 2016 08:09:44 +0200 Subject: [PATCH] Reuse body encoding This prevents emails from being garbled when delivered. Closes #166 --- CHANGELOG.md | 1 + lib/premailer/rails/hook.rb | 26 ++++++++++++++++++-------- spec/integration/hook_spec.rb | 16 ++++++++++++++++ spec/support/fixtures/message.rb | 16 ++++++++++++++++ 4 files changed, 51 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index deb08c1..d502f76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## HEAD - Improve check for Rails module +- Preserve body encoding to prevent garbled mails ## v1.9.3 diff --git a/lib/premailer/rails/hook.rb b/lib/premailer/rails/hook.rb index 83bca08..595c4b6 100644 --- a/lib/premailer/rails/hook.rb +++ b/lib/premailer/rails/hook.rb @@ -70,17 +70,27 @@ def generate_html_part # can end up containing CSS rules. generate_text_part if generate_text_part? - Mail::Part.new( - content_transfer_encoding: html_part.content_transfer_encoding, - content_type: "text/html; charset=#{html_part.charset}", - body: premailer.to_inline_css) + part = html_part + html = premailer.to_inline_css + Mail::Part.new do + content_transfer_encoding part.content_transfer_encoding + content_type "text/html; charset=#{part.charset}" + body html + body_encoding part.body.encoding + end end def generate_text_part - @text_part ||= Mail::Part.new( - content_transfer_encoding: html_part.content_transfer_encoding, - content_type: "text/plain; charset=#{html_part.charset}", - body: premailer.to_plain_text) + @text_part ||= begin + part = html_part + text = premailer.to_plain_text + Mail::Part.new do + content_transfer_encoding part.content_transfer_encoding + content_type "text/plain; charset=#{part.charset}" + body text + body_encoding part.body.encoding + end + end end def premailer diff --git a/spec/integration/hook_spec.rb b/spec/integration/hook_spec.rb index 791745b..e85e00f 100644 --- a/spec/integration/hook_spec.rb +++ b/spec/integration/hook_spec.rb @@ -5,6 +5,10 @@ def run_hook(message) Premailer::Rails::Hook.perform(message) end + def body_content(message) + Nokogiri::HTML(message.html_string).at('body').content + end + class Mail::Message def html_string (html_part || self).body.to_s @@ -54,6 +58,18 @@ def html_string end end + it 'does not screw up the text by maintaining the original body encoding' do + raw_msg = Fixtures::Message.latin_message + processed_msg = Fixtures::Message.latin_message + run_hook(processed_msg) + expect(body_content(processed_msg)).to eq(body_content(raw_msg)) + + raw_msg = Fixtures::Message.non_latin_message + processed_msg = Fixtures::Message.non_latin_message + run_hook(processed_msg) + expect(body_content(processed_msg)).to eq(body_content(raw_msg)) + end + it 'generates a text part from the html' do expect { run_hook(message) }.to change(message, :text_part) end diff --git a/spec/support/fixtures/message.rb b/spec/support/fixtures/message.rb index 0ac9dcf..bab679b 100644 --- a/spec/support/fixtures/message.rb +++ b/spec/support/fixtures/message.rb @@ -114,6 +114,22 @@ def with_body(body_type) message end + def latin_message + base_message.tap do |message| + message.body = HTML_PART + message.content_type 'text/html; charset=UTF-8' + message.ready_to_send! + end + end + + def non_latin_message + base_message.tap do |message| + message.body = HTML_PART_WITH_UNICODE + message.content_type 'text/html; charset=UTF-8' + message.ready_to_send! + end + end + private def base_message