Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: rails/rails
...
head fork: rails/rails
  • 11 commits
  • 11 files changed
  • 0 commit comments
  • 1 contributor
View
14 actionmailer/CHANGELOG
@@ -1,3 +1,7 @@
+* Removed all quoting.rb type files from ActionMailer and put Mail 2.2.0 in instead [ML]
+
+* Lot of updates to various test cases that now work better with the new Mail and so have different expectations
+
*Rails 3.0.0 [beta 2] (April 1st, 2010)*
* Added interceptors and observers from Mail [ML]
@@ -5,6 +9,16 @@
ActionMailer::Base.register_interceptor calls Mail.register_interceptor
ActionMailer::Base.register_observer calls Mail.register_observer
+* Mail::Part now no longer has nil as a default charset, it is always set to something, and defaults to UTF-8
+
+* Added explict setting of charset in set_fields! method to make sure Mail has the user defined default
+
+* Removed quoting.rb and refactored for Mail to take responsibility of all quoting and auto encoding requirements for the header.
+
+* Fixed several tests which had incorrect encoding.
+
+* Changed all utf-8 to UTF-8 for consistency
+
* Whole new API added with tests. See base.rb for full details. Old API is deprecated.
View
2  actionmailer/actionmailer.gemspec
@@ -20,6 +20,6 @@ Gem::Specification.new do |s|
s.has_rdoc = true
s.add_dependency('actionpack', version)
- s.add_dependency('mail', '~> 2.1.5.3')
+ s.add_dependency('mail', '~> 2.2.0')
s.add_dependency('text-format', '~> 1.0.0')
end
View
1  actionmailer/lib/action_mailer.rb
@@ -46,7 +46,6 @@ module ActionMailer
autoload :DeprecatedApi
autoload :MailHelper
autoload :OldApi
- autoload :Quoting
autoload :TestCase
autoload :TestHelper
end
View
24 actionmailer/lib/action_mailer/base.rb
@@ -207,7 +207,7 @@ module ActionMailer #:nodoc:
# scores instead of hyphens, so <tt>Content-Transfer-Encoding:</tt>
# becomes <tt>:content_transfer_encoding</tt>. The defaults set by Action Mailer are:
# * <tt>:mime_version => "1.0"</tt>
- # * <tt>:charset => "utf-8",</tt>
+ # * <tt>:charset => "UTF-8",</tt>
# * <tt>:content_type => "text/plain",</tt>
# * <tt>:parts_order => [ "text/plain", "text/enriched", "text/html" ]</tt>
#
@@ -264,7 +264,7 @@ module ActionMailer #:nodoc:
# (i.e. multiple parts are assembled from templates which specify the content type in their
# filenames) this variable controls how the parts are ordered.
class Base < AbstractController::Base
- include DeliveryMethods, Quoting
+ include DeliveryMethods
abstract!
include AbstractController::Logger
@@ -286,7 +286,7 @@ class Base < AbstractController::Base
class_attribute :default_params
self.default_params = {
:mime_version => "1.0",
- :charset => "utf-8",
+ :charset => "UTF-8",
:content_type => "text/plain",
:parts_order => [ "text/plain", "text/enriched", "text/html" ]
}.freeze
@@ -531,7 +531,7 @@ def mail(headers={}, &block)
# Quote fields
headers[:subject] ||= default_i18n_subject
- quote_fields!(headers, charset)
+ set_fields!(headers, charset)
# Render the templates and blocks
responses, explicit_order = collect_responses_and_parts_order(headers, &block)
@@ -577,15 +577,15 @@ def default_i18n_subject #:nodoc:
I18n.t(:subject, :scope => [:actionmailer, mailer_scope, action_name], :default => action_name.humanize)
end
- # TODO: Move this into Mail
- def quote_fields!(headers, charset) #:nodoc:
+ def set_fields!(headers, charset) #:nodoc:
m = @_message
- m.subject ||= quote_if_necessary(headers.delete(:subject), charset) if headers[:subject]
- m.to ||= quote_address_if_necessary(headers.delete(:to), charset) if headers[:to]
- m.from ||= quote_address_if_necessary(headers.delete(:from), charset) if headers[:from]
- m.cc ||= quote_address_if_necessary(headers.delete(:cc), charset) if headers[:cc]
- m.bcc ||= quote_address_if_necessary(headers.delete(:bcc), charset) if headers[:bcc]
- m.reply_to ||= quote_address_if_necessary(headers.delete(:reply_to), charset) if headers[:reply_to]
+ m.charset = charset
+ m.subject ||= headers.delete(:subject) if headers[:subject]
+ m.to ||= headers.delete(:to) if headers[:to]
+ m.from ||= headers.delete(:from) if headers[:from]
+ m.cc ||= headers.delete(:cc) if headers[:cc]
+ m.bcc ||= headers.delete(:bcc) if headers[:bcc]
+ m.reply_to ||= headers.delete(:reply_to) if headers[:reply_to]
end
def collect_responses_and_parts_order(headers) #:nodoc:
View
4 actionmailer/lib/action_mailer/old_api.rb
@@ -147,8 +147,8 @@ def normalize_file_hash(params)
def create_mail
m = @_message
- quote_fields!({:subject => subject, :to => recipients, :from => from,
- :bcc => bcc, :cc => cc, :reply_to => reply_to}, charset)
+ set_fields!({:subject => subject, :to => recipients, :from => from,
+ :bcc => bcc, :cc => cc, :reply_to => reply_to}, charset)
m.mime_version = mime_version unless mime_version.nil?
m.date = sent_on.to_time rescue sent_on if sent_on
View
64 actionmailer/lib/action_mailer/quoting.rb
@@ -1,64 +0,0 @@
-module ActionMailer
- module Quoting #:nodoc:
- # TODO extract this into Mail itself.
- #
- #
- # Convert the given text into quoted printable format, with an instruction
- # that the text be eventually interpreted in the given charset.
- def quoted_printable(text, charset)
- text = text.gsub( /[^a-z ]/i ) { quoted_printable_encode($&) }.
- gsub( / /, "_" )
- "=?#{charset}?Q?#{text}?="
- end
-
- # Convert the given character to quoted printable format, taking into
- # account multi-byte characters (if executing with $KCODE="u", for instance)
- def quoted_printable_encode(character)
- result = ""
- character.each_byte { |b| result << "=%02X" % b }
- result
- end
-
- # A quick-and-dirty regexp for determining whether a string contains any
- # characters that need escaping.
- if !defined?(CHARS_NEEDING_QUOTING)
- CHARS_NEEDING_QUOTING = Regexp.new('[\000-\011\013\014\016-\037\177-\377]', nil, 'n')
- end
-
- # Quote the given text if it contains any "illegal" characters
- def quote_if_necessary(text, charset)
- text = text.dup.force_encoding(Encoding::ASCII_8BIT) if text.respond_to?(:force_encoding)
-
- (text =~ CHARS_NEEDING_QUOTING) ?
- quoted_printable(text, charset) :
- text
- end
-
- # Quote any of the given strings if they contain any "illegal" characters
- def quote_any_if_necessary(charset, *args)
- args.map { |v| quote_if_necessary(v, charset) }
- end
-
- # Quote the given address if it needs to be. The address may be a
- # regular email address, or it can be a phrase followed by an address in
- # brackets. The phrase is the only part that will be quoted, and only if
- # it needs to be. This allows extended characters to be used in the
- # "to", "from", "cc", "bcc" and "reply-to" headers.
- def quote_address_if_necessary(address, charset)
- if Array === address
- address.map { |a| quote_address_if_necessary(a, charset) }.join(", ")
- elsif address =~ /^(\S.*)\s+(<.*>)$/
- address = $2
- phrase = quote_if_necessary($1.gsub(/^['"](.*)['"]$/, '\1'), charset)
- "\"#{phrase}\" #{address}"
- else
- address
- end
- end
-
- # Quote any of the given addresses, if they need to be.
- def quote_any_address_if_necessary(charset, *args)
- args.map { |v| quote_address_if_necessary(v, charset) }
- end
- end
-end
View
6 actionmailer/lib/action_mailer/test_case.rb
@@ -8,7 +8,7 @@ def initialize(name)
end
class TestCase < ActiveSupport::TestCase
- include Quoting, TestHelper
+ include TestHelper
setup :initialize_test_deliveries
setup :set_expected_mail
@@ -48,11 +48,11 @@ def set_expected_mail
private
def charset
- "utf-8"
+ "UTF-8"
end
def encode(subject)
- quoted_printable(subject, charset)
+ Mail::Encodings.q_value_encode(subject, charset)
end
def read_fixture(action)
View
85 actionmailer/test/old_base/mail_service_test.rb
@@ -105,7 +105,7 @@ def utf8_body(recipient)
sent_on Time.local(2004, 12, 12)
cc "Foo áëô îü <extended@example.net>"
bcc "Foo áëô îü <extended@example.net>"
- charset "utf-8"
+ charset "UTF-8"
body "åœö blah"
end
@@ -131,7 +131,7 @@ def multipart_with_utf8_subject(recipient)
recipients recipient
subject "Foo áëô îü"
from "test@example.com"
- charset "utf-8"
+ charset "UTF-8"
part "text/plain" do |p|
p.body = "blah"
@@ -316,18 +316,15 @@ def receive(mail)
end
class ActionMailerTest < Test::Unit::TestCase
- include ActionMailer::Quoting
- def encode( text, charset="utf-8" )
- quoted_printable( text, charset )
+ def encode( text, charset="UTF-8" )
+ Mail::Encodings.q_value_encode( text, charset )
end
- def new_mail( charset="utf-8" )
+ def new_mail( charset="UTF-8" )
mail = Mail.new
+ mail.charset = charset
mail.mime_version = "1.0"
- if charset
- mail.content_type ["text", "plain", { "charset" => charset }]
- end
mail
end
@@ -358,7 +355,7 @@ def test_nested_parts
assert_equal "multipart/mixed", created.mime_type
assert_equal "multipart/alternative", created.parts[0].mime_type
assert_equal "bar", created.parts[0].header['foo'].to_s
- assert_nil created.parts[0].charset
+ assert_not_nil created.parts[0].charset
assert_equal "text/plain", created.parts[0].parts[0].mime_type
assert_equal "text/html", created.parts[0].parts[1].mime_type
assert_equal "application/octet-stream", created.parts[1].mime_type
@@ -570,7 +567,6 @@ def test_reply_to
def test_iso_charset
TestMailer.delivery_method = :test
-
expected = new_mail( "iso-8859-1" )
expected.to = @recipient
expected.subject = encode "testing isø charsets", "iso-8859-1"
@@ -671,14 +667,14 @@ def test_performs_delivery_via_sendmail
def test_unquote_quoted_printable_subject
msg = <<EOF
From: me@example.com
-Subject: =?utf-8?Q?testing_testing_=D6=A4?=
+Subject: =?UTF-8?Q?testing_testing_=D6=A4?=
Content-Type: text/plain; charset=iso-8859-1
The body
EOF
mail = Mail.new(msg)
assert_equal "testing testing \326\244", mail.subject
- assert_equal "Subject: =?utf-8?Q?testing_testing_=D6=A4?=\r\n", mail[:subject].encoded
+ assert_equal "Subject: testing testing =?UTF-8?Q?_=D6=A4=?=\r\n", mail[:subject].encoded
end
def test_unquote_7bit_subject
@@ -719,7 +715,7 @@ def test_unquote_quoted_printable_body
EOF
mail = Mail.new(msg)
assert_equal "The=body", mail.body.to_s.strip
- assert_equal "The=3Dbody", mail.body.encoded.strip
+ assert_equal "The=3Dbody=", mail.body.encoded.strip
end
def test_unquote_base64_body
@@ -740,12 +736,12 @@ def test_extended_headers
@recipient = "Grytøyr <test@localhost>"
expected = new_mail "iso-8859-1"
- expected.to = quote_address_if_necessary @recipient, "iso-8859-1"
+ expected.to = @recipient
expected.subject = "testing extended headers"
expected.body = "Nothing to see here."
- expected.from = quote_address_if_necessary "Grytøyr <stian1@example.net>", "iso-8859-1"
- expected.cc = quote_address_if_necessary "Grytøyr <stian2@example.net>", "iso-8859-1"
- expected.bcc = quote_address_if_necessary "Grytøyr <stian3@example.net>", "iso-8859-1"
+ expected.from = "Grytøyr <stian1@example.net>"
+ expected.cc = "Grytøyr <stian2@example.net>"
+ expected.bcc = "Grytøyr <stian3@example.net>"
expected.date = Time.local 2004, 12, 12
created = nil
@@ -774,13 +770,13 @@ def test_extended_headers
def test_utf8_body_is_not_quoted
@recipient = "Foo áëô îü <extended@example.net>"
- expected = new_mail "utf-8"
- expected.to = quote_address_if_necessary @recipient, "utf-8"
- expected.subject = "testing utf-8 body"
+ expected = new_mail "UTF-8"
+ expected.to = @recipient
+ expected.subject = "testing UTF-8 body"
expected.body = "åœö blah"
- expected.from = quote_address_if_necessary @recipient, "utf-8"
- expected.cc = quote_address_if_necessary @recipient, "utf-8"
- expected.bcc = quote_address_if_necessary @recipient, "utf-8"
+ expected.from = @recipient
+ expected.cc = @recipient
+ expected.bcc = @recipient
expected.date = Time.local 2004, 12, 12
created = TestMailer.utf8_body @recipient
@@ -789,18 +785,21 @@ def test_utf8_body_is_not_quoted
def test_multiple_utf8_recipients
@recipient = ["\"Foo áëô îü\" <extended@example.net>", "\"Example Recipient\" <me@example.com>"]
- expected = new_mail "utf-8"
- expected.to = quote_address_if_necessary @recipient, "utf-8"
- expected.subject = "testing utf-8 body"
+ expected = new_mail "UTF-8"
+ expected.to = @recipient
+ expected.subject = "testing UTF-8 body"
expected.body = "åœö blah"
- expected.from = quote_address_if_necessary @recipient.first, "utf-8"
- expected.cc = quote_address_if_necessary @recipient, "utf-8"
- expected.bcc = quote_address_if_necessary @recipient, "utf-8"
+ expected.from = @recipient.first
+ expected.cc = @recipient
+ expected.bcc = @recipient
expected.date = Time.local 2004, 12, 12
created = TestMailer.utf8_body @recipient
- assert_match(/\nFrom: =\?utf-8\?Q\?Foo_.*?\?= <extended@example.net>\r/, created.encoded)
- assert_match(/\nTo: =\?utf-8\?Q\?Foo_.*?\?= <extended@example.net>, \r\n\tExample Recipient <me/, created.encoded)
+ from_regexp = Regexp.escape('From: Foo =?UTF-8?B?w6HDq8O0?= =?UTF-8?B?IMOuw7w=?=')
+ assert_match(/#{from_regexp}/m, created.encoded)
+
+ to_regexp = Regexp.escape("To: =?UTF-8?B?Rm9vIMOhw6vDtCDDrsO8?= <extended@example.net>")
+ assert_match(/#{to_regexp}/m, created.encoded)
end
def test_receive_decodes_base64_encoded_mail
@@ -864,12 +863,20 @@ def test_multipart_with_mime_version
def test_multipart_with_utf8_subject
mail = TestMailer.multipart_with_utf8_subject(@recipient)
- assert_match(/\nSubject: =\?utf-8\?Q\?Foo_.*?\?=/, mail.encoded)
+ regex = Regexp.escape('Subject: Foo =?UTF-8?Q?=C3=A1=C3=AB=C3=B4=?= =?UTF-8?Q?_=C3=AE=C3=BC=?=')
+ assert_match(/#{regex}/, mail.encoded)
+ string = "Foo áëô îü"
+ string.force_encoding('UTF-8') if string.respond_to?(:force_encoding)
+ assert_match(string, mail.subject)
end
def test_implicitly_multipart_with_utf8
mail = TestMailer.implicitly_multipart_with_utf8
- assert_match(/\nSubject: =\?utf-8\?Q\?Foo_.*?\?=/, mail.encoded)
+ regex = Regexp.escape('Subject: Foo =?UTF-8?Q?=C3=A1=C3=AB=C3=B4=?= =?UTF-8?Q?_=C3=AE=C3=BC=?=')
+ assert_match(/#{regex}/, mail.encoded)
+ string = "Foo áëô îü"
+ string.force_encoding('UTF-8') if string.respond_to?(:force_encoding)
+ assert_match(string, mail.subject)
end
def test_explicitly_multipart_messages
@@ -909,11 +916,11 @@ def test_implicitly_multipart_messages
assert_equal "1.0", mail.mime_version.to_s
assert_equal "multipart/alternative", mail.mime_type
assert_equal "text/plain", mail.parts[0].mime_type
- assert_equal "utf-8", mail.parts[0].charset
+ assert_equal "UTF-8", mail.parts[0].charset
assert_equal "text/html", mail.parts[1].mime_type
- assert_equal "utf-8", mail.parts[1].charset
+ assert_equal "UTF-8", mail.parts[1].charset
assert_equal "application/x-yaml", mail.parts[2].mime_type
- assert_equal "utf-8", mail.parts[2].charset
+ assert_equal "UTF-8", mail.parts[2].charset
end
def test_implicitly_multipart_messages_with_custom_order
@@ -1044,13 +1051,13 @@ def test_multipart_with_template_path_with_dots
mail = FunkyPathMailer.multipart_with_template_path_with_dots(@recipient)
assert_equal 2, mail.parts.length
assert "text/plain", mail.parts[1].mime_type
- assert "utf-8", mail.parts[1].charset
+ assert "UTF-8", mail.parts[1].charset
end
def test_custom_content_type_attributes
mail = TestMailer.custom_content_type_attributes
assert_match %r{format=flowed}, mail.content_type
- assert_match %r{charset=utf-8}, mail.content_type
+ assert_match %r{charset=UTF-8}, mail.content_type
end
def test_return_path_with_create
View
5 actionmailer/test/old_base/url_test.rb
@@ -29,13 +29,12 @@ def signed_up_with_url(recipient)
end
class ActionMailerUrlTest < Test::Unit::TestCase
- include ActionMailer::Quoting
- def encode( text, charset="utf-8" )
+ def encode( text, charset="UTF-8" )
quoted_printable( text, charset )
end
- def new_mail( charset="utf-8" )
+ def new_mail( charset="UTF-8" )
mail = Mail.new
mail.mime_version = "1.0"
if charset
View
106 actionmailer/test/quoting_test.rb
@@ -1,106 +0,0 @@
-# encoding: utf-8
-require 'abstract_unit'
-require 'tempfile'
-
-class QuotingTest < Test::Unit::TestCase
- # Move some tests from TMAIL here
- def test_unquote_quoted_printable
- a ="=?ISO-8859-1?Q?[166417]_Bekr=E6ftelse_fra_Rejsefeber?="
- b = Mail::Encodings.unquote_and_convert_to(a, 'utf-8')
- assert_equal "[166417] Bekr\303\246ftelse fra Rejsefeber", b
- end
-
- def test_unquote_base64
- a ="=?ISO-8859-1?B?WzE2NjQxN10gQmVrcuZmdGVsc2UgZnJhIFJlanNlZmViZXI=?="
- b = Mail::Encodings.unquote_and_convert_to(a, 'utf-8')
- assert_equal "[166417] Bekr\303\246ftelse fra Rejsefeber", b
- end
-
- def test_unquote_without_charset
- a ="[166417]_Bekr=E6ftelse_fra_Rejsefeber"
- b = Mail::Encodings.unquote_and_convert_to(a, 'utf-8')
- assert_equal "[166417]_Bekr=E6ftelse_fra_Rejsefeber", b
- end
-
- def test_unqoute_multiple
- a ="=?utf-8?q?Re=3A_=5B12=5D_=23137=3A_Inkonsistente_verwendung_von_=22Hin?==?utf-8?b?enVmw7xnZW4i?="
- b = Mail::Encodings.unquote_and_convert_to(a, 'utf-8')
- assert_equal "Re: [12] #137: Inkonsistente verwendung von \"Hinzuf\303\274gen\"", b
- end
-
- def test_unqoute_in_the_middle
- a ="Re: Photos =?ISO-8859-1?Q?Brosch=FCre_Rand?="
- b = Mail::Encodings.unquote_and_convert_to(a, 'utf-8')
- assert_equal "Re: Photos Brosch\303\274re Rand", b
- end
-
- def test_unqoute_iso
- a ="=?ISO-8859-1?Q?Brosch=FCre_Rand?="
- b = Mail::Encodings.unquote_and_convert_to(a, 'iso-8859-1')
- expected = "Brosch\374re Rand"
- expected.force_encoding 'iso-8859-1' if expected.respond_to?(:force_encoding)
- assert_equal expected, b
- end
-
- def test_quote_multibyte_chars
- original = "\303\246 \303\270 and \303\245"
- original.force_encoding('ASCII-8BIT') if original.respond_to?(:force_encoding)
-
- result = execute_in_sandbox(<<-CODE)
- $:.unshift(File.dirname(__FILE__) + "/../lib/")
- if RUBY_VERSION < '1.9'
- $KCODE = 'u'
- end
- require 'action_mailer/quoting'
- include ActionMailer::Quoting
- quoted_printable(#{original.inspect}, "UTF-8")
- CODE
-
- unquoted = Mail::Encodings.unquote_and_convert_to(result, nil)
-
- unquoted.force_encoding(Encoding::ASCII_8BIT) if unquoted.respond_to?(:force_encoding)
- original.force_encoding(Encoding::ASCII_8BIT) if original.respond_to?(:force_encoding)
-
- assert_equal unquoted, original
- end
-
-
- # test an email that has been created using \r\n newlines, instead of
- # \n newlines.
- def test_email_quoted_with_0d0a
- mail = Mail.new(IO.read("#{File.dirname(__FILE__)}/fixtures/raw_email_quoted_with_0d0a"))
- # CHANGED: subject returns an object now
- # assert_match %r{Elapsed time}, mail.body
- assert_match %r{Elapsed time}, mail.body.to_s
- end
-
- def test_email_with_partially_quoted_subject
- mail = Mail.new(IO.read("#{File.dirname(__FILE__)}/fixtures/raw_email_with_partially_quoted_subject"))
- # CHANGED: subject returns an object now
- # assert_equal "Re: Test: \"\346\274\242\345\255\227\" mid \"\346\274\242\345\255\227\" tail", mail.subject
- assert_equal "Re: Test: \"\346\274\242\345\255\227\" mid \"\346\274\242\345\255\227\" tail", mail.subject
- end
-
- private
- # This whole thing *could* be much simpler, but I don't think Tempfile,
- # popen and others exist on all platforms (like Windows).
- def execute_in_sandbox(code)
- test_name = "#{File.dirname(__FILE__)}/am-quoting-test.#{$$}.rb"
- res_name = "#{File.dirname(__FILE__)}/am-quoting-test.#{$$}.out"
-
- File.open(test_name, "w+") do |file|
- file.write(<<-CODE)
- block = Proc.new do
- #{code}
- end
- puts block.call
- CODE
- end
-
- system("ruby #{test_name} > #{res_name}") or raise "could not run test in sandbox"
- File.read(res_name).chomp
- ensure
- File.delete(test_name) rescue nil
- File.delete(res_name) rescue nil
- end
-end
View
6 actionmailer/test/test_helper_test.rb
@@ -34,11 +34,7 @@ def test_determine_default_mailer_raises_correct_error
end
def test_charset_is_utf_8
- assert_equal "utf-8", charset
- end
-
- def test_encode
- assert_equal "=?utf-8?Q?=0Aasdf=0A?=", encode("\nasdf\n")
+ assert_equal "UTF-8", charset
end
def test_assert_emails

No commit comments for this range

Something went wrong with that request. Please try again.