From 5b0c8a1266016c6418555399da83fbc7210c6734 Mon Sep 17 00:00:00 2001 From: Mikel Lindsaar Date: Fri, 15 Jan 2010 20:03:45 +1100 Subject: Removing internal delivery agents --- actionmailer/lib/action_mailer/delivery_method.rb | 56 ---------------------- .../lib/action_mailer/delivery_method/file.rb | 21 -------- .../lib/action_mailer/delivery_method/sendmail.rb | 22 --------- .../lib/action_mailer/delivery_method/smtp.rb | 30 ------------ .../lib/action_mailer/delivery_method/test.rb | 12 ----- 5 files changed, 141 deletions(-) delete mode 100644 actionmailer/lib/action_mailer/delivery_method.rb delete mode 100644 actionmailer/lib/action_mailer/delivery_method/file.rb delete mode 100644 actionmailer/lib/action_mailer/delivery_method/sendmail.rb delete mode 100644 actionmailer/lib/action_mailer/delivery_method/smtp.rb delete mode 100644 actionmailer/lib/action_mailer/delivery_method/test.rb (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/delivery_method.rb b/actionmailer/lib/action_mailer/delivery_method.rb deleted file mode 100644 index 4f7d3afc3c..0000000000 --- a/actionmailer/lib/action_mailer/delivery_method.rb +++ /dev/null @@ -1,56 +0,0 @@ -require 'active_support/core_ext/class' - -module ActionMailer - module DeliveryMethod - autoload :File, 'action_mailer/delivery_method/file' - autoload :Sendmail, 'action_mailer/delivery_method/sendmail' - autoload :Smtp, 'action_mailer/delivery_method/smtp' - autoload :Test, 'action_mailer/delivery_method/test' - - # Creates a new DeliveryMethod object according to the given options. - # - # If no arguments are passed to this method, then a new - # ActionMailer::DeliveryMethod::Stmp object will be returned. - # - # If you pass a Symbol as the first argument, then a corresponding - # delivery method class under the ActionMailer::DeliveryMethod namespace - # will be created. - # For example: - # - # ActionMailer::DeliveryMethod.lookup_method(:sendmail) - # # => returns a new ActionMailer::DeliveryMethod::Sendmail object - # - # If the first argument is not a Symbol, then it will simply be returned: - # - # ActionMailer::DeliveryMethod.lookup_method(MyOwnDeliveryMethod.new) - # # => returns MyOwnDeliveryMethod.new - def self.lookup_method(delivery_method) - case delivery_method - when Symbol - method_name = delivery_method.to_s.camelize - method_class = ActionMailer::DeliveryMethod.const_get(method_name) - method_class.new - when nil # default - Smtp.new - else - delivery_method - end - end - - # An abstract delivery method class. There are multiple delivery method classes. - # See the classes under the ActionMailer::DeliveryMethod, e.g. - # ActionMailer::DeliveryMethod::Smtp. - # Smtp is the default delivery method for production - # while Test is used in testing. - # - # each delivery method exposes just one method - # - # delivery_method = ActionMailer::DeliveryMethod::Smtp.new - # delivery_method.perform_delivery(mail) # send the mail via smtp - # - class Method - superclass_delegating_accessor :settings - self.settings = {} - end - end -end diff --git a/actionmailer/lib/action_mailer/delivery_method/file.rb b/actionmailer/lib/action_mailer/delivery_method/file.rb deleted file mode 100644 index 571e32df49..0000000000 --- a/actionmailer/lib/action_mailer/delivery_method/file.rb +++ /dev/null @@ -1,21 +0,0 @@ -require 'tmpdir' - -module ActionMailer - module DeliveryMethod - - # A delivery method implementation which writes all mails to a file. - class File < Method - self.settings = { - :location => defined?(Rails.root) ? "#{Rails.root}/tmp/mails" : "#{Dir.tmpdir}/mails" - } - - def perform_delivery(mail) - FileUtils.mkdir_p settings[:location] - - mail.destinations.uniq.each do |to| - ::File.open(::File.join(settings[:location], to), 'a') { |f| f.write(mail) } - end - end - end - end -end diff --git a/actionmailer/lib/action_mailer/delivery_method/sendmail.rb b/actionmailer/lib/action_mailer/delivery_method/sendmail.rb deleted file mode 100644 index db55af79f1..0000000000 --- a/actionmailer/lib/action_mailer/delivery_method/sendmail.rb +++ /dev/null @@ -1,22 +0,0 @@ -module ActionMailer - module DeliveryMethod - - # A delivery method implementation which sends via sendmail. - class Sendmail < Method - self.settings = { - :location => '/usr/sbin/sendmail', - :arguments => '-i -t' - } - - def perform_delivery(mail) - sendmail_args = settings[:arguments] - sendmail_args += " -f \"#{mail['return-path']}\"" if mail['return-path'] - IO.popen("#{settings[:location]} #{sendmail_args}","w+") do |sm| - sm.print(mail.encoded.gsub(/\r/, '')) - sm.flush - end - end - end - - end -end diff --git a/actionmailer/lib/action_mailer/delivery_method/smtp.rb b/actionmailer/lib/action_mailer/delivery_method/smtp.rb deleted file mode 100644 index af30c498b5..0000000000 --- a/actionmailer/lib/action_mailer/delivery_method/smtp.rb +++ /dev/null @@ -1,30 +0,0 @@ -require 'net/smtp' - -module ActionMailer - module DeliveryMethod - # A delivery method implementation which sends via smtp. - class Smtp < Method - self.settings = { - :address => "localhost", - :port => 25, - :domain => 'localhost.localdomain', - :user_name => nil, - :password => nil, - :authentication => nil, - :enable_starttls_auto => true, - } - - def perform_delivery(mail) - destinations = mail.destinations - sender = (mail['return-path'] && mail['return-path'].address) || mail['from'] - - smtp = Net::SMTP.new(settings[:address], settings[:port]) - smtp.enable_starttls_auto if settings[:enable_starttls_auto] && smtp.respond_to?(:enable_starttls_auto) - smtp.start(settings[:domain], settings[:user_name], settings[:password], - settings[:authentication]) do |smtp| - smtp.sendmail(mail.encoded, sender, destinations) - end - end - end - end -end diff --git a/actionmailer/lib/action_mailer/delivery_method/test.rb b/actionmailer/lib/action_mailer/delivery_method/test.rb deleted file mode 100644 index 6e3239d52a..0000000000 --- a/actionmailer/lib/action_mailer/delivery_method/test.rb +++ /dev/null @@ -1,12 +0,0 @@ -module ActionMailer - module DeliveryMethod - - # A delivery method implementation designed for testing, which just appends each record to the :deliveries array - class Test < Method - def perform_delivery(mail) - ActionMailer::Base.deliveries << mail - end - end - - end -end -- cgit v1.2.3 From 0750304c0117c85f06cf1ea608747b8fda0a0ecd Mon Sep 17 00:00:00 2001 From: Mikel Lindsaar Date: Sat, 16 Jan 2010 22:10:11 +1100 Subject: Migrated over to Mail doing delivery. --- actionmailer/lib/action_mailer/base.rb | 87 +++++++++++++++++++++++-------- actionmailer/test/abstract_unit.rb | 6 ++- actionmailer/test/delivery_method_test.rb | 63 +++++++++++++++++----- actionmailer/test/mail_service_test.rb | 12 ++--- actionmailer/test/test_helper_test.rb | 2 +- 5 files changed, 125 insertions(+), 45 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index b9a01356ba..89bd45a994 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -355,20 +355,42 @@ module ActionMailer #:nodoc: alias :controller_path :mailer_name class << self - attr_writer :mailer_name - - delegate :settings, :settings=, :to => ActionMailer::DeliveryMethod::File, :prefix => :file - delegate :settings, :settings=, :to => ActionMailer::DeliveryMethod::Sendmail, :prefix => :sendmail - delegate :settings, :settings=, :to => ActionMailer::DeliveryMethod::Smtp, :prefix => :smtp def mailer_name @mailer_name ||= name.underscore end - alias :controller_path :mailer_name + attr_writer :mailer_name + + def file_settings + @file_settings ||= {:location => defined?(Rails.root) ? "#{Rails.root}/tmp/mails" : "#{Dir.tmpdir}/mails"} + end + attr_writer :file_settings - def delivery_method=(method_name) - @delivery_method = ActionMailer::DeliveryMethod.lookup_method(method_name) + def sendmail_settings + @sendmail_settings ||= { :location => '/usr/sbin/sendmail', + :arguments => '-i -t' } end + attr_writer :sendmail_settings + + def smtp_settings + @smtp_settings ||= { :address => "localhost", + :port => 25, + :domain => 'localhost.localdomain', + :user_name => nil, + :password => nil, + :authentication => nil, + :enable_starttls_auto => true } + end + attr_writer :smtp_settings + + def custom_settings + @custom_settings ||= {} + end + attr_writer :custom_settings + + attr_writer :delivery_method + + alias :controller_path :mailer_name def respond_to?(method_symbol, include_private = false) #:nodoc: matches_dynamic_method?(method_symbol) || super @@ -413,7 +435,35 @@ module ActionMailer #:nodoc: # email.set_some_obscure_header "frobnicate" # MyMailer.deliver(email) def deliver(mail) - new.deliver!(mail) + raise "no mail object available for delivery!" unless mail + + begin + ActiveSupport::Notifications.instrument("action_mailer.deliver", + :mailer => self.name) do |payload| + set_payload_for_mail(payload, mail) + mail.delivery_method delivery_method, delivery_settings + if @@perform_deliveries + mail.deliver! + self.deliveries << mail + end + end + rescue Exception => e # Net::SMTP errors or sendmail pipe errors + raise e if raise_delivery_errors + end + + mail + end + + # Get the delivery settings set. This is set using the :smtp_settings, + # :sendmail_settings, :file_settings or :custom_setings + # options hashes. You can set :custom_settings if you are providing + # your own Custom Delivery Method and want to pass options to it. + def delivery_settings + if [:smtp, :sendmail, :file].include?(delivery_method) + instance_variable_get("@#{delivery_method}_settings") + else + @custom_settings + end end def template_root @@ -506,19 +556,7 @@ module ActionMailer #:nodoc: # object (from the create! method). If no cached mail object exists, and # no alternate has been given as the parameter, this will fail. def deliver!(mail = @mail) - raise "no mail object available for delivery!" unless mail - - begin - ActiveSupport::Notifications.instrument("action_mailer.deliver", - :template => template, :mailer => self.class.name) do |payload| - self.class.set_payload_for_mail(payload, mail) - self.delivery_method.perform_delivery(mail) if perform_deliveries - end - rescue Exception => e # Net::SMTP errors or sendmail pipe errors - raise e if raise_delivery_errors - end - - mail + self.class.deliver(mail) end private @@ -533,6 +571,11 @@ module ActionMailer #:nodoc: @mime_version ||= @@default_mime_version.dup if @@default_mime_version @mailer_name ||= self.class.mailer_name.dup + @delivery_method = self.class.delivery_method + @smtp_settings = self.class.smtp_settings.dup + @sendmail_settings = self.class.sendmail_settings.dup + @file_settings = self.class.file_settings.dup + @custom_settings = self.class.custom_settings.dup @template ||= method_name @parts ||= [] diff --git a/actionmailer/test/abstract_unit.rb b/actionmailer/test/abstract_unit.rb index 50b8a53006..1fc5ab85e0 100644 --- a/actionmailer/test/abstract_unit.rb +++ b/actionmailer/test/abstract_unit.rb @@ -26,6 +26,7 @@ FIXTURE_LOAD_PATH = File.join(File.dirname(__FILE__), 'fixtures') ActionMailer::Base.template_root = FIXTURE_LOAD_PATH class MockSMTP + def self.deliveries @@deliveries end @@ -41,6 +42,7 @@ class MockSMTP def start(*args) yield self end + end class Net::SMTP @@ -57,9 +59,9 @@ rescue LoadError $stderr.puts "Skipping #{test_name} tests. `gem install #{gem_name}` and try again." end -def set_delivery_method(delivery_method) +def set_delivery_method(method) @old_delivery_method = ActionMailer::Base.delivery_method - ActionMailer::Base.delivery_method = delivery_method + ActionMailer::Base.delivery_method = method end def restore_delivery_method diff --git a/actionmailer/test/delivery_method_test.rb b/actionmailer/test/delivery_method_test.rb index 8f8c6b0275..fb43086423 100644 --- a/actionmailer/test/delivery_method_test.rb +++ b/actionmailer/test/delivery_method_test.rb @@ -1,4 +1,5 @@ require 'abstract_unit' +require 'mail' class DefaultDeliveryMethodMailer < ActionMailer::Base end @@ -12,18 +13,22 @@ class FileDeliveryMethodMailer < ActionMailer::Base end class CustomDeliveryMethod - attr_accessor :custom_deliveries - def initialize() - @customer_deliveries = [] + + def initialize(values) + @custom_deliveries = [] end - def self.perform_delivery(mail) + attr_accessor :custom_deliveries + + attr_accessor :settings + + def deliver!(mail) self.custom_deliveries << mail end end class CustomerDeliveryMailer < ActionMailer::Base - self.delivery_method = CustomDeliveryMethod.new + self.delivery_method = CustomDeliveryMethod end class ActionMailerBase_delivery_method_Test < Test::Unit::TestCase @@ -36,7 +41,18 @@ class ActionMailerBase_delivery_method_Test < Test::Unit::TestCase end def test_should_be_the_default_smtp - assert_instance_of ActionMailer::DeliveryMethod::Smtp, ActionMailer::Base.delivery_method + assert_equal :smtp, ActionMailer::Base.delivery_method + end + + def test_should_have_default_smtp_delivery_method_settings + settings = { :address => "localhost", + :port => 25, + :domain => 'localhost.localdomain', + :user_name => nil, + :password => nil, + :authentication => nil, + :enable_starttls_auto => true } + assert_equal settings, ActionMailer::Base.smtp_settings end end @@ -50,7 +66,18 @@ class DefaultDeliveryMethodMailer_delivery_method_Test < Test::Unit::TestCase end def test_should_be_the_default_smtp - assert_instance_of ActionMailer::DeliveryMethod::Smtp, DefaultDeliveryMethodMailer.delivery_method + assert_equal :smtp, DefaultDeliveryMethodMailer.delivery_method + end + + def test_should_have_default_smtp_delivery_method_settings + settings = { :address => "localhost", + :port => 25, + :domain => 'localhost.localdomain', + :user_name => nil, + :password => nil, + :authentication => nil, + :enable_starttls_auto => true } + assert_equal settings, DefaultDeliveryMethodMailer.smtp_settings end end @@ -64,7 +91,13 @@ class NonDefaultDeliveryMethodMailer_delivery_method_Test < Test::Unit::TestCase end def test_should_be_the_set_delivery_method - assert_instance_of ActionMailer::DeliveryMethod::Sendmail, NonDefaultDeliveryMethodMailer.delivery_method + assert_equal :sendmail, NonDefaultDeliveryMethodMailer.delivery_method + end + + def test_should_have_default_sendmail_delivery_method_settings + settings = {:location => '/usr/sbin/sendmail', + :arguments => '-i -t'} + assert_equal settings, NonDefaultDeliveryMethodMailer.sendmail_settings end end @@ -78,11 +111,12 @@ class FileDeliveryMethodMailer_delivery_method_Test < Test::Unit::TestCase end def test_should_be_the_set_delivery_method - assert_instance_of ActionMailer::DeliveryMethod::File, FileDeliveryMethodMailer.delivery_method + assert_equal :file, FileDeliveryMethodMailer.delivery_method end - def test_should_default_location_to_the_tmpdir - assert_equal "#{Dir.tmpdir}/mails", ActionMailer::Base.file_settings[:location] + def test_should_have_default_file_delivery_method_settings + settings = {:location => "#{Dir.tmpdir}/mails"} + assert_equal settings, FileDeliveryMethodMailer.file_settings end end @@ -96,6 +130,11 @@ class CustomDeliveryMethodMailer_delivery_method_Test < Test::Unit::TestCase end def test_should_be_the_set_delivery_method - assert_instance_of CustomDeliveryMethod, CustomerDeliveryMailer.delivery_method + assert_equal CustomDeliveryMethod, CustomerDeliveryMailer.delivery_method + end + + def test_should_have_default_custom_delivery_method_settings + settings = {} + assert_equal settings, CustomerDeliveryMailer.custom_settings end end diff --git a/actionmailer/test/mail_service_test.rb b/actionmailer/test/mail_service_test.rb index cd41739f1a..c14dd644cd 100644 --- a/actionmailer/test/mail_service_test.rb +++ b/actionmailer/test/mail_service_test.rb @@ -546,7 +546,7 @@ class ActionMailerTest < Test::Unit::TestCase assert_not_nil mail mail, from, to = mail - assert_equal 'system@loudthinking.com', from.addresses.first + assert_equal 'system@loudthinking.com', from end def test_reply_to @@ -675,16 +675,13 @@ class ActionMailerTest < Test::Unit::TestCase def test_doesnt_raise_errors_when_raise_delivery_errors_is_false ActionMailer::Base.raise_delivery_errors = false - TestMailer.delivery_method.expects(:perform_delivery).raises(Exception) + Mail::Message.any_instance.expects(:deliver!).raises(Exception) assert_nothing_raised { TestMailer.deliver_signed_up(@recipient) } end def test_performs_delivery_via_sendmail - sm = mock() - sm.expects(:print).with(anything) - sm.expects(:flush) - IO.expects(:popen).once.with('/usr/sbin/sendmail -i -t', 'w+').yields(sm) - ActionMailer::Base.delivery_method = :sendmail + IO.expects(:popen).once.with('/usr/sbin/sendmail -i -t test@localhost', 'w+') + TestMailer.delivery_method = :sendmail TestMailer.deliver_signed_up(@recipient) end @@ -1113,7 +1110,6 @@ EOF def test_starttls_is_not_enabled ActionMailer::Base.smtp_settings[:enable_starttls_auto] = false MockSMTP.any_instance.expects(:respond_to?).never - MockSMTP.any_instance.expects(:enable_starttls_auto).never ActionMailer::Base.delivery_method = :smtp TestMailer.deliver_signed_up(@recipient) ensure diff --git a/actionmailer/test/test_helper_test.rb b/actionmailer/test/test_helper_test.rb index 1fed26f78f..48e4433e98 100644 --- a/actionmailer/test/test_helper_test.rb +++ b/actionmailer/test/test_helper_test.rb @@ -12,7 +12,7 @@ end class TestHelperMailerTest < ActionMailer::TestCase def test_setup_sets_right_action_mailer_options - assert_instance_of ActionMailer::DeliveryMethod::Test, ActionMailer::Base.delivery_method + assert_equal :test, ActionMailer::Base.delivery_method assert ActionMailer::Base.perform_deliveries assert_equal [], ActionMailer::Base.deliveries end -- cgit v1.2.3 From 03c1457eb5f05519dfc76750d72307258c7771e1 Mon Sep 17 00:00:00 2001 From: Mikel Lindsaar Date: Sat, 16 Jan 2010 22:43:13 +1100 Subject: Removed autoload of DeliveryMethods --- actionmailer/lib/action_mailer.rb | 1 - 1 file changed, 1 deletion(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer.rb b/actionmailer/lib/action_mailer.rb index 55ddbb24f4..66b07c39f4 100644 --- a/actionmailer/lib/action_mailer.rb +++ b/actionmailer/lib/action_mailer.rb @@ -32,7 +32,6 @@ module ActionMailer autoload :AdvAttrAccessor autoload :Base - autoload :DeliveryMethod autoload :DeprecatedBody autoload :MailHelper autoload :Quoting -- cgit v1.2.3 From 9a3a0d15fcf527894bec03b9e226c02bdc800f3e Mon Sep 17 00:00:00 2001 From: Mikel Lindsaar Date: Sun, 17 Jan 2010 21:02:38 +1100 Subject: Updating mail require to 2.0.0 --- actionmailer/actionmailer.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionmailer') diff --git a/actionmailer/actionmailer.gemspec b/actionmailer/actionmailer.gemspec index 96549bf29c..b860f3455a 100644 --- a/actionmailer/actionmailer.gemspec +++ b/actionmailer/actionmailer.gemspec @@ -11,7 +11,7 @@ Gem::Specification.new do |s| s.homepage = "http://www.rubyonrails.org" s.add_dependency('actionpack', '= 3.0.pre') - s.add_dependency('mail', '~> 1.6.0') + s.add_dependency('mail', '~> 2.0.0') s.files = Dir['CHANGELOG', 'README', 'MIT-LICENSE', 'lib/**/*'] s.has_rdoc = true -- cgit v1.2.3 From ccb7d9def3c20037c9ed5989d8cae1ed68763f4f Mon Sep 17 00:00:00 2001 From: Mikel Lindsaar Date: Sun, 17 Jan 2010 23:27:59 +1100 Subject: Fixing up base to refactor settings --- actionmailer/lib/action_mailer/base.rb | 70 +++++++++++++--------------------- actionmailer/test/mail_service_test.rb | 8 ++-- 2 files changed, 31 insertions(+), 47 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 89bd45a994..c1cce73303 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -361,39 +361,26 @@ module ActionMailer #:nodoc: end attr_writer :mailer_name - def file_settings - @file_settings ||= {:location => defined?(Rails.root) ? "#{Rails.root}/tmp/mails" : "#{Dir.tmpdir}/mails"} - end - attr_writer :file_settings - - def sendmail_settings - @sendmail_settings ||= { :location => '/usr/sbin/sendmail', - :arguments => '-i -t' } - end - attr_writer :sendmail_settings - - def smtp_settings - @smtp_settings ||= { :address => "localhost", - :port => 25, - :domain => 'localhost.localdomain', - :user_name => nil, - :password => nil, - :authentication => nil, - :enable_starttls_auto => true } - end - attr_writer :smtp_settings - - def custom_settings - @custom_settings ||= {} + def delivery_settings + @delivery_settings ||= { :file => { :location => defined?(Rails.root) ? "#{Rails.root}/tmp/mails" : "#{Dir.tmpdir}/mails" }, + :smtp => { :address => "localhost", + :port => 25, + :domain => 'localhost.localdomain', + :user_name => nil, + :password => nil, + :authentication => nil, + :enable_starttls_auto => true }, + :sendmail => { :location => '/usr/sbin/sendmail', + :arguments => '-i -t' } + } end - attr_writer :custom_settings attr_writer :delivery_method alias :controller_path :mailer_name def respond_to?(method_symbol, include_private = false) #:nodoc: - matches_dynamic_method?(method_symbol) || super + matches_dynamic_method?(method_symbol) || matches_settings_method?(method_symbol) || super end def method_missing(method_symbol, *parameters) #:nodoc: @@ -404,6 +391,8 @@ module ActionMailer #:nodoc: when 'new' then nil else super end + elsif match = matches_settings_method?(method_symbol) + delivery_settings[match[1].to_sym] = parameters[0] else super end @@ -441,7 +430,8 @@ module ActionMailer #:nodoc: ActiveSupport::Notifications.instrument("action_mailer.deliver", :mailer => self.name) do |payload| set_payload_for_mail(payload, mail) - mail.delivery_method delivery_method, delivery_settings + + mail.delivery_method delivery_method, get_delivery_settings(delivery_method) if @@perform_deliveries mail.deliver! self.deliveries << mail @@ -454,18 +444,6 @@ module ActionMailer #:nodoc: mail end - # Get the delivery settings set. This is set using the :smtp_settings, - # :sendmail_settings, :file_settings or :custom_setings - # options hashes. You can set :custom_settings if you are providing - # your own Custom Delivery Method and want to pass options to it. - def delivery_settings - if [:smtp, :sendmail, :file].include?(delivery_method) - instance_variable_get("@#{delivery_method}_settings") - else - @custom_settings - end - end - def template_root self.view_paths && self.view_paths.first end @@ -487,6 +465,16 @@ module ActionMailer #:nodoc: end private + + def get_delivery_settings(method) #:nodoc: + method.is_a?(Symbol) ? delivery_settings[method] : delivery_settings[:custom] + end + + def matches_settings_method?(method_name) #:nodoc: + method_name = method_name.to_s + delivery_method.is_a?(Symbol) ? method = delivery_method : method = :custom + /(file|sendmail|smtp)_settings$/.match(method_name) + end def matches_dynamic_method?(method_name) #:nodoc: method_name = method_name.to_s @@ -572,10 +560,6 @@ module ActionMailer #:nodoc: @mailer_name ||= self.class.mailer_name.dup @delivery_method = self.class.delivery_method - @smtp_settings = self.class.smtp_settings.dup - @sendmail_settings = self.class.sendmail_settings.dup - @file_settings = self.class.file_settings.dup - @custom_settings = self.class.custom_settings.dup @template ||= method_name @parts ||= [] diff --git a/actionmailer/test/mail_service_test.rb b/actionmailer/test/mail_service_test.rb index c14dd644cd..e53d8a38ef 100644 --- a/actionmailer/test/mail_service_test.rb +++ b/actionmailer/test/mail_service_test.rb @@ -1092,7 +1092,7 @@ EOF end def test_starttls_is_enabled_if_supported - ActionMailer::Base.smtp_settings[:enable_starttls_auto] = true + ActionMailer::Base.delivery_settings[:smtp].merge!(:enable_starttls_auto => true) MockSMTP.any_instance.expects(:respond_to?).with(:enable_starttls_auto).returns(true) MockSMTP.any_instance.expects(:enable_starttls_auto) ActionMailer::Base.delivery_method = :smtp @@ -1100,7 +1100,7 @@ EOF end def test_starttls_is_disabled_if_not_supported - ActionMailer::Base.smtp_settings[:enable_starttls_auto] = true + ActionMailer::Base.delivery_settings[:smtp].merge!(:enable_starttls_auto => true) MockSMTP.any_instance.expects(:respond_to?).with(:enable_starttls_auto).returns(false) MockSMTP.any_instance.expects(:enable_starttls_auto).never ActionMailer::Base.delivery_method = :smtp @@ -1108,12 +1108,12 @@ EOF end def test_starttls_is_not_enabled - ActionMailer::Base.smtp_settings[:enable_starttls_auto] = false + ActionMailer::Base.delivery_settings[:smtp].merge!(:enable_starttls_auto => false) MockSMTP.any_instance.expects(:respond_to?).never ActionMailer::Base.delivery_method = :smtp TestMailer.deliver_signed_up(@recipient) ensure - ActionMailer::Base.smtp_settings[:enable_starttls_auto] = true + ActionMailer::Base.delivery_settings[:smtp].merge!(:enable_starttls_auto => true) end end -- cgit v1.2.3 From d201d39437c754fa38b14dd4168fab601399918e Mon Sep 17 00:00:00 2001 From: Mikel Lindsaar Date: Tue, 19 Jan 2010 23:09:46 +1100 Subject: latest updates --- actionmailer/lib/action_mailer/base.rb | 22 ++++++++++------------ actionmailer/test/mail_layout_test.rb | 1 + 2 files changed, 11 insertions(+), 12 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index e0a99fa00c..fd251ff223 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -354,6 +354,8 @@ module ActionMailer #:nodoc: # Alias controller_path to mailer_name so render :partial in views work. alias :controller_path :mailer_name + class_inheritable_accessor :delivery_method + class << self def mailer_name @@ -361,21 +363,17 @@ module ActionMailer #:nodoc: end attr_writer :mailer_name + # Mail uses the same defaults as Rails, except for the file delivery method + # save location so we just add this here. def delivery_settings - @delivery_settings ||= { :file => { :location => defined?(Rails.root) ? "#{Rails.root}/tmp/mails" : "#{Dir.tmpdir}/mails" }, - :smtp => { :address => "localhost", - :port => 25, - :domain => 'localhost.localdomain', - :user_name => nil, - :password => nil, - :authentication => nil, - :enable_starttls_auto => true }, - :sendmail => { :location => '/usr/sbin/sendmail', - :arguments => '-i -t' } - } + @delivery_settings ||= {:file => {:location => defined?(Rails.root) ? "#{Rails.root}/tmp/mails" : "#{Dir.tmpdir}/mails"}} end - attr_writer :delivery_method + # Setup the default settings for Mail delivery + Mail.defaults do + method = ActionMailer::Base.delivery_method ||= :smtp + delivery_method method + end alias :controller_path :mailer_name diff --git a/actionmailer/test/mail_layout_test.rb b/actionmailer/test/mail_layout_test.rb index 0877e7b2cb..b9ff075461 100644 --- a/actionmailer/test/mail_layout_test.rb +++ b/actionmailer/test/mail_layout_test.rb @@ -1,6 +1,7 @@ require 'abstract_unit' class AutoLayoutMailer < ActionMailer::Base + def hello(recipient) recipients recipient subject "You have a mail" -- cgit v1.2.3 From c8e2998701653df9035232778d60f18c4a07abb4 Mon Sep 17 00:00:00 2001 From: Mikel Lindsaar Date: Tue, 19 Jan 2010 23:36:49 +1100 Subject: First pass on fixing delivery method --- actionmailer/lib/action_mailer/base.rb | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index fd251ff223..082560e695 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -354,7 +354,8 @@ module ActionMailer #:nodoc: # Alias controller_path to mailer_name so render :partial in views work. alias :controller_path :mailer_name - class_inheritable_accessor :delivery_method + superclass_delegating_accessor :delivery_method + self.delivery_method = :smtp class << self @@ -369,12 +370,6 @@ module ActionMailer #:nodoc: @delivery_settings ||= {:file => {:location => defined?(Rails.root) ? "#{Rails.root}/tmp/mails" : "#{Dir.tmpdir}/mails"}} end - # Setup the default settings for Mail delivery - Mail.defaults do - method = ActionMailer::Base.delivery_method ||= :smtp - delivery_method method - end - alias :controller_path :mailer_name def respond_to?(method_symbol, include_private = false) #:nodoc: @@ -390,6 +385,7 @@ module ActionMailer #:nodoc: else super end elsif match = matches_settings_method?(method_symbol) + # TODO Deprecation warning delivery_settings[match[1].to_sym] = parameters[0] else super @@ -463,7 +459,7 @@ module ActionMailer #:nodoc: end private - + def get_delivery_settings(method) #:nodoc: method.is_a?(Symbol) ? delivery_settings[method] : delivery_settings[:custom] end -- cgit v1.2.3 From c1848f9736d9a4a45181642106acecb6a83a45a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 19 Jan 2010 14:28:04 +0100 Subject: Get all tests passing. --- actionmailer/lib/action_mailer/base.rb | 36 ++++++++++++++++++++++++++++------ actionmailer/test/mail_service_test.rb | 9 ++------- 2 files changed, 32 insertions(+), 13 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 082560e695..5ece35e69b 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -367,7 +367,29 @@ module ActionMailer #:nodoc: # Mail uses the same defaults as Rails, except for the file delivery method # save location so we just add this here. def delivery_settings - @delivery_settings ||= {:file => {:location => defined?(Rails.root) ? "#{Rails.root}/tmp/mails" : "#{Dir.tmpdir}/mails"}} + @@delivery_settings ||= begin + hash = Hash.new { |h,k| h[k] = {} } + hash[:file] = { + :location => defined?(Rails.root) ? "#{Rails.root}/tmp/mails" : "#{Dir.tmpdir}/mails" + } + + hash[:smtp] = { + :address => "localhost", + :port => 25, + :domain => 'localhost.localdomain', + :user_name => nil, + :password => nil, + :authentication => nil, + :enable_starttls_auto => true + } + + hash[:sendmail] = { + :location => '/usr/sbin/sendmail', + :arguments => '-i -t' + } + + hash + end end alias :controller_path :mailer_name @@ -386,7 +408,11 @@ module ActionMailer #:nodoc: end elsif match = matches_settings_method?(method_symbol) # TODO Deprecation warning - delivery_settings[match[1].to_sym] = parameters[0] + if match[2] + delivery_settings[match[1].to_sym] = parameters[0] + else + delivery_settings[match[1].to_sym] + end else super end @@ -461,13 +487,11 @@ module ActionMailer #:nodoc: private def get_delivery_settings(method) #:nodoc: - method.is_a?(Symbol) ? delivery_settings[method] : delivery_settings[:custom] + delivery_settings[method] end def matches_settings_method?(method_name) #:nodoc: - method_name = method_name.to_s - delivery_method.is_a?(Symbol) ? method = delivery_method : method = :custom - /(file|sendmail|smtp)_settings$/.match(method_name) + /(\w+)_settings(=)?$/.match(method_name.to_s) end def matches_dynamic_method?(method_name) #:nodoc: diff --git a/actionmailer/test/mail_service_test.rb b/actionmailer/test/mail_service_test.rb index 17e7992e29..7b5f8b1ffc 100644 --- a/actionmailer/test/mail_service_test.rb +++ b/actionmailer/test/mail_service_test.rb @@ -680,7 +680,7 @@ class ActionMailerTest < Test::Unit::TestCase def test_performs_delivery_via_sendmail IO.expects(:popen).once.with('/usr/sbin/sendmail -i -t test@localhost', 'w+') - TestMailer.delivery_method = :sendmail + ActionMailer::Base.delivery_method = :sendmail TestMailer.deliver_signed_up(@recipient) end @@ -1069,12 +1069,7 @@ EOF def test_return_path_with_create mail = TestMailer.create_return_path - assert_equal "another@somewhere.test", mail['return-path'].to_s - end - - def test_return_path_with_create - mail = TestMailer.create_return_path - assert_equal ["another@somewhere.test"], mail.return_path + assert_equal "another@somewhere.test", mail.return_path end def test_return_path_with_deliver -- cgit v1.2.3 From e10f51b6b7b6260824cc86085be49cae216cf06c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 19 Jan 2010 15:34:58 +0100 Subject: Refactor delivery methods. --- actionmailer/lib/action_mailer.rb | 1 + actionmailer/lib/action_mailer/base.rb | 81 ++------------- actionmailer/lib/action_mailer/delivery_methods.rb | 71 +++++++++++++ actionmailer/lib/action_mailer/deprecated_body.rb | 10 +- actionmailer/test/delivery_method_test.rb | 115 +++++---------------- 5 files changed, 113 insertions(+), 165 deletions(-) create mode 100644 actionmailer/lib/action_mailer/delivery_methods.rb (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer.rb b/actionmailer/lib/action_mailer.rb index 66b07c39f4..f1c94e9e69 100644 --- a/actionmailer/lib/action_mailer.rb +++ b/actionmailer/lib/action_mailer.rb @@ -32,6 +32,7 @@ module ActionMailer autoload :AdvAttrAccessor autoload :Base + autoload :DeliveryMethods autoload :DeprecatedBody autoload :MailHelper autoload :Quoting diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 5ece35e69b..be6d93316f 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -264,6 +264,8 @@ module ActionMailer #:nodoc: helper ActionMailer::MailHelper include ActionMailer::DeprecatedBody + include ActionMailer::DeliveryMethods + private_class_method :new #:nodoc: @@raise_delivery_errors = true @@ -354,9 +356,6 @@ module ActionMailer #:nodoc: # Alias controller_path to mailer_name so render :partial in views work. alias :controller_path :mailer_name - superclass_delegating_accessor :delivery_method - self.delivery_method = :smtp - class << self def mailer_name @@ -364,38 +363,10 @@ module ActionMailer #:nodoc: end attr_writer :mailer_name - # Mail uses the same defaults as Rails, except for the file delivery method - # save location so we just add this here. - def delivery_settings - @@delivery_settings ||= begin - hash = Hash.new { |h,k| h[k] = {} } - hash[:file] = { - :location => defined?(Rails.root) ? "#{Rails.root}/tmp/mails" : "#{Dir.tmpdir}/mails" - } - - hash[:smtp] = { - :address => "localhost", - :port => 25, - :domain => 'localhost.localdomain', - :user_name => nil, - :password => nil, - :authentication => nil, - :enable_starttls_auto => true - } - - hash[:sendmail] = { - :location => '/usr/sbin/sendmail', - :arguments => '-i -t' - } - - hash - end - end - alias :controller_path :mailer_name def respond_to?(method_symbol, include_private = false) #:nodoc: - matches_dynamic_method?(method_symbol) || matches_settings_method?(method_symbol) || super + matches_dynamic_method?(method_symbol) || super end def method_missing(method_symbol, *parameters) #:nodoc: @@ -406,13 +377,6 @@ module ActionMailer #:nodoc: when 'new' then nil else super end - elsif match = matches_settings_method?(method_symbol) - # TODO Deprecation warning - if match[2] - delivery_settings[match[1].to_sym] = parameters[0] - else - delivery_settings[match[1].to_sym] - end else super end @@ -447,11 +411,13 @@ module ActionMailer #:nodoc: raise "no mail object available for delivery!" unless mail begin - ActiveSupport::Notifications.instrument("action_mailer.deliver", - :mailer => self.name) do |payload| + ActiveSupport::Notifications.instrument("action_mailer.deliver", :mailer => self.name) do |payload| set_payload_for_mail(payload, mail) - - mail.delivery_method delivery_method, get_delivery_settings(delivery_method) + + # TODO Move me to the instance + mail.delivery_method delivery_methods[delivery_method], + delivery_settings[delivery_method] + if @@perform_deliveries mail.deliver! self.deliveries << mail @@ -486,25 +452,12 @@ module ActionMailer #:nodoc: private - def get_delivery_settings(method) #:nodoc: - delivery_settings[method] - end - - def matches_settings_method?(method_name) #:nodoc: - /(\w+)_settings(=)?$/.match(method_name.to_s) - end - def matches_dynamic_method?(method_name) #:nodoc: method_name = method_name.to_s /^(create|deliver)_([_a-z]\w*)/.match(method_name) || /^(new)$/.match(method_name) end end - # Configure delivery method. Check ActionMailer::DeliveryMethod for more - # instructions. - superclass_delegating_reader :delivery_method - self.delivery_method = :smtp - # Add a part to a multipart message, with the given content-type. The # part itself is yielded to the block so that other properties (charset, # body, headers, etc.) can be set on it. @@ -534,20 +487,6 @@ module ActionMailer #:nodoc: part(params, &block) end - # Allow you to set assigns for your template: - # - # body :greetings => "Hi" - # - # Will make @greetings available in the template to be rendered. - def body(object=nil) - returning(super) do # Run deprecation hooks - if object.is_a?(Hash) - @assigns_set = true - object.each { |k, v| instance_variable_set(:"@#{k}", v) } - end - end - end - # Instantiate a new mailer object. If +method_name+ is not +nil+, the mailer # will be initialized according to the named method. If not, the mailer will # remain uninitialized (useful when you only need to invoke the "receive" @@ -591,6 +530,8 @@ module ActionMailer #:nodoc: # render_message "special_message" # render_message :template => "special_message" # render_message :inline => "<%= 'Hi!' %>" + # + # TODO Deprecate me def render_message(object) case object when String diff --git a/actionmailer/lib/action_mailer/delivery_methods.rb b/actionmailer/lib/action_mailer/delivery_methods.rb new file mode 100644 index 0000000000..c8c4148353 --- /dev/null +++ b/actionmailer/lib/action_mailer/delivery_methods.rb @@ -0,0 +1,71 @@ +module ActionMailer + # This modules makes a DSL for adding delivery methods to ActionMailer + module DeliveryMethods + extend ActiveSupport::Concern + + included do + add_delivery_method :smtp, Mail::SMTP, + :address => "localhost", + :port => 25, + :domain => 'localhost.localdomain', + :user_name => nil, + :password => nil, + :authentication => nil, + :enable_starttls_auto => true + + add_delivery_method :file, Mail::FileDelivery, + :location => defined?(Rails.root) ? "#{Rails.root}/tmp/mails" : "#{Dir.tmpdir}/mails" + + add_delivery_method :sendmail, Mail::Sendmail, + :location => '/usr/sbin/sendmail', + :arguments => '-i -t' + + add_delivery_method :test, Mail::TestMailer + + superclass_delegating_reader :delivery_method + self.delivery_method = :smtp + end + + module ClassMethods + def delivery_settings + @@delivery_settings ||= Hash.new { |h,k| h[k] = {} } + end + + def delivery_methods + @@delivery_methods ||= {} + end + + def delivery_method=(method) + raise ArgumentError, "Unknown delivery method #{method.inspect}" unless delivery_methods[method] + @delivery_method = method + end + + def add_delivery_method(symbol, klass, default_options={}) + self.delivery_methods[symbol] = klass + self.delivery_settings[symbol] = default_options + end + + def respond_to?(method_symbol, include_private = false) #:nodoc: + matches_settings_method?(method_symbol) || super + end + + protected + + def method_missing(method_symbol, *parameters) #:nodoc: + if match = matches_settings_method?(method_symbol) + if match[2] + delivery_settings[match[1].to_sym] = parameters[0] + else + delivery_settings[match[1].to_sym] + end + else + super + end + end + + def matches_settings_method?(method_name) #:nodoc: + /(#{delivery_methods.keys.join('|')})_settings(=)?$/.match(method_name.to_s) + end + end + end +end \ No newline at end of file diff --git a/actionmailer/lib/action_mailer/deprecated_body.rb b/actionmailer/lib/action_mailer/deprecated_body.rb index 5379b33a54..c82610014f 100644 --- a/actionmailer/lib/action_mailer/deprecated_body.rb +++ b/actionmailer/lib/action_mailer/deprecated_body.rb @@ -1,6 +1,6 @@ module ActionMailer # TODO Remove this module all together in a next release. Ensure that super - # hooks and @assigns_set in ActionMailer::Base are removed as well. + # hooks in ActionMailer::Base are removed as well. module DeprecatedBody extend ActionMailer::AdvAttrAccessor @@ -22,12 +22,14 @@ module ActionMailer end def create_parts - if String === @body && !defined?(@assigns_set) + if String === @body ActiveSupport::Deprecation.warn('body(String) is deprecated. To set the body with a text ' << 'call render(:text => "body")', caller[0,10]) self.response_body = @body - elsif self.response_body - @body = self.response_body + elsif @body.is_a?(Hash) && !@body.empty? + ActiveSupport::Deprecation.warn('body(Hash) is deprecated. Use instance variables to define ' << + 'assigns in your view', caller[0,10]) + @body.each { |k, v| instance_variable_set(:"@#{k}", v) } end end diff --git a/actionmailer/test/delivery_method_test.rb b/actionmailer/test/delivery_method_test.rb index fb43086423..1e7408d6d6 100644 --- a/actionmailer/test/delivery_method_test.rb +++ b/actionmailer/test/delivery_method_test.rb @@ -1,41 +1,14 @@ require 'abstract_unit' require 'mail' -class DefaultDeliveryMethodMailer < ActionMailer::Base +class MyCustomDelivery end -class NonDefaultDeliveryMethodMailer < ActionMailer::Base - self.delivery_method = :sendmail -end - -class FileDeliveryMethodMailer < ActionMailer::Base - self.delivery_method = :file -end - -class CustomDeliveryMethod - - def initialize(values) - @custom_deliveries = [] - end - - attr_accessor :custom_deliveries - - attr_accessor :settings - - def deliver!(mail) - self.custom_deliveries << mail - end -end - -class CustomerDeliveryMailer < ActionMailer::Base - self.delivery_method = CustomDeliveryMethod -end - -class ActionMailerBase_delivery_method_Test < Test::Unit::TestCase +class DefaultsDeliveryMethodsTest < ActionMailer::TestCase def setup set_delivery_method :smtp end - + def teardown restore_delivery_method end @@ -54,87 +27,47 @@ class ActionMailerBase_delivery_method_Test < Test::Unit::TestCase :enable_starttls_auto => true } assert_equal settings, ActionMailer::Base.smtp_settings end -end - -class DefaultDeliveryMethodMailer_delivery_method_Test < Test::Unit::TestCase - def setup - set_delivery_method :smtp - end - - def teardown - restore_delivery_method - end - - def test_should_be_the_default_smtp - assert_equal :smtp, DefaultDeliveryMethodMailer.delivery_method - end - - def test_should_have_default_smtp_delivery_method_settings - settings = { :address => "localhost", - :port => 25, - :domain => 'localhost.localdomain', - :user_name => nil, - :password => nil, - :authentication => nil, - :enable_starttls_auto => true } - assert_equal settings, DefaultDeliveryMethodMailer.smtp_settings - end -end - -class NonDefaultDeliveryMethodMailer_delivery_method_Test < Test::Unit::TestCase - def setup - set_delivery_method :smtp - end - - def teardown - restore_delivery_method - end - def test_should_be_the_set_delivery_method - assert_equal :sendmail, NonDefaultDeliveryMethodMailer.delivery_method + def test_should_have_default_file_delivery_method_settings + settings = {:location => "#{Dir.tmpdir}/mails"} + assert_equal settings, ActionMailer::Base.file_settings end def test_should_have_default_sendmail_delivery_method_settings settings = {:location => '/usr/sbin/sendmail', :arguments => '-i -t'} - assert_equal settings, NonDefaultDeliveryMethodMailer.sendmail_settings + assert_equal settings, ActionMailer::Base.sendmail_settings end end -class FileDeliveryMethodMailer_delivery_method_Test < Test::Unit::TestCase +class CustomDeliveryMethodsTest < ActionMailer::TestCase def setup - set_delivery_method :smtp + ActionMailer::Base.add_delivery_method :custom, MyCustomDelivery end def teardown - restore_delivery_method - end - - def test_should_be_the_set_delivery_method - assert_equal :file, FileDeliveryMethodMailer.delivery_method - end - - def test_should_have_default_file_delivery_method_settings - settings = {:location => "#{Dir.tmpdir}/mails"} - assert_equal settings, FileDeliveryMethodMailer.file_settings + ActionMailer::Base.delivery_methods.delete(:custom) + ActionMailer::Base.delivery_settings.delete(:custom) end -end -class CustomDeliveryMethodMailer_delivery_method_Test < Test::Unit::TestCase - def setup - set_delivery_method :smtp + def test_allow_to_add_a_custom_delivery_method + ActionMailer::Base.delivery_method = :custom + assert_equal :custom, ActionMailer::Base.delivery_method end - def teardown - restore_delivery_method + def test_allow_to_customize_custom_settings + ActionMailer::Base.custom_settings = { :foo => :bar } + assert_equal Hash[:foo => :bar], ActionMailer::Base.custom_settings end - def test_should_be_the_set_delivery_method - assert_equal CustomDeliveryMethod, CustomerDeliveryMailer.delivery_method + def test_respond_to_custom_method_settings + assert_respond_to ActionMailer::Base, :custom_settings + assert_respond_to ActionMailer::Base, :custom_settings= end - def test_should_have_default_custom_delivery_method_settings - settings = {} - assert_equal settings, CustomerDeliveryMailer.custom_settings + def test_should_not_respond_for_invalid_method_settings + assert_raise NoMethodError do + ActionMailer::Base.another_settings + end end end -- cgit v1.2.3 From 2a3ec5fee447a9b3729d04499d9e72b44079faef Mon Sep 17 00:00:00 2001 From: Mikel Lindsaar Date: Wed, 20 Jan 2010 14:12:05 +1100 Subject: Updating gemspec to 2.0.1 for mail --- actionmailer/actionmailer.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionmailer') diff --git a/actionmailer/actionmailer.gemspec b/actionmailer/actionmailer.gemspec index b860f3455a..cc1c25401e 100644 --- a/actionmailer/actionmailer.gemspec +++ b/actionmailer/actionmailer.gemspec @@ -11,7 +11,7 @@ Gem::Specification.new do |s| s.homepage = "http://www.rubyonrails.org" s.add_dependency('actionpack', '= 3.0.pre') - s.add_dependency('mail', '~> 2.0.0') + s.add_dependency('mail', '~> 2.0.1') s.files = Dir['CHANGELOG', 'README', 'MIT-LICENSE', 'lib/**/*'] s.has_rdoc = true -- cgit v1.2.3 From c04baed627c85e586e337896d64f61f397554a46 Mon Sep 17 00:00:00 2001 From: Mikel Lindsaar Date: Wed, 20 Jan 2010 14:12:17 +1100 Subject: Fixing failing test on sendmail expectation --- actionmailer/test/mail_service_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionmailer') diff --git a/actionmailer/test/mail_service_test.rb b/actionmailer/test/mail_service_test.rb index 7b5f8b1ffc..396dd00a91 100644 --- a/actionmailer/test/mail_service_test.rb +++ b/actionmailer/test/mail_service_test.rb @@ -679,7 +679,7 @@ class ActionMailerTest < Test::Unit::TestCase end def test_performs_delivery_via_sendmail - IO.expects(:popen).once.with('/usr/sbin/sendmail -i -t test@localhost', 'w+') + IO.expects(:popen).once.with('/usr/sbin/sendmail -i -t -f "system@loudthinking.com" test@localhost', 'w+') ActionMailer::Base.delivery_method = :sendmail TestMailer.deliver_signed_up(@recipient) end -- cgit v1.2.3 From 10c509fbfa70758ece26e8876d1c5c28f659f2f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Wed, 20 Jan 2010 22:25:09 +1100 Subject: Moved old API into deprecated_api.rb in preparation for new Rails 3 Mailer API --- actionmailer/lib/action_mailer.rb | 1 + .../lib/action_mailer/adv_attr_accessor.rb | 2 + actionmailer/lib/action_mailer/base.rb | 156 +------------------- actionmailer/lib/action_mailer/deprecated_api.rb | 163 +++++++++++++++++++++ actionmailer/test/base_test.rb | 39 +++++ 5 files changed, 208 insertions(+), 153 deletions(-) create mode 100644 actionmailer/lib/action_mailer/deprecated_api.rb create mode 100644 actionmailer/test/base_test.rb (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer.rb b/actionmailer/lib/action_mailer.rb index f1c94e9e69..1765aee9cc 100644 --- a/actionmailer/lib/action_mailer.rb +++ b/actionmailer/lib/action_mailer.rb @@ -34,6 +34,7 @@ module ActionMailer autoload :Base autoload :DeliveryMethods autoload :DeprecatedBody + autoload :DeprecatedApi autoload :MailHelper autoload :Quoting autoload :TestCase diff --git a/actionmailer/lib/action_mailer/adv_attr_accessor.rb b/actionmailer/lib/action_mailer/adv_attr_accessor.rb index be6b1feca9..91992ed839 100644 --- a/actionmailer/lib/action_mailer/adv_attr_accessor.rb +++ b/actionmailer/lib/action_mailer/adv_attr_accessor.rb @@ -1,6 +1,8 @@ module ActionMailer module AdvAttrAccessor #:nodoc: def adv_attr_accessor(*names) + + # TODO: ActiveSupport::Deprecation.warn() names.each do |name| ivar = "@#{name}" diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index e105beef63..9df482cdf6 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -263,9 +263,11 @@ module ActionMailer #:nodoc: helper ActionMailer::MailHelper include ActionMailer::DeprecatedBody + include ActionMailer::DeprecatedApi include ActionMailer::DeliveryMethods + private_class_method :new #:nodoc: @@raise_delivery_errors = true @@ -459,41 +461,13 @@ module ActionMailer #:nodoc: end end - # Add a part to a multipart message, with the given content-type. The - # part itself is yielded to the block so that other properties (charset, - # body, headers, etc.) can be set on it. - def part(params) - params = {:content_type => params} if String === params - - if custom_headers = params.delete(:headers) - ActiveSupport::Deprecation.warn('Passing custom headers with :headers => {} is deprecated. ' << - 'Please just pass in custom headers directly.', caller[0,10]) - params.merge!(custom_headers) - end - - part = Mail::Part.new(params) - yield part if block_given? - @parts << part - end - - # Add an attachment to a multipart message. This is simply a part with the - # content-disposition set to "attachment". - def attachment(params, &block) - super # Run deprecation hooks - - params = { :content_type => params } if String === params - params = { :content_disposition => "attachment", - :content_transfer_encoding => "base64" }.merge(params) - - part(params, &block) - end - # Instantiate a new mailer object. If +method_name+ is not +nil+, the mailer # will be initialized according to the named method. If not, the mailer will # remain uninitialized (useful when you only need to invoke the "receive" # method, for instance). def initialize(method_name=nil, *args) super() + @mail = Mail.new process(method_name, *args) if method_name end @@ -521,129 +495,5 @@ module ActionMailer #:nodoc: self.class.deliver(mail) end - private - - # Render a message but does not set it as mail body. Useful for rendering - # data for part and attachments. - # - # Examples: - # - # render_message "special_message" - # render_message :template => "special_message" - # render_message :inline => "<%= 'Hi!' %>" - # - # TODO Deprecate me - def render_message(object) - case object - when String - render_to_body(:template => object) - else - render_to_body(object) - end - end - - # Set up the default values for the various instance variables of this - # mailer. Subclasses may override this method to provide different - # defaults. - def initialize_defaults(method_name) #:nodoc: - @charset ||= @@default_charset.dup - @content_type ||= @@default_content_type.dup - @implicit_parts_order ||= @@default_implicit_parts_order.dup - @mime_version ||= @@default_mime_version.dup if @@default_mime_version - - @mailer_name ||= self.class.mailer_name.dup - @delivery_method = self.class.delivery_method - @template ||= method_name - - @parts ||= [] - @headers ||= {} - @sent_on ||= Time.now - - super # Run deprecation hooks - end - - def create_parts #:nodoc: - super # Run deprecation hooks - - if String === response_body - @parts.unshift create_inline_part(response_body) - else - self.class.template_root.find_all(@template, {}, @mailer_name).each do |template| - @parts << create_inline_part(render_to_body(:_template => template), template.mime_type) - end - - if @parts.size > 1 - @content_type = "multipart/alternative" if @content_type !~ /^multipart/ - end - - # If this is a multipart e-mail add the mime_version if it is not - # already set. - @mime_version ||= "1.0" if !@parts.empty? - end - end - - def create_inline_part(body, mime_type=nil) #:nodoc: - ct = mime_type || "text/plain" - main_type, sub_type = split_content_type(ct.to_s) - - Mail::Part.new( - :content_type => [main_type, sub_type, {:charset => charset}], - :content_disposition => "inline", - :body => body - ) - end - - def create_mail #:nodoc: - m = Mail.new - - m.subject, = quote_any_if_necessary(charset, subject) - m.to, m.from = quote_any_address_if_necessary(charset, recipients, from) - m.bcc = quote_address_if_necessary(bcc, charset) unless bcc.nil? - m.cc = quote_address_if_necessary(cc, charset) unless cc.nil? - m.reply_to = quote_address_if_necessary(reply_to, charset) unless reply_to.nil? - m.mime_version = mime_version unless mime_version.nil? - m.date = sent_on.to_time rescue sent_on if sent_on - - headers.each { |k, v| m[k] = v } - - real_content_type, ctype_attrs = parse_content_type - main_type, sub_type = split_content_type(real_content_type) - - if @parts.size == 1 && @parts.first.parts.empty? - m.content_type([main_type, sub_type, ctype_attrs]) - m.body = @parts.first.body.encoded - else - @parts.each do |p| - m.add_part(p) - end - - m.body.set_sort_order(@implicit_parts_order) - m.body.sort_parts! - - if real_content_type =~ /multipart/ - ctype_attrs.delete "charset" - m.content_type([main_type, sub_type, ctype_attrs]) - end - end - - m.content_transfer_encoding = '8bit' unless m.body.only_us_ascii? - - @mail = m - end - - def split_content_type(ct) #:nodoc: - ct.to_s.split("/") - end - - def parse_content_type(defaults=nil) #:nodoc: - if @content_type.blank? - [ nil, {} ] - else - ctype, *attrs = @content_type.split(/;\s*/) - attrs = attrs.inject({}) { |h,s| k,v = s.split(/\=/, 2); h[k] = v; h } - [ctype, {"charset" => @charset}.merge(attrs)] - end - end - end end diff --git a/actionmailer/lib/action_mailer/deprecated_api.rb b/actionmailer/lib/action_mailer/deprecated_api.rb new file mode 100644 index 0000000000..3334b47987 --- /dev/null +++ b/actionmailer/lib/action_mailer/deprecated_api.rb @@ -0,0 +1,163 @@ +module ActionMailer + # TODO Remove this module all together in Rails 3.1. Ensure that super + # hooks in ActionMailer::Base are removed as well. + # + # Moved here to allow us to add the new Mail API + module DeprecatedApi + extend ActionMailer::AdvAttrAccessor + + # Add a part to a multipart message, with the given content-type. The + # part itself is yielded to the block so that other properties (charset, + # body, headers, etc.) can be set on it. + def part(params) + params = {:content_type => params} if String === params + + if custom_headers = params.delete(:headers) + ActiveSupport::Deprecation.warn('Passing custom headers with :headers => {} is deprecated. ' << + 'Please just pass in custom headers directly.', caller[0,10]) + params.merge!(custom_headers) + end + + part = Mail::Part.new(params) + yield part if block_given? + @parts << part + end + + # Add an attachment to a multipart message. This is simply a part with the + # content-disposition set to "attachment". + def attachment(params, &block) + super # Run deprecation hooks + + params = { :content_type => params } if String === params + params = { :content_disposition => "attachment", + :content_transfer_encoding => "base64" }.merge(params) + + part(params, &block) + end + + private + + def create_mail #:nodoc: + m = @mail + + m.subject, = quote_any_if_necessary(charset, subject) + m.to, m.from = quote_any_address_if_necessary(charset, recipients, from) + m.bcc = quote_address_if_necessary(bcc, charset) unless bcc.nil? + m.cc = quote_address_if_necessary(cc, charset) unless cc.nil? + m.reply_to = quote_address_if_necessary(reply_to, charset) unless reply_to.nil? + m.mime_version = mime_version unless mime_version.nil? + m.date = sent_on.to_time rescue sent_on if sent_on + + headers.each { |k, v| m[k] = v } + + real_content_type, ctype_attrs = parse_content_type + main_type, sub_type = split_content_type(real_content_type) + + if @parts.size == 1 && @parts.first.parts.empty? + m.content_type([main_type, sub_type, ctype_attrs]) + m.body = @parts.first.body.encoded + else + @parts.each do |p| + m.add_part(p) + end + + m.body.set_sort_order(@implicit_parts_order) + m.body.sort_parts! + + if real_content_type =~ /multipart/ + ctype_attrs.delete "charset" + m.content_type([main_type, sub_type, ctype_attrs]) + end + end + + m.content_transfer_encoding = '8bit' unless m.body.only_us_ascii? + + @mail + end + + # Render a message but does not set it as mail body. Useful for rendering + # data for part and attachments. + # + # Examples: + # + # render_message "special_message" + # render_message :template => "special_message" + # render_message :inline => "<%= 'Hi!' %>" + # + # TODO Deprecate me + def render_message(object) + case object + when String + render_to_body(:template => object) + else + render_to_body(object) + end + end + + # Set up the default values for the various instance variables of this + # mailer. Subclasses may override this method to provide different + # defaults. + def initialize_defaults(method_name) #:nodoc: + @charset ||= self.class.default_charset.dup + @content_type ||= self.class.default_content_type.dup + @implicit_parts_order ||= self.class.default_implicit_parts_order.dup + @mime_version ||= self.class.default_mime_version.dup if self.class.default_mime_version + + @mailer_name ||= self.class.mailer_name.dup + @delivery_method = self.class.delivery_method + @template ||= method_name + + @parts ||= [] + @headers ||= {} + @sent_on ||= Time.now + + super # Run deprecation hooks + end + + def create_parts #:nodoc: + super # Run deprecation hooks + + if String === response_body + @parts.unshift create_inline_part(response_body) + else + self.class.template_root.find_all(@template, {}, @mailer_name).each do |template| + @parts << create_inline_part(render_to_body(:_template => template), template.mime_type) + end + + if @parts.size > 1 + @content_type = "multipart/alternative" if @content_type !~ /^multipart/ + end + + # If this is a multipart e-mail add the mime_version if it is not + # already set. + @mime_version ||= "1.0" if !@parts.empty? + end + end + + def create_inline_part(body, mime_type=nil) #:nodoc: + ct = mime_type || "text/plain" + main_type, sub_type = split_content_type(ct.to_s) + + Mail::Part.new( + :content_type => [main_type, sub_type, {:charset => charset}], + :content_disposition => "inline", + :body => body + ) + end + + def split_content_type(ct) #:nodoc: + ct.to_s.split("/") + end + + def parse_content_type(defaults=nil) #:nodoc: + if @content_type.blank? + [ nil, {} ] + else + ctype, *attrs = @content_type.split(/;\s*/) + attrs = attrs.inject({}) { |h,s| k,v = s.split(/\=/, 2); h[k] = v; h } + [ctype, {"charset" => @charset}.merge(attrs)] + end + end + + end +end \ No newline at end of file diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb new file mode 100644 index 0000000000..dc1fbc07be --- /dev/null +++ b/actionmailer/test/base_test.rb @@ -0,0 +1,39 @@ +# class Notifier < ActionMailer::Base +# delivers_from 'notifications@example.com' +# +# def welcome(user) +# @user = user # available to the view +# mail(:subject => 'Welcome!', :to => user.email_address) +# # auto renders both welcome.text.erb and welcome.html.erb +# end +# +# def goodbye(user) +# headers["Reply-To"] = 'cancelations@example.com' +# mail(:subject => 'Goodbye', :to => user.email_address) do |format| +# format.html { render "shared_template "} +# format.text # goodbye.text.erb +# end +# end +# +# def surprise(user, gift) +# attachments[gift.name] = File.read(gift.path) +# mail(:subject => 'Surprise!', :to => user.email_address) do |format| +# format.html(:charset => "ascii") # surprise.html.erb +# format.text(:transfer_encoding => "base64") # surprise.text.erb +# end +# end +# +# def special_surprise(user, gift) +# attachments[gift.name] = { :content_type => "application/x-gzip", :content => File.read(gift.path) } +# mail(:to => 'special@example.com') # subject not required +# # auto renders both special_surprise.text.erb and special_surprise.html.erb +# end +# end +# +# Notifier.welcome(user) # => returns a Mail object +# Notifier.welcome(user).deliver # => creates and sends the Mail in one step +class BaseTest < ActionMailer::Base + + + +end -- cgit v1.2.3 From c34cfcc29f705c95c2218889cbec1898e008335d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Wed, 20 Jan 2010 23:46:59 +1100 Subject: Created mail method for new API --- actionmailer/lib/action_mailer/base.rb | 59 ++++++++++++++++++------ actionmailer/lib/action_mailer/deprecated_api.rb | 4 +- actionmailer/test/base_test.rb | 46 ++++++++++++++++-- 3 files changed, 89 insertions(+), 20 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 9df482cdf6..8825bd35f9 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -297,7 +297,7 @@ module ActionMailer #:nodoc: @@default_implicit_parts_order = [ "text/plain", "text/enriched", "text/html" ] cattr_accessor :default_implicit_parts_order - @@protected_instance_variables = %w(@parts @mail) + @@protected_instance_variables = %w(@parts @message) cattr_reader :protected_instance_variables # Specify the BCC addresses for the message @@ -352,8 +352,8 @@ module ActionMailer #:nodoc: # location, you can use this to specify that location. adv_attr_accessor :mailer_name - # Expose the internal mail - attr_reader :mail + # Expose the internal Mail message + attr_reader :message # Alias controller_path to mailer_name so render :partial in views work. alias :controller_path :mailer_name @@ -374,7 +374,7 @@ module ActionMailer #:nodoc: def method_missing(method_symbol, *parameters) #:nodoc: if match = matches_dynamic_method?(method_symbol) case match[1] - when 'create' then new(match[2], *parameters).mail + when 'create' then new(match[2], *parameters).message when 'deliver' then new(match[2], *parameters).deliver! when 'new' then nil else super @@ -461,13 +461,40 @@ module ActionMailer #:nodoc: end end + def mail(headers = {}) + # Guard flag to prevent both the old and the new API from firing + # TODO - Move this @mail_was_called flag into deprecated_api.rb + @mail_was_called = true + + m = @message + + m.content_type ||= headers[:content_type] || @@default_content_type + m.charset ||= headers[:charset] || @@default_charset + m.mime_version ||= headers[:mime_version] || @@default_mime_version + + m.subject = quote_if_necessary(headers[:subject], m.charset) if headers[:subject] + m.to = quote_address_if_necessary(headers[:to], m.charset) if headers[:to] + m.from = quote_address_if_necessary(headers[:from], m.charset) if headers[:from] + m.cc = quote_address_if_necessary(headers[:cc], m.charset) if headers[:cc] + m.bcc = quote_address_if_necessary(headers[:bcc], m.charset) if headers[:bcc] + m.reply_to = quote_address_if_necessary(headers[:reply_to], m.charset) if headers[:reply_to] + m.mime_version = headers[:mime_version] if headers[:mime_version] + m.date = headers[:date] if headers[:date] + + m.body.set_sort_order(headers[:parts_order] || @@default_implicit_parts_order) + + # TODO: m.body.sort_parts! + m + end + # Instantiate a new mailer object. If +method_name+ is not +nil+, the mailer # will be initialized according to the named method. If not, the mailer will # remain uninitialized (useful when you only need to invoke the "receive" # method, for instance). def initialize(method_name=nil, *args) super() - @mail = Mail.new + @mail_was_called = false + @message = Mail.new process(method_name, *args) if method_name end @@ -475,23 +502,27 @@ module ActionMailer #:nodoc: # rendered and a new Mail object created. def process(method_name, *args) initialize_defaults(method_name) + super + + unless @mail_was_called + # Create e-mail parts + create_parts - # Create e-mail parts - create_parts + # Set the subject if not set yet + @subject ||= I18n.t(:subject, :scope => [:actionmailer, mailer_name, method_name], + :default => method_name.humanize) - # Set the subject if not set yet - @subject ||= I18n.t(:subject, :scope => [:actionmailer, mailer_name, method_name], - :default => method_name.humanize) - - # Build the mail object itself - create_mail + # Build the mail object itself + create_mail + end + @message end # Delivers a Mail object. By default, it delivers the cached mail # object (from the create! method). If no cached mail object exists, and # no alternate has been given as the parameter, this will fail. - def deliver!(mail = @mail) + def deliver!(mail = @message) self.class.deliver(mail) end diff --git a/actionmailer/lib/action_mailer/deprecated_api.rb b/actionmailer/lib/action_mailer/deprecated_api.rb index 3334b47987..e11dd4c46a 100644 --- a/actionmailer/lib/action_mailer/deprecated_api.rb +++ b/actionmailer/lib/action_mailer/deprecated_api.rb @@ -38,7 +38,7 @@ module ActionMailer private def create_mail #:nodoc: - m = @mail + m = @message m.subject, = quote_any_if_necessary(charset, subject) m.to, m.from = quote_any_address_if_necessary(charset, recipients, from) @@ -72,7 +72,7 @@ module ActionMailer m.content_transfer_encoding = '8bit' unless m.body.only_us_ascii? - @mail + @message end # Render a message but does not set it as mail body. Useful for rendering diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index dc1fbc07be..83d51274f0 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -1,3 +1,6 @@ +# encoding: utf-8 +require 'abstract_unit' + # class Notifier < ActionMailer::Base # delivers_from 'notifications@example.com' # @@ -30,10 +33,45 @@ # end # end # -# Notifier.welcome(user) # => returns a Mail object +# mail = Notifier.welcome(user) # => returns a Mail object +# mail.deliver +# # Notifier.welcome(user).deliver # => creates and sends the Mail in one step -class BaseTest < ActionMailer::Base +class BaseTest < Test::Unit::TestCase + class TestMailer < ActionMailer::Base + def welcome(hash = {}) + hash = {:to => 'mikel@test.lindsaar.net', :from => 'jose@test.plataformatec.com', + :subject => 'The first email on new API!'}.merge!(hash) + mail(hash) + end + end + + def test_the_method_call_to_mail_does_not_raise_error + assert_nothing_raised { TestMailer.deliver_welcome } + end + + def test_should_set_the_headers_of_the_mail_message + email = TestMailer.deliver_welcome + assert_equal(email.to, ['mikel@test.lindsaar.net']) + assert_equal(email.from, ['jose@test.plataformatec.com']) + assert_equal(email.subject, 'The first email on new API!') + end + + def test_calling_mail_should_pass_the_header_hash_to_the_new_mail_object + + end + + def test_it_should_guard_against_old_api_if_mail_method_called + + end + + # def test_that_class_defaults_are_set_on_instantiation + # pending + # end + # + # def test_should_set_the_subject_from_i18n + # pending + # end - -end +end \ No newline at end of file -- cgit v1.2.3 From d3da87ce771845f99bbdc04d6d6587b22655b063 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Thu, 21 Jan 2010 00:10:22 +1100 Subject: Mail method accepting all headers set via the hash --- actionmailer/lib/action_mailer/base.rb | 6 ++++-- actionmailer/test/base_test.rb | 32 +++++++++++++++++++++++++++----- 2 files changed, 31 insertions(+), 7 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 8825bd35f9..39ddafe7fe 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -1,4 +1,5 @@ require 'active_support/core_ext/class' +require "active_support/core_ext/module/delegation" require 'mail' require 'action_mailer/tmail_compat' @@ -267,7 +268,6 @@ module ActionMailer #:nodoc: include ActionMailer::DeliveryMethods - private_class_method :new #:nodoc: @@raise_delivery_errors = true @@ -355,6 +355,9 @@ module ActionMailer #:nodoc: # Expose the internal Mail message attr_reader :message + # Pass calls to headers and attachment to the Mail#Message instance + delegate :headers, :attachments, :to => :@message + # Alias controller_path to mailer_name so render :partial in views work. alias :controller_path :mailer_name @@ -478,7 +481,6 @@ module ActionMailer #:nodoc: m.cc = quote_address_if_necessary(headers[:cc], m.charset) if headers[:cc] m.bcc = quote_address_if_necessary(headers[:bcc], m.charset) if headers[:bcc] m.reply_to = quote_address_if_necessary(headers[:reply_to], m.charset) if headers[:reply_to] - m.mime_version = headers[:mime_version] if headers[:mime_version] m.date = headers[:date] if headers[:date] m.body.set_sort_order(headers[:parts_order] || @@default_implicit_parts_order) diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index 83d51274f0..b8d2e46241 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -11,7 +11,7 @@ require 'abstract_unit' # end # # def goodbye(user) -# headers["Reply-To"] = 'cancelations@example.com' +# headers["X-SPAM"] = 'Not-SPAM' # mail(:subject => 'Goodbye', :to => user.email_address) do |format| # format.html { render "shared_template "} # format.text # goodbye.text.erb @@ -40,11 +40,14 @@ require 'abstract_unit' class BaseTest < Test::Unit::TestCase class TestMailer < ActionMailer::Base + def welcome(hash = {}) + headers['X-SPAM'] = "Not SPAM" hash = {:to => 'mikel@test.lindsaar.net', :from => 'jose@test.plataformatec.com', :subject => 'The first email on new API!'}.merge!(hash) mail(hash) end + end def test_the_method_call_to_mail_does_not_raise_error @@ -57,12 +60,31 @@ class BaseTest < Test::Unit::TestCase assert_equal(email.from, ['jose@test.plataformatec.com']) assert_equal(email.subject, 'The first email on new API!') end - - def test_calling_mail_should_pass_the_header_hash_to_the_new_mail_object - + + def test_should_allow_all_headers_set + @time = Time.now + email = TestMailer.deliver_welcome(:bcc => 'bcc@test.lindsaar.net', + :cc => 'cc@test.lindsaar.net', + :content_type => 'multipart/mixed', + :charset => 'iso-8559-1', + :mime_version => '2.0', + :reply_to => 'reply-to@test.lindsaar.net', + :date => @time) + assert_equal(email.bcc, ['bcc@test.lindsaar.net']) + assert_equal(email.cc, ['cc@test.lindsaar.net']) + assert_equal(email.content_type, 'multipart/mixed') + assert_equal(email.charset, 'iso-8559-1') + assert_equal(email.mime_version, '2.0') + assert_equal(email.reply_to, ['reply-to@test.lindsaar.net']) + assert_equal(email.date, @time) end - def test_it_should_guard_against_old_api_if_mail_method_called +# def test_should_allow_custom_headers_to_be_set +# email = TestMailer.deliver_welcome +# assert_equal("Not SPAM", email['X-SPAM']) +# end + + def test_should_use_class_defaults end -- cgit v1.2.3 From 3829f9ecfd6fcd54edbc15f624ee3b68f6dae135 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Thu, 21 Jan 2010 20:03:55 +1100 Subject: Adding tests for attachments['blah.rb'] = {} et al --- actionmailer/actionmailer.gemspec | 2 +- actionmailer/lib/action_mailer/deprecated_api.rb | 12 ++++++++++- actionmailer/lib/action_mailer/tmail_compat.rb | 5 +++++ actionmailer/test/base_test.rb | 27 +++++++++++++++++++++++- actionmailer/test/mail_service_test.rb | 1 + 5 files changed, 44 insertions(+), 3 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/actionmailer.gemspec b/actionmailer/actionmailer.gemspec index cc1c25401e..9a8c1df9e8 100644 --- a/actionmailer/actionmailer.gemspec +++ b/actionmailer/actionmailer.gemspec @@ -11,7 +11,7 @@ Gem::Specification.new do |s| s.homepage = "http://www.rubyonrails.org" s.add_dependency('actionpack', '= 3.0.pre') - s.add_dependency('mail', '~> 2.0.1') + s.add_dependency('mail', '~> 2.0.2') s.files = Dir['CHANGELOG', 'README', 'MIT-LICENSE', 'lib/**/*'] s.has_rdoc = true diff --git a/actionmailer/lib/action_mailer/deprecated_api.rb b/actionmailer/lib/action_mailer/deprecated_api.rb index e11dd4c46a..d096ea6180 100644 --- a/actionmailer/lib/action_mailer/deprecated_api.rb +++ b/actionmailer/lib/action_mailer/deprecated_api.rb @@ -19,6 +19,7 @@ module ActionMailer end part = Mail::Part.new(params) + yield part if block_given? @parts << part end @@ -29,7 +30,16 @@ module ActionMailer super # Run deprecation hooks params = { :content_type => params } if String === params - params = { :content_disposition => "attachment", + + if filename = params.delete(:filename) + content_disposition = "attachment; filename=\"#{File.basename(filename)}\"" + else + content_disposition = "attachment" + end + + params[:content] = params.delete(:data) if params[:data] + + params = { :content_disposition => content_disposition, :content_transfer_encoding => "base64" }.merge(params) part(params, &block) diff --git a/actionmailer/lib/action_mailer/tmail_compat.rb b/actionmailer/lib/action_mailer/tmail_compat.rb index 2fd25ff145..94f21c7cf3 100644 --- a/actionmailer/lib/action_mailer/tmail_compat.rb +++ b/actionmailer/lib/action_mailer/tmail_compat.rb @@ -16,5 +16,10 @@ module Mail end end + def original_filename + STDERR.puts("Message#original_filename is deprecated, please call Message#filename.\n#{caller}") + filename + end + end end \ No newline at end of file diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index b8d2e46241..f1f5f38482 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -42,12 +42,18 @@ class BaseTest < Test::Unit::TestCase class TestMailer < ActionMailer::Base def welcome(hash = {}) - headers['X-SPAM'] = "Not SPAM" hash = {:to => 'mikel@test.lindsaar.net', :from => 'jose@test.plataformatec.com', :subject => 'The first email on new API!'}.merge!(hash) mail(hash) end + def invoice(hash = {}) + attachments['invoice.pdf'] = 'This is test File content' + hash = {:to => 'mikel@test.lindsaar.net', :from => 'jose@test.plataformatec.com', + :subject => 'Your invoice is attached'}.merge!(hash) + mail(hash) + end + end def test_the_method_call_to_mail_does_not_raise_error @@ -84,6 +90,25 @@ class BaseTest < Test::Unit::TestCase # assert_equal("Not SPAM", email['X-SPAM']) # end + def test_should_allow_you_to_send_an_attachment + assert_nothing_raised { TestMailer.deliver_invoice } + end + + def test_should_allow_you_to_send_an_attachment + email = TestMailer.deliver_invoice + assert_equal(1, email.attachments.length) + end + + def test_should_allow_you_to_send_an_attachment + email = TestMailer.deliver_invoice + assert_equal('invoice.pdf', email.attachments[0].filename) + end + + def test_should_allow_you_to_send_an_attachment + email = TestMailer.deliver_invoice + assert_equal('This is test File content', email.attachments['invoice.pdf'].decoded) + end + def test_should_use_class_defaults end diff --git a/actionmailer/test/mail_service_test.rb b/actionmailer/test/mail_service_test.rb index 396dd00a91..f83e13f16f 100644 --- a/actionmailer/test/mail_service_test.rb +++ b/actionmailer/test/mail_service_test.rb @@ -898,6 +898,7 @@ EOF assert_equal "iso-8859-1", mail.parts[1].charset assert_equal "image/jpeg", mail.parts[2].mime_type + assert_equal "attachment", mail.parts[2][:content_disposition].disposition_type assert_equal "foo.jpg", mail.parts[2][:content_disposition].filename assert_equal "foo.jpg", mail.parts[2][:content_type].filename -- cgit v1.2.3 From 02c5137eadbb3530033d919b7aebeb6f4f389b83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Fri, 22 Jan 2010 01:10:31 +0100 Subject: Add view paths to Engine setup. --- actionmailer/lib/action_mailer/railtie.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/railtie.rb b/actionmailer/lib/action_mailer/railtie.rb index b05d21ae5d..94d9eaf81b 100644 --- a/actionmailer/lib/action_mailer/railtie.rb +++ b/actionmailer/lib/action_mailer/railtie.rb @@ -21,8 +21,7 @@ module ActionMailer initializer "action_mailer.view_paths" do |app| # TODO: this should be combined with the logic for default config.action_mailer.view_paths - view_path = ActionView::PathSet.type_cast(app.config.view_path, app.config.cache_classes) - ActionMailer::Base.template_root = view_path if ActionMailer::Base.view_paths.blank? + ActionMailer::Base.template_root = [] if ActionMailer::Base.view_paths.blank? end end end \ No newline at end of file -- cgit v1.2.3 From 12c001fec449864db64eca9ba3a477a7da30b2ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Fri, 22 Jan 2010 12:46:19 +1100 Subject: Updating deprecated API to sanitize old style attachments hash to work with new mail.attachments method --- actionmailer/lib/action_mailer/deprecated_api.rb | 45 ++++++++++++++++++------ actionmailer/test/mail_service_test.rb | 2 +- 2 files changed, 36 insertions(+), 11 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/deprecated_api.rb b/actionmailer/lib/action_mailer/deprecated_api.rb index d096ea6180..19c94aee8d 100644 --- a/actionmailer/lib/action_mailer/deprecated_api.rb +++ b/actionmailer/lib/action_mailer/deprecated_api.rb @@ -30,23 +30,48 @@ module ActionMailer super # Run deprecation hooks params = { :content_type => params } if String === params - - if filename = params.delete(:filename) - content_disposition = "attachment; filename=\"#{File.basename(filename)}\"" + + if params[:filename] + params = normalize_file_hash(params) else - content_disposition = "attachment" + params = normalize_nonfile_hash(params) end - - params[:content] = params.delete(:data) if params[:data] - - params = { :content_disposition => content_disposition, - :content_transfer_encoding => "base64" }.merge(params) - part(params, &block) end private + def normalize_nonfile_hash(params) + content_disposition = "attachment;" + + mime_type = params.delete(:mime_type) + + if content_type = params.delete(:content_type) + content_type = "#{mime_type || content_type};" + end + + params[:body] = params.delete(:data) if params[:data] + + { :content_type => content_type, + :content_disposition => content_disposition }.merge(params) + end + + def normalize_file_hash(params) + filename = File.basename(params.delete(:filename)) + content_disposition = "attachment; filename=\"#{File.basename(filename)}\"" + + mime_type = params.delete(:mime_type) + + if (content_type = params.delete(:content_type)) && (content_type !~ /filename=/) + content_type = "#{mime_type || content_type}; filename=\"#{filename}\"" + end + + params[:body] = params.delete(:data) if params[:data] + + { :content_type => content_type, + :content_disposition => content_disposition }.merge(params) + end + def create_mail #:nodoc: m = @message diff --git a/actionmailer/test/mail_service_test.rb b/actionmailer/test/mail_service_test.rb index f83e13f16f..51d722ea00 100644 --- a/actionmailer/test/mail_service_test.rb +++ b/actionmailer/test/mail_service_test.rb @@ -1036,7 +1036,7 @@ EOF def test_empty_header_values_omitted result = TestMailer.create_unnamed_attachment(@recipient).encoded assert_match %r{Content-Type: application/octet-stream;}, result - assert_match %r{Content-Disposition: attachment[^;]}, result + assert_match %r{Content-Disposition: attachment;}, result end def test_headers_with_nonalpha_chars -- cgit v1.2.3 From 77986f6bdb18414d730fa1ec686365dff26bb4fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Fri, 22 Jan 2010 12:49:13 +1100 Subject: Added use of AS::Notifications for tmail_compat.rb --- actionmailer/lib/action_mailer/tmail_compat.rb | 9 ++++++--- actionmailer/test/tmail_compat_test.rb | 2 -- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/tmail_compat.rb b/actionmailer/lib/action_mailer/tmail_compat.rb index 94f21c7cf3..da13aac677 100644 --- a/actionmailer/lib/action_mailer/tmail_compat.rb +++ b/actionmailer/lib/action_mailer/tmail_compat.rb @@ -2,14 +2,16 @@ module Mail class Message def set_content_type(*args) - STDERR.puts("Message#set_content_type is deprecated, please just call Message#content_type with the same arguments.\n#{caller}") + ActiveSupport::Deprecation.warn('Message#set_content_type is deprecated, please just call ' << + 'Message#content_type with the same arguments.', caller[0,10]) content_type(*args) end alias :old_transfer_encoding :transfer_encoding def transfer_encoding(value = nil) if value - STDERR.puts("Message#transfer_encoding is deprecated, please call Message#content_transfer_encoding with the same arguments.\n#{caller}") + ActiveSupport::Deprecation.warn('Message#transfer_encoding is deprecated, please call ' << + 'Message#content_transfer_encoding with the same arguments.', caller[0,10]) content_transfer_encoding(value) else old_transfer_encoding @@ -17,7 +19,8 @@ module Mail end def original_filename - STDERR.puts("Message#original_filename is deprecated, please call Message#filename.\n#{caller}") + ActiveSupport::Deprecation.warn('Message#original_filename is deprecated, ' << + 'please call Message#filename.', caller[0,10]) filename end diff --git a/actionmailer/test/tmail_compat_test.rb b/actionmailer/test/tmail_compat_test.rb index a1ca6a7243..b7fcb3cfea 100644 --- a/actionmailer/test/tmail_compat_test.rb +++ b/actionmailer/test/tmail_compat_test.rb @@ -4,7 +4,6 @@ class TmailCompatTest < Test::Unit::TestCase def test_set_content_type_raises_deprecation_warning mail = Mail.new - STDERR.expects(:puts) # Deprecation warning assert_nothing_raised do mail.set_content_type "text/plain" end @@ -13,7 +12,6 @@ class TmailCompatTest < Test::Unit::TestCase def test_transfer_encoding_raises_deprecation_warning mail = Mail.new - STDERR.expects(:puts) # Deprecation warning assert_nothing_raised do mail.transfer_encoding "base64" end -- cgit v1.2.3 From 90bbed233e14957376d6c1985202c495b3af6ed4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Fri, 22 Jan 2010 12:51:07 +1100 Subject: Updating deprecated_body.rb to use :content instead of :data or :body in the params hash --- actionmailer/lib/action_mailer/deprecated_body.rb | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/deprecated_body.rb b/actionmailer/lib/action_mailer/deprecated_body.rb index c82610014f..daaf145327 100644 --- a/actionmailer/lib/action_mailer/deprecated_body.rb +++ b/actionmailer/lib/action_mailer/deprecated_body.rb @@ -14,10 +14,15 @@ module ActionMailer end def attachment(params, &block) + if params[:data] + ActiveSupport::Deprecation.warn('attachment :data => "string" is deprecated. To set the body of an attachment ' << + 'please use :content instead, like attachment :content => "string"', caller[0,10]) + params[:content] = params.delete(:data) + end if params[:body] - ActiveSupport::Deprecation.warn('attachment :body => "string" is deprecated. To set the body of an attachment ' << - 'please use :data instead, like attachment :data => "string"', caller[0,10]) - params[:data] = params.delete(:body) + ActiveSupport::Deprecation.warn('attachment :data => "string" is deprecated. To set the body of an attachment ' << + 'please use :content instead, like attachment :content => "string"', caller[0,10]) + params[:content] = params.delete(:body) end end -- cgit v1.2.3 From 343ac48f45a433b2ef0dc67f9cd9d1245fb5ef2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Fri, 22 Jan 2010 11:01:21 +0100 Subject: Moved deprecated_body.rb to deprecatead_api.rb --- actionmailer/lib/action_mailer.rb | 1 - actionmailer/lib/action_mailer/base.rb | 61 ---------- actionmailer/lib/action_mailer/deprecated_api.rb | 141 +++++++++++++++++----- actionmailer/lib/action_mailer/deprecated_body.rb | 53 -------- actionmailer/lib/action_mailer/mail_helper.rb | 5 + actionmailer/lib/action_mailer/tmail_compat.rb | 6 +- actionmailer/test/mail_service_test.rb | 12 -- 7 files changed, 118 insertions(+), 161 deletions(-) delete mode 100644 actionmailer/lib/action_mailer/deprecated_body.rb (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer.rb b/actionmailer/lib/action_mailer.rb index 1765aee9cc..37c95baea7 100644 --- a/actionmailer/lib/action_mailer.rb +++ b/actionmailer/lib/action_mailer.rb @@ -33,7 +33,6 @@ module ActionMailer autoload :AdvAttrAccessor autoload :Base autoload :DeliveryMethods - autoload :DeprecatedBody autoload :DeprecatedApi autoload :MailHelper autoload :Quoting diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 39ddafe7fe..0b3b44e326 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -263,7 +263,6 @@ module ActionMailer #:nodoc: include AbstractController::UrlFor helper ActionMailer::MailHelper - include ActionMailer::DeprecatedBody include ActionMailer::DeprecatedApi include ActionMailer::DeliveryMethods @@ -297,69 +296,11 @@ module ActionMailer #:nodoc: @@default_implicit_parts_order = [ "text/plain", "text/enriched", "text/html" ] cattr_accessor :default_implicit_parts_order - @@protected_instance_variables = %w(@parts @message) - cattr_reader :protected_instance_variables - - # Specify the BCC addresses for the message - adv_attr_accessor :bcc - - # Specify the CC addresses for the message. - adv_attr_accessor :cc - - # Specify the charset to use for the message. This defaults to the - # +default_charset+ specified for ActionMailer::Base. - adv_attr_accessor :charset - - # Specify the content type for the message. This defaults to text/plain - # in most cases, but can be automatically set in some situations. - adv_attr_accessor :content_type - - # Specify the from address for the message. - adv_attr_accessor :from - - # Specify the address (if different than the "from" address) to direct - # replies to this message. - adv_attr_accessor :reply_to - - # Specify additional headers to be added to the message. - adv_attr_accessor :headers - - # Specify the order in which parts should be sorted, based on content-type. - # This defaults to the value for the +default_implicit_parts_order+. - adv_attr_accessor :implicit_parts_order - - # Defaults to "1.0", but may be explicitly given if needed. - adv_attr_accessor :mime_version - - # The recipient addresses for the message, either as a string (for a single - # address) or an array (for multiple addresses). - adv_attr_accessor :recipients - - # The date on which the message was sent. If not set (the default), the - # header will be set by the delivery agent. - adv_attr_accessor :sent_on - - # Specify the subject of the message. - adv_attr_accessor :subject - - # Specify the template name to use for current message. This is the "base" - # template name, without the extension or directory, and may be used to - # have multiple mailer methods share the same template. - adv_attr_accessor :template - - # Override the mailer name, which defaults to an inflected version of the - # mailer's class name. If you want to use a template in a non-standard - # location, you can use this to specify that location. - adv_attr_accessor :mailer_name - # Expose the internal Mail message attr_reader :message # Pass calls to headers and attachment to the Mail#Message instance delegate :headers, :attachments, :to => :@message - - # Alias controller_path to mailer_name so render :partial in views work. - alias :controller_path :mailer_name class << self @@ -504,9 +445,7 @@ module ActionMailer #:nodoc: # rendered and a new Mail object created. def process(method_name, *args) initialize_defaults(method_name) - super - unless @mail_was_called # Create e-mail parts create_parts diff --git a/actionmailer/lib/action_mailer/deprecated_api.rb b/actionmailer/lib/action_mailer/deprecated_api.rb index 19c94aee8d..32ea4162dc 100644 --- a/actionmailer/lib/action_mailer/deprecated_api.rb +++ b/actionmailer/lib/action_mailer/deprecated_api.rb @@ -3,8 +3,87 @@ module ActionMailer # hooks in ActionMailer::Base are removed as well. # # Moved here to allow us to add the new Mail API - module DeprecatedApi - extend ActionMailer::AdvAttrAccessor + module DeprecatedApi #:nodoc: + extend ActiveSupport::Concern + + included do + extend ActionMailer::AdvAttrAccessor + + @@protected_instance_variables = %w(@parts) + cattr_reader :protected_instance_variables + + # Specify the BCC addresses for the message + adv_attr_accessor :bcc + + # Specify the CC addresses for the message. + adv_attr_accessor :cc + + # Specify the charset to use for the message. This defaults to the + # +default_charset+ specified for ActionMailer::Base. + adv_attr_accessor :charset + + # Specify the content type for the message. This defaults to text/plain + # in most cases, but can be automatically set in some situations. + adv_attr_accessor :content_type + + # Specify the from address for the message. + adv_attr_accessor :from + + # Specify the address (if different than the "from" address) to direct + # replies to this message. + adv_attr_accessor :reply_to + + # Specify additional headers to be added to the message. + adv_attr_accessor :headers + + # Specify the order in which parts should be sorted, based on content-type. + # This defaults to the value for the +default_implicit_parts_order+. + adv_attr_accessor :implicit_parts_order + + # Defaults to "1.0", but may be explicitly given if needed. + adv_attr_accessor :mime_version + + # The recipient addresses for the message, either as a string (for a single + # address) or an array (for multiple addresses). + adv_attr_accessor :recipients + + # The date on which the message was sent. If not set (the default), the + # header will be set by the delivery agent. + adv_attr_accessor :sent_on + + # Specify the subject of the message. + adv_attr_accessor :subject + + # Specify the template name to use for current message. This is the "base" + # template name, without the extension or directory, and may be used to + # have multiple mailer methods share the same template. + adv_attr_accessor :template + + # Override the mailer name, which defaults to an inflected version of the + # mailer's class name. If you want to use a template in a non-standard + # location, you can use this to specify that location. + adv_attr_accessor :mailer_name + + # Define the body of the message. This is either a Hash (in which case it + # specifies the variables to pass to the template when it is rendered), + # or a string, in which case it specifies the actual text of the message. + adv_attr_accessor :body + + # Alias controller_path to mailer_name so render :partial in views work. + alias :controller_path :mailer_name + end + + def render(*args) + options = args.last.is_a?(Hash) ? args.last : {} + if options[:body] + ActiveSupport::Deprecation.warn(':body in render deprecated. Please call body ' << + 'with a hash instead', caller[0,1]) + + body options.delete(:body) + end + + super + end # Add a part to a multipart message, with the given content-type. The # part itself is yielded to the block so that other properties (charset, @@ -13,8 +92,6 @@ module ActionMailer params = {:content_type => params} if String === params if custom_headers = params.delete(:headers) - ActiveSupport::Deprecation.warn('Passing custom headers with :headers => {} is deprecated. ' << - 'Please just pass in custom headers directly.', caller[0,10]) params.merge!(custom_headers) end @@ -27,19 +104,38 @@ module ActionMailer # Add an attachment to a multipart message. This is simply a part with the # content-disposition set to "attachment". def attachment(params, &block) - super # Run deprecation hooks - params = { :content_type => params } if String === params + params[:content] ||= params.delete(:data) || params.delete(:body) + if params[:filename] params = normalize_file_hash(params) else params = normalize_nonfile_hash(params) end + part(params, &block) end - private + # Render a message but does not set it as mail body. Useful for rendering + # data for part and attachments. + # + # Examples: + # + # render_message "special_message" + # render_message :template => "special_message" + # render_message :inline => "<%= 'Hi!' %>" + # + def render_message(object) + case object + when String + render_to_body(:template => object) + else + render_to_body(object) + end + end + + private def normalize_nonfile_hash(params) content_disposition = "attachment;" @@ -109,25 +205,6 @@ module ActionMailer @message end - - # Render a message but does not set it as mail body. Useful for rendering - # data for part and attachments. - # - # Examples: - # - # render_message "special_message" - # render_message :template => "special_message" - # render_message :inline => "<%= 'Hi!' %>" - # - # TODO Deprecate me - def render_message(object) - case object - when String - render_to_body(:template => object) - else - render_to_body(object) - end - end # Set up the default values for the various instance variables of this # mailer. Subclasses may override this method to provide different @@ -139,18 +216,20 @@ module ActionMailer @mime_version ||= self.class.default_mime_version.dup if self.class.default_mime_version @mailer_name ||= self.class.mailer_name.dup - @delivery_method = self.class.delivery_method @template ||= method_name @parts ||= [] @headers ||= {} @sent_on ||= Time.now - - super # Run deprecation hooks + @body ||= {} end def create_parts #:nodoc: - super # Run deprecation hooks + if String === @body + self.response_body = @body + elsif @body.is_a?(Hash) && !@body.empty? + @body.each { |k, v| instance_variable_set(:"@#{k}", v) } + end if String === response_body @parts.unshift create_inline_part(response_body) @@ -179,7 +258,7 @@ module ActionMailer :body => body ) end - + def split_content_type(ct) #:nodoc: ct.to_s.split("/") end diff --git a/actionmailer/lib/action_mailer/deprecated_body.rb b/actionmailer/lib/action_mailer/deprecated_body.rb deleted file mode 100644 index daaf145327..0000000000 --- a/actionmailer/lib/action_mailer/deprecated_body.rb +++ /dev/null @@ -1,53 +0,0 @@ -module ActionMailer - # TODO Remove this module all together in a next release. Ensure that super - # hooks in ActionMailer::Base are removed as well. - module DeprecatedBody - extend ActionMailer::AdvAttrAccessor - - # Define the body of the message. This is either a Hash (in which case it - # specifies the variables to pass to the template when it is rendered), - # or a string, in which case it specifies the actual text of the message. - adv_attr_accessor :body - - def initialize_defaults(method_name) - @body ||= {} - end - - def attachment(params, &block) - if params[:data] - ActiveSupport::Deprecation.warn('attachment :data => "string" is deprecated. To set the body of an attachment ' << - 'please use :content instead, like attachment :content => "string"', caller[0,10]) - params[:content] = params.delete(:data) - end - if params[:body] - ActiveSupport::Deprecation.warn('attachment :data => "string" is deprecated. To set the body of an attachment ' << - 'please use :content instead, like attachment :content => "string"', caller[0,10]) - params[:content] = params.delete(:body) - end - end - - def create_parts - if String === @body - ActiveSupport::Deprecation.warn('body(String) is deprecated. To set the body with a text ' << - 'call render(:text => "body")', caller[0,10]) - self.response_body = @body - elsif @body.is_a?(Hash) && !@body.empty? - ActiveSupport::Deprecation.warn('body(Hash) is deprecated. Use instance variables to define ' << - 'assigns in your view', caller[0,10]) - @body.each { |k, v| instance_variable_set(:"@#{k}", v) } - end - end - - def render(*args) - options = args.last.is_a?(Hash) ? args.last : {} - if options[:body] - ActiveSupport::Deprecation.warn(':body in render deprecated. Please call body ' << - 'with a hash instead', caller[0,1]) - - body options.delete(:body) - end - - super - end - end -end diff --git a/actionmailer/lib/action_mailer/mail_helper.rb b/actionmailer/lib/action_mailer/mail_helper.rb index 701dc34431..702c9ba8f7 100644 --- a/actionmailer/lib/action_mailer/mail_helper.rb +++ b/actionmailer/lib/action_mailer/mail_helper.rb @@ -20,5 +20,10 @@ module ActionMailer def mailer #:nodoc: @controller end + + # Access the message instance. + def message + @message + end end end diff --git a/actionmailer/lib/action_mailer/tmail_compat.rb b/actionmailer/lib/action_mailer/tmail_compat.rb index da13aac677..d78332c135 100644 --- a/actionmailer/lib/action_mailer/tmail_compat.rb +++ b/actionmailer/lib/action_mailer/tmail_compat.rb @@ -3,7 +3,7 @@ module Mail def set_content_type(*args) ActiveSupport::Deprecation.warn('Message#set_content_type is deprecated, please just call ' << - 'Message#content_type with the same arguments.', caller[0,10]) + 'Message#content_type with the same arguments', caller[0,10]) content_type(*args) end @@ -11,7 +11,7 @@ module Mail def transfer_encoding(value = nil) if value ActiveSupport::Deprecation.warn('Message#transfer_encoding is deprecated, please call ' << - 'Message#content_transfer_encoding with the same arguments.', caller[0,10]) + 'Message#content_transfer_encoding with the same arguments', caller[0,10]) content_transfer_encoding(value) else old_transfer_encoding @@ -20,7 +20,7 @@ module Mail def original_filename ActiveSupport::Deprecation.warn('Message#original_filename is deprecated, ' << - 'please call Message#filename.', caller[0,10]) + 'please call Message#filename', caller[0,10]) filename end diff --git a/actionmailer/test/mail_service_test.rb b/actionmailer/test/mail_service_test.rb index 51d722ea00..ec820e3464 100644 --- a/actionmailer/test/mail_service_test.rb +++ b/actionmailer/test/mail_service_test.rb @@ -301,13 +301,6 @@ class TestMailer < ActionMailer::Base render :text => "testing" end - def body_ivar(recipient) - recipients recipient - subject "Body as a local variable" - from "test@example.com" - body :body => "foo", :bar => "baz" - end - def subject_with_i18n(recipient) recipients recipient from "system@loudthinking.com" @@ -1080,11 +1073,6 @@ EOF assert_equal "another@somewhere.test", MockSMTP.deliveries[0][1].to_s end - def test_body_is_stored_as_an_ivar - mail = TestMailer.create_body_ivar(@recipient) - assert_equal "body: foo\nbar: baz", mail.body.to_s - end - def test_starttls_is_enabled_if_supported ActionMailer::Base.delivery_settings[:smtp].merge!(:enable_starttls_auto => true) MockSMTP.any_instance.expects(:respond_to?).with(:enable_starttls_auto).returns(true) -- cgit v1.2.3 From bb9d71ff9e537597ff4d5962e7870ad99001f605 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Fri, 22 Jan 2010 11:10:37 +0100 Subject: Move class methods to deprecated stuff. --- actionmailer/lib/action_mailer/base.rb | 53 +++--------------------- actionmailer/lib/action_mailer/deprecated_api.rb | 48 +++++++++++++++++++++ 2 files changed, 54 insertions(+), 47 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 0b3b44e326..2c1de0e3b4 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -253,7 +253,6 @@ module ActionMailer #:nodoc: # +implicit_parts_order+. class Base < AbstractController::Base include Quoting - extend AdvAttrAccessor include AbstractController::Logger include AbstractController::Rendering @@ -311,23 +310,6 @@ module ActionMailer #:nodoc: alias :controller_path :mailer_name - def respond_to?(method_symbol, include_private = false) #:nodoc: - matches_dynamic_method?(method_symbol) || super - end - - def method_missing(method_symbol, *parameters) #:nodoc: - if match = matches_dynamic_method?(method_symbol) - case match[1] - when 'create' then new(match[2], *parameters).message - when 'deliver' then new(match[2], *parameters).deliver! - when 'new' then nil - else super - end - else - super - end - end - # Receives a raw email, parses it into an email object, decodes it, # instantiates a new mailer, and passes the email object to the mailer # object's +receive+ method. If you want your mailer to be able to @@ -357,7 +339,6 @@ module ActionMailer #:nodoc: raise "no mail object available for delivery!" unless mail ActiveSupport::Notifications.instrument("action_mailer.deliver", :mailer => self.name) do |payload| - self.set_payload_for_mail(payload, mail) mail.delivery_method delivery_methods[delivery_method], @@ -396,18 +377,11 @@ module ActionMailer #:nodoc: payload[:date] = mail.date payload[:mail] = mail.encoded end - - private - - def matches_dynamic_method?(method_name) #:nodoc: - method_name = method_name.to_s - /^(create|deliver)_([_a-z]\w*)/.match(method_name) || /^(new)$/.match(method_name) - end end def mail(headers = {}) # Guard flag to prevent both the old and the new API from firing - # TODO - Move this @mail_was_called flag into deprecated_api.rb + # Should be removed when old API is deprecated @mail_was_called = true m = @message @@ -426,6 +400,11 @@ module ActionMailer #:nodoc: m.body.set_sort_order(headers[:parts_order] || @@default_implicit_parts_order) + # # Set the subject if not set yet + # @subject ||= I18n.t(:subject, :scope => [:actionmailer, mailer_name, method_name], + # :default => method_name.humanize) + + # TODO: m.body.sort_parts! m end @@ -436,30 +415,10 @@ module ActionMailer #:nodoc: # method, for instance). def initialize(method_name=nil, *args) super() - @mail_was_called = false @message = Mail.new process(method_name, *args) if method_name end - # Process the mailer via the given +method_name+. The body will be - # rendered and a new Mail object created. - def process(method_name, *args) - initialize_defaults(method_name) - super - unless @mail_was_called - # Create e-mail parts - create_parts - - # Set the subject if not set yet - @subject ||= I18n.t(:subject, :scope => [:actionmailer, mailer_name, method_name], - :default => method_name.humanize) - - # Build the mail object itself - create_mail - end - @message - end - # Delivers a Mail object. By default, it delivers the cached mail # object (from the create! method). If no cached mail object exists, and # no alternate has been given as the parameter, this will fail. diff --git a/actionmailer/lib/action_mailer/deprecated_api.rb b/actionmailer/lib/action_mailer/deprecated_api.rb index 32ea4162dc..430b0cef4a 100644 --- a/actionmailer/lib/action_mailer/deprecated_api.rb +++ b/actionmailer/lib/action_mailer/deprecated_api.rb @@ -73,6 +73,37 @@ module ActionMailer alias :controller_path :mailer_name end + module ClassMethods + def respond_to?(method_symbol, include_private = false) #:nodoc: + matches_dynamic_method?(method_symbol) || super + end + + def method_missing(method_symbol, *parameters) #:nodoc: + if match = matches_dynamic_method?(method_symbol) + case match[1] + when 'create' then new(match[2], *parameters).message + when 'deliver' then new(match[2], *parameters).deliver! + when 'new' then nil + else super + end + else + super + end + end + + private + + def matches_dynamic_method?(method_name) #:nodoc: + method_name = method_name.to_s + /^(create|deliver)_([_a-z]\w*)/.match(method_name) || /^(new)$/.match(method_name) + end + end + + def initialize(*) + super() + @mail_was_called = false + end + def render(*args) options = args.last.is_a?(Hash) ? args.last : {} if options[:body] @@ -85,6 +116,23 @@ module ActionMailer super end + def process(method_name, *args) + initialize_defaults(method_name) + super + unless @mail_was_called + # Create e-mail parts + create_parts + + # Set the subject if not set yet + @subject ||= I18n.t(:subject, :scope => [:actionmailer, mailer_name, method_name], + :default => method_name.humanize) + + # Build the mail object itself + create_mail + end + end + + # Add a part to a multipart message, with the given content-type. The # part itself is yielded to the block so that other properties (charset, # body, headers, etc.) can be set on it. -- cgit v1.2.3 From b30eb39ff072ce95ccd5ce94ae08d116c23fd260 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Fri, 22 Jan 2010 11:57:54 +0100 Subject: Add more tests to new API. --- actionmailer/lib/action_mailer/base.rb | 38 +++++--- actionmailer/lib/action_mailer/deprecated_api.rb | 2 +- actionmailer/test/base_test.rb | 115 ++++++++++++++++------- 3 files changed, 107 insertions(+), 48 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 2c1de0e3b4..d75bbe952f 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -277,14 +277,14 @@ module ActionMailer #:nodoc: @@deliveries = [] cattr_accessor :deliveries - @@default_charset = "utf-8" - cattr_accessor :default_charset + extlib_inheritable_accessor :default_charset + self.default_charset = "utf-8" - @@default_content_type = "text/plain" - cattr_accessor :default_content_type + extlib_inheritable_accessor :default_content_type + self.default_content_type = "text/plain" - @@default_mime_version = "1.0" - cattr_accessor :default_mime_version + extlib_inheritable_accessor :default_mime_version + self.default_mime_version = "1.0" # This specifies the order that the parts of a multipart email will be. Usually you put # text/plain at the top so someone without a MIME capable email reader can read the plain @@ -292,14 +292,24 @@ module ActionMailer #:nodoc: # # Any content type that is not listed here will be inserted in the order you add them to # the email after the content types you list here. - @@default_implicit_parts_order = [ "text/plain", "text/enriched", "text/html" ] - cattr_accessor :default_implicit_parts_order + extlib_inheritable_accessor :default_implicit_parts_order + self.default_implicit_parts_order = [ "text/plain", "text/enriched", "text/html" ] # Expose the internal Mail message attr_reader :message - # Pass calls to headers and attachment to the Mail#Message instance - delegate :headers, :attachments, :to => :@message + def headers(args=nil) + if args + ActiveSupport::Deprecation.warn "headers(Hash) is deprecated, please do headers[key] = value instead", caller + @headers = args + else + @message + end + end + + def attachments + @message.attachments + end class << self @@ -386,9 +396,9 @@ module ActionMailer #:nodoc: m = @message - m.content_type ||= headers[:content_type] || @@default_content_type - m.charset ||= headers[:charset] || @@default_charset - m.mime_version ||= headers[:mime_version] || @@default_mime_version + m.content_type ||= headers[:content_type] || self.class.default_content_type + m.charset ||= headers[:charset] || self.class.default_charset + m.mime_version ||= headers[:mime_version] || self.class.default_mime_version m.subject = quote_if_necessary(headers[:subject], m.charset) if headers[:subject] m.to = quote_address_if_necessary(headers[:to], m.charset) if headers[:to] @@ -398,7 +408,7 @@ module ActionMailer #:nodoc: m.reply_to = quote_address_if_necessary(headers[:reply_to], m.charset) if headers[:reply_to] m.date = headers[:date] if headers[:date] - m.body.set_sort_order(headers[:parts_order] || @@default_implicit_parts_order) + m.body.set_sort_order(headers[:parts_order] || self.class.default_implicit_parts_order) # # Set the subject if not set yet # @subject ||= I18n.t(:subject, :scope => [:actionmailer, mailer_name, method_name], diff --git a/actionmailer/lib/action_mailer/deprecated_api.rb b/actionmailer/lib/action_mailer/deprecated_api.rb index 430b0cef4a..90e2aebf53 100644 --- a/actionmailer/lib/action_mailer/deprecated_api.rb +++ b/actionmailer/lib/action_mailer/deprecated_api.rb @@ -227,7 +227,7 @@ module ActionMailer m.mime_version = mime_version unless mime_version.nil? m.date = sent_on.to_time rescue sent_on if sent_on - headers.each { |k, v| m[k] = v } + @headers.each { |k, v| m[k] = v } real_content_type, ctype_attrs = parse_content_type main_type, sub_type = split_content_type(real_content_type) diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index f1f5f38482..b11631f444 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -37,37 +37,43 @@ require 'abstract_unit' # mail.deliver # # Notifier.welcome(user).deliver # => creates and sends the Mail in one step -class BaseTest < Test::Unit::TestCase - +class BaseTest < ActiveSupport::TestCase + DEFAULT_HEADERS = { + :to => 'mikel@test.lindsaar.net', + :from => 'jose@test.plataformatec.com', + :subject => 'The first email on new API!' + } + class TestMailer < ActionMailer::Base - def welcome(hash = {}) - hash = {:to => 'mikel@test.lindsaar.net', :from => 'jose@test.plataformatec.com', - :subject => 'The first email on new API!'}.merge!(hash) - mail(hash) + headers['X-SPAM'] = "Not SPAM" + mail(DEFAULT_HEADERS.merge(hash)) end - - def invoice(hash = {}) + + def attachment_with_content attachments['invoice.pdf'] = 'This is test File content' - hash = {:to => 'mikel@test.lindsaar.net', :from => 'jose@test.plataformatec.com', - :subject => 'Your invoice is attached'}.merge!(hash) - mail(hash) + mail(DEFAULT_HEADERS) + end + + def attachment_with_hash + attachments['invoice.jpg'] = { :content => "you smiling", :mime_type => "image/x-jpg", + :transfer_encoding => "base64" } + mail(DEFAULT_HEADERS) end - end - def test_the_method_call_to_mail_does_not_raise_error + test "method call to mail does not raise error" do assert_nothing_raised { TestMailer.deliver_welcome } end - def test_should_set_the_headers_of_the_mail_message + test "mail() should set the headers of the mail message" do email = TestMailer.deliver_welcome assert_equal(email.to, ['mikel@test.lindsaar.net']) assert_equal(email.from, ['jose@test.plataformatec.com']) assert_equal(email.subject, 'The first email on new API!') end - - def test_should_allow_all_headers_set + + test "mail() with bcc, cc, content_type, charset, mime_version, reply_to and date" do @time = Time.now email = TestMailer.deliver_welcome(:bcc => 'bcc@test.lindsaar.net', :cc => 'cc@test.lindsaar.net', @@ -85,32 +91,58 @@ class BaseTest < Test::Unit::TestCase assert_equal(email.date, @time) end -# def test_should_allow_custom_headers_to_be_set -# email = TestMailer.deliver_welcome -# assert_equal("Not SPAM", email['X-SPAM']) -# end - - def test_should_allow_you_to_send_an_attachment - assert_nothing_raised { TestMailer.deliver_invoice } + test "custom headers" do + email = TestMailer.deliver_welcome + assert_equal("Not SPAM", email['X-SPAM'].decoded) end - def test_should_allow_you_to_send_an_attachment - email = TestMailer.deliver_invoice + test "attachment with content" do + email = TestMailer.deliver_attachment_with_content assert_equal(1, email.attachments.length) + assert_equal('invoice.pdf', email.attachments[0].filename) + assert_equal('This is test File content', email.attachments['invoice.pdf'].decoded) end - def test_should_allow_you_to_send_an_attachment - email = TestMailer.deliver_invoice + test "attachment gets content type from filename" do + email = TestMailer.deliver_attachment_with_content assert_equal('invoice.pdf', email.attachments[0].filename) end - def test_should_allow_you_to_send_an_attachment - email = TestMailer.deliver_invoice - assert_equal('This is test File content', email.attachments['invoice.pdf'].decoded) + test "attachment with hash" do + email = TestMailer.deliver_attachment_with_hash + assert_equal(1, email.attachments.length) + assert_equal('invoice.jpg', email.attachments[0].filename) + assert_equal("\312\213\254\232)b", email.attachments['invoice.jpg'].decoded) + end + + test "uses default charset from class" do + swap TestMailer, :default_charset => "US-ASCII" do + email = TestMailer.deliver_welcome + assert_equal("US-ASCII", email.charset) + + email = TestMailer.deliver_welcome(:charset => "iso-8559-1") + assert_equal("iso-8559-1", email.charset) + end end - def test_should_use_class_defaults - + test "uses default content type from class" do + swap TestMailer, :default_content_type => "text/html" do + email = TestMailer.deliver_welcome + assert_equal("text/html", email.mime_type) + + email = TestMailer.deliver_welcome(:content_type => "application/xml") + assert_equal("application/xml", email.mime_type) + end + end + + test "uses default mime version from class" do + swap TestMailer, :default_mime_version => "2.0" do + email = TestMailer.deliver_welcome + assert_equal("2.0", email.mime_version) + + email = TestMailer.deliver_welcome(:mime_version => "1.0") + assert_equal("1.0", email.mime_version) + end end # def test_that_class_defaults_are_set_on_instantiation @@ -120,5 +152,22 @@ class BaseTest < Test::Unit::TestCase # def test_should_set_the_subject_from_i18n # pending # end - + + protected + + # Execute the block setting the given values and restoring old values after + # the block is executed. + def swap(object, new_values) + old_values = {} + new_values.each do |key, value| + old_values[key] = object.send key + object.send :"#{key}=", value + end + yield + ensure + old_values.each do |key, value| + object.send :"#{key}=", value + end + end + end \ No newline at end of file -- cgit v1.2.3 From dcb925369389fa98d1548b25504c8e3a07eaeea3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Fri, 22 Jan 2010 13:27:20 +0100 Subject: Add basic template rendering to new DSL. --- actionmailer/lib/action_mailer/base.rb | 69 ++++++++++++++++------ actionmailer/lib/action_mailer/deprecated_api.rb | 9 +-- actionmailer/lib/action_mailer/mail_helper.rb | 2 +- actionmailer/test/base_test.rb | 66 +++++++++++---------- actionmailer/test/fixtures/base_mailer/welcome.erb | 1 + .../test/fixtures/test_mailer/body_ivar.erb | 2 - actionmailer/test/mail_service_test.rb | 9 --- 7 files changed, 88 insertions(+), 70 deletions(-) create mode 100644 actionmailer/test/fixtures/base_mailer/welcome.erb delete mode 100644 actionmailer/test/fixtures/test_mailer/body_ivar.erb (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index d75bbe952f..1f432c2a80 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -280,6 +280,7 @@ module ActionMailer #:nodoc: extlib_inheritable_accessor :default_charset self.default_charset = "utf-8" + # TODO This should be used when calling render extlib_inheritable_accessor :default_content_type self.default_content_type = "text/plain" @@ -357,7 +358,7 @@ module ActionMailer #:nodoc: begin # TODO Move me to the instance if @@perform_deliveries - mail.deliver! + mail.deliver! self.deliveries << mail end rescue Exception => e # Net::SMTP errors or sendmail pipe errors @@ -393,32 +394,62 @@ module ActionMailer #:nodoc: # Guard flag to prevent both the old and the new API from firing # Should be removed when old API is deprecated @mail_was_called = true - m = @message - - m.content_type ||= headers[:content_type] || self.class.default_content_type - m.charset ||= headers[:charset] || self.class.default_charset - m.mime_version ||= headers[:mime_version] || self.class.default_mime_version - - m.subject = quote_if_necessary(headers[:subject], m.charset) if headers[:subject] - m.to = quote_address_if_necessary(headers[:to], m.charset) if headers[:to] - m.from = quote_address_if_necessary(headers[:from], m.charset) if headers[:from] - m.cc = quote_address_if_necessary(headers[:cc], m.charset) if headers[:cc] - m.bcc = quote_address_if_necessary(headers[:bcc], m.charset) if headers[:bcc] - m.reply_to = quote_address_if_necessary(headers[:reply_to], m.charset) if headers[:reply_to] - m.date = headers[:date] if headers[:date] - m.body.set_sort_order(headers[:parts_order] || self.class.default_implicit_parts_order) - - # # Set the subject if not set yet - # @subject ||= I18n.t(:subject, :scope => [:actionmailer, mailer_name, method_name], - # :default => method_name.humanize) + # Get default subject from I18n if none is set + headers[:subject] ||= I18n.t(:subject, :scope => [:actionmailer, mailer_name, action_name], + :default => action_name.humanize) + + # Give preference to headers and fallbacks to the ones set in mail + headers[:content_type] ||= m.content_type + headers[:charset] ||= m.charset + headers[:mime_version] ||= m.mime_version + + m.content_type = headers[:content_type] || self.class.default_content_type.dup + m.charset = headers[:charset] || self.class.default_charset.dup + m.mime_version = headers[:mime_version] || self.class.default_mime_version.dup + + m.subject ||= quote_if_necessary(headers[:subject], m.charset) if headers[:subject] + m.to ||= quote_address_if_necessary(headers[:to], m.charset) if headers[:to] + m.from ||= quote_address_if_necessary(headers[:from], m.charset) if headers[:from] + m.cc ||= quote_address_if_necessary(headers[:cc], m.charset) if headers[:cc] + m.bcc ||= quote_address_if_necessary(headers[:bcc], m.charset) if headers[:bcc] + m.reply_to ||= quote_address_if_necessary(headers[:reply_to], m.charset) if headers[:reply_to] + m.date ||= headers[:date] if headers[:date] + + if block_given? + # Do something + else + # TODO Ensure that we don't need to pass I18n.locale as detail + templates = self.class.template_root.find_all(action_name, {}, mailer_name) + + if templates.size == 1 + unless headers[:content_type] + proper_charset = m.charset + m.content_type = templates[0].mime_type.to_s + m.charset = proper_charset + end + m.body = render_to_body(:_template => templates[0]) + else + templates.each do |template| + part = Mail::Part.new + part.content_type = template.mime_type.to_s + part.charset = m.charset + part.body = render_to_body(:_template => template) + end + end + end + m.body.set_sort_order(headers[:parts_order] || self.class.default_implicit_parts_order.dup) # TODO: m.body.sort_parts! m end + def fill_in_part(part, template, charset) + + end + # Instantiate a new mailer object. If +method_name+ is not +nil+, the mailer # will be initialized according to the named method. If not, the mailer will # remain uninitialized (useful when you only need to invoke the "receive" diff --git a/actionmailer/lib/action_mailer/deprecated_api.rb b/actionmailer/lib/action_mailer/deprecated_api.rb index 90e2aebf53..b2bb6a64aa 100644 --- a/actionmailer/lib/action_mailer/deprecated_api.rb +++ b/actionmailer/lib/action_mailer/deprecated_api.rb @@ -120,19 +120,12 @@ module ActionMailer initialize_defaults(method_name) super unless @mail_was_called - # Create e-mail parts create_parts - - # Set the subject if not set yet - @subject ||= I18n.t(:subject, :scope => [:actionmailer, mailer_name, method_name], - :default => method_name.humanize) - - # Build the mail object itself create_mail end + @message end - # Add a part to a multipart message, with the given content-type. The # part itself is yielded to the block so that other properties (charset, # body, headers, etc.) can be set on it. diff --git a/actionmailer/lib/action_mailer/mail_helper.rb b/actionmailer/lib/action_mailer/mail_helper.rb index 702c9ba8f7..45ba6f0714 100644 --- a/actionmailer/lib/action_mailer/mail_helper.rb +++ b/actionmailer/lib/action_mailer/mail_helper.rb @@ -22,7 +22,7 @@ module ActionMailer end # Access the message instance. - def message + def message #:nodoc: @message end end diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index b11631f444..f22b20a6ba 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -44,7 +44,9 @@ class BaseTest < ActiveSupport::TestCase :subject => 'The first email on new API!' } - class TestMailer < ActionMailer::Base + class BaseMailer < ActionMailer::Base + self.mailer_name = "base_mailer" + def welcome(hash = {}) headers['X-SPAM'] = "Not SPAM" mail(DEFAULT_HEADERS.merge(hash)) @@ -63,11 +65,11 @@ class BaseTest < ActiveSupport::TestCase end test "method call to mail does not raise error" do - assert_nothing_raised { TestMailer.deliver_welcome } + assert_nothing_raised { BaseMailer.deliver_welcome } end test "mail() should set the headers of the mail message" do - email = TestMailer.deliver_welcome + email = BaseMailer.deliver_welcome assert_equal(email.to, ['mikel@test.lindsaar.net']) assert_equal(email.from, ['jose@test.plataformatec.com']) assert_equal(email.subject, 'The first email on new API!') @@ -75,7 +77,7 @@ class BaseTest < ActiveSupport::TestCase test "mail() with bcc, cc, content_type, charset, mime_version, reply_to and date" do @time = Time.now - email = TestMailer.deliver_welcome(:bcc => 'bcc@test.lindsaar.net', + email = BaseMailer.deliver_welcome(:bcc => 'bcc@test.lindsaar.net', :cc => 'cc@test.lindsaar.net', :content_type => 'multipart/mixed', :charset => 'iso-8559-1', @@ -91,68 +93,70 @@ class BaseTest < ActiveSupport::TestCase assert_equal(email.date, @time) end + test "mail() renders the template using the method being processed" do + email = BaseMailer.deliver_welcome + assert_equal("Welcome", email.body.encoded) + end + test "custom headers" do - email = TestMailer.deliver_welcome + email = BaseMailer.deliver_welcome assert_equal("Not SPAM", email['X-SPAM'].decoded) end test "attachment with content" do - email = TestMailer.deliver_attachment_with_content + email = BaseMailer.deliver_attachment_with_content assert_equal(1, email.attachments.length) assert_equal('invoice.pdf', email.attachments[0].filename) assert_equal('This is test File content', email.attachments['invoice.pdf'].decoded) end test "attachment gets content type from filename" do - email = TestMailer.deliver_attachment_with_content + email = BaseMailer.deliver_attachment_with_content assert_equal('invoice.pdf', email.attachments[0].filename) end test "attachment with hash" do - email = TestMailer.deliver_attachment_with_hash + email = BaseMailer.deliver_attachment_with_hash assert_equal(1, email.attachments.length) assert_equal('invoice.jpg', email.attachments[0].filename) assert_equal("\312\213\254\232)b", email.attachments['invoice.jpg'].decoded) end + # test "mail sets proper content type when attachment is included" do + # email = BaseMailer.deliver_attachment_with_content + # assert_equal(1, email.attachments.length) + # assert_equal("multipart/mixed", email.content_type) + # end + test "uses default charset from class" do - swap TestMailer, :default_charset => "US-ASCII" do - email = TestMailer.deliver_welcome + swap BaseMailer, :default_charset => "US-ASCII" do + email = BaseMailer.deliver_welcome assert_equal("US-ASCII", email.charset) - email = TestMailer.deliver_welcome(:charset => "iso-8559-1") + email = BaseMailer.deliver_welcome(:charset => "iso-8559-1") assert_equal("iso-8559-1", email.charset) end end - test "uses default content type from class" do - swap TestMailer, :default_content_type => "text/html" do - email = TestMailer.deliver_welcome - assert_equal("text/html", email.mime_type) - - email = TestMailer.deliver_welcome(:content_type => "application/xml") - assert_equal("application/xml", email.mime_type) - end - end - test "uses default mime version from class" do - swap TestMailer, :default_mime_version => "2.0" do - email = TestMailer.deliver_welcome + swap BaseMailer, :default_mime_version => "2.0" do + email = BaseMailer.deliver_welcome assert_equal("2.0", email.mime_version) - email = TestMailer.deliver_welcome(:mime_version => "1.0") + email = BaseMailer.deliver_welcome(:mime_version => "1.0") assert_equal("1.0", email.mime_version) end end - # def test_that_class_defaults_are_set_on_instantiation - # pending - # end - # - # def test_should_set_the_subject_from_i18n - # pending - # end + test "subject gets default from I18n" do + email = BaseMailer.deliver_welcome(:subject => nil) + assert_equal "Welcome", email.subject + I18n.backend.store_translations('en', :actionmailer => {:base_mailer => {:welcome => {:subject => "New Subject!"}}}) + email = BaseMailer.deliver_welcome(:subject => nil) + assert_equal "New Subject!", email.subject + end + protected # Execute the block setting the given values and restoring old values after diff --git a/actionmailer/test/fixtures/base_mailer/welcome.erb b/actionmailer/test/fixtures/base_mailer/welcome.erb new file mode 100644 index 0000000000..01f3f00c63 --- /dev/null +++ b/actionmailer/test/fixtures/base_mailer/welcome.erb @@ -0,0 +1 @@ +Welcome \ No newline at end of file diff --git a/actionmailer/test/fixtures/test_mailer/body_ivar.erb b/actionmailer/test/fixtures/test_mailer/body_ivar.erb deleted file mode 100644 index 1421e5c908..0000000000 --- a/actionmailer/test/fixtures/test_mailer/body_ivar.erb +++ /dev/null @@ -1,2 +0,0 @@ -body: <%= @body %> -bar: <%= @bar %> \ No newline at end of file diff --git a/actionmailer/test/mail_service_test.rb b/actionmailer/test/mail_service_test.rb index ec820e3464..62422fb4b3 100644 --- a/actionmailer/test/mail_service_test.rb +++ b/actionmailer/test/mail_service_test.rb @@ -416,15 +416,6 @@ class ActionMailerTest < Test::Unit::TestCase assert_equal expected.encoded, delivered.encoded end - def test_subject_with_i18n - assert_nothing_raised { TestMailer.deliver_subject_with_i18n(@recipient) } - assert_equal "Subject with i18n", ActionMailer::Base.deliveries.first.subject.to_s - - I18n.backend.store_translations('en', :actionmailer => {:test_mailer => {:subject_with_i18n => {:subject => "New Subject!"}}}) - assert_nothing_raised { TestMailer.deliver_subject_with_i18n(@recipient) } - assert_equal "New Subject!", ActionMailer::Base.deliveries.last.subject.to_s - end - def test_custom_template expected = new_mail expected.to = @recipient -- cgit v1.2.3 From 1cd55928c6f638affeb5d89293f478817675d7b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Fri, 22 Jan 2010 13:56:06 +0100 Subject: First work on implicit multipart. --- actionmailer/lib/action_mailer/base.rb | 49 +++++++++++----------- actionmailer/test/base_test.rb | 18 +++++++- .../base_mailer/implicit_multipart.html.erb | 1 + .../base_mailer/implicit_multipart.text.erb | 1 + 4 files changed, 44 insertions(+), 25 deletions(-) create mode 100644 actionmailer/test/fixtures/base_mailer/implicit_multipart.html.erb create mode 100644 actionmailer/test/fixtures/base_mailer/implicit_multipart.text.erb (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 1f432c2a80..fb1dab7c39 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -401,21 +401,18 @@ module ActionMailer #:nodoc: :default => action_name.humanize) # Give preference to headers and fallbacks to the ones set in mail - headers[:content_type] ||= m.content_type - headers[:charset] ||= m.charset - headers[:mime_version] ||= m.mime_version - - m.content_type = headers[:content_type] || self.class.default_content_type.dup - m.charset = headers[:charset] || self.class.default_charset.dup - m.mime_version = headers[:mime_version] || self.class.default_mime_version.dup - - m.subject ||= quote_if_necessary(headers[:subject], m.charset) if headers[:subject] - m.to ||= quote_address_if_necessary(headers[:to], m.charset) if headers[:to] - m.from ||= quote_address_if_necessary(headers[:from], m.charset) if headers[:from] - m.cc ||= quote_address_if_necessary(headers[:cc], m.charset) if headers[:cc] - m.bcc ||= quote_address_if_necessary(headers[:bcc], m.charset) if headers[:bcc] - m.reply_to ||= quote_address_if_necessary(headers[:reply_to], m.charset) if headers[:reply_to] - m.date ||= headers[:date] if headers[:date] + content_type = headers[:content_type] || m.content_type + charset = headers[:charset] || m.charset + mime_version = headers[:mime_version] || m.mime_version + body = nil + + m.subject ||= quote_if_necessary(headers[:subject], charset) if headers[:subject] + m.to ||= quote_address_if_necessary(headers[:to], charset) if headers[:to] + m.from ||= quote_address_if_necessary(headers[:from], charset) if headers[:from] + m.cc ||= quote_address_if_necessary(headers[:cc], charset) if headers[:cc] + m.bcc ||= quote_address_if_necessary(headers[:bcc], charset) if headers[:bcc] + m.reply_to ||= quote_address_if_necessary(headers[:reply_to], charset) if headers[:reply_to] + m.date ||= headers[:date] if headers[:date] if block_given? # Do something @@ -424,25 +421,29 @@ module ActionMailer #:nodoc: templates = self.class.template_root.find_all(action_name, {}, mailer_name) if templates.size == 1 - unless headers[:content_type] - proper_charset = m.charset - m.content_type = templates[0].mime_type.to_s - m.charset = proper_charset - end + content_type ||= templates[0].mime_type.to_s m.body = render_to_body(:_template => templates[0]) else + content_type ||= "multipart/alternate" + templates.each do |template| part = Mail::Part.new part.content_type = template.mime_type.to_s - part.charset = m.charset + part.charset = charset part.body = render_to_body(:_template => template) + m.add_part(part) end end end + + m.content_type = content_type || self.class.default_content_type.dup + m.charset = charset || self.class.default_charset.dup + m.mime_version = mime_version || self.class.default_mime_version.dup + + # TODO Add me and test me + # m.body.set_sort_order(headers[:parts_order] || self.class.default_implicit_parts_order.dup) + # m.body.sort_parts! - m.body.set_sort_order(headers[:parts_order] || self.class.default_implicit_parts_order.dup) - - # TODO: m.body.sort_parts! m end diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index f22b20a6ba..8502b29ba4 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -62,6 +62,10 @@ class BaseTest < ActiveSupport::TestCase :transfer_encoding => "base64" } mail(DEFAULT_HEADERS) end + + def implicit_multipart + mail(DEFAULT_HEADERS) + end end test "method call to mail does not raise error" do @@ -156,7 +160,19 @@ class BaseTest < ActiveSupport::TestCase email = BaseMailer.deliver_welcome(:subject => nil) assert_equal "New Subject!", email.subject end - + + test "implicit multipart tests" do + require 'ruby-debug' + $BREAK = true + email = BaseMailer.deliver_implicit_multipart + + assert_equal(2, email.parts.size) + + assert_equal("multipart/alternate", email.mime_type) + assert_equal("text/plain", email.parts[0].mime_type) + assert_equal("text/html", email.parts[1].mime_type) + end + protected # Execute the block setting the given values and restoring old values after diff --git a/actionmailer/test/fixtures/base_mailer/implicit_multipart.html.erb b/actionmailer/test/fixtures/base_mailer/implicit_multipart.html.erb new file mode 100644 index 0000000000..23745cd282 --- /dev/null +++ b/actionmailer/test/fixtures/base_mailer/implicit_multipart.html.erb @@ -0,0 +1 @@ +HTML Implicit Multipart \ No newline at end of file diff --git a/actionmailer/test/fixtures/base_mailer/implicit_multipart.text.erb b/actionmailer/test/fixtures/base_mailer/implicit_multipart.text.erb new file mode 100644 index 0000000000..d51437fc72 --- /dev/null +++ b/actionmailer/test/fixtures/base_mailer/implicit_multipart.text.erb @@ -0,0 +1 @@ +TEXT Implicit Multipart \ No newline at end of file -- cgit v1.2.3 From 951397b4a2143eee4b900356dab525aed99430ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Fri, 22 Jan 2010 14:38:41 +0100 Subject: Get implicit multipart and attachments working together. --- actionmailer/lib/action_mailer/base.rb | 50 ++++++----- actionmailer/lib/action_mailer/delivery_methods.rb | 2 + actionmailer/test/base_test.rb | 96 ++++++++++++++++++---- .../base_mailer/attachment_with_content.erb | 1 + 4 files changed, 109 insertions(+), 40 deletions(-) create mode 100644 actionmailer/test/fixtures/base_mailer/attachment_with_content.erb (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index fb1dab7c39..98e559154a 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -390,6 +390,7 @@ module ActionMailer #:nodoc: end end + # TODO Add new delivery method goodness def mail(headers = {}) # Guard flag to prevent both the old and the new API from firing # Should be removed when old API is deprecated @@ -402,9 +403,8 @@ module ActionMailer #:nodoc: # Give preference to headers and fallbacks to the ones set in mail content_type = headers[:content_type] || m.content_type - charset = headers[:charset] || m.charset - mime_version = headers[:mime_version] || m.mime_version - body = nil + charset = headers[:charset] || m.charset || self.class.default_charset.dup + mime_version = headers[:mime_version] || m.mime_version || self.class.default_mime_version.dup m.subject ||= quote_if_necessary(headers[:subject], charset) if headers[:subject] m.to ||= quote_address_if_necessary(headers[:to], charset) if headers[:to] @@ -420,35 +420,41 @@ module ActionMailer #:nodoc: # TODO Ensure that we don't need to pass I18n.locale as detail templates = self.class.template_root.find_all(action_name, {}, mailer_name) - if templates.size == 1 + if templates.size == 1 && !m.has_attachments? content_type ||= templates[0].mime_type.to_s m.body = render_to_body(:_template => templates[0]) + elsif templates.size > 1 && m.has_attachments? + container = Mail::Part.new + container.content_type = "multipart/alternate" + templates.each { |t| insert_part(container, t, charset) } + m.add_part(container) else - content_type ||= "multipart/alternate" - - templates.each do |template| - part = Mail::Part.new - part.content_type = template.mime_type.to_s - part.charset = charset - part.body = render_to_body(:_template => template) - m.add_part(part) - end + templates.each { |t| insert_part(m, t, charset) } end + + content_type ||= (m.has_attachments? ? "multipart/mixed" : "multipart/alternate") end - + + # Check if the content_type was not overwriten along the way and if so, + # fallback to default. m.content_type = content_type || self.class.default_content_type.dup - m.charset = charset || self.class.default_charset.dup - m.mime_version = mime_version || self.class.default_mime_version.dup - - # TODO Add me and test me - # m.body.set_sort_order(headers[:parts_order] || self.class.default_implicit_parts_order.dup) - # m.body.sort_parts! + m.charset = charset + m.mime_version = mime_version + + unless m.parts.empty? + m.body.set_sort_order(headers[:parts_order] || self.class.default_implicit_parts_order.dup) + m.body.sort_parts! + end m end - def fill_in_part(part, template, charset) - + def insert_part(container, template, charset) + part = Mail::Part.new + part.content_type = template.mime_type.to_s + part.charset = charset + part.body = render_to_body(:_template => template) + container.add_part(part) end # Instantiate a new mailer object. If +method_name+ is not +nil+, the mailer diff --git a/actionmailer/lib/action_mailer/delivery_methods.rb b/actionmailer/lib/action_mailer/delivery_methods.rb index c8c4148353..5883e446f2 100644 --- a/actionmailer/lib/action_mailer/delivery_methods.rb +++ b/actionmailer/lib/action_mailer/delivery_methods.rb @@ -27,6 +27,7 @@ module ActionMailer end module ClassMethods + # TODO Make me class inheritable def delivery_settings @@delivery_settings ||= Hash.new { |h,k| h[k] = {} } end @@ -51,6 +52,7 @@ module ActionMailer protected + # TODO Get rid of this method missing magic def method_missing(method_symbol, *parameters) #:nodoc: if match = matches_settings_method?(method_symbol) if match[2] diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index 8502b29ba4..df0eed695d 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -3,13 +3,13 @@ require 'abstract_unit' # class Notifier < ActionMailer::Base # delivers_from 'notifications@example.com' -# +# # def welcome(user) # @user = user # available to the view # mail(:subject => 'Welcome!', :to => user.email_address) # # auto renders both welcome.text.erb and welcome.html.erb # end -# +# # def goodbye(user) # headers["X-SPAM"] = 'Not-SPAM' # mail(:subject => 'Goodbye', :to => user.email_address) do |format| @@ -17,7 +17,7 @@ require 'abstract_unit' # format.text # goodbye.text.erb # end # end -# +# # def surprise(user, gift) # attachments[gift.name] = File.read(gift.path) # mail(:subject => 'Surprise!', :to => user.email_address) do |format| @@ -25,17 +25,17 @@ require 'abstract_unit' # format.text(:transfer_encoding => "base64") # surprise.text.erb # end # end -# +# # def special_surprise(user, gift) # attachments[gift.name] = { :content_type => "application/x-gzip", :content => File.read(gift.path) } # mail(:to => 'special@example.com') # subject not required # # auto renders both special_surprise.text.erb and special_surprise.html.erb # end # end -# +# # mail = Notifier.welcome(user) # => returns a Mail object # mail.deliver -# +# # Notifier.welcome(user).deliver # => creates and sends the Mail in one step class BaseTest < ActiveSupport::TestCase DEFAULT_HEADERS = { @@ -44,6 +44,8 @@ class BaseTest < ActiveSupport::TestCase :subject => 'The first email on new API!' } + # TODO Think on the simple case where I want to send an e-mail + # with attachment and small text (without need to add a template). class BaseMailer < ActionMailer::Base self.mailer_name = "base_mailer" @@ -63,8 +65,9 @@ class BaseTest < ActiveSupport::TestCase mail(DEFAULT_HEADERS) end - def implicit_multipart - mail(DEFAULT_HEADERS) + def implicit_multipart(hash = {}) + attachments['invoice.pdf'] = 'This is test File content' if hash.delete(:attachments) + mail(DEFAULT_HEADERS.merge(hash)) end end @@ -72,6 +75,7 @@ class BaseTest < ActiveSupport::TestCase assert_nothing_raised { BaseMailer.deliver_welcome } end + # Basic mail usage without block test "mail() should set the headers of the mail message" do email = BaseMailer.deliver_welcome assert_equal(email.to, ['mikel@test.lindsaar.net']) @@ -102,11 +106,13 @@ class BaseTest < ActiveSupport::TestCase assert_equal("Welcome", email.body.encoded) end + # Custom headers test "custom headers" do email = BaseMailer.deliver_welcome assert_equal("Not SPAM", email['X-SPAM'].decoded) end + # Attachments test "attachment with content" do email = BaseMailer.deliver_attachment_with_content assert_equal(1, email.attachments.length) @@ -126,12 +132,22 @@ class BaseTest < ActiveSupport::TestCase assert_equal("\312\213\254\232)b", email.attachments['invoice.jpg'].decoded) end - # test "mail sets proper content type when attachment is included" do - # email = BaseMailer.deliver_attachment_with_content - # assert_equal(1, email.attachments.length) - # assert_equal("multipart/mixed", email.content_type) - # end + test "sets mime type to multipart/mixed when attachment is included" do + email = BaseMailer.deliver_attachment_with_content + assert_equal(1, email.attachments.length) + assert_equal("multipart/mixed", email.mime_type) + end + test "adds the rendered template as part" do + email = BaseMailer.deliver_attachment_with_content + assert_equal(2, email.parts.length) + assert_equal("text/html", email.parts[0].mime_type) + assert_equal("Attachment with content", email.parts[0].body.encoded) + assert_equal("application/pdf", email.parts[1].mime_type) + assert_equal("VGhpcyBpcyB0ZXN0IEZpbGUgY29udGVudA==\r\n", email.parts[1].body.encoded) + end + + # Defaults values test "uses default charset from class" do swap BaseMailer, :default_charset => "US-ASCII" do email = BaseMailer.deliver_welcome @@ -142,6 +158,16 @@ class BaseTest < ActiveSupport::TestCase end end + test "uses default content type from class" do + swap BaseMailer, :default_content_type => "text/html" do + email = BaseMailer.deliver_welcome + assert_equal("text/html", email.mime_type) + + email = BaseMailer.deliver_welcome(:content_type => "text/plain") + assert_equal("text/plain", email.mime_type) + end + end + test "uses default mime version from class" do swap BaseMailer, :default_mime_version => "2.0" do email = BaseMailer.deliver_welcome @@ -161,18 +187,52 @@ class BaseTest < ActiveSupport::TestCase assert_equal "New Subject!", email.subject end + # Implicit multipart test "implicit multipart tests" do - require 'ruby-debug' - $BREAK = true email = BaseMailer.deliver_implicit_multipart - assert_equal(2, email.parts.size) - assert_equal("multipart/alternate", email.mime_type) assert_equal("text/plain", email.parts[0].mime_type) - assert_equal("text/html", email.parts[1].mime_type) + assert_equal("TEXT Implicit Multipart", email.parts[0].body.encoded) + assert_equal("text/html", email.parts[1].mime_type) + assert_equal("HTML Implicit Multipart", email.parts[1].body.encoded) + end + + test "implicit multipart tests with sort order" do + order = ["text/html", "text/plain"] + swap BaseMailer, :default_implicit_parts_order => order do + email = BaseMailer.deliver_implicit_multipart + assert_equal("text/html", email.parts[0].mime_type) + assert_equal("text/plain", email.parts[1].mime_type) + + email = BaseMailer.deliver_implicit_multipart(:parts_order => order.reverse) + assert_equal("text/plain", email.parts[0].mime_type) + assert_equal("text/html", email.parts[1].mime_type) + end + end + + test "implicit multipart with attachments creates nested parts" do + email = BaseMailer.deliver_implicit_multipart(:attachments => true) + assert_equal("application/pdf", email.parts[0].mime_type) + assert_equal("multipart/alternate", email.parts[1].mime_type) + assert_equal("text/plain", email.parts[1].parts[0].mime_type) + assert_equal("TEXT Implicit Multipart", email.parts[1].parts[0].body.encoded) + assert_equal("text/html", email.parts[1].parts[1].mime_type) + assert_equal("HTML Implicit Multipart", email.parts[1].parts[1].body.encoded) end + # TODO This should be fixed in mail. Sort parts should be recursive. + # test "implicit multipart with attachments and sort order" do + # order = ["text/html", "text/plain"] + # swap BaseMailer, :default_implicit_parts_order => order do + # email = BaseMailer.deliver_implicit_multipart(:attachments => true) + # assert_equal("application/pdf", email.parts[0].mime_type) + # assert_equal("multipart/alternate", email.parts[1].mime_type) + # assert_equal("text/plain", email.parts[1].parts[1].mime_type) + # assert_equal("text/html", email.parts[1].parts[0].mime_type) + # end + # end + protected # Execute the block setting the given values and restoring old values after diff --git a/actionmailer/test/fixtures/base_mailer/attachment_with_content.erb b/actionmailer/test/fixtures/base_mailer/attachment_with_content.erb new file mode 100644 index 0000000000..deb9dbd03b --- /dev/null +++ b/actionmailer/test/fixtures/base_mailer/attachment_with_content.erb @@ -0,0 +1 @@ +Attachment with content \ No newline at end of file -- cgit v1.2.3 From c8cc8a987213bf90fe6922517d52befb7c0587a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Fri, 22 Jan 2010 20:44:29 +0100 Subject: Moved more configuration away from bootstrap. --- actionmailer/lib/action_mailer/railtie.rb | 5 ----- 1 file changed, 5 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/railtie.rb b/actionmailer/lib/action_mailer/railtie.rb index 94d9eaf81b..ac6f514dfa 100644 --- a/actionmailer/lib/action_mailer/railtie.rb +++ b/actionmailer/lib/action_mailer/railtie.rb @@ -18,10 +18,5 @@ module ActionMailer initializer "action_mailer.logger" do ActionMailer::Base.logger ||= Rails.logger end - - initializer "action_mailer.view_paths" do |app| - # TODO: this should be combined with the logic for default config.action_mailer.view_paths - ActionMailer::Base.template_root = [] if ActionMailer::Base.view_paths.blank? - end end end \ No newline at end of file -- cgit v1.2.3 From bd24c75fc619fa80af03662cc4dd18fc9b70cafb Mon Sep 17 00:00:00 2001 From: Mikel Lindsaar Date: Sat, 23 Jan 2010 18:45:59 +1100 Subject: Updated Gemspec to mail 2.0.3 from gemcutter --- actionmailer/actionmailer.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionmailer') diff --git a/actionmailer/actionmailer.gemspec b/actionmailer/actionmailer.gemspec index 9a8c1df9e8..576ca97334 100644 --- a/actionmailer/actionmailer.gemspec +++ b/actionmailer/actionmailer.gemspec @@ -11,7 +11,7 @@ Gem::Specification.new do |s| s.homepage = "http://www.rubyonrails.org" s.add_dependency('actionpack', '= 3.0.pre') - s.add_dependency('mail', '~> 2.0.2') + s.add_dependency('mail', '~> 2.0.3') s.files = Dir['CHANGELOG', 'README', 'MIT-LICENSE', 'lib/**/*'] s.has_rdoc = true -- cgit v1.2.3 From 5c3ef8c17dba23d000d301467b1a620811c940b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Sat, 23 Jan 2010 10:24:19 +0100 Subject: Refactor subject with i18n. --- actionmailer/lib/action_mailer/base.rb | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 98e559154a..94e20d4b63 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -398,8 +398,7 @@ module ActionMailer #:nodoc: m = @message # Get default subject from I18n if none is set - headers[:subject] ||= I18n.t(:subject, :scope => [:actionmailer, mailer_name, action_name], - :default => action_name.humanize) + headers[:subject] ||= default_subject # Give preference to headers and fallbacks to the ones set in mail content_type = headers[:content_type] || m.content_type @@ -418,7 +417,7 @@ module ActionMailer #:nodoc: # Do something else # TODO Ensure that we don't need to pass I18n.locale as detail - templates = self.class.template_root.find_all(action_name, {}, mailer_name) + templates = self.class.template_root.find_all(action_name, {}, self.class.mailer_name) if templates.size == 1 && !m.has_attachments? content_type ||= templates[0].mime_type.to_s @@ -449,6 +448,11 @@ module ActionMailer #:nodoc: m end + def default_subject + mailer_scope = self.class.mailer_name.gsub('/', '.') + I18n.t(:subject, :scope => [:actionmailer, mailer_scope, action_name], :default => action_name.humanize) + end + def insert_part(container, template, charset) part = Mail::Part.new part.content_type = template.mime_type.to_s -- cgit v1.2.3 From c6b16260fe3d1435848e78415bd0b40c10ad7424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Sat, 23 Jan 2010 21:37:34 +1100 Subject: Added basic explicit multipart rendering and tests --- actionmailer/lib/action_mailer.rb | 1 + actionmailer/lib/action_mailer/base.rb | 28 ++++++++--- actionmailer/lib/action_mailer/mail_helper.rb | 2 +- actionmailer/test/base_test.rb | 67 ++++++++++++++++++++++----- 4 files changed, 79 insertions(+), 19 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer.rb b/actionmailer/lib/action_mailer.rb index 37c95baea7..67466e15e2 100644 --- a/actionmailer/lib/action_mailer.rb +++ b/actionmailer/lib/action_mailer.rb @@ -31,6 +31,7 @@ module ActionMailer extend ::ActiveSupport::Autoload autoload :AdvAttrAccessor + autoload :Collector autoload :Base autoload :DeliveryMethods autoload :DeprecatedApi diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 94e20d4b63..28e4c88b5a 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -297,8 +297,9 @@ module ActionMailer #:nodoc: self.default_implicit_parts_order = [ "text/plain", "text/enriched", "text/html" ] # Expose the internal Mail message + # TODO: Make this an _internal ivar? attr_reader :message - + def headers(args=nil) if args ActiveSupport::Deprecation.warn "headers(Hash) is deprecated, please do headers[key] = value instead", caller @@ -413,12 +414,25 @@ module ActionMailer #:nodoc: m.reply_to ||= quote_address_if_necessary(headers[:reply_to], charset) if headers[:reply_to] m.date ||= headers[:date] if headers[:date] - if block_given? - # Do something + if headers[:body] + templates = [ActionView::Template::Text.new(headers[:body], format_for_text)] + elsif block_given? + collector = ActionMailer::Collector.new(self, {:charset => charset}) do + render action_name + end + yield collector + + collector.responses.each do |response| + part = Mail::Part.new(response) + m.add_part(part) + end + else # TODO Ensure that we don't need to pass I18n.locale as detail templates = self.class.template_root.find_all(action_name, {}, self.class.mailer_name) - + end + + if templates if templates.size == 1 && !m.has_attachments? content_type ||= templates[0].mime_type.to_s m.body = render_to_body(:_template => templates[0]) @@ -430,17 +444,17 @@ module ActionMailer #:nodoc: else templates.each { |t| insert_part(m, t, charset) } end - - content_type ||= (m.has_attachments? ? "multipart/mixed" : "multipart/alternate") end + content_type ||= (m.has_attachments? ? "multipart/mixed" : "multipart/alternate") + # Check if the content_type was not overwriten along the way and if so, # fallback to default. m.content_type = content_type || self.class.default_content_type.dup m.charset = charset m.mime_version = mime_version - unless m.parts.empty? + if m.parts.present? && templates m.body.set_sort_order(headers[:parts_order] || self.class.default_implicit_parts_order.dup) m.body.sort_parts! end diff --git a/actionmailer/lib/action_mailer/mail_helper.rb b/actionmailer/lib/action_mailer/mail_helper.rb index 45ba6f0714..adba94cbef 100644 --- a/actionmailer/lib/action_mailer/mail_helper.rb +++ b/actionmailer/lib/action_mailer/mail_helper.rb @@ -18,7 +18,7 @@ module ActionMailer # Access the mailer instance. def mailer #:nodoc: - @controller + @_controller end # Access the message instance. diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index df0eed695d..bae50868ae 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -69,6 +69,14 @@ class BaseTest < ActiveSupport::TestCase attachments['invoice.pdf'] = 'This is test File content' if hash.delete(:attachments) mail(DEFAULT_HEADERS.merge(hash)) end + + def explicit_multipart(hash = {}) + mail(DEFAULT_HEADERS.merge(hash)) do |format| + format.text { render :text => "TEXT Explicit Multipart" } + format.html { render :text => "HTML Explicit Multipart" } + end + end + end test "method call to mail does not raise error" do @@ -106,6 +114,11 @@ class BaseTest < ActiveSupport::TestCase assert_equal("Welcome", email.body.encoded) end + test "can pass in :body to the mail method hash" do + email = BaseMailer.deliver_welcome(:body => "Hello there") + assert_equal("Hello there", email.body.encoded) + end + # Custom headers test "custom headers" do email = BaseMailer.deliver_welcome @@ -221,17 +234,49 @@ class BaseTest < ActiveSupport::TestCase assert_equal("HTML Implicit Multipart", email.parts[1].parts[1].body.encoded) end - # TODO This should be fixed in mail. Sort parts should be recursive. - # test "implicit multipart with attachments and sort order" do - # order = ["text/html", "text/plain"] - # swap BaseMailer, :default_implicit_parts_order => order do - # email = BaseMailer.deliver_implicit_multipart(:attachments => true) - # assert_equal("application/pdf", email.parts[0].mime_type) - # assert_equal("multipart/alternate", email.parts[1].mime_type) - # assert_equal("text/plain", email.parts[1].parts[1].mime_type) - # assert_equal("text/html", email.parts[1].parts[0].mime_type) - # end - # end + test "implicit multipart with attachments and sort order" do + order = ["text/html", "text/plain"] + swap BaseMailer, :default_implicit_parts_order => order do + email = BaseMailer.deliver_implicit_multipart(:attachments => true) + assert_equal("application/pdf", email.parts[0].mime_type) + assert_equal("multipart/alternate", email.parts[1].mime_type) + assert_equal("text/plain", email.parts[1].parts[1].mime_type) + assert_equal("text/html", email.parts[1].parts[0].mime_type) + end + end + + test "explicit multipart tests" do + email = BaseMailer.deliver_explicit_multipart + assert_equal(2, email.parts.size) + assert_equal("multipart/alternate", email.mime_type) + assert_equal("text/plain", email.parts[0].mime_type) + assert_equal("TEXT Explicit Multipart", email.parts[0].body.encoded) + assert_equal("text/html", email.parts[1].mime_type) + assert_equal("HTML Explicit Multipart", email.parts[1].body.encoded) + end + + test "explicit multipart does not sort order" do + order = ["text/html", "text/plain"] + swap BaseMailer, :default_implicit_parts_order => order do + email = BaseMailer.deliver_explicit_multipart + assert_equal("text/plain", email.parts[0].mime_type) + assert_equal("text/html", email.parts[1].mime_type) + + email = BaseMailer.deliver_explicit_multipart(:parts_order => order.reverse) + assert_equal("text/plain", email.parts[0].mime_type) + assert_equal("text/html", email.parts[1].mime_type) + end + end + + #test "explicit multipart with attachments creates nested parts" do + # email = BaseMailer.deliver_explicit_multipart(:attachments => true) + # assert_equal("application/pdf", email.parts[0].mime_type) + # assert_equal("multipart/alternate", email.parts[1].mime_type) + # assert_equal("text/plain", email.parts[1].parts[0].mime_type) + # assert_equal("TEXT Implicit Multipart", email.parts[1].parts[0].body.encoded) + # assert_equal("text/html", email.parts[1].parts[1].mime_type) + # assert_equal("HTML Implicit Multipart", email.parts[1].parts[1].body.encoded) + #end protected -- cgit v1.2.3 From 5a19d24892b9d842ef7d27875eacecbbad71a9aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Sat, 23 Jan 2010 21:50:36 +1100 Subject: Adding collector to ActionMailer --- actionmailer/lib/action_mailer/collector.rb | 32 +++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 actionmailer/lib/action_mailer/collector.rb (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/collector.rb b/actionmailer/lib/action_mailer/collector.rb new file mode 100644 index 0000000000..49c3f04bad --- /dev/null +++ b/actionmailer/lib/action_mailer/collector.rb @@ -0,0 +1,32 @@ +require 'abstract_controller/collector' + +module ActionMailer #:nodoc: + + class Collector + + include AbstractController::Collector + + attr_accessor :responses + + def initialize(context, options, &block) + @default_options = options + @default_render = block + @default_formats = context.formats + @context = context + @responses = [] + end + + def custom(mime, options={}, &block) + options = @default_options.merge(:content_type => mime.to_s).merge(options) + @context.formats = [mime.to_sym] + options[:body] = if block + block.call + else + @default_render.call + end + @responses << options + @context.formats = @default_formats + end + + end +end \ No newline at end of file -- cgit v1.2.3 From 6ba944608e527b8d7fc564a6e450e2d4c4355ddb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Sat, 23 Jan 2010 12:20:20 +0100 Subject: Make implicit and explicit templates pass through the same part creation process. --- actionmailer/lib/action_mailer/base.rb | 126 ++++++++++++++-------------- actionmailer/lib/action_mailer/collector.rb | 25 +++--- actionmailer/test/base_test.rb | 37 +++++--- 3 files changed, 104 insertions(+), 84 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 28e4c88b5a..5e61b8693a 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -1,5 +1,5 @@ require 'active_support/core_ext/class' -require "active_support/core_ext/module/delegation" +require 'active_support/core_ext/module/delegation' require 'mail' require 'action_mailer/tmail_compat' @@ -391,70 +391,63 @@ module ActionMailer #:nodoc: end end + # Instantiate a new mailer object. If +method_name+ is not +nil+, the mailer + # will be initialized according to the named method. If not, the mailer will + # remain uninitialized (useful when you only need to invoke the "receive" + # method, for instance). + def initialize(method_name=nil, *args) + super() + @message = Mail.new + process(method_name, *args) if method_name + end + + # Delivers a Mail object. By default, it delivers the cached mail + # object (from the create! method). If no cached mail object exists, and + # no alternate has been given as the parameter, this will fail. + def deliver!(mail = @message) + self.class.deliver(mail) + end + # TODO Add new delivery method goodness def mail(headers = {}) # Guard flag to prevent both the old and the new API from firing # Should be removed when old API is deprecated @mail_was_called = true - m = @message - # Get default subject from I18n if none is set - headers[:subject] ||= default_subject + m, sort_parts = @message, true - # Give preference to headers and fallbacks to the ones set in mail + # Give preference to headers and fallback to the ones set in mail content_type = headers[:content_type] || m.content_type charset = headers[:charset] || m.charset || self.class.default_charset.dup mime_version = headers[:mime_version] || m.mime_version || self.class.default_mime_version.dup - m.subject ||= quote_if_necessary(headers[:subject], charset) if headers[:subject] - m.to ||= quote_address_if_necessary(headers[:to], charset) if headers[:to] - m.from ||= quote_address_if_necessary(headers[:from], charset) if headers[:from] - m.cc ||= quote_address_if_necessary(headers[:cc], charset) if headers[:cc] - m.bcc ||= quote_address_if_necessary(headers[:bcc], charset) if headers[:bcc] - m.reply_to ||= quote_address_if_necessary(headers[:reply_to], charset) if headers[:reply_to] - m.date ||= headers[:date] if headers[:date] + headers[:subject] ||= default_subject + quote_fields(m, headers, charset) - if headers[:body] - templates = [ActionView::Template::Text.new(headers[:body], format_for_text)] + responses = if headers[:body] + [ { :body => headers[:body], :content_type => self.class.default_content_type.dup } ] elsif block_given? - collector = ActionMailer::Collector.new(self, {:charset => charset}) do - render action_name - end - yield collector - - collector.responses.each do |response| - part = Mail::Part.new(response) - m.add_part(part) - end - + sort_parts = false + collector = ActionMailer::Collector.new(self) { render(action_name) } + yield(collector) + collector.responses else # TODO Ensure that we don't need to pass I18n.locale as detail templates = self.class.template_root.find_all(action_name, {}, self.class.mailer_name) - end - - if templates - if templates.size == 1 && !m.has_attachments? - content_type ||= templates[0].mime_type.to_s - m.body = render_to_body(:_template => templates[0]) - elsif templates.size > 1 && m.has_attachments? - container = Mail::Part.new - container.content_type = "multipart/alternate" - templates.each { |t| insert_part(container, t, charset) } - m.add_part(container) - else - templates.each { |t| insert_part(m, t, charset) } + + templates.map do |template| + { :body => render_to_body(:_template => template), + :content_type => template.mime_type.to_s } end end - content_type ||= (m.has_attachments? ? "multipart/mixed" : "multipart/alternate") + content_type ||= create_parts_from_responses(m, responses, charset) - # Check if the content_type was not overwriten along the way and if so, - # fallback to default. - m.content_type = content_type || self.class.default_content_type.dup + m.content_type = content_type m.charset = charset m.mime_version = mime_version - if m.parts.present? && templates + if sort_parts && m.parts.present? m.body.set_sort_order(headers[:parts_order] || self.class.default_implicit_parts_order.dup) m.body.sort_parts! end @@ -462,34 +455,43 @@ module ActionMailer #:nodoc: m end - def default_subject + protected + + def default_subject #:nodoc: mailer_scope = self.class.mailer_name.gsub('/', '.') I18n.t(:subject, :scope => [:actionmailer, mailer_scope, action_name], :default => action_name.humanize) end - def insert_part(container, template, charset) - part = Mail::Part.new - part.content_type = template.mime_type.to_s - part.charset = charset - part.body = render_to_body(:_template => template) - container.add_part(part) + def quote_fields(m, headers, charset) #:nodoc: + m.subject ||= quote_if_necessary(headers[:subject], charset) if headers[:subject] + m.to ||= quote_address_if_necessary(headers[:to], charset) if headers[:to] + m.from ||= quote_address_if_necessary(headers[:from], charset) if headers[:from] + m.cc ||= quote_address_if_necessary(headers[:cc], charset) if headers[:cc] + m.bcc ||= quote_address_if_necessary(headers[:bcc], charset) if headers[:bcc] + m.reply_to ||= quote_address_if_necessary(headers[:reply_to], charset) if headers[:reply_to] + m.date ||= headers[:date] if headers[:date] end - # Instantiate a new mailer object. If +method_name+ is not +nil+, the mailer - # will be initialized according to the named method. If not, the mailer will - # remain uninitialized (useful when you only need to invoke the "receive" - # method, for instance). - def initialize(method_name=nil, *args) - super() - @message = Mail.new - process(method_name, *args) if method_name + def create_parts_from_responses(m, responses, charset) #:nodoc: + if responses.size == 1 && !m.has_attachments? + m.body = responses[0][:body] + return responses[0][:content_type] + elsif responses.size > 1 && m.has_attachments? + container = Mail::Part.new + container.content_type = "multipart/alternate" + responses.each { |r| insert_part(container, r, charset) } + m.add_part(container) + else + responses.each { |r| insert_part(m, r, charset) } + end + + m.has_attachments? ? "multipart/mixed" : "multipart/alternate" end - # Delivers a Mail object. By default, it delivers the cached mail - # object (from the create! method). If no cached mail object exists, and - # no alternate has been given as the parameter, this will fail. - def deliver!(mail = @message) - self.class.deliver(mail) + def insert_part(container, response, charset) #:nodoc: + response[:charset] ||= charset + part = Mail::Part.new(response) + container.add_part(part) end end diff --git a/actionmailer/lib/action_mailer/collector.rb b/actionmailer/lib/action_mailer/collector.rb index 49c3f04bad..0891b6f123 100644 --- a/actionmailer/lib/action_mailer/collector.rb +++ b/actionmailer/lib/action_mailer/collector.rb @@ -1,23 +1,29 @@ require 'abstract_controller/collector' +require 'active_support/core_ext/hash/reverse_merge' +require 'active_support/core_ext/array/extract_options' module ActionMailer #:nodoc: - class Collector - include AbstractController::Collector - - attr_accessor :responses + attr_reader :responses - def initialize(context, options, &block) - @default_options = options - @default_render = block - @default_formats = context.formats + def initialize(context, &block) @context = context @responses = [] + @default_render = block + @default_formats = context.formats + end + + # TODO Test me + def any(*args, &block) + options = args.extract_options! + raise "You have to supply at least one format" if args.empty? + args.each { |type| send(type, options, &block) } end + alias :all :any def custom(mime, options={}, &block) - options = @default_options.merge(:content_type => mime.to_s).merge(options) + options.reverse_merge!(:content_type => mime.to_s) @context.formats = [mime.to_sym] options[:body] = if block block.call @@ -27,6 +33,5 @@ module ActionMailer #:nodoc: @responses << options @context.formats = @default_formats end - end end \ No newline at end of file diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index bae50868ae..3033b2db0f 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -54,9 +54,9 @@ class BaseTest < ActiveSupport::TestCase mail(DEFAULT_HEADERS.merge(hash)) end - def attachment_with_content + def attachment_with_content(hash = {}) attachments['invoice.pdf'] = 'This is test File content' - mail(DEFAULT_HEADERS) + mail(DEFAULT_HEADERS.merge(hash)) end def attachment_with_hash @@ -69,8 +69,9 @@ class BaseTest < ActiveSupport::TestCase attachments['invoice.pdf'] = 'This is test File content' if hash.delete(:attachments) mail(DEFAULT_HEADERS.merge(hash)) end - + def explicit_multipart(hash = {}) + attachments['invoice.pdf'] = 'This is test File content' if hash.delete(:attachments) mail(DEFAULT_HEADERS.merge(hash)) do |format| format.text { render :text => "TEXT Explicit Multipart" } format.html { render :text => "HTML Explicit Multipart" } @@ -116,6 +117,7 @@ class BaseTest < ActiveSupport::TestCase test "can pass in :body to the mail method hash" do email = BaseMailer.deliver_welcome(:body => "Hello there") + assert_equal("text/plain", email.mime_type) assert_equal("Hello there", email.body.encoded) end @@ -154,12 +156,23 @@ class BaseTest < ActiveSupport::TestCase test "adds the rendered template as part" do email = BaseMailer.deliver_attachment_with_content assert_equal(2, email.parts.length) + assert_equal("multipart/mixed", email.mime_type) assert_equal("text/html", email.parts[0].mime_type) assert_equal("Attachment with content", email.parts[0].body.encoded) assert_equal("application/pdf", email.parts[1].mime_type) assert_equal("VGhpcyBpcyB0ZXN0IEZpbGUgY29udGVudA==\r\n", email.parts[1].body.encoded) end + test "adds the given :body as part" do + email = BaseMailer.deliver_attachment_with_content(:body => "I'm the eggman") + assert_equal(2, email.parts.length) + assert_equal("multipart/mixed", email.mime_type) + assert_equal("text/plain", email.parts[0].mime_type) + assert_equal("I'm the eggman", email.parts[0].body.encoded) + assert_equal("application/pdf", email.parts[1].mime_type) + assert_equal("VGhpcyBpcyB0ZXN0IEZpbGUgY29udGVudA==\r\n", email.parts[1].body.encoded) + end + # Defaults values test "uses default charset from class" do swap BaseMailer, :default_charset => "US-ASCII" do @@ -268,15 +281,15 @@ class BaseTest < ActiveSupport::TestCase end end - #test "explicit multipart with attachments creates nested parts" do - # email = BaseMailer.deliver_explicit_multipart(:attachments => true) - # assert_equal("application/pdf", email.parts[0].mime_type) - # assert_equal("multipart/alternate", email.parts[1].mime_type) - # assert_equal("text/plain", email.parts[1].parts[0].mime_type) - # assert_equal("TEXT Implicit Multipart", email.parts[1].parts[0].body.encoded) - # assert_equal("text/html", email.parts[1].parts[1].mime_type) - # assert_equal("HTML Implicit Multipart", email.parts[1].parts[1].body.encoded) - #end + test "explicit multipart with attachments creates nested parts" do + email = BaseMailer.deliver_explicit_multipart(:attachments => true) + assert_equal("application/pdf", email.parts[0].mime_type) + assert_equal("multipart/alternate", email.parts[1].mime_type) + assert_equal("text/plain", email.parts[1].parts[0].mime_type) + assert_equal("TEXT Explicit Multipart", email.parts[1].parts[0].body.encoded) + assert_equal("text/html", email.parts[1].parts[1].mime_type) + assert_equal("HTML Explicit Multipart", email.parts[1].parts[1].body.encoded) + end protected -- cgit v1.2.3 From c985a0ee3d9ae279fd02814ca60782e2f93215e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Sat, 23 Jan 2010 12:46:33 +0100 Subject: Add some tests to collector with templates and any. --- actionmailer/lib/action_mailer/base.rb | 2 +- actionmailer/lib/action_mailer/collector.rb | 3 +- actionmailer/test/base_test.rb | 57 +++++++++++++++++----- .../explicit_multipart_templates.html.erb | 1 + .../explicit_multipart_templates.text.erb | 1 + 5 files changed, 50 insertions(+), 14 deletions(-) create mode 100644 actionmailer/test/fixtures/base_mailer/explicit_multipart_templates.html.erb create mode 100644 actionmailer/test/fixtures/base_mailer/explicit_multipart_templates.text.erb (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 5e61b8693a..4ab3761807 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -2,6 +2,7 @@ require 'active_support/core_ext/class' require 'active_support/core_ext/module/delegation' require 'mail' require 'action_mailer/tmail_compat' +require 'action_mailer/collector' module ActionMailer #:nodoc: # Action Mailer allows you to send email from your application using a mailer model and views. @@ -442,7 +443,6 @@ module ActionMailer #:nodoc: end content_type ||= create_parts_from_responses(m, responses, charset) - m.content_type = content_type m.charset = charset m.mime_version = mime_version diff --git a/actionmailer/lib/action_mailer/collector.rb b/actionmailer/lib/action_mailer/collector.rb index 0891b6f123..5431efccfe 100644 --- a/actionmailer/lib/action_mailer/collector.rb +++ b/actionmailer/lib/action_mailer/collector.rb @@ -14,11 +14,10 @@ module ActionMailer #:nodoc: @default_formats = context.formats end - # TODO Test me def any(*args, &block) options = args.extract_options! raise "You have to supply at least one format" if args.empty? - args.each { |type| send(type, options, &block) } + args.each { |type| send(type, options.dup, &block) } end alias :all :any diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index 3033b2db0f..83943162d2 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -77,7 +77,19 @@ class BaseTest < ActiveSupport::TestCase format.html { render :text => "HTML Explicit Multipart" } end end - + + def explicit_multipart_templates(hash = {}) + mail(DEFAULT_HEADERS.merge(hash)) do |format| + format.html + format.text + end + end + + def explicit_multipart_with_any(hash = {}) + mail(DEFAULT_HEADERS.merge(hash)) do |format| + format.any(:text, :html){ render :text => "Format with any!" } + end + end end test "method call to mail does not raise error" do @@ -214,7 +226,7 @@ class BaseTest < ActiveSupport::TestCase end # Implicit multipart - test "implicit multipart tests" do + test "implicit multipart" do email = BaseMailer.deliver_implicit_multipart assert_equal(2, email.parts.size) assert_equal("multipart/alternate", email.mime_type) @@ -224,7 +236,7 @@ class BaseTest < ActiveSupport::TestCase assert_equal("HTML Implicit Multipart", email.parts[1].body.encoded) end - test "implicit multipart tests with sort order" do + test "implicit multipart with sort order" do order = ["text/html", "text/plain"] swap BaseMailer, :default_implicit_parts_order => order do email = BaseMailer.deliver_implicit_multipart @@ -258,7 +270,8 @@ class BaseTest < ActiveSupport::TestCase end end - test "explicit multipart tests" do + # Explicit multipart + test "explicit multipart" do email = BaseMailer.deliver_explicit_multipart assert_equal(2, email.parts.size) assert_equal("multipart/alternate", email.mime_type) @@ -282,15 +295,37 @@ class BaseTest < ActiveSupport::TestCase end test "explicit multipart with attachments creates nested parts" do - email = BaseMailer.deliver_explicit_multipart(:attachments => true) - assert_equal("application/pdf", email.parts[0].mime_type) - assert_equal("multipart/alternate", email.parts[1].mime_type) - assert_equal("text/plain", email.parts[1].parts[0].mime_type) - assert_equal("TEXT Explicit Multipart", email.parts[1].parts[0].body.encoded) - assert_equal("text/html", email.parts[1].parts[1].mime_type) - assert_equal("HTML Explicit Multipart", email.parts[1].parts[1].body.encoded) + email = BaseMailer.deliver_explicit_multipart(:attachments => true) + assert_equal("application/pdf", email.parts[0].mime_type) + assert_equal("multipart/alternate", email.parts[1].mime_type) + assert_equal("text/plain", email.parts[1].parts[0].mime_type) + assert_equal("TEXT Explicit Multipart", email.parts[1].parts[0].body.encoded) + assert_equal("text/html", email.parts[1].parts[1].mime_type) + assert_equal("HTML Explicit Multipart", email.parts[1].parts[1].body.encoded) end + # TODO Seems Mail is sorting the templates automatically, and not on demand + # test "explicit multipart with templates" do + # email = BaseMailer.deliver_explicit_multipart_templates + # assert_equal(2, email.parts.size) + # assert_equal("multipart/alternate", email.mime_type) + # assert_equal("text/html", email.parts[0].mime_type) + # assert_equal("HTML Explicit Multipart Templates", email.parts[0].body.encoded) + # assert_equal("text/plain", email.parts[1].mime_type) + # assert_equal("TEXT Explicit Multipart Templates", email.parts[1].body.encoded) + # end + + test "explicit multipart with any" do + email = BaseMailer.deliver_explicit_multipart_with_any + assert_equal(2, email.parts.size) + assert_equal("multipart/alternate", email.mime_type) + assert_equal("text/plain", email.parts[0].mime_type) + assert_equal("Format with any!", email.parts[0].body.encoded) + assert_equal("text/html", email.parts[1].mime_type) + assert_equal("Format with any!", email.parts[1].body.encoded) + end + + protected # Execute the block setting the given values and restoring old values after diff --git a/actionmailer/test/fixtures/base_mailer/explicit_multipart_templates.html.erb b/actionmailer/test/fixtures/base_mailer/explicit_multipart_templates.html.erb new file mode 100644 index 0000000000..c0a61b6249 --- /dev/null +++ b/actionmailer/test/fixtures/base_mailer/explicit_multipart_templates.html.erb @@ -0,0 +1 @@ +HTML Explicit Multipart Templates \ No newline at end of file diff --git a/actionmailer/test/fixtures/base_mailer/explicit_multipart_templates.text.erb b/actionmailer/test/fixtures/base_mailer/explicit_multipart_templates.text.erb new file mode 100644 index 0000000000..507230b1de --- /dev/null +++ b/actionmailer/test/fixtures/base_mailer/explicit_multipart_templates.text.erb @@ -0,0 +1 @@ +TEXT Explicit Multipart Templates \ No newline at end of file -- cgit v1.2.3 From e7e4ed48df3048f32d94e398e99d0048a66ba67e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Sun, 24 Jan 2010 09:34:50 +1100 Subject: Set sort order for explicit parts from the collector's template sequence --- actionmailer/lib/action_mailer/base.rb | 12 ++++++++---- actionmailer/test/base_test.rb | 19 +++++++++---------- 2 files changed, 17 insertions(+), 14 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 4ab3761807..e95643ca44 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -415,7 +415,7 @@ module ActionMailer #:nodoc: # Should be removed when old API is deprecated @mail_was_called = true - m, sort_parts = @message, true + m = @message # Give preference to headers and fallback to the ones set in mail content_type = headers[:content_type] || m.content_type @@ -425,12 +425,16 @@ module ActionMailer #:nodoc: headers[:subject] ||= default_subject quote_fields(m, headers, charset) + sort_order = headers[:parts_order] || self.class.default_implicit_parts_order.dup + responses = if headers[:body] [ { :body => headers[:body], :content_type => self.class.default_content_type.dup } ] elsif block_given? - sort_parts = false collector = ActionMailer::Collector.new(self) { render(action_name) } yield(collector) + # Collect the sort order of the parts from the collector as Mail will always + # sort parts on encode into a "sane" sequence. + sort_order = collector.responses.map { |r| r[:content_type] } collector.responses else # TODO Ensure that we don't need to pass I18n.locale as detail @@ -447,8 +451,8 @@ module ActionMailer #:nodoc: m.charset = charset m.mime_version = mime_version - if sort_parts && m.parts.present? - m.body.set_sort_order(headers[:parts_order] || self.class.default_implicit_parts_order.dup) + if m.multipart? + m.body.set_sort_order(sort_order) m.body.sort_parts! end diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index 83943162d2..ad0e1d9fe2 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -304,16 +304,15 @@ class BaseTest < ActiveSupport::TestCase assert_equal("HTML Explicit Multipart", email.parts[1].parts[1].body.encoded) end - # TODO Seems Mail is sorting the templates automatically, and not on demand - # test "explicit multipart with templates" do - # email = BaseMailer.deliver_explicit_multipart_templates - # assert_equal(2, email.parts.size) - # assert_equal("multipart/alternate", email.mime_type) - # assert_equal("text/html", email.parts[0].mime_type) - # assert_equal("HTML Explicit Multipart Templates", email.parts[0].body.encoded) - # assert_equal("text/plain", email.parts[1].mime_type) - # assert_equal("TEXT Explicit Multipart Templates", email.parts[1].body.encoded) - # end + test "explicit multipart with templates" do + email = BaseMailer.deliver_explicit_multipart_templates + assert_equal(2, email.parts.size) + assert_equal("multipart/alternate", email.mime_type) + assert_equal("text/html", email.parts[0].mime_type) + assert_equal("HTML Explicit Multipart Templates", email.parts[0].body.encoded) + assert_equal("text/plain", email.parts[1].mime_type) + assert_equal("TEXT Explicit Multipart Templates", email.parts[1].body.encoded) + end test "explicit multipart with any" do email = BaseMailer.deliver_explicit_multipart_with_any -- cgit v1.2.3 From 258ca148004eaa63740ab2186338b3ac872b8187 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Sun, 24 Jan 2010 11:15:42 +1100 Subject: Delegated ActionMailer::Base.deliveries to Mail.deliveries, added callback support in Mail to call ActionMailer on delivery, moved deliver to deprecated API in preparation for new API --- actionmailer/actionmailer.gemspec | 2 +- actionmailer/lib/action_mailer/base.rb | 56 ++++++++---------------- actionmailer/lib/action_mailer/deprecated_api.rb | 32 ++++++++++++++ actionmailer/lib/action_mailer/test_case.rb | 2 +- actionmailer/test/asset_host_test.rb | 2 +- actionmailer/test/base_test.rb | 9 ++++ actionmailer/test/mail_helper_test.rb | 2 +- actionmailer/test/mail_layout_test.rb | 2 +- actionmailer/test/mail_render_test.rb | 4 +- actionmailer/test/mail_service_test.rb | 6 +-- actionmailer/test/url_test.rb | 2 +- 11 files changed, 70 insertions(+), 49 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/actionmailer.gemspec b/actionmailer/actionmailer.gemspec index 576ca97334..4f53c709c4 100644 --- a/actionmailer/actionmailer.gemspec +++ b/actionmailer/actionmailer.gemspec @@ -11,7 +11,7 @@ Gem::Specification.new do |s| s.homepage = "http://www.rubyonrails.org" s.add_dependency('actionpack', '= 3.0.pre') - s.add_dependency('mail', '~> 2.0.3') + s.add_dependency('mail', '~> 2.0.5') s.files = Dir['CHANGELOG', 'README', 'MIT-LICENSE', 'lib/**/*'] s.has_rdoc = true diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index e95643ca44..c1dc415728 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -275,8 +275,16 @@ module ActionMailer #:nodoc: @@perform_deliveries = true cattr_accessor :perform_deliveries - @@deliveries = [] - cattr_accessor :deliveries + # Provides a list of emails that have been delivered by Mail + def self.deliveries + Mail.deliveries + end + + # Allows you to over write the default deliveries store from an array to some + # other object. If you just want to clear the store, call Mail.deliveries.clear. + def self.deliveries=(val) + Mail.deliveries = val + end extlib_inheritable_accessor :default_charset self.default_charset = "utf-8" @@ -342,35 +350,6 @@ module ActionMailer #:nodoc: end end - # Deliver the given mail object directly. This can be used to deliver - # a preconstructed mail object, like: - # - # email = MyMailer.create_some_mail(parameters) - # email.set_some_obscure_header "frobnicate" - # MyMailer.deliver(email) - def deliver(mail) - raise "no mail object available for delivery!" unless mail - - ActiveSupport::Notifications.instrument("action_mailer.deliver", :mailer => self.name) do |payload| - self.set_payload_for_mail(payload, mail) - - mail.delivery_method delivery_methods[delivery_method], - delivery_settings[delivery_method] - - begin - # TODO Move me to the instance - if @@perform_deliveries - mail.deliver! - self.deliveries << mail - end - rescue Exception => e # Net::SMTP errors or sendmail pipe errors - raise e if raise_delivery_errors - end - end - - mail - end - def template_root self.view_paths && self.view_paths.first end @@ -380,6 +359,12 @@ module ActionMailer #:nodoc: self.view_paths = ActionView::Base.process_view_paths(root) end + def delivered_email(mail) + ActiveSupport::Notifications.instrument("action_mailer.deliver", :mailer => self.name) do |payload| + self.set_payload_for_mail(payload, mail) + end + end + def set_payload_for_mail(payload, mail) #:nodoc: payload[:message_id] = mail.message_id payload[:subject] = mail.subject @@ -402,13 +387,6 @@ module ActionMailer #:nodoc: process(method_name, *args) if method_name end - # Delivers a Mail object. By default, it delivers the cached mail - # object (from the create! method). If no cached mail object exists, and - # no alternate has been given as the parameter, this will fail. - def deliver!(mail = @message) - self.class.deliver(mail) - end - # TODO Add new delivery method goodness def mail(headers = {}) # Guard flag to prevent both the old and the new API from firing @@ -417,6 +395,8 @@ module ActionMailer #:nodoc: m = @message + m.register_for_delivery_notification(self.class) + # Give preference to headers and fallback to the ones set in mail content_type = headers[:content_type] || m.content_type charset = headers[:charset] || m.charset || self.class.default_charset.dup diff --git a/actionmailer/lib/action_mailer/deprecated_api.rb b/actionmailer/lib/action_mailer/deprecated_api.rb index b2bb6a64aa..a9ebd70f86 100644 --- a/actionmailer/lib/action_mailer/deprecated_api.rb +++ b/actionmailer/lib/action_mailer/deprecated_api.rb @@ -71,9 +71,34 @@ module ActionMailer # Alias controller_path to mailer_name so render :partial in views work. alias :controller_path :mailer_name + end module ClassMethods + + # Deliver the given mail object directly. This can be used to deliver + # a preconstructed mail object, like: + # + # email = MyMailer.create_some_mail(parameters) + # email.set_some_obscure_header "frobnicate" + # MyMailer.deliver(email) + def deliver(mail) + raise "no mail object available for delivery!" unless mail + + ActiveSupport::Notifications.instrument("action_mailer.deliver", :mailer => self.name) do |payload| + self.set_payload_for_mail(payload, mail) + + mail.delivery_method delivery_methods[delivery_method], + delivery_settings[delivery_method] + + mail.raise_delivery_errors = raise_delivery_errors + mail.perform_deliveries = perform_deliveries + mail.deliver + end + + mail + end + def respond_to?(method_symbol, include_private = false) #:nodoc: matches_dynamic_method?(method_symbol) || super end @@ -104,6 +129,13 @@ module ActionMailer @mail_was_called = false end + # Delivers a Mail object. By default, it delivers the cached mail + # object (from the create! method). If no cached mail object exists, and + # no alternate has been given as the parameter, this will fail. + def deliver!(mail = @message) + self.class.deliver(mail) + end + def render(*args) options = args.last.is_a?(Hash) ? args.last : {} if options[:body] diff --git a/actionmailer/lib/action_mailer/test_case.rb b/actionmailer/lib/action_mailer/test_case.rb index 0ca4f5494e..7c4033a125 100644 --- a/actionmailer/lib/action_mailer/test_case.rb +++ b/actionmailer/lib/action_mailer/test_case.rb @@ -37,7 +37,7 @@ module ActionMailer def initialize_test_deliveries ActionMailer::Base.delivery_method = :test ActionMailer::Base.perform_deliveries = true - ActionMailer::Base.deliveries = [] + ActionMailer::Base.deliveries.clear end def set_expected_mail diff --git a/actionmailer/test/asset_host_test.rb b/actionmailer/test/asset_host_test.rb index f3383e5608..7ba78b6daa 100644 --- a/actionmailer/test/asset_host_test.rb +++ b/actionmailer/test/asset_host_test.rb @@ -12,7 +12,7 @@ class AssetHostTest < Test::Unit::TestCase def setup set_delivery_method :test ActionMailer::Base.perform_deliveries = true - ActionMailer::Base.deliveries = [] + ActionMailer::Base.deliveries.clear @recipient = 'test@localhost' end diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index ad0e1d9fe2..43a9fb29bb 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -324,6 +324,15 @@ class BaseTest < ActiveSupport::TestCase assert_equal("Format with any!", email.parts[1].body.encoded) end + test "ActionMailer should be told when Mail gets delivered" do + BaseMailer.expects(:delivered_email).once + email = BaseMailer.deliver_welcome + end + + # test "ActionMailer should be told when Mail gets delivered using new API" do + # BaseMailer.expects(:delivered_email).once + # email = BaseMailer.welcome.deliver + # end protected diff --git a/actionmailer/test/mail_helper_test.rb b/actionmailer/test/mail_helper_test.rb index 2d3565d159..d81bc57ce0 100644 --- a/actionmailer/test/mail_helper_test.rb +++ b/actionmailer/test/mail_helper_test.rb @@ -63,7 +63,7 @@ class MailerHelperTest < Test::Unit::TestCase def setup set_delivery_method :test ActionMailer::Base.perform_deliveries = true - ActionMailer::Base.deliveries = [] + ActionMailer::Base.deliveries.clear @recipient = 'test@localhost' end diff --git a/actionmailer/test/mail_layout_test.rb b/actionmailer/test/mail_layout_test.rb index b9ff075461..b4bd583616 100644 --- a/actionmailer/test/mail_layout_test.rb +++ b/actionmailer/test/mail_layout_test.rb @@ -55,7 +55,7 @@ class LayoutMailerTest < Test::Unit::TestCase def setup set_delivery_method :test ActionMailer::Base.perform_deliveries = true - ActionMailer::Base.deliveries = [] + ActionMailer::Base.deliveries.clear @recipient = 'test@localhost' end diff --git a/actionmailer/test/mail_render_test.rb b/actionmailer/test/mail_render_test.rb index 09ce5e4854..3424823c99 100644 --- a/actionmailer/test/mail_render_test.rb +++ b/actionmailer/test/mail_render_test.rb @@ -86,7 +86,7 @@ class RenderHelperTest < Test::Unit::TestCase def setup set_delivery_method :test ActionMailer::Base.perform_deliveries = true - ActionMailer::Base.deliveries = [] + ActionMailer::Base.deliveries.clear @recipient = 'test@localhost' end @@ -135,7 +135,7 @@ class FirstSecondHelperTest < Test::Unit::TestCase def setup set_delivery_method :test ActionMailer::Base.perform_deliveries = true - ActionMailer::Base.deliveries = [] + ActionMailer::Base.deliveries.clear @recipient = 'test@localhost' end diff --git a/actionmailer/test/mail_service_test.rb b/actionmailer/test/mail_service_test.rb index 62422fb4b3..df5afda447 100644 --- a/actionmailer/test/mail_service_test.rb +++ b/actionmailer/test/mail_service_test.rb @@ -337,7 +337,7 @@ class ActionMailerTest < Test::Unit::TestCase set_delivery_method :test ActionMailer::Base.perform_deliveries = true ActionMailer::Base.raise_delivery_errors = true - ActionMailer::Base.deliveries = [] + ActionMailer::Base.deliveries.clear @original_logger = TestMailer.logger @recipient = 'test@localhost' @@ -658,7 +658,7 @@ class ActionMailerTest < Test::Unit::TestCase def test_doesnt_raise_errors_when_raise_delivery_errors_is_false ActionMailer::Base.raise_delivery_errors = false - Mail::Message.any_instance.expects(:deliver!).raises(Exception) + Mail::TestMailer.any_instance.expects(:deliver!).raises(Exception) assert_nothing_raised { TestMailer.deliver_signed_up(@recipient) } end @@ -1113,7 +1113,7 @@ class MethodNamingTest < Test::Unit::TestCase def setup set_delivery_method :test ActionMailer::Base.perform_deliveries = true - ActionMailer::Base.deliveries = [] + ActionMailer::Base.deliveries.clear end def teardown diff --git a/actionmailer/test/url_test.rb b/actionmailer/test/url_test.rb index 12bf609dce..b7ae5304ed 100644 --- a/actionmailer/test/url_test.rb +++ b/actionmailer/test/url_test.rb @@ -44,7 +44,7 @@ class ActionMailerUrlTest < Test::Unit::TestCase def setup set_delivery_method :test ActionMailer::Base.perform_deliveries = true - ActionMailer::Base.deliveries = [] + ActionMailer::Base.deliveries.clear @recipient = 'test@localhost' end -- cgit v1.2.3 From afc758297c553de467b0c434330cb703d62795f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Sun, 24 Jan 2010 12:30:13 +1100 Subject: Moving AS::Notifications call to one location in base --- actionmailer/lib/action_mailer/deprecated_api.rb | 16 +++++++--------- actionmailer/test/base_test.rb | 7 ++----- 2 files changed, 9 insertions(+), 14 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/deprecated_api.rb b/actionmailer/lib/action_mailer/deprecated_api.rb index a9ebd70f86..a2fa481d0e 100644 --- a/actionmailer/lib/action_mailer/deprecated_api.rb +++ b/actionmailer/lib/action_mailer/deprecated_api.rb @@ -83,19 +83,17 @@ module ActionMailer # email.set_some_obscure_header "frobnicate" # MyMailer.deliver(email) def deliver(mail) + return if @mail_was_called raise "no mail object available for delivery!" unless mail - ActiveSupport::Notifications.instrument("action_mailer.deliver", :mailer => self.name) do |payload| - self.set_payload_for_mail(payload, mail) + mail.register_for_delivery_notification(self) - mail.delivery_method delivery_methods[delivery_method], - delivery_settings[delivery_method] - - mail.raise_delivery_errors = raise_delivery_errors - mail.perform_deliveries = perform_deliveries - mail.deliver - end + mail.delivery_method delivery_methods[delivery_method], + delivery_settings[delivery_method] + mail.raise_delivery_errors = raise_delivery_errors + mail.perform_deliveries = perform_deliveries + mail.deliver mail end diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index 43a9fb29bb..0b650e9a28 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -325,15 +325,12 @@ class BaseTest < ActiveSupport::TestCase end test "ActionMailer should be told when Mail gets delivered" do + BaseMailer.deliveries.clear BaseMailer.expects(:delivered_email).once email = BaseMailer.deliver_welcome + assert_equal(1, BaseMailer.deliveries.length) end - # test "ActionMailer should be told when Mail gets delivered using new API" do - # BaseMailer.expects(:delivered_email).once - # email = BaseMailer.welcome.deliver - # end - protected # Execute the block setting the given values and restoring old values after -- cgit v1.2.3 From 73a9000402b5766e660dbf3489f5289c21c3f472 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Sun, 24 Jan 2010 20:38:53 +1100 Subject: Adding failing tests for calling just the action, instead of :create_action_name and :deliver_action_name --- actionmailer/lib/action_mailer/base.rb | 4 +++- actionmailer/test/base_test.rb | 16 +++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index c1dc415728..e7eb6bffcd 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -387,7 +387,8 @@ module ActionMailer #:nodoc: process(method_name, *args) if method_name end - # TODO Add new delivery method goodness + # TODO: Clean this up and refactor before Rails 3.0 release. + # This works for now, but not neat def mail(headers = {}) # Guard flag to prevent both the old and the new API from firing # Should be removed when old API is deprecated @@ -446,6 +447,7 @@ module ActionMailer #:nodoc: I18n.t(:subject, :scope => [:actionmailer, mailer_scope, action_name], :default => action_name.humanize) end + # TODO: Move this into Mail def quote_fields(m, headers, charset) #:nodoc: m.subject ||= quote_if_necessary(headers[:subject], charset) if headers[:subject] m.to ||= quote_address_if_necessary(headers[:to], charset) if headers[:to] diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index 0b650e9a28..7f41f3485c 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -327,7 +327,21 @@ class BaseTest < ActiveSupport::TestCase test "ActionMailer should be told when Mail gets delivered" do BaseMailer.deliveries.clear BaseMailer.expects(:delivered_email).once - email = BaseMailer.deliver_welcome + BaseMailer.deliver_welcome + assert_equal(1, BaseMailer.deliveries.length) + end + + test "Calling just the action should return the generated mail object" do + BaseMailer.deliveries.clear + email = BaseMailer.welcome + assert_equal(0, BaseMailer.deliveries.length) + assert_equal('The first email on new API!', email.subject) + end + + test "Calling deliver on the action should deliver the mail object" do + BaseMailer.deliveries.clear + BaseMailer.expects(:delivered_email).once + BaseMailer.welcome.deliver assert_equal(1, BaseMailer.deliveries.length) end -- cgit v1.2.3 From e548f96b1d5cb6529dd6fbc6544f03a3a840b48c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sun, 24 Jan 2010 12:23:21 +0100 Subject: Rename plugin_name to railtie_name and engine_name. --- actionmailer/lib/action_mailer/railtie.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/railtie.rb b/actionmailer/lib/action_mailer/railtie.rb index ac6f514dfa..fbbcf98854 100644 --- a/actionmailer/lib/action_mailer/railtie.rb +++ b/actionmailer/lib/action_mailer/railtie.rb @@ -3,7 +3,7 @@ require "rails" module ActionMailer class Railtie < Rails::Railtie - plugin_name :action_mailer + railtie_name :action_mailer require "action_mailer/railties/subscriber" subscriber ActionMailer::Railties::Subscriber.new -- cgit v1.2.3 From 6545a68264682e8d0a0ee0e913fa98d92fef9428 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sun, 24 Jan 2010 15:08:06 +0100 Subject: Fix failing tests after merge. --- actionmailer/lib/action_mailer/mail_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/mail_helper.rb b/actionmailer/lib/action_mailer/mail_helper.rb index 701dc34431..df71330fd5 100644 --- a/actionmailer/lib/action_mailer/mail_helper.rb +++ b/actionmailer/lib/action_mailer/mail_helper.rb @@ -18,7 +18,7 @@ module ActionMailer # Access the mailer instance. def mailer #:nodoc: - @controller + @_controller end end end -- cgit v1.2.3 From 7409b734841c8bd691006634dd072212aa905cf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Sun, 24 Jan 2010 16:37:28 +0100 Subject: Some refactoring. --- actionmailer/lib/action_mailer/base.rb | 164 ++++++++++++--------- actionmailer/lib/action_mailer/delivery_methods.rb | 92 ++++++------ actionmailer/lib/action_mailer/deprecated_api.rb | 66 ++++----- actionmailer/lib/action_mailer/tmail_compat.rb | 6 +- 4 files changed, 164 insertions(+), 164 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index e7eb6bffcd..b881611cfb 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -263,33 +263,42 @@ module ActionMailer #:nodoc: include AbstractController::UrlFor helper ActionMailer::MailHelper + include ActionMailer::DeprecatedApi + extend ActionMailer::DeliveryMethods + + add_delivery_method :smtp, Mail::SMTP, + :address => "localhost", + :port => 25, + :domain => 'localhost.localdomain', + :user_name => nil, + :password => nil, + :authentication => nil, + :enable_starttls_auto => true + + add_delivery_method :file, Mail::FileDelivery, + :location => defined?(Rails.root) ? "#{Rails.root}/tmp/mails" : "#{Dir.tmpdir}/mails" + + add_delivery_method :sendmail, Mail::Sendmail, + :location => '/usr/sbin/sendmail', + :arguments => '-i -t' - include ActionMailer::DeliveryMethods + add_delivery_method :test, Mail::TestMailer + + superclass_delegating_reader :delivery_method + self.delivery_method = :smtp private_class_method :new #:nodoc: - @@raise_delivery_errors = true cattr_accessor :raise_delivery_errors + @@raise_delivery_errors = true - @@perform_deliveries = true cattr_accessor :perform_deliveries - - # Provides a list of emails that have been delivered by Mail - def self.deliveries - Mail.deliveries - end - - # Allows you to over write the default deliveries store from an array to some - # other object. If you just want to clear the store, call Mail.deliveries.clear. - def self.deliveries=(val) - Mail.deliveries = val - end + @@perform_deliveries = true extlib_inheritable_accessor :default_charset self.default_charset = "utf-8" - # TODO This should be used when calling render extlib_inheritable_accessor :default_content_type self.default_content_type = "text/plain" @@ -305,24 +314,9 @@ module ActionMailer #:nodoc: extlib_inheritable_accessor :default_implicit_parts_order self.default_implicit_parts_order = [ "text/plain", "text/enriched", "text/html" ] - # Expose the internal Mail message - # TODO: Make this an _internal ivar? - attr_reader :message - - def headers(args=nil) - if args - ActiveSupport::Deprecation.warn "headers(Hash) is deprecated, please do headers[key] = value instead", caller - @headers = args - else - @message - end - end - - def attachments - @message.attachments - end - class << self + # Provides a list of emails that have been delivered by Mail + delegate :deliveries, :deliveries=, :to => Mail def mailer_name @mailer_name ||= name.underscore @@ -359,6 +353,7 @@ module ActionMailer #:nodoc: self.view_paths = ActionView::Base.process_view_paths(root) end + # TODO The delivery should happen inside the instrument block def delivered_email(mail) ActiveSupport::Notifications.instrument("action_mailer.deliver", :mailer => self.name) do |payload| self.set_payload_for_mail(payload, mail) @@ -377,66 +372,63 @@ module ActionMailer #:nodoc: end end + attr_internal :message + # Instantiate a new mailer object. If +method_name+ is not +nil+, the mailer # will be initialized according to the named method. If not, the mailer will # remain uninitialized (useful when you only need to invoke the "receive" # method, for instance). def initialize(method_name=nil, *args) super() - @message = Mail.new + @_message = Mail.new process(method_name, *args) if method_name end - # TODO: Clean this up and refactor before Rails 3.0 release. - # This works for now, but not neat - def mail(headers = {}) - # Guard flag to prevent both the old and the new API from firing - # Should be removed when old API is deprecated - @mail_was_called = true + def headers(args=nil) + if args + ActiveSupport::Deprecation.warn "headers(Hash) is deprecated, please do headers[key] = value instead", caller[0,2] + @headers = args + else + @_message + end + end - m = @message + def attachments + @_message.attachments + end - m.register_for_delivery_notification(self.class) + def mail(headers={}, &block) + # Guard flag to prevent both the old and the new API from firing + # Should be removed when old API is removed + @mail_was_called = true + m = @_message # Give preference to headers and fallback to the ones set in mail content_type = headers[:content_type] || m.content_type charset = headers[:charset] || m.charset || self.class.default_charset.dup mime_version = headers[:mime_version] || m.mime_version || self.class.default_mime_version.dup + # Set subjects and fields quotings headers[:subject] ||= default_subject - quote_fields(m, headers, charset) - - sort_order = headers[:parts_order] || self.class.default_implicit_parts_order.dup - - responses = if headers[:body] - [ { :body => headers[:body], :content_type => self.class.default_content_type.dup } ] - elsif block_given? - collector = ActionMailer::Collector.new(self) { render(action_name) } - yield(collector) - # Collect the sort order of the parts from the collector as Mail will always - # sort parts on encode into a "sane" sequence. - sort_order = collector.responses.map { |r| r[:content_type] } - collector.responses - else - # TODO Ensure that we don't need to pass I18n.locale as detail - templates = self.class.template_root.find_all(action_name, {}, self.class.mailer_name) - - templates.map do |template| - { :body => render_to_body(:_template => template), - :content_type => template.mime_type.to_s } - end - end + quote_fields!(headers, charset) + # Render the templates and blocks + responses, sort_order = collect_responses_and_sort_order(headers, &block) content_type ||= create_parts_from_responses(m, responses, charset) + + # Tidy up content type, charset, mime version and sort order m.content_type = content_type m.charset = charset m.mime_version = mime_version + sort_order = headers[:parts_order] || sort_order || self.class.default_implicit_parts_order.dup if m.multipart? m.body.set_sort_order(sort_order) m.body.sort_parts! end + # Finaly set delivery behavior configured in class + wrap_delivery_behavior!(headers[:delivery_method]) m end @@ -448,14 +440,44 @@ module ActionMailer #:nodoc: end # TODO: Move this into Mail - def quote_fields(m, headers, charset) #:nodoc: - m.subject ||= quote_if_necessary(headers[:subject], charset) if headers[:subject] - m.to ||= quote_address_if_necessary(headers[:to], charset) if headers[:to] - m.from ||= quote_address_if_necessary(headers[:from], charset) if headers[:from] - m.cc ||= quote_address_if_necessary(headers[:cc], charset) if headers[:cc] - m.bcc ||= quote_address_if_necessary(headers[:bcc], charset) if headers[:bcc] - m.reply_to ||= quote_address_if_necessary(headers[:reply_to], charset) if headers[:reply_to] - m.date ||= headers[:date] if headers[:date] + def quote_fields!(headers, charset) #:nodoc: + m = @_message + m.subject ||= quote_if_necessary(headers[:subject], charset) if headers[:subject] + m.to ||= quote_address_if_necessary(headers[:to], charset) if headers[:to] + m.from ||= quote_address_if_necessary(headers[:from], charset) if headers[:from] + m.cc ||= quote_address_if_necessary(headers[:cc], charset) if headers[:cc] + m.bcc ||= quote_address_if_necessary(headers[:bcc], charset) if headers[:bcc] + m.reply_to ||= quote_address_if_necessary(headers[:reply_to], charset) if headers[:reply_to] + m.date ||= headers[:date] if headers[:date] + end + + def collect_responses_and_sort_order(headers) #:nodoc: + responses, sort_order = [], nil + + if block_given? + collector = ActionMailer::Collector.new(self) { render(action_name) } + yield(collector) + sort_order = collector.responses.map { |r| r[:content_type] } + responses = collector.responses + elsif headers[:body] + responses << { + :body => headers[:body], + :content_type => self.class.default_content_type.dup + } + else + self.class.template_root.find_all(action_name, {}, self.class.mailer_name).each do |template| + responses << { + :body => render_to_body(:_template => template), + :content_type => template.mime_type.to_s + } + end + end + + [responses, sort_order] + end + + def wrap_delivery_behavior!(method=nil) #:nodoc: + self.class.wrap_delivery_behavior(@_message, method) end def create_parts_from_responses(m, responses, charset) #:nodoc: diff --git a/actionmailer/lib/action_mailer/delivery_methods.rb b/actionmailer/lib/action_mailer/delivery_methods.rb index 5883e446f2..16b84d4118 100644 --- a/actionmailer/lib/action_mailer/delivery_methods.rb +++ b/actionmailer/lib/action_mailer/delivery_methods.rb @@ -1,73 +1,63 @@ module ActionMailer # This modules makes a DSL for adding delivery methods to ActionMailer module DeliveryMethods - extend ActiveSupport::Concern - - included do - add_delivery_method :smtp, Mail::SMTP, - :address => "localhost", - :port => 25, - :domain => 'localhost.localdomain', - :user_name => nil, - :password => nil, - :authentication => nil, - :enable_starttls_auto => true - - add_delivery_method :file, Mail::FileDelivery, - :location => defined?(Rails.root) ? "#{Rails.root}/tmp/mails" : "#{Dir.tmpdir}/mails" + # TODO Make me class inheritable + def delivery_settings + @@delivery_settings ||= Hash.new { |h,k| h[k] = {} } + end - add_delivery_method :sendmail, Mail::Sendmail, - :location => '/usr/sbin/sendmail', - :arguments => '-i -t' + def delivery_methods + @@delivery_methods ||= {} + end - add_delivery_method :test, Mail::TestMailer + def delivery_method=(method) + raise ArgumentError, "Unknown delivery method #{method.inspect}" unless delivery_methods[method] + @delivery_method = method + end - superclass_delegating_reader :delivery_method - self.delivery_method = :smtp + def add_delivery_method(symbol, klass, default_options={}) + self.delivery_methods[symbol] = klass + self.delivery_settings[symbol] = default_options end - module ClassMethods - # TODO Make me class inheritable - def delivery_settings - @@delivery_settings ||= Hash.new { |h,k| h[k] = {} } - end + def wrap_delivery_behavior(mail, method=nil) + method ||= delivery_method - def delivery_methods - @@delivery_methods ||= {} - end + mail.register_for_delivery_notification(self) - def delivery_method=(method) - raise ArgumentError, "Unknown delivery method #{method.inspect}" unless delivery_methods[method] - @delivery_method = method + if method.is_a?(Symbol) + mail.delivery_method(delivery_methods[method], + delivery_settings[method]) + else + mail.delivery_method(method) end - def add_delivery_method(symbol, klass, default_options={}) - self.delivery_methods[symbol] = klass - self.delivery_settings[symbol] = default_options - end + mail.perform_deliveries = perform_deliveries + mail.raise_delivery_errors = raise_delivery_errors + end - def respond_to?(method_symbol, include_private = false) #:nodoc: - matches_settings_method?(method_symbol) || super - end - protected + def respond_to?(method_symbol, include_private = false) #:nodoc: + matches_settings_method?(method_symbol) || super + end - # TODO Get rid of this method missing magic - def method_missing(method_symbol, *parameters) #:nodoc: - if match = matches_settings_method?(method_symbol) - if match[2] - delivery_settings[match[1].to_sym] = parameters[0] - else - delivery_settings[match[1].to_sym] - end + protected + + # TODO Get rid of this method missing magic + def method_missing(method_symbol, *parameters) #:nodoc: + if match = matches_settings_method?(method_symbol) + if match[2] + delivery_settings[match[1].to_sym] = parameters[0] else - super + delivery_settings[match[1].to_sym] end + else + super end + end - def matches_settings_method?(method_name) #:nodoc: - /(#{delivery_methods.keys.join('|')})_settings(=)?$/.match(method_name.to_s) - end + def matches_settings_method?(method_name) #:nodoc: + /(#{delivery_methods.keys.join('|')})_settings(=)?$/.match(method_name.to_s) end end end \ No newline at end of file diff --git a/actionmailer/lib/action_mailer/deprecated_api.rb b/actionmailer/lib/action_mailer/deprecated_api.rb index a2fa481d0e..f969584a17 100644 --- a/actionmailer/lib/action_mailer/deprecated_api.rb +++ b/actionmailer/lib/action_mailer/deprecated_api.rb @@ -71,7 +71,6 @@ module ActionMailer # Alias controller_path to mailer_name so render :partial in views work. alias :controller_path :mailer_name - end module ClassMethods @@ -82,17 +81,14 @@ module ActionMailer # email = MyMailer.create_some_mail(parameters) # email.set_some_obscure_header "frobnicate" # MyMailer.deliver(email) - def deliver(mail) - return if @mail_was_called - raise "no mail object available for delivery!" unless mail - - mail.register_for_delivery_notification(self) - - mail.delivery_method delivery_methods[delivery_method], - delivery_settings[delivery_method] + def deliver(mail, show_warning=true) + if show_warning + ActiveSupport::Deprecation.warn "ActionMailer::Base.deliver is deprecated, just call " << + "deliver in the instance instead", caller + end - mail.raise_delivery_errors = raise_delivery_errors - mail.perform_deliveries = perform_deliveries + raise "no mail object available for delivery!" unless mail + wrap_delivery_behavior(mail) mail.deliver mail end @@ -122,23 +118,19 @@ module ActionMailer end end - def initialize(*) - super() - @mail_was_called = false - end - # Delivers a Mail object. By default, it delivers the cached mail # object (from the create! method). If no cached mail object exists, and # no alternate has been given as the parameter, this will fail. - def deliver!(mail = @message) - self.class.deliver(mail) + def deliver!(mail = @_message) + self.class.deliver(mail, false) end + alias :deliver :deliver! def render(*args) options = args.last.is_a?(Hash) ? args.last : {} if options[:body] - ActiveSupport::Deprecation.warn(':body in render deprecated. Please call body ' << - 'with a hash instead', caller[0,1]) + ActiveSupport::Deprecation.warn(':body in render deprecated. Please use instance ' << + 'variables as assigns instead', caller[0,1]) body options.delete(:body) end @@ -153,7 +145,7 @@ module ActionMailer create_parts create_mail end - @message + @_message end # Add a part to a multipart message, with the given content-type. The @@ -175,6 +167,7 @@ module ActionMailer # Add an attachment to a multipart message. This is simply a part with the # content-disposition set to "attachment". def attachment(params, &block) + ActiveSupport::Deprecation.warn "attachment is deprecated, please use the attachments API instead", caller[0,2] params = { :content_type => params } if String === params params[:content] ||= params.delete(:data) || params.delete(:body) @@ -197,13 +190,9 @@ module ActionMailer # render_message :template => "special_message" # render_message :inline => "<%= 'Hi!' %>" # - def render_message(object) - case object - when String - render_to_body(:template => object) - else - render_to_body(object) - end + def render_message(*args) + ActiveSupport::Deprecation.warn "render_message is deprecated, use render instead", caller[0,2] + render(*args) end private @@ -240,14 +229,12 @@ module ActionMailer end def create_mail #:nodoc: - m = @message - - m.subject, = quote_any_if_necessary(charset, subject) - m.to, m.from = quote_any_address_if_necessary(charset, recipients, from) - m.bcc = quote_address_if_necessary(bcc, charset) unless bcc.nil? - m.cc = quote_address_if_necessary(cc, charset) unless cc.nil? - m.reply_to = quote_address_if_necessary(reply_to, charset) unless reply_to.nil? - m.mime_version = mime_version unless mime_version.nil? + m = @_message + + quote_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 @headers.each { |k, v| m[k] = v } @@ -274,7 +261,7 @@ module ActionMailer m.content_transfer_encoding = '8bit' unless m.body.only_us_ascii? - @message + @_message end # Set up the default values for the various instance variables of this @@ -286,8 +273,9 @@ module ActionMailer @implicit_parts_order ||= self.class.default_implicit_parts_order.dup @mime_version ||= self.class.default_mime_version.dup if self.class.default_mime_version - @mailer_name ||= self.class.mailer_name.dup - @template ||= method_name + @mailer_name ||= self.class.mailer_name.dup + @template ||= method_name + @mail_was_called = false @parts ||= [] @headers ||= {} diff --git a/actionmailer/lib/action_mailer/tmail_compat.rb b/actionmailer/lib/action_mailer/tmail_compat.rb index d78332c135..c6efdc53b6 100644 --- a/actionmailer/lib/action_mailer/tmail_compat.rb +++ b/actionmailer/lib/action_mailer/tmail_compat.rb @@ -3,7 +3,7 @@ module Mail def set_content_type(*args) ActiveSupport::Deprecation.warn('Message#set_content_type is deprecated, please just call ' << - 'Message#content_type with the same arguments', caller[0,10]) + 'Message#content_type with the same arguments', caller[0,2]) content_type(*args) end @@ -11,7 +11,7 @@ module Mail def transfer_encoding(value = nil) if value ActiveSupport::Deprecation.warn('Message#transfer_encoding is deprecated, please call ' << - 'Message#content_transfer_encoding with the same arguments', caller[0,10]) + 'Message#content_transfer_encoding with the same arguments', caller[0,2]) content_transfer_encoding(value) else old_transfer_encoding @@ -20,7 +20,7 @@ module Mail def original_filename ActiveSupport::Deprecation.warn('Message#original_filename is deprecated, ' << - 'please call Message#filename', caller[0,10]) + 'please call Message#filename', caller[0,2]) filename end -- cgit v1.2.3 From f30d73bab4c676b187276797ac2a6dc89132c43f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Sun, 24 Jan 2010 17:31:18 +0100 Subject: Add new class delivery method API. --- actionmailer/lib/action_mailer/base.rb | 18 ++- actionmailer/lib/action_mailer/deprecated_api.rb | 25 ++-- actionmailer/test/asset_host_test.rb | 12 +- actionmailer/test/base_test.rb | 135 +++++++++------------ actionmailer/test/mail_helper_test.rb | 28 ++--- actionmailer/test/mail_layout_test.rb | 42 +++---- actionmailer/test/mail_render_test.rb | 62 +++++----- actionmailer/test/mail_service_test.rb | 148 +++++++++++------------ actionmailer/test/subscriber_test.rb | 18 +-- actionmailer/test/test_helper_test.rb | 24 ++-- actionmailer/test/tmail_compat_test.rb | 14 ++- actionmailer/test/url_test.rb | 4 +- 12 files changed, 259 insertions(+), 271 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index b881611cfb..8e30c54c49 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -253,6 +253,8 @@ module ActionMailer #:nodoc: # and appear last in the mime encoded message. You can also pick a different order from inside a method with # +implicit_parts_order+. class Base < AbstractController::Base + abstract! + include Quoting include AbstractController::Logger @@ -264,8 +266,8 @@ module ActionMailer #:nodoc: helper ActionMailer::MailHelper - include ActionMailer::DeprecatedApi extend ActionMailer::DeliveryMethods + include ActionMailer::DeprecatedApi add_delivery_method :smtp, Mail::SMTP, :address => "localhost", @@ -370,6 +372,20 @@ module ActionMailer #:nodoc: payload[:date] = mail.date payload[:mail] = mail.encoded end + + def respond_to?(method, *args) + super || action_methods.include?(method.to_s) + end + + protected + + def method_missing(method, *args) + if action_methods.include?(method.to_s) + new(method, *args).message + else + super + end + end end attr_internal :message diff --git a/actionmailer/lib/action_mailer/deprecated_api.rb b/actionmailer/lib/action_mailer/deprecated_api.rb index f969584a17..f36b1befd6 100644 --- a/actionmailer/lib/action_mailer/deprecated_api.rb +++ b/actionmailer/lib/action_mailer/deprecated_api.rb @@ -1,8 +1,8 @@ module ActionMailer - # TODO Remove this module all together in Rails 3.1. Ensure that super - # hooks in ActionMailer::Base are removed as well. - # - # Moved here to allow us to add the new Mail API + # Part of this API is deprecated and is going to be removed in Rails 3.1 (just check + # the methods which give you a warning). + # All the rest will be deprecated after 3.1 release instead, this allows a smoother + # migration path. module DeprecatedApi #:nodoc: extend ActiveSupport::Concern @@ -83,8 +83,8 @@ module ActionMailer # MyMailer.deliver(email) def deliver(mail, show_warning=true) if show_warning - ActiveSupport::Deprecation.warn "ActionMailer::Base.deliver is deprecated, just call " << - "deliver in the instance instead", caller + ActiveSupport::Deprecation.warn "#{self}.deliver is deprecated, call " << + "deliver in the mailer instance instead", caller[0,2] end raise "no mail object available for delivery!" unless mail @@ -100,9 +100,14 @@ module ActionMailer def method_missing(method_symbol, *parameters) #:nodoc: if match = matches_dynamic_method?(method_symbol) case match[1] - when 'create' then new(match[2], *parameters).message - when 'deliver' then new(match[2], *parameters).deliver! - when 'new' then nil + when 'create' + ActiveSupport::Deprecation.warn "#{self}.create_#{match[2]} is deprecated, " << + "use #{self}.#{match[2]} instead", caller[0,2] + new(match[2], *parameters).message + when 'deliver' + ActiveSupport::Deprecation.warn "#{self}.deliver_#{match[2]} is deprecated, " << + "use #{self}.#{match[2]}.deliver instead", caller[0,2] + new(match[2], *parameters).deliver else super end else @@ -167,7 +172,6 @@ module ActionMailer # Add an attachment to a multipart message. This is simply a part with the # content-disposition set to "attachment". def attachment(params, &block) - ActiveSupport::Deprecation.warn "attachment is deprecated, please use the attachments API instead", caller[0,2] params = { :content_type => params } if String === params params[:content] ||= params.delete(:data) || params.delete(:body) @@ -259,6 +263,7 @@ module ActionMailer end end + wrap_delivery_behavior! m.content_transfer_encoding = '8bit' unless m.body.only_us_ascii? @_message diff --git a/actionmailer/test/asset_host_test.rb b/actionmailer/test/asset_host_test.rb index 7ba78b6daa..124032f1d9 100644 --- a/actionmailer/test/asset_host_test.rb +++ b/actionmailer/test/asset_host_test.rb @@ -1,8 +1,8 @@ require 'abstract_unit' class AssetHostMailer < ActionMailer::Base - def email_with_asset(recipient) - recipients recipient + def email_with_asset + recipients 'test@localhost' subject "testing email containing asset path while asset_host is set" from "tester@example.com" end @@ -13,8 +13,6 @@ class AssetHostTest < Test::Unit::TestCase set_delivery_method :test ActionMailer::Base.perform_deliveries = true ActionMailer::Base.deliveries.clear - - @recipient = 'test@localhost' end def teardown @@ -23,7 +21,7 @@ class AssetHostTest < Test::Unit::TestCase def test_asset_host_as_string ActionController::Base.asset_host = "http://www.example.com" - mail = AssetHostMailer.deliver_email_with_asset(@recipient) + mail = AssetHostMailer.email_with_asset assert_equal "\"Somelogo\"", mail.body.to_s.strip end @@ -35,7 +33,7 @@ class AssetHostTest < Test::Unit::TestCase "http://assets.example.com" end } - mail = AssetHostMailer.deliver_email_with_asset(@recipient) + mail = AssetHostMailer.email_with_asset assert_equal "\"Somelogo\"", mail.body.to_s.strip end @@ -48,7 +46,7 @@ class AssetHostTest < Test::Unit::TestCase end } mail = nil - assert_nothing_raised { mail = AssetHostMailer.deliver_email_with_asset(@recipient) } + assert_nothing_raised { mail = AssetHostMailer.email_with_asset } assert_equal "\"Somelogo\"", mail.body.to_s.strip end end \ No newline at end of file diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index 7f41f3485c..3b2a072dce 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -3,40 +3,6 @@ require 'abstract_unit' # class Notifier < ActionMailer::Base # delivers_from 'notifications@example.com' -# -# def welcome(user) -# @user = user # available to the view -# mail(:subject => 'Welcome!', :to => user.email_address) -# # auto renders both welcome.text.erb and welcome.html.erb -# end -# -# def goodbye(user) -# headers["X-SPAM"] = 'Not-SPAM' -# mail(:subject => 'Goodbye', :to => user.email_address) do |format| -# format.html { render "shared_template "} -# format.text # goodbye.text.erb -# end -# end -# -# def surprise(user, gift) -# attachments[gift.name] = File.read(gift.path) -# mail(:subject => 'Surprise!', :to => user.email_address) do |format| -# format.html(:charset => "ascii") # surprise.html.erb -# format.text(:transfer_encoding => "base64") # surprise.text.erb -# end -# end -# -# def special_surprise(user, gift) -# attachments[gift.name] = { :content_type => "application/x-gzip", :content => File.read(gift.path) } -# mail(:to => 'special@example.com') # subject not required -# # auto renders both special_surprise.text.erb and special_surprise.html.erb -# end -# end -# -# mail = Notifier.welcome(user) # => returns a Mail object -# mail.deliver -# -# Notifier.welcome(user).deliver # => creates and sends the Mail in one step class BaseTest < ActiveSupport::TestCase DEFAULT_HEADERS = { :to => 'mikel@test.lindsaar.net', @@ -44,8 +10,6 @@ class BaseTest < ActiveSupport::TestCase :subject => 'The first email on new API!' } - # TODO Think on the simple case where I want to send an e-mail - # with attachment and small text (without need to add a template). class BaseMailer < ActionMailer::Base self.mailer_name = "base_mailer" @@ -60,7 +24,7 @@ class BaseTest < ActiveSupport::TestCase end def attachment_with_hash - attachments['invoice.jpg'] = { :content => "you smiling", :mime_type => "image/x-jpg", + attachments['invoice.jpg'] = { :data => "you smiling", :mime_type => "image/x-jpg", :transfer_encoding => "base64" } mail(DEFAULT_HEADERS) end @@ -93,12 +57,12 @@ class BaseTest < ActiveSupport::TestCase end test "method call to mail does not raise error" do - assert_nothing_raised { BaseMailer.deliver_welcome } + assert_nothing_raised { BaseMailer.welcome.deliver } end # Basic mail usage without block test "mail() should set the headers of the mail message" do - email = BaseMailer.deliver_welcome + email = BaseMailer.welcome.deliver assert_equal(email.to, ['mikel@test.lindsaar.net']) assert_equal(email.from, ['jose@test.plataformatec.com']) assert_equal(email.subject, 'The first email on new API!') @@ -106,13 +70,13 @@ class BaseTest < ActiveSupport::TestCase test "mail() with bcc, cc, content_type, charset, mime_version, reply_to and date" do @time = Time.now - email = BaseMailer.deliver_welcome(:bcc => 'bcc@test.lindsaar.net', - :cc => 'cc@test.lindsaar.net', - :content_type => 'multipart/mixed', - :charset => 'iso-8559-1', - :mime_version => '2.0', - :reply_to => 'reply-to@test.lindsaar.net', - :date => @time) + email = BaseMailer.welcome(:bcc => 'bcc@test.lindsaar.net', + :cc => 'cc@test.lindsaar.net', + :content_type => 'multipart/mixed', + :charset => 'iso-8559-1', + :mime_version => '2.0', + :reply_to => 'reply-to@test.lindsaar.net', + :date => @time).deliver assert_equal(email.bcc, ['bcc@test.lindsaar.net']) assert_equal(email.cc, ['cc@test.lindsaar.net']) assert_equal(email.content_type, 'multipart/mixed') @@ -123,50 +87,50 @@ class BaseTest < ActiveSupport::TestCase end test "mail() renders the template using the method being processed" do - email = BaseMailer.deliver_welcome + email = BaseMailer.welcome.deliver assert_equal("Welcome", email.body.encoded) end test "can pass in :body to the mail method hash" do - email = BaseMailer.deliver_welcome(:body => "Hello there") + email = BaseMailer.welcome(:body => "Hello there").deliver assert_equal("text/plain", email.mime_type) assert_equal("Hello there", email.body.encoded) end # Custom headers test "custom headers" do - email = BaseMailer.deliver_welcome + email = BaseMailer.welcome.deliver assert_equal("Not SPAM", email['X-SPAM'].decoded) end # Attachments test "attachment with content" do - email = BaseMailer.deliver_attachment_with_content + email = BaseMailer.attachment_with_content.deliver assert_equal(1, email.attachments.length) assert_equal('invoice.pdf', email.attachments[0].filename) assert_equal('This is test File content', email.attachments['invoice.pdf'].decoded) end test "attachment gets content type from filename" do - email = BaseMailer.deliver_attachment_with_content + email = BaseMailer.attachment_with_content.deliver assert_equal('invoice.pdf', email.attachments[0].filename) end test "attachment with hash" do - email = BaseMailer.deliver_attachment_with_hash + email = BaseMailer.attachment_with_hash.deliver assert_equal(1, email.attachments.length) assert_equal('invoice.jpg', email.attachments[0].filename) assert_equal("\312\213\254\232)b", email.attachments['invoice.jpg'].decoded) end test "sets mime type to multipart/mixed when attachment is included" do - email = BaseMailer.deliver_attachment_with_content + email = BaseMailer.attachment_with_content.deliver assert_equal(1, email.attachments.length) assert_equal("multipart/mixed", email.mime_type) end test "adds the rendered template as part" do - email = BaseMailer.deliver_attachment_with_content + email = BaseMailer.attachment_with_content.deliver assert_equal(2, email.parts.length) assert_equal("multipart/mixed", email.mime_type) assert_equal("text/html", email.parts[0].mime_type) @@ -176,7 +140,7 @@ class BaseTest < ActiveSupport::TestCase end test "adds the given :body as part" do - email = BaseMailer.deliver_attachment_with_content(:body => "I'm the eggman") + email = BaseMailer.attachment_with_content(:body => "I'm the eggman").deliver assert_equal(2, email.parts.length) assert_equal("multipart/mixed", email.mime_type) assert_equal("text/plain", email.parts[0].mime_type) @@ -188,46 +152,46 @@ class BaseTest < ActiveSupport::TestCase # Defaults values test "uses default charset from class" do swap BaseMailer, :default_charset => "US-ASCII" do - email = BaseMailer.deliver_welcome + email = BaseMailer.welcome.deliver assert_equal("US-ASCII", email.charset) - email = BaseMailer.deliver_welcome(:charset => "iso-8559-1") + email = BaseMailer.welcome(:charset => "iso-8559-1").deliver assert_equal("iso-8559-1", email.charset) end end test "uses default content type from class" do swap BaseMailer, :default_content_type => "text/html" do - email = BaseMailer.deliver_welcome + email = BaseMailer.welcome.deliver assert_equal("text/html", email.mime_type) - email = BaseMailer.deliver_welcome(:content_type => "text/plain") + email = BaseMailer.welcome(:content_type => "text/plain").deliver assert_equal("text/plain", email.mime_type) end end test "uses default mime version from class" do swap BaseMailer, :default_mime_version => "2.0" do - email = BaseMailer.deliver_welcome + email = BaseMailer.welcome.deliver assert_equal("2.0", email.mime_version) - email = BaseMailer.deliver_welcome(:mime_version => "1.0") + email = BaseMailer.welcome(:mime_version => "1.0").deliver assert_equal("1.0", email.mime_version) end end test "subject gets default from I18n" do - email = BaseMailer.deliver_welcome(:subject => nil) + email = BaseMailer.welcome(:subject => nil).deliver assert_equal "Welcome", email.subject I18n.backend.store_translations('en', :actionmailer => {:base_mailer => {:welcome => {:subject => "New Subject!"}}}) - email = BaseMailer.deliver_welcome(:subject => nil) + email = BaseMailer.welcome(:subject => nil).deliver assert_equal "New Subject!", email.subject end # Implicit multipart test "implicit multipart" do - email = BaseMailer.deliver_implicit_multipart + email = BaseMailer.implicit_multipart.deliver assert_equal(2, email.parts.size) assert_equal("multipart/alternate", email.mime_type) assert_equal("text/plain", email.parts[0].mime_type) @@ -239,18 +203,18 @@ class BaseTest < ActiveSupport::TestCase test "implicit multipart with sort order" do order = ["text/html", "text/plain"] swap BaseMailer, :default_implicit_parts_order => order do - email = BaseMailer.deliver_implicit_multipart + email = BaseMailer.implicit_multipart.deliver assert_equal("text/html", email.parts[0].mime_type) assert_equal("text/plain", email.parts[1].mime_type) - email = BaseMailer.deliver_implicit_multipart(:parts_order => order.reverse) + email = BaseMailer.implicit_multipart(:parts_order => order.reverse).deliver assert_equal("text/plain", email.parts[0].mime_type) assert_equal("text/html", email.parts[1].mime_type) end end test "implicit multipart with attachments creates nested parts" do - email = BaseMailer.deliver_implicit_multipart(:attachments => true) + email = BaseMailer.implicit_multipart(:attachments => true).deliver assert_equal("application/pdf", email.parts[0].mime_type) assert_equal("multipart/alternate", email.parts[1].mime_type) assert_equal("text/plain", email.parts[1].parts[0].mime_type) @@ -262,7 +226,7 @@ class BaseTest < ActiveSupport::TestCase test "implicit multipart with attachments and sort order" do order = ["text/html", "text/plain"] swap BaseMailer, :default_implicit_parts_order => order do - email = BaseMailer.deliver_implicit_multipart(:attachments => true) + email = BaseMailer.implicit_multipart(:attachments => true).deliver assert_equal("application/pdf", email.parts[0].mime_type) assert_equal("multipart/alternate", email.parts[1].mime_type) assert_equal("text/plain", email.parts[1].parts[1].mime_type) @@ -272,7 +236,7 @@ class BaseTest < ActiveSupport::TestCase # Explicit multipart test "explicit multipart" do - email = BaseMailer.deliver_explicit_multipart + email = BaseMailer.explicit_multipart.deliver assert_equal(2, email.parts.size) assert_equal("multipart/alternate", email.mime_type) assert_equal("text/plain", email.parts[0].mime_type) @@ -284,18 +248,18 @@ class BaseTest < ActiveSupport::TestCase test "explicit multipart does not sort order" do order = ["text/html", "text/plain"] swap BaseMailer, :default_implicit_parts_order => order do - email = BaseMailer.deliver_explicit_multipart + email = BaseMailer.explicit_multipart.deliver assert_equal("text/plain", email.parts[0].mime_type) assert_equal("text/html", email.parts[1].mime_type) - email = BaseMailer.deliver_explicit_multipart(:parts_order => order.reverse) + email = BaseMailer.explicit_multipart(:parts_order => order.reverse).deliver assert_equal("text/plain", email.parts[0].mime_type) assert_equal("text/html", email.parts[1].mime_type) end end test "explicit multipart with attachments creates nested parts" do - email = BaseMailer.deliver_explicit_multipart(:attachments => true) + email = BaseMailer.explicit_multipart(:attachments => true).deliver assert_equal("application/pdf", email.parts[0].mime_type) assert_equal("multipart/alternate", email.parts[1].mime_type) assert_equal("text/plain", email.parts[1].parts[0].mime_type) @@ -305,7 +269,7 @@ class BaseTest < ActiveSupport::TestCase end test "explicit multipart with templates" do - email = BaseMailer.deliver_explicit_multipart_templates + email = BaseMailer.explicit_multipart_templates.deliver assert_equal(2, email.parts.size) assert_equal("multipart/alternate", email.mime_type) assert_equal("text/html", email.parts[0].mime_type) @@ -315,7 +279,7 @@ class BaseTest < ActiveSupport::TestCase end test "explicit multipart with any" do - email = BaseMailer.deliver_explicit_multipart_with_any + email = BaseMailer.explicit_multipart_with_any.deliver assert_equal(2, email.parts.size) assert_equal("multipart/alternate", email.mime_type) assert_equal("text/plain", email.parts[0].mime_type) @@ -324,21 +288,30 @@ class BaseTest < ActiveSupport::TestCase assert_equal("Format with any!", email.parts[1].body.encoded) end - test "ActionMailer should be told when Mail gets delivered" do - BaseMailer.deliveries.clear - BaseMailer.expects(:delivered_email).once - BaseMailer.deliver_welcome - assert_equal(1, BaseMailer.deliveries.length) + # Class level API with method missing + test "should respond to action methods" do + assert BaseMailer.respond_to?(:welcome) + assert BaseMailer.respond_to?(:implicit_multipart) + assert !BaseMailer.respond_to?(:mail) + assert !BaseMailer.respond_to?(:headers) end - test "Calling just the action should return the generated mail object" do + test "calling just the action should return the generated mail object" do BaseMailer.deliveries.clear email = BaseMailer.welcome assert_equal(0, BaseMailer.deliveries.length) assert_equal('The first email on new API!', email.subject) end - test "Calling deliver on the action should deliver the mail object" do + test "calling deliver on the action should deliver the mail object" do + BaseMailer.deliveries.clear + BaseMailer.expects(:delivered_email).once + BaseMailer.welcome.deliver + assert_equal(1, BaseMailer.deliveries.length) + end + + # Delivery hooks + test "ActionMailer should be told when Mail gets delivered" do BaseMailer.deliveries.clear BaseMailer.expects(:delivered_email).once BaseMailer.welcome.deliver diff --git a/actionmailer/test/mail_helper_test.rb b/actionmailer/test/mail_helper_test.rb index d81bc57ce0..a9b3cd3ce1 100644 --- a/actionmailer/test/mail_helper_test.rb +++ b/actionmailer/test/mail_helper_test.rb @@ -10,22 +10,22 @@ class HelperMailer < ActionMailer::Base helper MailerHelper helper :example - def use_helper(recipient) - recipients recipient + def use_helper + recipients 'test@localhost' subject "using helpers" from "tester@example.com" end - def use_example_helper(recipient) - recipients recipient + def use_example_helper + recipients 'test@localhost' subject "using helpers" from "tester@example.com" @text = "emphasize me!" end - def use_mail_helper(recipient) - recipients recipient + def use_mail_helper + recipients 'test@localhost' subject "using mailing helpers" from "tester@example.com" @@ -37,8 +37,8 @@ class HelperMailer < ActionMailer::Base "it off!" end - def use_helper_method(recipient) - recipients recipient + def use_helper_method + recipients 'test@localhost' subject "using helpers" from "tester@example.com" @@ -53,7 +53,7 @@ class HelperMailer < ActionMailer::Base helper_method :name_of_the_mailer_class end -class MailerHelperTest < Test::Unit::TestCase +class MailerHelperTest < ActiveSupport::TestCase def new_mail( charset="utf-8" ) mail = Mail.new mail.set_content_type "text", "plain", { "charset" => charset } if charset @@ -64,8 +64,6 @@ class MailerHelperTest < Test::Unit::TestCase set_delivery_method :test ActionMailer::Base.perform_deliveries = true ActionMailer::Base.deliveries.clear - - @recipient = 'test@localhost' end def teardown @@ -73,22 +71,22 @@ class MailerHelperTest < Test::Unit::TestCase end def test_use_helper - mail = HelperMailer.create_use_helper(@recipient) + mail = HelperMailer.use_helper assert_match %r{Mr. Joe Person}, mail.encoded end def test_use_example_helper - mail = HelperMailer.create_use_example_helper(@recipient) + mail = HelperMailer.use_example_helper assert_match %r{emphasize me!}, mail.encoded end def test_use_helper_method - mail = HelperMailer.create_use_helper_method(@recipient) + mail = HelperMailer.use_helper_method assert_match %r{HelperMailer}, mail.encoded end def test_use_mail_helper - mail = HelperMailer.create_use_mail_helper(@recipient) + mail = HelperMailer.use_mail_helper assert_match %r{ But soft!}, mail.encoded assert_match %r{east, and\r\n Juliet}, mail.encoded end diff --git a/actionmailer/test/mail_layout_test.rb b/actionmailer/test/mail_layout_test.rb index b4bd583616..4038fbf339 100644 --- a/actionmailer/test/mail_layout_test.rb +++ b/actionmailer/test/mail_layout_test.rb @@ -2,14 +2,14 @@ require 'abstract_unit' class AutoLayoutMailer < ActionMailer::Base - def hello(recipient) - recipients recipient + def hello + recipients 'test@localhost' subject "You have a mail" from "tester@example.com" end - def spam(recipient) - recipients recipient + def spam + recipients 'test@localhost' subject "You have a mail" from "tester@example.com" @@ -17,8 +17,8 @@ class AutoLayoutMailer < ActionMailer::Base render(:inline => "Hello, <%= @world %>", :layout => 'spam') end - def nolayout(recipient) - recipients recipient + def nolayout + recipients 'test@localhost' subject "You have a mail" from "tester@example.com" @@ -26,8 +26,8 @@ class AutoLayoutMailer < ActionMailer::Base render(:inline => "Hello, <%= @world %>", :layout => false) end - def multipart(recipient, type = nil) - recipients recipient + def multipart(type = nil) + recipients 'test@localhost' subject "You have a mail" from "tester@example.com" @@ -38,14 +38,14 @@ end class ExplicitLayoutMailer < ActionMailer::Base layout 'spam', :except => [:logout] - def signup(recipient) - recipients recipient + def signup + recipients 'test@localhost' subject "You have a mail" from "tester@example.com" end - def logout(recipient) - recipients recipient + def logout + recipients 'test@localhost' subject "You have a mail" from "tester@example.com" end @@ -56,8 +56,6 @@ class LayoutMailerTest < Test::Unit::TestCase set_delivery_method :test ActionMailer::Base.perform_deliveries = true ActionMailer::Base.deliveries.clear - - @recipient = 'test@localhost' end def teardown @@ -65,12 +63,12 @@ class LayoutMailerTest < Test::Unit::TestCase end def test_should_pickup_default_layout - mail = AutoLayoutMailer.create_hello(@recipient) + mail = AutoLayoutMailer.hello assert_equal "Hello from layout Inside", mail.body.to_s.strip end def test_should_pickup_multipart_layout - mail = AutoLayoutMailer.create_multipart(@recipient) + mail = AutoLayoutMailer.multipart # CHANGED: content_type returns an object # assert_equal "multipart/alternative", mail.content_type assert_equal "multipart/alternative", mail.mime_type @@ -94,7 +92,7 @@ class LayoutMailerTest < Test::Unit::TestCase end def test_should_pickup_multipartmixed_layout - mail = AutoLayoutMailer.create_multipart(@recipient, "multipart/mixed") + mail = AutoLayoutMailer.multipart("multipart/mixed") # CHANGED: content_type returns an object # assert_equal "multipart/mixed", mail.content_type assert_equal "multipart/mixed", mail.mime_type @@ -116,7 +114,7 @@ class LayoutMailerTest < Test::Unit::TestCase end def test_should_fix_multipart_layout - mail = AutoLayoutMailer.create_multipart(@recipient, "text/plain") + mail = AutoLayoutMailer.multipart("text/plain") assert_equal "multipart/alternative", mail.mime_type assert_equal 2, mail.parts.size @@ -129,22 +127,22 @@ class LayoutMailerTest < Test::Unit::TestCase def test_should_pickup_layout_given_to_render - mail = AutoLayoutMailer.create_spam(@recipient) + mail = AutoLayoutMailer.spam assert_equal "Spammer layout Hello, Earth", mail.body.to_s.strip end def test_should_respect_layout_false - mail = AutoLayoutMailer.create_nolayout(@recipient) + mail = AutoLayoutMailer.nolayout assert_equal "Hello, Earth", mail.body.to_s.strip end def test_explicit_class_layout - mail = ExplicitLayoutMailer.create_signup(@recipient) + mail = ExplicitLayoutMailer.signup assert_equal "Spammer layout We do not spam", mail.body.to_s.strip end def test_explicit_layout_exceptions - mail = ExplicitLayoutMailer.create_logout(@recipient) + mail = ExplicitLayoutMailer.logout assert_equal "You logged out", mail.body.to_s.strip end end diff --git a/actionmailer/test/mail_render_test.rb b/actionmailer/test/mail_render_test.rb index 3424823c99..804200fd36 100644 --- a/actionmailer/test/mail_render_test.rb +++ b/actionmailer/test/mail_render_test.rb @@ -1,8 +1,8 @@ require 'abstract_unit' class RenderMailer < ActionMailer::Base - def inline_template(recipient) - recipients recipient + def inline_template + recipients 'test@localhost' subject "using helpers" from "tester@example.com" @@ -10,46 +10,46 @@ class RenderMailer < ActionMailer::Base render :inline => "Hello, <%= @world %>" end - def file_template(recipient) - recipients recipient + def file_template + recipients 'test@localhost' subject "using helpers" from "tester@example.com" - @recipient = recipient + @recipient = 'test@localhost' render :file => "templates/signed_up" end - def implicit_body(recipient) - recipients recipient + def implicit_body + recipients 'test@localhost' subject "using helpers" from "tester@example.com" - @recipient = recipient + @recipient = 'test@localhost' render :template => "templates/signed_up" end - def rxml_template(recipient) - recipients recipient + def rxml_template + recipients 'test@localhost' subject "rendering rxml template" from "tester@example.com" end - def included_subtemplate(recipient) - recipients recipient + def included_subtemplate + recipients 'test@localhost' subject "Including another template in the one being rendered" from "tester@example.com" end - def mailer_accessor(recipient) - recipients recipient + def mailer_accessor + recipients 'test@localhost' subject "Mailer Accessor" from "tester@example.com" render :inline => "Look, <%= mailer.subject %>!" end - def no_instance_variable(recipient) - recipients recipient + def no_instance_variable + recipients 'test@localhost' subject "No Instance Variable" from "tester@example.com" @@ -65,16 +65,16 @@ class RenderMailer < ActionMailer::Base end class FirstMailer < ActionMailer::Base - def share(recipient) - recipients recipient + def share + recipients 'test@localhost' subject "using helpers" from "tester@example.com" end end class SecondMailer < ActionMailer::Base - def share(recipient) - recipients recipient + def share + recipients 'test@localhost' subject "using helpers" from "tester@example.com" end @@ -96,37 +96,37 @@ class RenderHelperTest < Test::Unit::TestCase end def test_implicit_body - mail = RenderMailer.create_implicit_body(@recipient) + mail = RenderMailer.implicit_body assert_equal "Hello there, \n\nMr. test@localhost", mail.body.to_s.strip end def test_inline_template - mail = RenderMailer.create_inline_template(@recipient) + mail = RenderMailer.inline_template assert_equal "Hello, Earth", mail.body.to_s.strip end def test_file_template - mail = RenderMailer.create_file_template(@recipient) + mail = RenderMailer.file_template assert_equal "Hello there, \n\nMr. test@localhost", mail.body.to_s.strip end def test_rxml_template - mail = RenderMailer.deliver_rxml_template(@recipient) + mail = RenderMailer.rxml_template.deliver assert_equal "\n", mail.body.to_s.strip end def test_included_subtemplate - mail = RenderMailer.deliver_included_subtemplate(@recipient) + mail = RenderMailer.included_subtemplate.deliver assert_equal "Hey Ho, let's go!", mail.body.to_s.strip end def test_mailer_accessor - mail = RenderMailer.deliver_mailer_accessor(@recipient) + mail = RenderMailer.mailer_accessor.deliver assert_equal "Look, Mailer Accessor!", mail.body.to_s.strip end def test_no_instance_variable - mail = RenderMailer.deliver_no_instance_variable(@recipient) + mail = RenderMailer.no_instance_variable.deliver assert_equal "Look, subject.nil? is true!", mail.body.to_s.strip end end @@ -145,13 +145,13 @@ class FirstSecondHelperTest < Test::Unit::TestCase end def test_ordering - mail = FirstMailer.create_share(@recipient) + mail = FirstMailer.share assert_equal "first mail", mail.body.to_s.strip - mail = SecondMailer.create_share(@recipient) + mail = SecondMailer.share assert_equal "second mail", mail.body.to_s.strip - mail = FirstMailer.create_share(@recipient) + mail = FirstMailer.share assert_equal "first mail", mail.body.to_s.strip - mail = SecondMailer.create_share(@recipient) + mail = SecondMailer.share assert_equal "second mail", mail.body.to_s.strip end end diff --git a/actionmailer/test/mail_service_test.rb b/actionmailer/test/mail_service_test.rb index df5afda447..b3bf1b9acd 100644 --- a/actionmailer/test/mail_service_test.rb +++ b/actionmailer/test/mail_service_test.rb @@ -120,11 +120,11 @@ class TestMailer < ActionMailer::Base content_type "multipart/alternative" part "text/plain" do |p| - p.body = render_message(:text => "blah") + p.body = render(:text => "blah") end part "text/html" do |p| - p.body = render_message(:inline => "<%= content_tag(:b, 'blah') %>") + p.body = render(:inline => "<%= content_tag(:b, 'blah') %>") end end @@ -297,7 +297,7 @@ class TestMailer < ActionMailer::Base recipients "no.one@nowhere.test" subject "return path test" from "some.one@somewhere.test" - headers "return-path" => "another@somewhere.test" + headers["return-path"] = "another@somewhere.test" render :text => "testing" end @@ -350,7 +350,7 @@ class ActionMailerTest < Test::Unit::TestCase def test_nested_parts created = nil - assert_nothing_raised { created = TestMailer.create_nested_multipart(@recipient)} + assert_nothing_raised { created = TestMailer.nested_multipart(@recipient)} assert_equal 2, created.parts.size assert_equal 2, created.parts.first.parts.size @@ -366,8 +366,8 @@ class ActionMailerTest < Test::Unit::TestCase def test_nested_parts_with_body created = nil - TestMailer.create_nested_multipart_with_body(@recipient) - assert_nothing_raised { created = TestMailer.create_nested_multipart_with_body(@recipient)} + TestMailer.nested_multipart_with_body(@recipient) + assert_nothing_raised { created = TestMailer.nested_multipart_with_body(@recipient)} assert_equal 1,created.parts.size assert_equal 2,created.parts.first.parts.size @@ -382,7 +382,7 @@ class ActionMailerTest < Test::Unit::TestCase def test_attachment_with_custom_header created = nil - assert_nothing_raised { created = TestMailer.create_attachment_with_custom_header(@recipient) } + assert_nothing_raised { created = TestMailer.attachment_with_custom_header(@recipient) } assert created.parts.any? { |p| p.header['content-id'].to_s == "" } end @@ -397,7 +397,7 @@ class ActionMailerTest < Test::Unit::TestCase expected.date = Time.now created = nil - assert_nothing_raised { created = TestMailer.create_signed_up(@recipient) } + assert_nothing_raised { created = TestMailer.signed_up(@recipient) } assert_not_nil created expected.message_id = '<123@456>' @@ -405,7 +405,7 @@ class ActionMailerTest < Test::Unit::TestCase assert_equal expected.encoded, created.encoded - assert_nothing_raised { TestMailer.deliver_signed_up(@recipient) } + assert_nothing_raised { TestMailer.signed_up(@recipient).deliver } delivered = ActionMailer::Base.deliveries.first assert_not_nil delivered @@ -425,7 +425,7 @@ class ActionMailerTest < Test::Unit::TestCase expected.date = Time.local(2004, 12, 12) created = nil - assert_nothing_raised { created = TestMailer.create_custom_template(@recipient) } + assert_nothing_raised { created = TestMailer.custom_template(@recipient) } assert_not_nil created expected.message_id = '<123@456>' created.message_id = '<123@456>' @@ -448,7 +448,7 @@ class ActionMailerTest < Test::Unit::TestCase # Now that the template is registered, there should be one part. The text/plain part. created = nil - assert_nothing_raised { created = TestMailer.create_custom_templating_extension(@recipient) } + assert_nothing_raised { created = TestMailer.custom_templating_extension(@recipient) } assert_not_nil created assert_equal 2, created.parts.length assert_equal 'text/plain', created.parts[0].mime_type @@ -464,13 +464,13 @@ class ActionMailerTest < Test::Unit::TestCase expected.date = Time.local(2004, 12, 12) created = nil - assert_nothing_raised { created = TestMailer.create_cancelled_account(@recipient) } + assert_nothing_raised { created = TestMailer.cancelled_account(@recipient) } assert_not_nil created expected.message_id = '<123@456>' created.message_id = '<123@456>' assert_equal expected.encoded, created.encoded - assert_nothing_raised { TestMailer.deliver_cancelled_account(@recipient) } + assert_nothing_raised { TestMailer.cancelled_account(@recipient).deliver } assert_not_nil ActionMailer::Base.deliveries.first delivered = ActionMailer::Base.deliveries.first expected.message_id = '<123@456>' @@ -491,7 +491,7 @@ class ActionMailerTest < Test::Unit::TestCase created = nil assert_nothing_raised do - created = TestMailer.create_cc_bcc @recipient + created = TestMailer.cc_bcc @recipient end assert_not_nil created expected.message_id = '<123@456>' @@ -499,7 +499,7 @@ class ActionMailerTest < Test::Unit::TestCase assert_equal expected.encoded, created.encoded assert_nothing_raised do - TestMailer.deliver_cc_bcc @recipient + TestMailer.cc_bcc(@recipient).deliver end assert_not_nil ActionMailer::Base.deliveries.first @@ -512,7 +512,7 @@ class ActionMailerTest < Test::Unit::TestCase def test_from_without_name_for_smtp ActionMailer::Base.delivery_method = :smtp - TestMailer.deliver_from_without_name + TestMailer.from_without_name.deliver mail = MockSMTP.deliveries.first assert_not_nil mail @@ -523,7 +523,7 @@ class ActionMailerTest < Test::Unit::TestCase def test_from_with_name_for_smtp ActionMailer::Base.delivery_method = :smtp - TestMailer.deliver_from_with_name + TestMailer.from_with_name.deliver mail = MockSMTP.deliveries.first assert_not_nil mail @@ -544,7 +544,7 @@ class ActionMailerTest < Test::Unit::TestCase created = nil assert_nothing_raised do - created = TestMailer.create_different_reply_to @recipient + created = TestMailer.different_reply_to @recipient end assert_not_nil created @@ -554,7 +554,7 @@ class ActionMailerTest < Test::Unit::TestCase assert_equal expected.encoded, created.encoded assert_nothing_raised do - TestMailer.deliver_different_reply_to @recipient + TestMailer.different_reply_to(@recipient).deliver end delivered = ActionMailer::Base.deliveries.first @@ -578,7 +578,7 @@ class ActionMailerTest < Test::Unit::TestCase created = nil assert_nothing_raised do - created = TestMailer.create_iso_charset @recipient + created = TestMailer.iso_charset @recipient end assert_not_nil created @@ -588,7 +588,7 @@ class ActionMailerTest < Test::Unit::TestCase assert_equal expected.encoded, created.encoded assert_nothing_raised do - TestMailer.deliver_iso_charset @recipient + TestMailer.iso_charset(@recipient).deliver end delivered = ActionMailer::Base.deliveries.first @@ -612,7 +612,7 @@ class ActionMailerTest < Test::Unit::TestCase created = nil assert_nothing_raised do - created = TestMailer.create_unencoded_subject @recipient + created = TestMailer.unencoded_subject @recipient end assert_not_nil created @@ -622,7 +622,7 @@ class ActionMailerTest < Test::Unit::TestCase assert_equal expected.encoded, created.encoded assert_nothing_raised do - TestMailer.deliver_unencoded_subject @recipient + TestMailer.unencoded_subject(@recipient).deliver end delivered = ActionMailer::Base.deliveries.first @@ -634,38 +634,33 @@ class ActionMailerTest < Test::Unit::TestCase assert_equal expected.encoded, delivered.encoded end - def test_instances_are_nil - assert_nil ActionMailer::Base.new - assert_nil TestMailer.new - end - def test_deliveries_array assert_not_nil ActionMailer::Base.deliveries assert_equal 0, ActionMailer::Base.deliveries.size - TestMailer.deliver_signed_up(@recipient) + TestMailer.signed_up(@recipient).deliver assert_equal 1, ActionMailer::Base.deliveries.size assert_not_nil ActionMailer::Base.deliveries.first end def test_perform_deliveries_flag ActionMailer::Base.perform_deliveries = false - TestMailer.deliver_signed_up(@recipient) + TestMailer.signed_up(@recipient).deliver assert_equal 0, ActionMailer::Base.deliveries.size ActionMailer::Base.perform_deliveries = true - TestMailer.deliver_signed_up(@recipient) + TestMailer.signed_up(@recipient).deliver assert_equal 1, ActionMailer::Base.deliveries.size end def test_doesnt_raise_errors_when_raise_delivery_errors_is_false ActionMailer::Base.raise_delivery_errors = false Mail::TestMailer.any_instance.expects(:deliver!).raises(Exception) - assert_nothing_raised { TestMailer.deliver_signed_up(@recipient) } + assert_nothing_raised { TestMailer.signed_up(@recipient).deliver } end def test_performs_delivery_via_sendmail IO.expects(:popen).once.with('/usr/sbin/sendmail -i -t -f "system@loudthinking.com" test@localhost', 'w+') ActionMailer::Base.delivery_method = :sendmail - TestMailer.deliver_signed_up(@recipient) + TestMailer.signed_up(@recipient).deliver end def test_unquote_quoted_printable_subject @@ -750,7 +745,7 @@ EOF created = nil assert_nothing_raised do - created = TestMailer.create_extended_headers @recipient + created = TestMailer.extended_headers @recipient end assert_not_nil created @@ -760,7 +755,7 @@ EOF assert_equal expected.encoded, created.encoded assert_nothing_raised do - TestMailer.deliver_extended_headers @recipient + TestMailer.extended_headers(@recipient).deliver end delivered = ActionMailer::Base.deliveries.first @@ -783,7 +778,7 @@ EOF expected.bcc = quote_address_if_necessary @recipient, "utf-8" expected.date = Time.local 2004, 12, 12 - created = TestMailer.create_utf8_body @recipient + created = TestMailer.utf8_body @recipient assert_match(/åœö blah/, created.encoded) end @@ -798,7 +793,7 @@ EOF expected.bcc = quote_address_if_necessary @recipient, "utf-8" expected.date = Time.local 2004, 12, 12 - created = TestMailer.create_utf8_body @recipient + created = TestMailer.utf8_body @recipient assert_match(/\nFrom: =\?utf-8\?Q\?Foo_.*?\?= \r/, created.encoded) assert_match(/\nTo: =\?utf-8\?Q\?Foo_.*?\?= , \r\n\tExample Recipient _Google}, mail.body.to_s end def test_various_newlines - mail = TestMailer.create_various_newlines(@recipient) + mail = TestMailer.various_newlines(@recipient) assert_equal("line #1\nline #2\nline #3\nline #4\n\n" + "line #5\n\nline#6\n\nline #7", mail.body.to_s) end def test_various_newlines_multipart - mail = TestMailer.create_various_newlines_multipart(@recipient) + mail = TestMailer.various_newlines_multipart(@recipient) assert_equal "line #1\nline #2\nline #3\nline #4\n\n", mail.parts[0].body.to_s assert_equal "

line #1

\n

line #2

\n

line #3

\n

line #4

\n\n", mail.parts[1].body.to_s assert_equal "line #1\r\nline #2\r\nline #3\r\nline #4\r\n\r\n", mail.parts[0].body.encoded @@ -962,7 +957,7 @@ EOF def test_headers_removed_on_smtp_delivery ActionMailer::Base.delivery_method = :smtp - TestMailer.deliver_cc_bcc(@recipient) + TestMailer.cc_bcc(@recipient).deliver assert MockSMTP.deliveries[0][2].include?("root@loudthinking.com") assert MockSMTP.deliveries[0][2].include?("nobody@loudthinking.com") assert MockSMTP.deliveries[0][2].include?(@recipient) @@ -975,7 +970,7 @@ EOF ActionMailer::Base.delivery_method = :file tmp_location = ActionMailer::Base.file_settings[:location] - TestMailer.deliver_cc_bcc(@recipient) + TestMailer.cc_bcc(@recipient).deliver assert File.exists?(tmp_location) assert File.directory?(tmp_location) assert File.exists?(File.join(tmp_location, @recipient)) @@ -1002,12 +997,12 @@ EOF expected = "01 Quien Te Dij\212at. Pitbull.mp3" if expected.respond_to?(:force_encoding) - result = attachment.original_filename.dup + result = attachment.filename.dup expected.force_encoding(Encoding::ASCII_8BIT) result.force_encoding(Encoding::ASCII_8BIT) assert_equal expected, result else - assert_equal expected, attachment.original_filename + assert_equal expected, attachment.filename end end @@ -1018,13 +1013,13 @@ EOF end def test_empty_header_values_omitted - result = TestMailer.create_unnamed_attachment(@recipient).encoded + result = TestMailer.unnamed_attachment(@recipient).encoded assert_match %r{Content-Type: application/octet-stream;}, result assert_match %r{Content-Disposition: attachment;}, result end def test_headers_with_nonalpha_chars - mail = TestMailer.create_headers_with_nonalpha_chars(@recipient) + mail = TestMailer.headers_with_nonalpha_chars(@recipient) assert !mail.from_addrs.empty? assert !mail.cc_addrs.empty? assert !mail.bcc_addrs.empty? @@ -1033,33 +1028,33 @@ EOF assert_match(/:/, mail[:bcc].decoded) end - def test_deliver_with_mail_object - mail = TestMailer.create_headers_with_nonalpha_chars(@recipient) - assert_nothing_raised { TestMailer.deliver(mail) } + def test_with_mail_object_deliver + mail = TestMailer.headers_with_nonalpha_chars(@recipient) + assert_nothing_raised { mail.deliver } assert_equal 1, TestMailer.deliveries.length end def test_multipart_with_template_path_with_dots - mail = FunkyPathMailer.create_multipart_with_template_path_with_dots(@recipient) + 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 end def test_custom_content_type_attributes - mail = TestMailer.create_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 end def test_return_path_with_create - mail = TestMailer.create_return_path + mail = TestMailer.return_path assert_equal "another@somewhere.test", mail.return_path end def test_return_path_with_deliver ActionMailer::Base.delivery_method = :smtp - TestMailer.deliver_return_path + TestMailer.return_path.deliver assert_match %r{^Return-Path: }, MockSMTP.deliveries[0][0] assert_equal "another@somewhere.test", MockSMTP.deliveries[0][1].to_s end @@ -1069,7 +1064,7 @@ EOF MockSMTP.any_instance.expects(:respond_to?).with(:enable_starttls_auto).returns(true) MockSMTP.any_instance.expects(:enable_starttls_auto) ActionMailer::Base.delivery_method = :smtp - TestMailer.deliver_signed_up(@recipient) + TestMailer.signed_up(@recipient).deliver end def test_starttls_is_disabled_if_not_supported @@ -1077,16 +1072,16 @@ EOF MockSMTP.any_instance.expects(:respond_to?).with(:enable_starttls_auto).returns(false) MockSMTP.any_instance.expects(:enable_starttls_auto).never ActionMailer::Base.delivery_method = :smtp - TestMailer.deliver_signed_up(@recipient) + TestMailer.signed_up(@recipient).deliver end def test_starttls_is_not_enabled - ActionMailer::Base.delivery_settings[:smtp].merge!(:enable_starttls_auto => false) + TestMailer.delivery_settings[:smtp].merge!(:enable_starttls_auto => false) MockSMTP.any_instance.expects(:respond_to?).never - ActionMailer::Base.delivery_method = :smtp - TestMailer.deliver_signed_up(@recipient) + TestMailer.delivery_method = :smtp + TestMailer.signed_up(@recipient).deliver ensure - ActionMailer::Base.delivery_settings[:smtp].merge!(:enable_starttls_auto => true) + TestMailer.delivery_settings[:smtp].merge!(:enable_starttls_auto => true) end end @@ -1103,7 +1098,7 @@ class InheritableTemplateRootTest < Test::Unit::TestCase end end -class MethodNamingTest < Test::Unit::TestCase +class MethodNamingTest < ActiveSupport::TestCase class TestMailer < ActionMailer::Base def send render :text => 'foo' @@ -1123,12 +1118,13 @@ class MethodNamingTest < Test::Unit::TestCase def test_send_method assert_nothing_raised do assert_emails 1 do - TestMailer.deliver_send + assert_deprecated do + TestMailer.deliver_send + end end end end end - class RespondToTest < Test::Unit::TestCase class RespondToMailer < ActionMailer::Base; end @@ -1191,4 +1187,4 @@ class RespondToTest < Test::Unit::TestCase assert_match(/undefined method.*not_a_method/, error.message) end -end +end \ No newline at end of file diff --git a/actionmailer/test/subscriber_test.rb b/actionmailer/test/subscriber_test.rb index aed5d2ca7e..6c347b8392 100644 --- a/actionmailer/test/subscriber_test.rb +++ b/actionmailer/test/subscriber_test.rb @@ -24,21 +24,21 @@ class AMSubscriberTest < ActionMailer::TestCase end def test_deliver_is_notified - TestMailer.deliver_basic + TestMailer.basic.deliver wait - assert_equal 1, @logger.logged(:info).size - assert_match /Sent mail to somewhere@example.com/, @logger.logged(:info).first - assert_equal 1, @logger.logged(:debug).size - assert_match /Hello world/, @logger.logged(:debug).first + assert_equal(1, @logger.logged(:info).size) + assert_match(/Sent mail to somewhere@example.com/, @logger.logged(:info).first) + assert_equal(1, @logger.logged(:debug).size) + assert_match(/Hello world/, @logger.logged(:debug).first) end def test_receive_is_notified fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email") TestMailer.receive(fixture) wait - assert_equal 1, @logger.logged(:info).size - assert_match /Received mail/, @logger.logged(:info).first - assert_equal 1, @logger.logged(:debug).size - assert_match /Jamis/, @logger.logged(:debug).first + assert_equal(1, @logger.logged(:info).size) + assert_match(/Received mail/, @logger.logged(:info).first) + assert_equal(1, @logger.logged(:debug).size) + assert_match(/Jamis/, @logger.logged(:debug).first) end end \ No newline at end of file diff --git a/actionmailer/test/test_helper_test.rb b/actionmailer/test/test_helper_test.rb index 48e4433e98..3a38a91c28 100644 --- a/actionmailer/test/test_helper_test.rb +++ b/actionmailer/test/test_helper_test.rb @@ -44,7 +44,7 @@ class TestHelperMailerTest < ActionMailer::TestCase def test_assert_emails assert_nothing_raised do assert_emails 1 do - TestHelperMailer.deliver_test + TestHelperMailer.test.deliver end end end @@ -52,27 +52,27 @@ class TestHelperMailerTest < ActionMailer::TestCase def test_repeated_assert_emails_calls assert_nothing_raised do assert_emails 1 do - TestHelperMailer.deliver_test + TestHelperMailer.test.deliver end end assert_nothing_raised do assert_emails 2 do - TestHelperMailer.deliver_test - TestHelperMailer.deliver_test + TestHelperMailer.test.deliver + TestHelperMailer.test.deliver end end end def test_assert_emails_with_no_block assert_nothing_raised do - TestHelperMailer.deliver_test + TestHelperMailer.test.deliver assert_emails 1 end assert_nothing_raised do - TestHelperMailer.deliver_test - TestHelperMailer.deliver_test + TestHelperMailer.test.deliver + TestHelperMailer.test.deliver assert_emails 3 end end @@ -80,7 +80,7 @@ class TestHelperMailerTest < ActionMailer::TestCase def test_assert_no_emails assert_nothing_raised do assert_no_emails do - TestHelperMailer.create_test + TestHelperMailer.test end end end @@ -88,7 +88,7 @@ class TestHelperMailerTest < ActionMailer::TestCase def test_assert_emails_too_few_sent error = assert_raise ActiveSupport::TestCase::Assertion do assert_emails 2 do - TestHelperMailer.deliver_test + TestHelperMailer.test.deliver end end @@ -98,8 +98,8 @@ class TestHelperMailerTest < ActionMailer::TestCase def test_assert_emails_too_many_sent error = assert_raise ActiveSupport::TestCase::Assertion do assert_emails 1 do - TestHelperMailer.deliver_test - TestHelperMailer.deliver_test + TestHelperMailer.test.deliver + TestHelperMailer.test.deliver end end @@ -109,7 +109,7 @@ class TestHelperMailerTest < ActionMailer::TestCase def test_assert_no_emails_failure error = assert_raise ActiveSupport::TestCase::Assertion do assert_no_emails do - TestHelperMailer.deliver_test + TestHelperMailer.test.deliver end end diff --git a/actionmailer/test/tmail_compat_test.rb b/actionmailer/test/tmail_compat_test.rb index b7fcb3cfea..7c1d9a07c1 100644 --- a/actionmailer/test/tmail_compat_test.rb +++ b/actionmailer/test/tmail_compat_test.rb @@ -1,19 +1,23 @@ require 'abstract_unit' -class TmailCompatTest < Test::Unit::TestCase +class TmailCompatTest < ActiveSupport::TestCase def test_set_content_type_raises_deprecation_warning mail = Mail.new - assert_nothing_raised do - mail.set_content_type "text/plain" + assert_deprecated do + assert_nothing_raised do + mail.set_content_type "text/plain" + end end assert_equal mail.mime_type, "text/plain" end def test_transfer_encoding_raises_deprecation_warning mail = Mail.new - assert_nothing_raised do - mail.transfer_encoding "base64" + assert_deprecated do + assert_nothing_raised do + mail.transfer_encoding "base64" + end end assert_equal mail.content_transfer_encoding, "base64" end diff --git a/actionmailer/test/url_test.rb b/actionmailer/test/url_test.rb index b7ae5304ed..10b6a36efd 100644 --- a/actionmailer/test/url_test.rb +++ b/actionmailer/test/url_test.rb @@ -67,14 +67,14 @@ class ActionMailerUrlTest < Test::Unit::TestCase expected.date = Time.local(2004, 12, 12) created = nil - assert_nothing_raised { created = TestMailer.create_signed_up_with_url(@recipient) } + assert_nothing_raised { created = TestMailer.signed_up_with_url(@recipient) } assert_not_nil created expected.message_id = '<123@456>' created.message_id = '<123@456>' assert_equal expected.encoded, created.encoded - assert_nothing_raised { TestMailer.deliver_signed_up_with_url(@recipient) } + assert_nothing_raised { TestMailer.signed_up_with_url(@recipient).deliver } assert_not_nil ActionMailer::Base.deliveries.first delivered = ActionMailer::Base.deliveries.first -- cgit v1.2.3 From 5dead5bb88cf04b039df8a1a51ffdb18d0443efe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Sun, 24 Jan 2010 17:49:44 +0100 Subject: Maintain old_api and deprecated_api in different files. --- actionmailer/lib/action_mailer.rb | 1 + actionmailer/lib/action_mailer/base.rb | 1 + actionmailer/lib/action_mailer/deprecated_api.rb | 252 +---------------------- actionmailer/lib/action_mailer/old_api.rb | 250 ++++++++++++++++++++++ 4 files changed, 261 insertions(+), 243 deletions(-) create mode 100644 actionmailer/lib/action_mailer/old_api.rb (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer.rb b/actionmailer/lib/action_mailer.rb index 67466e15e2..8339826197 100644 --- a/actionmailer/lib/action_mailer.rb +++ b/actionmailer/lib/action_mailer.rb @@ -36,6 +36,7 @@ module ActionMailer autoload :DeliveryMethods autoload :DeprecatedApi autoload :MailHelper + autoload :OldApi autoload :Quoting autoload :TestCase autoload :TestHelper diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 8e30c54c49..77b9ac4a97 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -267,6 +267,7 @@ module ActionMailer #:nodoc: helper ActionMailer::MailHelper extend ActionMailer::DeliveryMethods + include ActionMailer::OldApi include ActionMailer::DeprecatedApi add_delivery_method :smtp, Mail::SMTP, diff --git a/actionmailer/lib/action_mailer/deprecated_api.rb b/actionmailer/lib/action_mailer/deprecated_api.rb index f36b1befd6..530a9c1922 100644 --- a/actionmailer/lib/action_mailer/deprecated_api.rb +++ b/actionmailer/lib/action_mailer/deprecated_api.rb @@ -1,78 +1,10 @@ module ActionMailer - # Part of this API is deprecated and is going to be removed in Rails 3.1 (just check - # the methods which give you a warning). - # All the rest will be deprecated after 3.1 release instead, this allows a smoother - # migration path. + # This is the API which is deprecated and is going to be removed on Rails 3.1 release. + # Part of the old API will be deprecated after 3.1, for a smoother deprecation process. + # Chech those in OldApi instead. module DeprecatedApi #:nodoc: extend ActiveSupport::Concern - included do - extend ActionMailer::AdvAttrAccessor - - @@protected_instance_variables = %w(@parts) - cattr_reader :protected_instance_variables - - # Specify the BCC addresses for the message - adv_attr_accessor :bcc - - # Specify the CC addresses for the message. - adv_attr_accessor :cc - - # Specify the charset to use for the message. This defaults to the - # +default_charset+ specified for ActionMailer::Base. - adv_attr_accessor :charset - - # Specify the content type for the message. This defaults to text/plain - # in most cases, but can be automatically set in some situations. - adv_attr_accessor :content_type - - # Specify the from address for the message. - adv_attr_accessor :from - - # Specify the address (if different than the "from" address) to direct - # replies to this message. - adv_attr_accessor :reply_to - - # Specify additional headers to be added to the message. - adv_attr_accessor :headers - - # Specify the order in which parts should be sorted, based on content-type. - # This defaults to the value for the +default_implicit_parts_order+. - adv_attr_accessor :implicit_parts_order - - # Defaults to "1.0", but may be explicitly given if needed. - adv_attr_accessor :mime_version - - # The recipient addresses for the message, either as a string (for a single - # address) or an array (for multiple addresses). - adv_attr_accessor :recipients - - # The date on which the message was sent. If not set (the default), the - # header will be set by the delivery agent. - adv_attr_accessor :sent_on - - # Specify the subject of the message. - adv_attr_accessor :subject - - # Specify the template name to use for current message. This is the "base" - # template name, without the extension or directory, and may be used to - # have multiple mailer methods share the same template. - adv_attr_accessor :template - - # Override the mailer name, which defaults to an inflected version of the - # mailer's class name. If you want to use a template in a non-standard - # location, you can use this to specify that location. - adv_attr_accessor :mailer_name - - # Define the body of the message. This is either a Hash (in which case it - # specifies the variables to pass to the template when it is rendered), - # or a string, in which case it specifies the actual text of the message. - adv_attr_accessor :body - - # Alias controller_path to mailer_name so render :partial in views work. - alias :controller_path :mailer_name - end - module ClassMethods # Deliver the given mail object directly. This can be used to deliver @@ -107,7 +39,7 @@ module ActionMailer when 'deliver' ActiveSupport::Deprecation.warn "#{self}.deliver_#{match[2]} is deprecated, " << "use #{self}.#{match[2]}.deliver instead", caller[0,2] - new(match[2], *parameters).deliver + new(match[2], *parameters).message.deliver else super end else @@ -127,6 +59,8 @@ module ActionMailer # object (from the create! method). If no cached mail object exists, and # no alternate has been given as the parameter, this will fail. def deliver!(mail = @_message) + ActiveSupport::Deprecation.warn "Calling deliver in the AM::Base object is deprecated, " << + "please call deliver in the Mail instance", caller[0,2] self.class.deliver(mail, false) end alias :deliver :deliver! @@ -143,48 +77,6 @@ module ActionMailer super end - def process(method_name, *args) - initialize_defaults(method_name) - super - unless @mail_was_called - create_parts - create_mail - end - @_message - end - - # Add a part to a multipart message, with the given content-type. The - # part itself is yielded to the block so that other properties (charset, - # body, headers, etc.) can be set on it. - def part(params) - params = {:content_type => params} if String === params - - if custom_headers = params.delete(:headers) - params.merge!(custom_headers) - end - - part = Mail::Part.new(params) - - yield part if block_given? - @parts << part - end - - # Add an attachment to a multipart message. This is simply a part with the - # content-disposition set to "attachment". - def attachment(params, &block) - params = { :content_type => params } if String === params - - params[:content] ||= params.delete(:data) || params.delete(:body) - - if params[:filename] - params = normalize_file_hash(params) - else - params = normalize_nonfile_hash(params) - end - - part(params, &block) - end - # Render a message but does not set it as mail body. Useful for rendering # data for part and attachments. # @@ -201,140 +93,14 @@ module ActionMailer private - def normalize_nonfile_hash(params) - content_disposition = "attachment;" - - mime_type = params.delete(:mime_type) - - if content_type = params.delete(:content_type) - content_type = "#{mime_type || content_type};" - end - - params[:body] = params.delete(:data) if params[:data] - - { :content_type => content_type, - :content_disposition => content_disposition }.merge(params) - end - - def normalize_file_hash(params) - filename = File.basename(params.delete(:filename)) - content_disposition = "attachment; filename=\"#{File.basename(filename)}\"" - - mime_type = params.delete(:mime_type) - - if (content_type = params.delete(:content_type)) && (content_type !~ /filename=/) - content_type = "#{mime_type || content_type}; filename=\"#{filename}\"" - end - - params[:body] = params.delete(:data) if params[:data] - - { :content_type => content_type, - :content_disposition => content_disposition }.merge(params) - end - - def create_mail #:nodoc: - m = @_message - - quote_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 - - @headers.each { |k, v| m[k] = v } - - real_content_type, ctype_attrs = parse_content_type - main_type, sub_type = split_content_type(real_content_type) - - if @parts.size == 1 && @parts.first.parts.empty? - m.content_type([main_type, sub_type, ctype_attrs]) - m.body = @parts.first.body.encoded - else - @parts.each do |p| - m.add_part(p) - end - - m.body.set_sort_order(@implicit_parts_order) - m.body.sort_parts! - - if real_content_type =~ /multipart/ - ctype_attrs.delete "charset" - m.content_type([main_type, sub_type, ctype_attrs]) - end - end - - wrap_delivery_behavior! - m.content_transfer_encoding = '8bit' unless m.body.only_us_ascii? - - @_message - end - - # Set up the default values for the various instance variables of this - # mailer. Subclasses may override this method to provide different - # defaults. - def initialize_defaults(method_name) #:nodoc: - @charset ||= self.class.default_charset.dup - @content_type ||= self.class.default_content_type.dup - @implicit_parts_order ||= self.class.default_implicit_parts_order.dup - @mime_version ||= self.class.default_mime_version.dup if self.class.default_mime_version - - @mailer_name ||= self.class.mailer_name.dup - @template ||= method_name - @mail_was_called = false - - @parts ||= [] - @headers ||= {} - @sent_on ||= Time.now - @body ||= {} - end def create_parts #:nodoc: - if String === @body - self.response_body = @body - elsif @body.is_a?(Hash) && !@body.empty? + if @body.is_a?(Hash) && !@body.empty? + ActiveSupport::Deprecation.warn "Giving a hash to body is deprecated, please use instance variables instead", caller[0,2] @body.each { |k, v| instance_variable_set(:"@#{k}", v) } end - if String === response_body - @parts.unshift create_inline_part(response_body) - else - self.class.template_root.find_all(@template, {}, @mailer_name).each do |template| - @parts << create_inline_part(render_to_body(:_template => template), template.mime_type) - end - - if @parts.size > 1 - @content_type = "multipart/alternative" if @content_type !~ /^multipart/ - end - - # If this is a multipart e-mail add the mime_version if it is not - # already set. - @mime_version ||= "1.0" if !@parts.empty? - end - end - - def create_inline_part(body, mime_type=nil) #:nodoc: - ct = mime_type || "text/plain" - main_type, sub_type = split_content_type(ct.to_s) - - Mail::Part.new( - :content_type => [main_type, sub_type, {:charset => charset}], - :content_disposition => "inline", - :body => body - ) - end - - def split_content_type(ct) #:nodoc: - ct.to_s.split("/") - end - - def parse_content_type(defaults=nil) #:nodoc: - if @content_type.blank? - [ nil, {} ] - else - ctype, *attrs = @content_type.split(/;\s*/) - attrs = attrs.inject({}) { |h,s| k,v = s.split(/\=/, 2); h[k] = v; h } - [ctype, {"charset" => @charset}.merge(attrs)] - end + super end end diff --git a/actionmailer/lib/action_mailer/old_api.rb b/actionmailer/lib/action_mailer/old_api.rb new file mode 100644 index 0000000000..204dc473e8 --- /dev/null +++ b/actionmailer/lib/action_mailer/old_api.rb @@ -0,0 +1,250 @@ +module ActionMailer + module OldApi + extend ActiveSupport::Concern + + included do + extend ActionMailer::AdvAttrAccessor + + @@protected_instance_variables = %w(@parts) + cattr_reader :protected_instance_variables + + # Specify the BCC addresses for the message + adv_attr_accessor :bcc + + # Specify the CC addresses for the message. + adv_attr_accessor :cc + + # Specify the charset to use for the message. This defaults to the + # +default_charset+ specified for ActionMailer::Base. + adv_attr_accessor :charset + + # Specify the content type for the message. This defaults to text/plain + # in most cases, but can be automatically set in some situations. + adv_attr_accessor :content_type + + # Specify the from address for the message. + adv_attr_accessor :from + + # Specify the address (if different than the "from" address) to direct + # replies to this message. + adv_attr_accessor :reply_to + + # Specify additional headers to be added to the message. + adv_attr_accessor :headers + + # Specify the order in which parts should be sorted, based on content-type. + # This defaults to the value for the +default_implicit_parts_order+. + adv_attr_accessor :implicit_parts_order + + # Defaults to "1.0", but may be explicitly given if needed. + adv_attr_accessor :mime_version + + # The recipient addresses for the message, either as a string (for a single + # address) or an array (for multiple addresses). + adv_attr_accessor :recipients + + # The date on which the message was sent. If not set (the default), the + # header will be set by the delivery agent. + adv_attr_accessor :sent_on + + # Specify the subject of the message. + adv_attr_accessor :subject + + # Specify the template name to use for current message. This is the "base" + # template name, without the extension or directory, and may be used to + # have multiple mailer methods share the same template. + adv_attr_accessor :template + + # Override the mailer name, which defaults to an inflected version of the + # mailer's class name. If you want to use a template in a non-standard + # location, you can use this to specify that location. + adv_attr_accessor :mailer_name + + # Define the body of the message. This is either a Hash (in which case it + # specifies the variables to pass to the template when it is rendered), + # or a string, in which case it specifies the actual text of the message. + adv_attr_accessor :body + + # Alias controller_path to mailer_name so render :partial in views work. + alias :controller_path :mailer_name + end + + def process(method_name, *args) + initialize_defaults(method_name) + super + unless @mail_was_called + create_parts + create_mail + end + @_message + end + + # Add a part to a multipart message, with the given content-type. The + # part itself is yielded to the block so that other properties (charset, + # body, headers, etc.) can be set on it. + def part(params) + params = {:content_type => params} if String === params + + if custom_headers = params.delete(:headers) + params.merge!(custom_headers) + end + + part = Mail::Part.new(params) + + yield part if block_given? + @parts << part + end + + # Add an attachment to a multipart message. This is simply a part with the + # content-disposition set to "attachment". + def attachment(params, &block) + params = { :content_type => params } if String === params + + params[:content] ||= params.delete(:data) || params.delete(:body) + + if params[:filename] + params = normalize_file_hash(params) + else + params = normalize_nonfile_hash(params) + end + + part(params, &block) + end + + protected + + def normalize_nonfile_hash(params) + content_disposition = "attachment;" + + mime_type = params.delete(:mime_type) + + if content_type = params.delete(:content_type) + content_type = "#{mime_type || content_type};" + end + + params[:body] = params.delete(:data) if params[:data] + + { :content_type => content_type, + :content_disposition => content_disposition }.merge(params) + end + + def normalize_file_hash(params) + filename = File.basename(params.delete(:filename)) + content_disposition = "attachment; filename=\"#{File.basename(filename)}\"" + + mime_type = params.delete(:mime_type) + + if (content_type = params.delete(:content_type)) && (content_type !~ /filename=/) + content_type = "#{mime_type || content_type}; filename=\"#{filename}\"" + end + + params[:body] = params.delete(:data) if params[:data] + + { :content_type => content_type, + :content_disposition => content_disposition }.merge(params) + end + + def create_mail #:nodoc: + m = @_message + + quote_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 + + @headers.each { |k, v| m[k] = v } + + real_content_type, ctype_attrs = parse_content_type + main_type, sub_type = split_content_type(real_content_type) + + if @parts.size == 1 && @parts.first.parts.empty? + m.content_type([main_type, sub_type, ctype_attrs]) + m.body = @parts.first.body.encoded + else + @parts.each do |p| + m.add_part(p) + end + + m.body.set_sort_order(@implicit_parts_order) + m.body.sort_parts! + + if real_content_type =~ /multipart/ + ctype_attrs.delete "charset" + m.content_type([main_type, sub_type, ctype_attrs]) + end + end + + wrap_delivery_behavior! + m.content_transfer_encoding = '8bit' unless m.body.only_us_ascii? + + @_message + end + + # Set up the default values for the various instance variables of this + # mailer. Subclasses may override this method to provide different + # defaults. + def initialize_defaults(method_name) #:nodoc: + @charset ||= self.class.default_charset.dup + @content_type ||= self.class.default_content_type.dup + @implicit_parts_order ||= self.class.default_implicit_parts_order.dup + @mime_version ||= self.class.default_mime_version.dup if self.class.default_mime_version + + @mailer_name ||= self.class.mailer_name.dup + @template ||= method_name + @mail_was_called = false + + @parts ||= [] + @headers ||= {} + @sent_on ||= Time.now + @body ||= {} + end + + def create_parts #:nodoc: + if String === @body + self.response_body = @body + end + + if String === response_body + @parts.unshift create_inline_part(response_body) + else + self.class.template_root.find_all(@template, {}, @mailer_name).each do |template| + @parts << create_inline_part(render_to_body(:_template => template), template.mime_type) + end + + if @parts.size > 1 + @content_type = "multipart/alternative" if @content_type !~ /^multipart/ + end + + # If this is a multipart e-mail add the mime_version if it is not + # already set. + @mime_version ||= "1.0" if !@parts.empty? + end + end + + def create_inline_part(body, mime_type=nil) #:nodoc: + ct = mime_type || "text/plain" + main_type, sub_type = split_content_type(ct.to_s) + + Mail::Part.new( + :content_type => [main_type, sub_type, {:charset => charset}], + :content_disposition => "inline", + :body => body + ) + end + + def split_content_type(ct) #:nodoc: + ct.to_s.split("/") + end + + def parse_content_type(defaults=nil) #:nodoc: + if @content_type.blank? + [ nil, {} ] + else + ctype, *attrs = @content_type.split(/;\s*/) + attrs = attrs.inject({}) { |h,s| k,v = s.split(/\=/, 2); h[k] = v; h } + [ctype, {"charset" => @charset}.merge(attrs)] + end + end + end +end \ No newline at end of file -- cgit v1.2.3 From 0d931fecbb1132abb71a83bb91435812f2012d0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Sun, 24 Jan 2010 18:11:57 +0100 Subject: Finish cleaning up delivery methods implementation. --- actionmailer/lib/action_mailer/base.rb | 29 +------ actionmailer/lib/action_mailer/delivery_methods.rb | 96 ++++++++++++---------- actionmailer/test/delivery_method_test.rb | 73 ---------------- actionmailer/test/delivery_methods_test.rb | 72 ++++++++++++++++ actionmailer/test/mail_service_test.rb | 22 ++--- 5 files changed, 138 insertions(+), 154 deletions(-) delete mode 100644 actionmailer/test/delivery_method_test.rb create mode 100644 actionmailer/test/delivery_methods_test.rb (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 77b9ac4a97..ad3a9c3c6d 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -253,10 +253,9 @@ module ActionMailer #:nodoc: # and appear last in the mime encoded message. You can also pick a different order from inside a method with # +implicit_parts_order+. class Base < AbstractController::Base + include DeliveryMethods, Quoting abstract! - include Quoting - include AbstractController::Logger include AbstractController::Rendering include AbstractController::LocalizedCache @@ -266,31 +265,9 @@ module ActionMailer #:nodoc: helper ActionMailer::MailHelper - extend ActionMailer::DeliveryMethods include ActionMailer::OldApi include ActionMailer::DeprecatedApi - add_delivery_method :smtp, Mail::SMTP, - :address => "localhost", - :port => 25, - :domain => 'localhost.localdomain', - :user_name => nil, - :password => nil, - :authentication => nil, - :enable_starttls_auto => true - - add_delivery_method :file, Mail::FileDelivery, - :location => defined?(Rails.root) ? "#{Rails.root}/tmp/mails" : "#{Dir.tmpdir}/mails" - - add_delivery_method :sendmail, Mail::Sendmail, - :location => '/usr/sbin/sendmail', - :arguments => '-i -t' - - add_delivery_method :test, Mail::TestMailer - - superclass_delegating_reader :delivery_method - self.delivery_method = :smtp - private_class_method :new #:nodoc: cattr_accessor :raise_delivery_errors @@ -493,10 +470,6 @@ module ActionMailer #:nodoc: [responses, sort_order] end - def wrap_delivery_behavior!(method=nil) #:nodoc: - self.class.wrap_delivery_behavior(@_message, method) - end - def create_parts_from_responses(m, responses, charset) #:nodoc: if responses.size == 1 && !m.has_attachments? m.body = responses[0][:body] diff --git a/actionmailer/lib/action_mailer/delivery_methods.rb b/actionmailer/lib/action_mailer/delivery_methods.rb index 16b84d4118..38325e512f 100644 --- a/actionmailer/lib/action_mailer/delivery_methods.rb +++ b/actionmailer/lib/action_mailer/delivery_methods.rb @@ -1,63 +1,75 @@ +require 'tmpdir' + module ActionMailer - # This modules makes a DSL for adding delivery methods to ActionMailer + # Provides a DSL for adding delivery methods to ActionMailer. module DeliveryMethods - # TODO Make me class inheritable - def delivery_settings - @@delivery_settings ||= Hash.new { |h,k| h[k] = {} } - end + extend ActiveSupport::Concern - def delivery_methods - @@delivery_methods ||= {} - end + included do + extlib_inheritable_accessor :delivery_methods, :delivery_method, + :instance_writer => false - def delivery_method=(method) - raise ArgumentError, "Unknown delivery method #{method.inspect}" unless delivery_methods[method] - @delivery_method = method - end + self.delivery_methods = {} + self.delivery_method = :smtp - def add_delivery_method(symbol, klass, default_options={}) - self.delivery_methods[symbol] = klass - self.delivery_settings[symbol] = default_options - end + add_delivery_method :smtp, Mail::SMTP, + :address => "localhost", + :port => 25, + :domain => 'localhost.localdomain', + :user_name => nil, + :password => nil, + :authentication => nil, + :enable_starttls_auto => true - def wrap_delivery_behavior(mail, method=nil) - method ||= delivery_method + add_delivery_method :file, Mail::FileDelivery, + :location => defined?(Rails.root) ? "#{Rails.root}/tmp/mails" : "#{Dir.tmpdir}/mails" - mail.register_for_delivery_notification(self) + add_delivery_method :sendmail, Mail::Sendmail, + :location => '/usr/sbin/sendmail', + :arguments => '-i -t' - if method.is_a?(Symbol) - mail.delivery_method(delivery_methods[method], - delivery_settings[method]) - else - mail.delivery_method(method) - end - - mail.perform_deliveries = perform_deliveries - mail.raise_delivery_errors = raise_delivery_errors + add_delivery_method :test, Mail::TestMailer end + module ClassMethods + # Adds a new delivery method through the given class using the given symbol + # as alias and the default options supplied: + # + # Example: + # + # add_delivery_method :sendmail, Mail::Sendmail, + # :location => '/usr/sbin/sendmail', + # :arguments => '-i -t' + # + def add_delivery_method(symbol, klass, default_options={}) + unless respond_to?(:"#{symbol}_settings") + extlib_inheritable_accessor(:"#{symbol}_settings", :instance_writer => false) + end - def respond_to?(method_symbol, include_private = false) #:nodoc: - matches_settings_method?(method_symbol) || super - end + send(:"#{symbol}_settings=", default_options) + self.delivery_methods[symbol.to_sym] = klass + end - protected + def wrap_delivery_behavior(mail, method=delivery_method) #:nodoc: + mail.register_for_delivery_notification(self) - # TODO Get rid of this method missing magic - def method_missing(method_symbol, *parameters) #:nodoc: - if match = matches_settings_method?(method_symbol) - if match[2] - delivery_settings[match[1].to_sym] = parameters[0] + if method.is_a?(Symbol) + if klass = delivery_methods[method.to_sym] + mail.delivery_method(klass, send(:"#{method}_settings")) + else + raise "Invalid delivery method #{method.inspect}" + end else - delivery_settings[match[1].to_sym] + mail.delivery_method(method) end - else - super + + mail.perform_deliveries = perform_deliveries + mail.raise_delivery_errors = raise_delivery_errors end end - def matches_settings_method?(method_name) #:nodoc: - /(#{delivery_methods.keys.join('|')})_settings(=)?$/.match(method_name.to_s) + def wrap_delivery_behavior!(*args) #:nodoc: + self.class.wrap_delivery_behavior(message, *args) end end end \ No newline at end of file diff --git a/actionmailer/test/delivery_method_test.rb b/actionmailer/test/delivery_method_test.rb deleted file mode 100644 index 1e7408d6d6..0000000000 --- a/actionmailer/test/delivery_method_test.rb +++ /dev/null @@ -1,73 +0,0 @@ -require 'abstract_unit' -require 'mail' - -class MyCustomDelivery -end - -class DefaultsDeliveryMethodsTest < ActionMailer::TestCase - def setup - set_delivery_method :smtp - end - - def teardown - restore_delivery_method - end - - def test_should_be_the_default_smtp - assert_equal :smtp, ActionMailer::Base.delivery_method - end - - def test_should_have_default_smtp_delivery_method_settings - settings = { :address => "localhost", - :port => 25, - :domain => 'localhost.localdomain', - :user_name => nil, - :password => nil, - :authentication => nil, - :enable_starttls_auto => true } - assert_equal settings, ActionMailer::Base.smtp_settings - end - - def test_should_have_default_file_delivery_method_settings - settings = {:location => "#{Dir.tmpdir}/mails"} - assert_equal settings, ActionMailer::Base.file_settings - end - - def test_should_have_default_sendmail_delivery_method_settings - settings = {:location => '/usr/sbin/sendmail', - :arguments => '-i -t'} - assert_equal settings, ActionMailer::Base.sendmail_settings - end -end - -class CustomDeliveryMethodsTest < ActionMailer::TestCase - def setup - ActionMailer::Base.add_delivery_method :custom, MyCustomDelivery - end - - def teardown - ActionMailer::Base.delivery_methods.delete(:custom) - ActionMailer::Base.delivery_settings.delete(:custom) - end - - def test_allow_to_add_a_custom_delivery_method - ActionMailer::Base.delivery_method = :custom - assert_equal :custom, ActionMailer::Base.delivery_method - end - - def test_allow_to_customize_custom_settings - ActionMailer::Base.custom_settings = { :foo => :bar } - assert_equal Hash[:foo => :bar], ActionMailer::Base.custom_settings - end - - def test_respond_to_custom_method_settings - assert_respond_to ActionMailer::Base, :custom_settings - assert_respond_to ActionMailer::Base, :custom_settings= - end - - def test_should_not_respond_for_invalid_method_settings - assert_raise NoMethodError do - ActionMailer::Base.another_settings - end - end -end diff --git a/actionmailer/test/delivery_methods_test.rb b/actionmailer/test/delivery_methods_test.rb new file mode 100644 index 0000000000..de3d54197d --- /dev/null +++ b/actionmailer/test/delivery_methods_test.rb @@ -0,0 +1,72 @@ +require 'abstract_unit' +require 'mail' + +class MyCustomDelivery +end + +class DefaultsDeliveryMethodsTest < ActionMailer::TestCase + def setup + set_delivery_method :smtp + end + + def teardown + restore_delivery_method + end + + def test_should_be_the_default_smtp + assert_equal :smtp, ActionMailer::Base.delivery_method + end + + def test_should_have_default_smtp_delivery_method_settings + settings = { :address => "localhost", + :port => 25, + :domain => 'localhost.localdomain', + :user_name => nil, + :password => nil, + :authentication => nil, + :enable_starttls_auto => true } + assert_equal settings, ActionMailer::Base.smtp_settings + end + + def test_should_have_default_file_delivery_method_settings + settings = {:location => "#{Dir.tmpdir}/mails"} + assert_equal settings, ActionMailer::Base.file_settings + end + + def test_should_have_default_sendmail_delivery_method_settings + settings = {:location => '/usr/sbin/sendmail', + :arguments => '-i -t'} + assert_equal settings, ActionMailer::Base.sendmail_settings + end +end + +class CustomDeliveryMethodsTest < ActionMailer::TestCase + def setup + ActionMailer::Base.add_delivery_method :custom, MyCustomDelivery + end + + def teardown + ActionMailer::Base.delivery_methods.delete(:custom) + end + + def test_allow_to_add_a_custom_delivery_method + ActionMailer::Base.delivery_method = :custom + assert_equal :custom, ActionMailer::Base.delivery_method + end + + def test_allow_to_customize_custom_settings + ActionMailer::Base.custom_settings = { :foo => :bar } + assert_equal Hash[:foo => :bar], ActionMailer::Base.custom_settings + end + + def test_respond_to_custom_method_settings + assert_respond_to ActionMailer::Base, :custom_settings + assert_respond_to ActionMailer::Base, :custom_settings= + end + + def test_should_not_respond_for_invalid_method_settings + assert_raise NoMethodError do + ActionMailer::Base.another_settings + end + end +end diff --git a/actionmailer/test/mail_service_test.rb b/actionmailer/test/mail_service_test.rb index b3bf1b9acd..c0a3f655b9 100644 --- a/actionmailer/test/mail_service_test.rb +++ b/actionmailer/test/mail_service_test.rb @@ -511,7 +511,7 @@ class ActionMailerTest < Test::Unit::TestCase end def test_from_without_name_for_smtp - ActionMailer::Base.delivery_method = :smtp + TestMailer.delivery_method = :smtp TestMailer.from_without_name.deliver mail = MockSMTP.deliveries.first @@ -522,7 +522,7 @@ class ActionMailerTest < Test::Unit::TestCase end def test_from_with_name_for_smtp - ActionMailer::Base.delivery_method = :smtp + TestMailer.delivery_method = :smtp TestMailer.from_with_name.deliver mail = MockSMTP.deliveries.first @@ -659,7 +659,7 @@ class ActionMailerTest < Test::Unit::TestCase def test_performs_delivery_via_sendmail IO.expects(:popen).once.with('/usr/sbin/sendmail -i -t -f "system@loudthinking.com" test@localhost', 'w+') - ActionMailer::Base.delivery_method = :sendmail + TestMailer.delivery_method = :sendmail TestMailer.signed_up(@recipient).deliver end @@ -956,7 +956,7 @@ EOF end def test_headers_removed_on_smtp_delivery - ActionMailer::Base.delivery_method = :smtp + TestMailer.delivery_method = :smtp TestMailer.cc_bcc(@recipient).deliver assert MockSMTP.deliveries[0][2].include?("root@loudthinking.com") assert MockSMTP.deliveries[0][2].include?("nobody@loudthinking.com") @@ -1053,35 +1053,35 @@ EOF end def test_return_path_with_deliver - ActionMailer::Base.delivery_method = :smtp + TestMailer.delivery_method = :smtp TestMailer.return_path.deliver assert_match %r{^Return-Path: }, MockSMTP.deliveries[0][0] assert_equal "another@somewhere.test", MockSMTP.deliveries[0][1].to_s end def test_starttls_is_enabled_if_supported - ActionMailer::Base.delivery_settings[:smtp].merge!(:enable_starttls_auto => true) + TestMailer.smtp_settings.merge!(:enable_starttls_auto => true) MockSMTP.any_instance.expects(:respond_to?).with(:enable_starttls_auto).returns(true) MockSMTP.any_instance.expects(:enable_starttls_auto) - ActionMailer::Base.delivery_method = :smtp + TestMailer.delivery_method = :smtp TestMailer.signed_up(@recipient).deliver end def test_starttls_is_disabled_if_not_supported - ActionMailer::Base.delivery_settings[:smtp].merge!(:enable_starttls_auto => true) + TestMailer.smtp_settings.merge!(:enable_starttls_auto => true) MockSMTP.any_instance.expects(:respond_to?).with(:enable_starttls_auto).returns(false) MockSMTP.any_instance.expects(:enable_starttls_auto).never - ActionMailer::Base.delivery_method = :smtp + TestMailer.delivery_method = :smtp TestMailer.signed_up(@recipient).deliver end def test_starttls_is_not_enabled - TestMailer.delivery_settings[:smtp].merge!(:enable_starttls_auto => false) + TestMailer.smtp_settings.merge!(:enable_starttls_auto => false) MockSMTP.any_instance.expects(:respond_to?).never TestMailer.delivery_method = :smtp TestMailer.signed_up(@recipient).deliver ensure - TestMailer.delivery_settings[:smtp].merge!(:enable_starttls_auto => true) + TestMailer.smtp_settings.merge!(:enable_starttls_auto => true) end end -- cgit v1.2.3 From 99f960a3d73b62a957988bbee0906264f35afc2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Sun, 24 Jan 2010 18:40:04 +0100 Subject: Handle some TODOs and deprecations. --- .../lib/action_mailer/adv_attr_accessor.rb | 2 -- actionmailer/lib/action_mailer/base.rb | 39 +++++++++++----------- actionmailer/lib/action_mailer/deprecated_api.rb | 21 +++++++----- actionmailer/lib/action_mailer/old_api.rb | 16 ++++----- actionmailer/lib/action_mailer/test_helper.rb | 1 - actionmailer/test/mail_service_test.rb | 6 ++-- 6 files changed, 45 insertions(+), 40 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/adv_attr_accessor.rb b/actionmailer/lib/action_mailer/adv_attr_accessor.rb index 91992ed839..be6b1feca9 100644 --- a/actionmailer/lib/action_mailer/adv_attr_accessor.rb +++ b/actionmailer/lib/action_mailer/adv_attr_accessor.rb @@ -1,8 +1,6 @@ module ActionMailer module AdvAttrAccessor #:nodoc: def adv_attr_accessor(*names) - - # TODO: ActiveSupport::Deprecation.warn() names.each do |name| ivar = "@#{name}" diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index ad3a9c3c6d..7e984124b7 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -302,7 +302,6 @@ module ActionMailer #:nodoc: @mailer_name ||= name.underscore end attr_writer :mailer_name - alias :controller_path :mailer_name # Receives a raw email, parses it into an email object, decodes it, @@ -324,23 +323,21 @@ module ActionMailer #:nodoc: end end - def template_root - self.view_paths && self.view_paths.first - end - - # Should template root overwrite the whole view_paths? - def template_root=(root) - self.view_paths = ActionView::Base.process_view_paths(root) - end - # TODO The delivery should happen inside the instrument block def delivered_email(mail) - ActiveSupport::Notifications.instrument("action_mailer.deliver", :mailer => self.name) do |payload| + ActiveSupport::Notifications.instrument("action_mailer.deliver") do |payload| self.set_payload_for_mail(payload, mail) end end + def respond_to?(method, *args) #:nodoc: + super || action_methods.include?(method.to_s) + end + + protected + def set_payload_for_mail(payload, mail) #:nodoc: + payload[:mailer] = self.name payload[:message_id] = mail.message_id payload[:subject] = mail.subject payload[:to] = mail.to @@ -351,13 +348,7 @@ module ActionMailer #:nodoc: payload[:mail] = mail.encoded end - def respond_to?(method, *args) - super || action_methods.include?(method.to_s) - end - - protected - - def method_missing(method, *args) + def method_missing(method, *args) #:nodoc: if action_methods.include?(method.to_s) new(method, *args).message else @@ -459,7 +450,7 @@ module ActionMailer #:nodoc: :content_type => self.class.default_content_type.dup } else - self.class.template_root.find_all(action_name, {}, self.class.mailer_name).each do |template| + each_template do |template| responses << { :body => render_to_body(:_template => template), :content_type => template.mime_type.to_s @@ -470,6 +461,16 @@ module ActionMailer #:nodoc: [responses, sort_order] end + def each_template(&block) #:nodoc: + self.class.view_paths.each do |load_paths| + templates = load_paths.find_all(action_name, {}, self.class.mailer_name) + unless templates.empty? + templates.each(&block) + return + end + end + end + def create_parts_from_responses(m, responses, charset) #:nodoc: if responses.size == 1 && !m.has_attachments? m.body = responses[0][:body] diff --git a/actionmailer/lib/action_mailer/deprecated_api.rb b/actionmailer/lib/action_mailer/deprecated_api.rb index 530a9c1922..0eb8d85676 100644 --- a/actionmailer/lib/action_mailer/deprecated_api.rb +++ b/actionmailer/lib/action_mailer/deprecated_api.rb @@ -25,11 +25,20 @@ module ActionMailer mail end - def respond_to?(method_symbol, include_private = false) #:nodoc: + def template_root + self.view_paths && self.view_paths.first + end + + def template_root=(root) + ActiveSupport::Deprecation.warn "template_root= is deprecated, use view_paths.unshift instead", caller[0,2] + self.view_paths = ActionView::Base.process_view_paths(root) + end + + def respond_to?(method_symbol, include_private = false) matches_dynamic_method?(method_symbol) || super end - def method_missing(method_symbol, *parameters) #:nodoc: + def method_missing(method_symbol, *parameters) if match = matches_dynamic_method?(method_symbol) case match[1] when 'create' @@ -49,7 +58,7 @@ module ActionMailer private - def matches_dynamic_method?(method_name) #:nodoc: + def matches_dynamic_method?(method_name) method_name = method_name.to_s /^(create|deliver)_([_a-z]\w*)/.match(method_name) || /^(new)$/.match(method_name) end @@ -70,10 +79,8 @@ module ActionMailer if options[:body] ActiveSupport::Deprecation.warn(':body in render deprecated. Please use instance ' << 'variables as assigns instead', caller[0,1]) - body options.delete(:body) end - super end @@ -93,13 +100,11 @@ module ActionMailer private - - def create_parts #:nodoc: + def create_parts if @body.is_a?(Hash) && !@body.empty? ActiveSupport::Deprecation.warn "Giving a hash to body is deprecated, please use instance variables instead", caller[0,2] @body.each { |k, v| instance_variable_set(:"@#{k}", v) } end - super end diff --git a/actionmailer/lib/action_mailer/old_api.rb b/actionmailer/lib/action_mailer/old_api.rb index 204dc473e8..f5b077ab98 100644 --- a/actionmailer/lib/action_mailer/old_api.rb +++ b/actionmailer/lib/action_mailer/old_api.rb @@ -1,5 +1,5 @@ module ActionMailer - module OldApi + module OldApi #:nodoc: extend ActiveSupport::Concern included do @@ -144,7 +144,7 @@ module ActionMailer :content_disposition => content_disposition }.merge(params) end - def create_mail #:nodoc: + def create_mail m = @_message quote_fields!({:subject => subject, :to => recipients, :from => from, @@ -184,7 +184,7 @@ module ActionMailer # Set up the default values for the various instance variables of this # mailer. Subclasses may override this method to provide different # defaults. - def initialize_defaults(method_name) #:nodoc: + def initialize_defaults(method_name) @charset ||= self.class.default_charset.dup @content_type ||= self.class.default_content_type.dup @implicit_parts_order ||= self.class.default_implicit_parts_order.dup @@ -200,7 +200,7 @@ module ActionMailer @body ||= {} end - def create_parts #:nodoc: + def create_parts if String === @body self.response_body = @body end @@ -208,7 +208,7 @@ module ActionMailer if String === response_body @parts.unshift create_inline_part(response_body) else - self.class.template_root.find_all(@template, {}, @mailer_name).each do |template| + self.class.view_paths.first.find_all(@template, {}, @mailer_name).each do |template| @parts << create_inline_part(render_to_body(:_template => template), template.mime_type) end @@ -222,7 +222,7 @@ module ActionMailer end end - def create_inline_part(body, mime_type=nil) #:nodoc: + def create_inline_part(body, mime_type=nil) ct = mime_type || "text/plain" main_type, sub_type = split_content_type(ct.to_s) @@ -233,11 +233,11 @@ module ActionMailer ) end - def split_content_type(ct) #:nodoc: + def split_content_type(ct) ct.to_s.split("/") end - def parse_content_type(defaults=nil) #:nodoc: + def parse_content_type(defaults=nil) if @content_type.blank? [ nil, {} ] else diff --git a/actionmailer/lib/action_mailer/test_helper.rb b/actionmailer/lib/action_mailer/test_helper.rb index f234c0248c..3a1612442f 100644 --- a/actionmailer/lib/action_mailer/test_helper.rb +++ b/actionmailer/lib/action_mailer/test_helper.rb @@ -58,7 +58,6 @@ module ActionMailer end end -# TODO: Deprecate this module Test module Unit class TestCase diff --git a/actionmailer/test/mail_service_test.rb b/actionmailer/test/mail_service_test.rb index c0a3f655b9..aa31c9a803 100644 --- a/actionmailer/test/mail_service_test.rb +++ b/actionmailer/test/mail_service_test.rb @@ -1085,13 +1085,15 @@ EOF end end -class InheritableTemplateRootTest < Test::Unit::TestCase +class InheritableTemplateRootTest < ActiveSupport::TestCase def test_attr expected = File.expand_path("#{File.dirname(__FILE__)}/fixtures/path.with.dots") assert_equal expected, FunkyPathMailer.template_root.to_s sub = Class.new(FunkyPathMailer) - sub.template_root = 'test/path' + assert_deprecated do + sub.template_root = 'test/path' + end assert_equal File.expand_path('test/path'), sub.template_root.to_s assert_equal expected, FunkyPathMailer.template_root.to_s -- cgit v1.2.3 From bd96614101262e0ad0cc176ed8e2d95a5c17936b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Sun, 24 Jan 2010 19:36:42 +0100 Subject: Move old tests to a specific folder and add some delivery method tests. --- actionmailer/Rakefile | 4 +- actionmailer/lib/action_mailer/base.rb | 10 +- actionmailer/lib/action_mailer/delivery_methods.rb | 16 +- actionmailer/lib/action_mailer/mail_helper.rb | 2 +- actionmailer/test/abstract_unit.rb | 24 +- actionmailer/test/adv_attr_test.rb | 36 - actionmailer/test/asset_host_test.rb | 52 - actionmailer/test/base_test.rb | 8 - actionmailer/test/delivery_methods_test.rb | 112 +- actionmailer/test/mail_helper_test.rb | 94 -- actionmailer/test/mail_layout_test.rb | 148 --- actionmailer/test/mail_render_test.rb | 157 --- actionmailer/test/mail_service_test.rb | 1192 -------------------- actionmailer/test/mail_test.rb | 2 - actionmailer/test/old_base/adv_attr_test.rb | 36 + actionmailer/test/old_base/asset_host_test.rb | 52 + actionmailer/test/old_base/mail_helper_test.rb | 94 ++ actionmailer/test/old_base/mail_layout_test.rb | 148 +++ actionmailer/test/old_base/mail_render_test.rb | 157 +++ actionmailer/test/old_base/mail_service_test.rb | 1192 ++++++++++++++++++++ actionmailer/test/old_base/tmail_compat_test.rb | 25 + actionmailer/test/old_base/url_test.rb | 84 ++ actionmailer/test/tmail_compat_test.rb | 25 - actionmailer/test/url_test.rb | 84 -- 24 files changed, 1906 insertions(+), 1848 deletions(-) delete mode 100644 actionmailer/test/adv_attr_test.rb delete mode 100644 actionmailer/test/asset_host_test.rb delete mode 100644 actionmailer/test/mail_helper_test.rb delete mode 100644 actionmailer/test/mail_layout_test.rb delete mode 100644 actionmailer/test/mail_render_test.rb delete mode 100644 actionmailer/test/mail_service_test.rb create mode 100644 actionmailer/test/old_base/adv_attr_test.rb create mode 100644 actionmailer/test/old_base/asset_host_test.rb create mode 100644 actionmailer/test/old_base/mail_helper_test.rb create mode 100644 actionmailer/test/old_base/mail_layout_test.rb create mode 100644 actionmailer/test/old_base/mail_render_test.rb create mode 100644 actionmailer/test/old_base/mail_service_test.rb create mode 100644 actionmailer/test/old_base/tmail_compat_test.rb create mode 100644 actionmailer/test/old_base/url_test.rb delete mode 100644 actionmailer/test/tmail_compat_test.rb delete mode 100644 actionmailer/test/url_test.rb (limited to 'actionmailer') diff --git a/actionmailer/Rakefile b/actionmailer/Rakefile index 6c19371514..2619d9359e 100644 --- a/actionmailer/Rakefile +++ b/actionmailer/Rakefile @@ -22,14 +22,14 @@ task :default => [ :test ] # Run the unit tests Rake::TestTask.new { |t| t.libs << "test" - t.pattern = 'test/*_test.rb' + t.pattern = 'test/**/*_test.rb' t.warning = true } namespace :test do task :isolated do ruby = File.join(*RbConfig::CONFIG.values_at('bindir', 'RUBY_INSTALL_NAME')) - Dir.glob("test/*_test.rb").all? do |file| + Dir.glob("test/**/*_test.rb").all? do |file| system(ruby, '-Ilib:test', file) end or raise "Failures" end diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 7e984124b7..1b81cbf5af 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -256,6 +256,7 @@ module ActionMailer #:nodoc: include DeliveryMethods, Quoting abstract! + # TODO Add some sanity tests for the included modules include AbstractController::Logger include AbstractController::Rendering include AbstractController::LocalizedCache @@ -270,12 +271,6 @@ module ActionMailer #:nodoc: private_class_method :new #:nodoc: - cattr_accessor :raise_delivery_errors - @@raise_delivery_errors = true - - cattr_accessor :perform_deliveries - @@perform_deliveries = true - extlib_inheritable_accessor :default_charset self.default_charset = "utf-8" @@ -295,9 +290,6 @@ module ActionMailer #:nodoc: self.default_implicit_parts_order = [ "text/plain", "text/enriched", "text/html" ] class << self - # Provides a list of emails that have been delivered by Mail - delegate :deliveries, :deliveries=, :to => Mail - def mailer_name @mailer_name ||= name.underscore end diff --git a/actionmailer/lib/action_mailer/delivery_methods.rb b/actionmailer/lib/action_mailer/delivery_methods.rb index 38325e512f..21909d5d57 100644 --- a/actionmailer/lib/action_mailer/delivery_methods.rb +++ b/actionmailer/lib/action_mailer/delivery_methods.rb @@ -1,7 +1,8 @@ require 'tmpdir' module ActionMailer - # Provides a DSL for adding delivery methods to ActionMailer. + # This modules handles everything related to the delivery, from registering new + # delivery methods to configuring the mail object to be send. module DeliveryMethods extend ActiveSupport::Concern @@ -9,6 +10,13 @@ module ActionMailer extlib_inheritable_accessor :delivery_methods, :delivery_method, :instance_writer => false + # Do not make this inheritable, because we always want it to propagate + cattr_accessor :raise_delivery_errors + self.raise_delivery_errors = true + + cattr_accessor :perform_deliveries + self.perform_deliveries = true + self.delivery_methods = {} self.delivery_method = :smtp @@ -32,6 +40,9 @@ module ActionMailer end module ClassMethods + # Provides a list of emails that have been delivered by Mail + delegate :deliveries, :deliveries=, :to => Mail + # Adds a new delivery method through the given class using the given symbol # as alias and the default options supplied: # @@ -50,7 +61,8 @@ module ActionMailer self.delivery_methods[symbol.to_sym] = klass end - def wrap_delivery_behavior(mail, method=delivery_method) #:nodoc: + def wrap_delivery_behavior(mail, method=nil) #:nodoc: + method ||= self.delivery_method mail.register_for_delivery_notification(self) if method.is_a?(Symbol) diff --git a/actionmailer/lib/action_mailer/mail_helper.rb b/actionmailer/lib/action_mailer/mail_helper.rb index adba94cbef..01da954b03 100644 --- a/actionmailer/lib/action_mailer/mail_helper.rb +++ b/actionmailer/lib/action_mailer/mail_helper.rb @@ -23,7 +23,7 @@ module ActionMailer # Access the message instance. def message #:nodoc: - @message + @_message end end end diff --git a/actionmailer/test/abstract_unit.rb b/actionmailer/test/abstract_unit.rb index 1fc5ab85e0..781e49ae05 100644 --- a/actionmailer/test/abstract_unit.rb +++ b/actionmailer/test/abstract_unit.rb @@ -8,7 +8,6 @@ $:.unshift(lib) unless $:.include?('lib') || $:.include?(lib) require 'rubygems' require 'test/unit' - require 'action_mailer' # Show backtraces for deprecated behavior for quicker cleanup. @@ -18,15 +17,11 @@ ActiveSupport::Deprecation.debug = true ActionView::Template.register_template_handler :haml, lambda { |template| "Look its HAML!".inspect } ActionView::Template.register_template_handler :bak, lambda { |template| "Lame backup".inspect } -ActionView::Base::DEFAULT_CONFIG = { :assets_dir => '/nowhere' } - -$:.unshift "#{File.dirname(__FILE__)}/fixtures/helpers" +FIXTURE_LOAD_PATH = File.expand_path('fixtures', File.dirname(__FILE__)) +ActionMailer::Base.view_paths = FIXTURE_LOAD_PATH +$:.unshift File.join(FIXTURE_LOAD_PATH, 'helpers') -FIXTURE_LOAD_PATH = File.join(File.dirname(__FILE__), 'fixtures') -ActionMailer::Base.template_root = FIXTURE_LOAD_PATH - -class MockSMTP - +class MockSMTP def self.deliveries @@deliveries end @@ -42,7 +37,6 @@ class MockSMTP def start(*args) yield self end - end class Net::SMTP @@ -51,14 +45,6 @@ class Net::SMTP end end -def uses_gem(gem_name, test_name, version = '> 0') - gem gem_name.to_s, version - require gem_name.to_s - yield -rescue LoadError - $stderr.puts "Skipping #{test_name} tests. `gem install #{gem_name}` and try again." -end - def set_delivery_method(method) @old_delivery_method = ActionMailer::Base.delivery_method ActionMailer::Base.delivery_method = method @@ -66,4 +52,4 @@ end def restore_delivery_method ActionMailer::Base.delivery_method = @old_delivery_method -end +end \ No newline at end of file diff --git a/actionmailer/test/adv_attr_test.rb b/actionmailer/test/adv_attr_test.rb deleted file mode 100644 index f22d733bc5..0000000000 --- a/actionmailer/test/adv_attr_test.rb +++ /dev/null @@ -1,36 +0,0 @@ -require 'abstract_unit' -require 'action_mailer/adv_attr_accessor' - -class AdvAttrTest < ActiveSupport::TestCase - class Person - cattr_reader :protected_instance_variables - @@protected_instance_variables = [] - - extend ActionMailer::AdvAttrAccessor - adv_attr_accessor :name - end - - def setup - @person = Person.new - end - - def test_adv_attr - assert_nil @person.name - @person.name 'Bob' - assert_equal 'Bob', @person.name - end - - def test_adv_attr_writer - assert_nil @person.name - @person.name = 'Bob' - assert_equal 'Bob', @person.name - end - - def test_raise_an_error_with_multiple_args - assert_raise(ArgumentError) { @person.name('x', 'y') } - end - - def test_ivar_is_added_to_protected_instnace_variables - assert Person.protected_instance_variables.include?('@name') - end -end diff --git a/actionmailer/test/asset_host_test.rb b/actionmailer/test/asset_host_test.rb deleted file mode 100644 index 124032f1d9..0000000000 --- a/actionmailer/test/asset_host_test.rb +++ /dev/null @@ -1,52 +0,0 @@ -require 'abstract_unit' - -class AssetHostMailer < ActionMailer::Base - def email_with_asset - recipients 'test@localhost' - subject "testing email containing asset path while asset_host is set" - from "tester@example.com" - end -end - -class AssetHostTest < Test::Unit::TestCase - def setup - set_delivery_method :test - ActionMailer::Base.perform_deliveries = true - ActionMailer::Base.deliveries.clear - end - - def teardown - restore_delivery_method - end - - def test_asset_host_as_string - ActionController::Base.asset_host = "http://www.example.com" - mail = AssetHostMailer.email_with_asset - assert_equal "\"Somelogo\"", mail.body.to_s.strip - end - - def test_asset_host_as_one_arguement_proc - ActionController::Base.asset_host = Proc.new { |source| - if source.starts_with?('/images') - "http://images.example.com" - else - "http://assets.example.com" - end - } - mail = AssetHostMailer.email_with_asset - assert_equal "\"Somelogo\"", mail.body.to_s.strip - end - - def test_asset_host_as_two_arguement_proc - ActionController::Base.asset_host = Proc.new {|source,request| - if request && request.ssl? - "https://www.example.com" - else - "http://www.example.com" - end - } - mail = nil - assert_nothing_raised { mail = AssetHostMailer.email_with_asset } - assert_equal "\"Somelogo\"", mail.body.to_s.strip - end -end \ No newline at end of file diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index 3b2a072dce..dd17bf868b 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -310,14 +310,6 @@ class BaseTest < ActiveSupport::TestCase assert_equal(1, BaseMailer.deliveries.length) end - # Delivery hooks - test "ActionMailer should be told when Mail gets delivered" do - BaseMailer.deliveries.clear - BaseMailer.expects(:delivered_email).once - BaseMailer.welcome.deliver - assert_equal(1, BaseMailer.deliveries.length) - end - protected # Execute the block setting the given values and restoring old values after diff --git a/actionmailer/test/delivery_methods_test.rb b/actionmailer/test/delivery_methods_test.rb index de3d54197d..5b2ce61ca9 100644 --- a/actionmailer/test/delivery_methods_test.rb +++ b/actionmailer/test/delivery_methods_test.rb @@ -4,20 +4,17 @@ require 'mail' class MyCustomDelivery end -class DefaultsDeliveryMethodsTest < ActionMailer::TestCase - def setup - set_delivery_method :smtp +class BogusDelivery + def initialize(*) end - def teardown - restore_delivery_method - end - - def test_should_be_the_default_smtp - assert_equal :smtp, ActionMailer::Base.delivery_method + def deliver!(mail) + raise "failed" end +end - def test_should_have_default_smtp_delivery_method_settings +class DefaultsDeliveryMethodsTest < ActiveSupport::TestCase + test "default smtp settings" do settings = { :address => "localhost", :port => 25, :domain => 'localhost.localdomain', @@ -28,45 +25,126 @@ class DefaultsDeliveryMethodsTest < ActionMailer::TestCase assert_equal settings, ActionMailer::Base.smtp_settings end - def test_should_have_default_file_delivery_method_settings + test "default file delivery settings" do settings = {:location => "#{Dir.tmpdir}/mails"} assert_equal settings, ActionMailer::Base.file_settings end - def test_should_have_default_sendmail_delivery_method_settings + test "default sendmail settings" do settings = {:location => '/usr/sbin/sendmail', :arguments => '-i -t'} assert_equal settings, ActionMailer::Base.sendmail_settings end end -class CustomDeliveryMethodsTest < ActionMailer::TestCase +class CustomDeliveryMethodsTest < ActiveSupport::TestCase def setup + @old_delivery_method = ActionMailer::Base.delivery_method ActionMailer::Base.add_delivery_method :custom, MyCustomDelivery end def teardown + ActionMailer::Base.delivery_method = @old_delivery_method ActionMailer::Base.delivery_methods.delete(:custom) end - def test_allow_to_add_a_custom_delivery_method + test "allow to add custom delivery method" do ActionMailer::Base.delivery_method = :custom assert_equal :custom, ActionMailer::Base.delivery_method end - def test_allow_to_customize_custom_settings + test "allow to customize custom settings" do ActionMailer::Base.custom_settings = { :foo => :bar } assert_equal Hash[:foo => :bar], ActionMailer::Base.custom_settings end - def test_respond_to_custom_method_settings + test "respond to custom settings" do assert_respond_to ActionMailer::Base, :custom_settings assert_respond_to ActionMailer::Base, :custom_settings= end - def test_should_not_respond_for_invalid_method_settings + test "does not respond to unknown settings" do assert_raise NoMethodError do ActionMailer::Base.another_settings end end end + +class MailDeliveryTest < ActiveSupport::TestCase + class DeliverMail < ActionMailer::Base + DEFAULT_HEADERS = { + :to => 'mikel@test.lindsaar.net', + :from => 'jose@test.plataformatec.com' + } + + def welcome(hash={}) + mail(DEFAULT_HEADERS.merge(hash)) + end + end + + def setup + ActionMailer::Base.delivery_method = :smtp + end + + def teardown + DeliverMail.delivery_method = :smtp + DeliverMail.perform_deliveries = true + DeliverMail.raise_delivery_errors = true + end + + test "ActionMailer should be told when Mail gets delivered" do + DeliverMail.deliveries.clear + DeliverMail.expects(:delivered_email).once + DeliverMail.welcome.deliver + assert_equal(1, DeliverMail.deliveries.length) + end + + test "delivery method can be customized per instance" do + email = DeliverMail.welcome.deliver + assert_instance_of Mail::SMTP, email.delivery_method + email = DeliverMail.welcome(:delivery_method => :test).deliver + assert_instance_of Mail::TestMailer, email.delivery_method + end + + test "delivery method can be customized in subclasses not changing the parent" do + DeliverMail.delivery_method = :test + assert_equal :smtp, ActionMailer::Base.delivery_method + $BREAK = true + email = DeliverMail.welcome.deliver + assert_instance_of Mail::TestMailer, email.delivery_method + end + + test "non registered delivery methods raises errors" do + DeliverMail.delivery_method = :unknown + assert_raise RuntimeError do + DeliverMail.welcome.deliver + end + end + + test "does not perform deliveries if requested" do + DeliverMail.perform_deliveries = false + DeliverMail.deliveries.clear + DeliverMail.expects(:delivered_email).never + DeliverMail.welcome.deliver + assert_equal(0, DeliverMail.deliveries.length) + end + + test "raise errors on bogus deliveries" do + DeliverMail.delivery_method = BogusDelivery + DeliverMail.deliveries.clear + DeliverMail.expects(:delivered_email).never + assert_raise RuntimeError do + DeliverMail.welcome.deliver + end + assert_equal(0, DeliverMail.deliveries.length) + end + + test "does not raise errors on bogus deliveries if set" do + DeliverMail.delivery_method = BogusDelivery + DeliverMail.raise_delivery_errors = false + DeliverMail.deliveries.clear + DeliverMail.expects(:delivered_email).once + DeliverMail.welcome.deliver + assert_equal(1, DeliverMail.deliveries.length) + end +end \ No newline at end of file diff --git a/actionmailer/test/mail_helper_test.rb b/actionmailer/test/mail_helper_test.rb deleted file mode 100644 index a9b3cd3ce1..0000000000 --- a/actionmailer/test/mail_helper_test.rb +++ /dev/null @@ -1,94 +0,0 @@ -require 'abstract_unit' - -module MailerHelper - def person_name - "Mr. Joe Person" - end -end - -class HelperMailer < ActionMailer::Base - helper MailerHelper - helper :example - - def use_helper - recipients 'test@localhost' - subject "using helpers" - from "tester@example.com" - end - - def use_example_helper - recipients 'test@localhost' - subject "using helpers" - from "tester@example.com" - - @text = "emphasize me!" - end - - def use_mail_helper - recipients 'test@localhost' - subject "using mailing helpers" - from "tester@example.com" - - @text = "But soft! What light through yonder window breaks? It is the east, " + - "and Juliet is the sun. Arise, fair sun, and kill the envious moon, " + - "which is sick and pale with grief that thou, her maid, art far more " + - "fair than she. Be not her maid, for she is envious! Her vestal " + - "livery is but sick and green, and none but fools do wear it. Cast " + - "it off!" - end - - def use_helper_method - recipients 'test@localhost' - subject "using helpers" - from "tester@example.com" - - @text = "emphasize me!" - end - - private - - def name_of_the_mailer_class - self.class.name - end - helper_method :name_of_the_mailer_class -end - -class MailerHelperTest < ActiveSupport::TestCase - def new_mail( charset="utf-8" ) - mail = Mail.new - mail.set_content_type "text", "plain", { "charset" => charset } if charset - mail - end - - def setup - set_delivery_method :test - ActionMailer::Base.perform_deliveries = true - ActionMailer::Base.deliveries.clear - end - - def teardown - restore_delivery_method - end - - def test_use_helper - mail = HelperMailer.use_helper - assert_match %r{Mr. Joe Person}, mail.encoded - end - - def test_use_example_helper - mail = HelperMailer.use_example_helper - assert_match %r{emphasize me!}, mail.encoded - end - - def test_use_helper_method - mail = HelperMailer.use_helper_method - assert_match %r{HelperMailer}, mail.encoded - end - - def test_use_mail_helper - mail = HelperMailer.use_mail_helper - assert_match %r{ But soft!}, mail.encoded - assert_match %r{east, and\r\n Juliet}, mail.encoded - end -end - diff --git a/actionmailer/test/mail_layout_test.rb b/actionmailer/test/mail_layout_test.rb deleted file mode 100644 index 4038fbf339..0000000000 --- a/actionmailer/test/mail_layout_test.rb +++ /dev/null @@ -1,148 +0,0 @@ -require 'abstract_unit' - -class AutoLayoutMailer < ActionMailer::Base - - def hello - recipients 'test@localhost' - subject "You have a mail" - from "tester@example.com" - end - - def spam - recipients 'test@localhost' - subject "You have a mail" - from "tester@example.com" - - @world = "Earth" - render(:inline => "Hello, <%= @world %>", :layout => 'spam') - end - - def nolayout - recipients 'test@localhost' - subject "You have a mail" - from "tester@example.com" - - @world = "Earth" - render(:inline => "Hello, <%= @world %>", :layout => false) - end - - def multipart(type = nil) - recipients 'test@localhost' - subject "You have a mail" - from "tester@example.com" - - content_type(type) if type - end -end - -class ExplicitLayoutMailer < ActionMailer::Base - layout 'spam', :except => [:logout] - - def signup - recipients 'test@localhost' - subject "You have a mail" - from "tester@example.com" - end - - def logout - recipients 'test@localhost' - subject "You have a mail" - from "tester@example.com" - end -end - -class LayoutMailerTest < Test::Unit::TestCase - def setup - set_delivery_method :test - ActionMailer::Base.perform_deliveries = true - ActionMailer::Base.deliveries.clear - end - - def teardown - restore_delivery_method - end - - def test_should_pickup_default_layout - mail = AutoLayoutMailer.hello - assert_equal "Hello from layout Inside", mail.body.to_s.strip - end - - def test_should_pickup_multipart_layout - mail = AutoLayoutMailer.multipart - # CHANGED: content_type returns an object - # assert_equal "multipart/alternative", mail.content_type - assert_equal "multipart/alternative", mail.mime_type - assert_equal 2, mail.parts.size - - # CHANGED: content_type returns an object - # assert_equal 'text/plain', mail.parts.first.content_type - assert_equal 'text/plain', mail.parts.first.mime_type - - # CHANGED: body returns an object - # assert_equal "text/plain layout - text/plain multipart", mail.parts.first.body - assert_equal "text/plain layout - text/plain multipart", mail.parts.first.body.to_s - - # CHANGED: content_type returns an object - # assert_equal 'text/html', mail.parts.last.content_type - assert_equal 'text/html', mail.parts.last.mime_type - - # CHANGED: body returns an object - # assert_equal "Hello from layout text/html multipart", mail.parts.last.body - assert_equal "Hello from layout text/html multipart", mail.parts.last.body.to_s - end - - def test_should_pickup_multipartmixed_layout - mail = AutoLayoutMailer.multipart("multipart/mixed") - # CHANGED: content_type returns an object - # assert_equal "multipart/mixed", mail.content_type - assert_equal "multipart/mixed", mail.mime_type - assert_equal 2, mail.parts.size - - # CHANGED: content_type returns an object - # assert_equal 'text/plain', mail.parts.first.content_type - assert_equal 'text/plain', mail.parts.first.mime_type - # CHANGED: body returns an object - # assert_equal "text/plain layout - text/plain multipart", mail.parts.first.body - assert_equal "text/plain layout - text/plain multipart", mail.parts.first.body.to_s - - # CHANGED: content_type returns an object - # assert_equal 'text/html', mail.parts.last.content_type - assert_equal 'text/html', mail.parts.last.mime_type - # CHANGED: body returns an object - # assert_equal "Hello from layout text/html multipart", mail.parts.last.body - assert_equal "Hello from layout text/html multipart", mail.parts.last.body.to_s - end - - def test_should_fix_multipart_layout - mail = AutoLayoutMailer.multipart("text/plain") - assert_equal "multipart/alternative", mail.mime_type - assert_equal 2, mail.parts.size - - assert_equal 'text/plain', mail.parts.first.mime_type - assert_equal "text/plain layout - text/plain multipart", mail.parts.first.body.to_s - - assert_equal 'text/html', mail.parts.last.mime_type - assert_equal "Hello from layout text/html multipart", mail.parts.last.body.to_s - end - - - def test_should_pickup_layout_given_to_render - mail = AutoLayoutMailer.spam - assert_equal "Spammer layout Hello, Earth", mail.body.to_s.strip - end - - def test_should_respect_layout_false - mail = AutoLayoutMailer.nolayout - assert_equal "Hello, Earth", mail.body.to_s.strip - end - - def test_explicit_class_layout - mail = ExplicitLayoutMailer.signup - assert_equal "Spammer layout We do not spam", mail.body.to_s.strip - end - - def test_explicit_layout_exceptions - mail = ExplicitLayoutMailer.logout - assert_equal "You logged out", mail.body.to_s.strip - end -end diff --git a/actionmailer/test/mail_render_test.rb b/actionmailer/test/mail_render_test.rb deleted file mode 100644 index 804200fd36..0000000000 --- a/actionmailer/test/mail_render_test.rb +++ /dev/null @@ -1,157 +0,0 @@ -require 'abstract_unit' - -class RenderMailer < ActionMailer::Base - def inline_template - recipients 'test@localhost' - subject "using helpers" - from "tester@example.com" - - @world = "Earth" - render :inline => "Hello, <%= @world %>" - end - - def file_template - recipients 'test@localhost' - subject "using helpers" - from "tester@example.com" - - @recipient = 'test@localhost' - render :file => "templates/signed_up" - end - - def implicit_body - recipients 'test@localhost' - subject "using helpers" - from "tester@example.com" - - @recipient = 'test@localhost' - render :template => "templates/signed_up" - end - - def rxml_template - recipients 'test@localhost' - subject "rendering rxml template" - from "tester@example.com" - end - - def included_subtemplate - recipients 'test@localhost' - subject "Including another template in the one being rendered" - from "tester@example.com" - end - - def mailer_accessor - recipients 'test@localhost' - subject "Mailer Accessor" - from "tester@example.com" - - render :inline => "Look, <%= mailer.subject %>!" - end - - def no_instance_variable - recipients 'test@localhost' - subject "No Instance Variable" - from "tester@example.com" - - silence_warnings do - render :inline => "Look, subject.nil? is <%= @subject.nil? %>!" - end - end - - def initialize_defaults(method_name) - super - mailer_name "test_mailer" - end -end - -class FirstMailer < ActionMailer::Base - def share - recipients 'test@localhost' - subject "using helpers" - from "tester@example.com" - end -end - -class SecondMailer < ActionMailer::Base - def share - recipients 'test@localhost' - subject "using helpers" - from "tester@example.com" - end -end - -# CHANGED: Those tests were changed because body returns an object now -# Instead of mail.body.strip, we should mail.body.to_s.strip -class RenderHelperTest < Test::Unit::TestCase - def setup - set_delivery_method :test - ActionMailer::Base.perform_deliveries = true - ActionMailer::Base.deliveries.clear - - @recipient = 'test@localhost' - end - - def teardown - restore_delivery_method - end - - def test_implicit_body - mail = RenderMailer.implicit_body - assert_equal "Hello there, \n\nMr. test@localhost", mail.body.to_s.strip - end - - def test_inline_template - mail = RenderMailer.inline_template - assert_equal "Hello, Earth", mail.body.to_s.strip - end - - def test_file_template - mail = RenderMailer.file_template - assert_equal "Hello there, \n\nMr. test@localhost", mail.body.to_s.strip - end - - def test_rxml_template - mail = RenderMailer.rxml_template.deliver - assert_equal "\n", mail.body.to_s.strip - end - - def test_included_subtemplate - mail = RenderMailer.included_subtemplate.deliver - assert_equal "Hey Ho, let's go!", mail.body.to_s.strip - end - - def test_mailer_accessor - mail = RenderMailer.mailer_accessor.deliver - assert_equal "Look, Mailer Accessor!", mail.body.to_s.strip - end - - def test_no_instance_variable - mail = RenderMailer.no_instance_variable.deliver - assert_equal "Look, subject.nil? is true!", mail.body.to_s.strip - end -end - -class FirstSecondHelperTest < Test::Unit::TestCase - def setup - set_delivery_method :test - ActionMailer::Base.perform_deliveries = true - ActionMailer::Base.deliveries.clear - - @recipient = 'test@localhost' - end - - def teardown - restore_delivery_method - end - - def test_ordering - mail = FirstMailer.share - assert_equal "first mail", mail.body.to_s.strip - mail = SecondMailer.share - assert_equal "second mail", mail.body.to_s.strip - mail = FirstMailer.share - assert_equal "first mail", mail.body.to_s.strip - mail = SecondMailer.share - assert_equal "second mail", mail.body.to_s.strip - end -end diff --git a/actionmailer/test/mail_service_test.rb b/actionmailer/test/mail_service_test.rb deleted file mode 100644 index aa31c9a803..0000000000 --- a/actionmailer/test/mail_service_test.rb +++ /dev/null @@ -1,1192 +0,0 @@ -# encoding: utf-8 -require 'abstract_unit' - -class FunkyPathMailer < ActionMailer::Base - self.template_root = "#{File.dirname(__FILE__)}/fixtures/path.with.dots" - - def multipart_with_template_path_with_dots(recipient) - recipients recipient - subject "This path has dots" - from "Chad Fowler " - attachment :content_type => "text/plain", - :data => "dots dots dots..." - end -end - -class TestMailer < ActionMailer::Base - def signed_up(recipient) - recipients recipient - subject "[Signed up] Welcome #{recipient}" - from "system@loudthinking.com" - - @recipient = recipient - end - - def cancelled_account(recipient) - recipients recipient - subject "[Cancelled] Goodbye #{recipient}" - from "system@loudthinking.com" - sent_on Time.local(2004, 12, 12) - - render :text => "Goodbye, Mr. #{recipient}" - end - - def from_with_name - from "System " - recipients "root@loudthinking.com" - render :text => "Nothing to see here." - end - - def from_without_name - from "system@loudthinking.com" - recipients "root@loudthinking.com" - render :text => "Nothing to see here." - end - - def cc_bcc(recipient) - recipients recipient - subject "testing bcc/cc" - from "system@loudthinking.com" - sent_on Time.local(2004, 12, 12) - cc "nobody@loudthinking.com" - bcc "root@loudthinking.com" - - render :text => "Nothing to see here." - end - - def different_reply_to(recipient) - recipients recipient - subject "testing reply_to" - from "system@loudthinking.com" - sent_on Time.local(2008, 5, 23) - reply_to "atraver@gmail.com" - - render :text => "Nothing to see here." - end - - def iso_charset(recipient) - recipients recipient - subject "testing isø charsets" - from "system@loudthinking.com" - sent_on Time.local(2004, 12, 12) - cc "nobody@loudthinking.com" - bcc "root@loudthinking.com" - charset "iso-8859-1" - - render :text => "Nothing to see here." - end - - def unencoded_subject(recipient) - recipients recipient - subject "testing unencoded subject" - from "system@loudthinking.com" - sent_on Time.local(2004, 12, 12) - cc "nobody@loudthinking.com" - bcc "root@loudthinking.com" - - render :text => "Nothing to see here." - end - - def extended_headers(recipient) - recipients recipient - subject "testing extended headers" - from "Grytøyr " - sent_on Time.local(2004, 12, 12) - cc "Grytøyr " - bcc "Grytøyr " - charset "iso-8859-1" - - render :text => "Nothing to see here." - end - - def utf8_body(recipient) - recipients recipient - subject "testing utf-8 body" - from "Foo áëô îü " - sent_on Time.local(2004, 12, 12) - cc "Foo áëô îü " - bcc "Foo áëô îü " - charset "utf-8" - - render :text => "åœö blah" - end - - def multipart_with_mime_version(recipient) - recipients recipient - subject "multipart with mime_version" - from "test@example.com" - sent_on Time.local(2004, 12, 12) - mime_version "1.1" - content_type "multipart/alternative" - - part "text/plain" do |p| - p.body = render(:text => "blah") - end - - part "text/html" do |p| - p.body = render(:inline => "<%= content_tag(:b, 'blah') %>") - end - end - - def multipart_with_utf8_subject(recipient) - recipients recipient - subject "Foo áëô îü" - from "test@example.com" - charset "utf-8" - - part "text/plain" do |p| - p.body = "blah" - end - - part "text/html" do |p| - p.body = "blah" - end - end - - def explicitly_multipart_example(recipient, ct=nil) - recipients recipient - subject "multipart example" - from "test@example.com" - sent_on Time.local(2004, 12, 12) - content_type ct if ct - - part "text/html" do |p| - p.charset = "iso-8859-1" - p.body = "blah" - end - - attachment :content_type => "image/jpeg", :filename => File.join(File.dirname(__FILE__), "fixtures", "attachments", "foo.jpg"), - :data => "123456789" - - render :text => "plain text default" - end - - def implicitly_multipart_example(recipient, cs = nil, order = nil) - recipients recipient - subject "multipart example" - from "test@example.com" - sent_on Time.local(2004, 12, 12) - - @charset = cs if cs - @recipient = recipient - @implicit_parts_order = order if order - end - - def implicitly_multipart_with_utf8 - recipients "no.one@nowhere.test" - subject "Foo áëô îü" - from "some.one@somewhere.test" - template "implicitly_multipart_example" - - @recipient = "no.one@nowhere.test" - end - - def html_mail(recipient) - recipients recipient - subject "html mail" - from "test@example.com" - content_type "text/html" - - render :text => "Emphasize this" - end - - def html_mail_with_underscores(recipient) - subject "html mail with underscores" - render :text => %{_Google} - end - - def custom_template(recipient) - recipients recipient - subject "[Signed up] Welcome #{recipient}" - from "system@loudthinking.com" - sent_on Time.local(2004, 12, 12) - template "signed_up" - - @recipient = recipient - end - - def custom_templating_extension(recipient) - recipients recipient - subject "[Signed up] Welcome #{recipient}" - from "system@loudthinking.com" - sent_on Time.local(2004, 12, 12) - - @recipient = recipient - end - - def various_newlines(recipient) - recipients recipient - subject "various newlines" - from "test@example.com" - - render :text => "line #1\nline #2\rline #3\r\nline #4\r\r" + - "line #5\n\nline#6\r\n\r\nline #7" - end - - def various_newlines_multipart(recipient) - recipients recipient - subject "various newlines multipart" - from "test@example.com" - content_type "multipart/alternative" - - part :content_type => "text/plain", :body => "line #1\nline #2\rline #3\r\nline #4\r\r" - part :content_type => "text/html", :body => "

line #1

\n

line #2

\r

line #3

\r\n

line #4

\r\r" - end - - def nested_multipart(recipient) - recipients recipient - subject "nested multipart" - from "test@example.com" - content_type "multipart/mixed" - - part :content_type => "multipart/alternative", :content_disposition => "inline", "foo" => "bar" do |p| - p.part :content_type => "text/plain", :body => "test text\nline #2" - p.part :content_type => "text/html", :body => "test HTML
\nline #2" - end - - attachment :content_type => "application/octet-stream", :filename => "test.txt", :data => "test abcdefghijklmnopqstuvwxyz" - end - - def nested_multipart_with_body(recipient) - recipients recipient - subject "nested multipart with body" - from "test@example.com" - content_type "multipart/mixed" - - part :content_type => "multipart/alternative", :content_disposition => "inline", :body => "Nothing to see here." do |p| - p.part :content_type => "text/html", :body => "test HTML
" - end - end - - def attachment_with_custom_header(recipient) - recipients recipient - subject "custom header in attachment" - from "test@example.com" - content_type "multipart/related" - part :content_type => "text/html", :body => 'yo' - attachment :content_type => "image/jpeg", :filename => File.join(File.dirname(__FILE__), "fixtures", "attachments", "test.jpg"), :data => "i am not a real picture", 'Content-ID' => '' - end - - def unnamed_attachment(recipient) - recipients recipient - subject "nested multipart" - from "test@example.com" - content_type "multipart/mixed" - part :content_type => "text/plain", :body => "hullo" - attachment :content_type => "application/octet-stream", :data => "test abcdefghijklmnopqstuvwxyz" - end - - def headers_with_nonalpha_chars(recipient) - recipients recipient - subject "nonalpha chars" - from "One: Two " - cc "Three: Four " - bcc "Five: Six " - render :text => "testing" - end - - def custom_content_type_attributes - recipients "no.one@nowhere.test" - subject "custom content types" - from "some.one@somewhere.test" - content_type "text/plain; format=flowed" - render :text => "testing" - end - - def return_path - recipients "no.one@nowhere.test" - subject "return path test" - from "some.one@somewhere.test" - headers["return-path"] = "another@somewhere.test" - render :text => "testing" - end - - def subject_with_i18n(recipient) - recipients recipient - from "system@loudthinking.com" - render :text => "testing" - end - - class << self - attr_accessor :received_body - end - - def receive(mail) - self.class.received_body = mail.body - end -end - -class ActionMailerTest < Test::Unit::TestCase - include ActionMailer::Quoting - - def encode( text, charset="utf-8" ) - quoted_printable( text, charset ) - end - - def new_mail( charset="utf-8" ) - mail = Mail.new - mail.mime_version = "1.0" - if charset - mail.content_type ["text", "plain", { "charset" => charset }] - end - mail - end - - # Replacing logger work around for mocha bug. Should be fixed in mocha 0.3.3 - def setup - set_delivery_method :test - ActionMailer::Base.perform_deliveries = true - ActionMailer::Base.raise_delivery_errors = true - ActionMailer::Base.deliveries.clear - - @original_logger = TestMailer.logger - @recipient = 'test@localhost' - end - - def teardown - TestMailer.logger = @original_logger - restore_delivery_method - end - - def test_nested_parts - created = nil - assert_nothing_raised { created = TestMailer.nested_multipart(@recipient)} - assert_equal 2, created.parts.size - assert_equal 2, created.parts.first.parts.size - - 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_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 - - end - - def test_nested_parts_with_body - created = nil - TestMailer.nested_multipart_with_body(@recipient) - assert_nothing_raised { created = TestMailer.nested_multipart_with_body(@recipient)} - - assert_equal 1,created.parts.size - assert_equal 2,created.parts.first.parts.size - - assert_equal "multipart/mixed", created.mime_type - assert_equal "multipart/alternative", created.parts.first.mime_type - assert_equal "text/plain", created.parts.first.parts.first.mime_type - assert_equal "Nothing to see here.", created.parts.first.parts.first.body.to_s - assert_equal "text/html", created.parts.first.parts.second.mime_type - assert_equal "test HTML
", created.parts.first.parts.second.body.to_s - end - - def test_attachment_with_custom_header - created = nil - assert_nothing_raised { created = TestMailer.attachment_with_custom_header(@recipient) } - assert created.parts.any? { |p| p.header['content-id'].to_s == "" } - end - - def test_signed_up - Time.stubs(:now => Time.now) - - expected = new_mail - expected.to = @recipient - expected.subject = "[Signed up] Welcome #{@recipient}" - expected.body = "Hello there, \n\nMr. #{@recipient}" - expected.from = "system@loudthinking.com" - expected.date = Time.now - - created = nil - assert_nothing_raised { created = TestMailer.signed_up(@recipient) } - assert_not_nil created - - expected.message_id = '<123@456>' - created.message_id = '<123@456>' - - assert_equal expected.encoded, created.encoded - - assert_nothing_raised { TestMailer.signed_up(@recipient).deliver } - - delivered = ActionMailer::Base.deliveries.first - assert_not_nil delivered - - expected.message_id = '<123@456>' - delivered.message_id = '<123@456>' - - assert_equal expected.encoded, delivered.encoded - end - - def test_custom_template - expected = new_mail - expected.to = @recipient - expected.subject = "[Signed up] Welcome #{@recipient}" - expected.body = "Hello there, \n\nMr. #{@recipient}" - expected.from = "system@loudthinking.com" - expected.date = Time.local(2004, 12, 12) - - created = nil - assert_nothing_raised { created = TestMailer.custom_template(@recipient) } - assert_not_nil created - expected.message_id = '<123@456>' - created.message_id = '<123@456>' - assert_equal expected.encoded, created.encoded - end - - def test_custom_templating_extension - assert ActionView::Template.template_handler_extensions.include?("haml"), "haml extension was not registered" - - # N.b., custom_templating_extension.text.plain.haml is expected to be in fixtures/test_mailer directory - expected = new_mail - expected.to = @recipient - expected.subject = "[Signed up] Welcome #{@recipient}" - expected.body = "Hello there, \n\nMr. #{@recipient}" - expected.from = "system@loudthinking.com" - expected.date = Time.local(2004, 12, 12) - - # Stub the render method so no alternative renderers need be present. - ActionView::Base.any_instance.stubs(:render).returns("Hello there, \n\nMr. #{@recipient}") - - # Now that the template is registered, there should be one part. The text/plain part. - created = nil - assert_nothing_raised { created = TestMailer.custom_templating_extension(@recipient) } - assert_not_nil created - assert_equal 2, created.parts.length - assert_equal 'text/plain', created.parts[0].mime_type - assert_equal 'text/html', created.parts[1].mime_type - end - - def test_cancelled_account - expected = new_mail - expected.to = @recipient - expected.subject = "[Cancelled] Goodbye #{@recipient}" - expected.body = "Goodbye, Mr. #{@recipient}" - expected.from = "system@loudthinking.com" - expected.date = Time.local(2004, 12, 12) - - created = nil - assert_nothing_raised { created = TestMailer.cancelled_account(@recipient) } - assert_not_nil created - expected.message_id = '<123@456>' - created.message_id = '<123@456>' - assert_equal expected.encoded, created.encoded - - assert_nothing_raised { TestMailer.cancelled_account(@recipient).deliver } - assert_not_nil ActionMailer::Base.deliveries.first - delivered = ActionMailer::Base.deliveries.first - expected.message_id = '<123@456>' - delivered.message_id = '<123@456>' - - assert_equal expected.encoded, delivered.encoded - end - - def test_cc_bcc - expected = new_mail - expected.to = @recipient - expected.subject = "testing bcc/cc" - expected.body = "Nothing to see here." - expected.from = "system@loudthinking.com" - expected.cc = "nobody@loudthinking.com" - expected.bcc = "root@loudthinking.com" - expected.date = Time.local 2004, 12, 12 - - created = nil - assert_nothing_raised do - created = TestMailer.cc_bcc @recipient - end - assert_not_nil created - expected.message_id = '<123@456>' - created.message_id = '<123@456>' - assert_equal expected.encoded, created.encoded - - assert_nothing_raised do - TestMailer.cc_bcc(@recipient).deliver - end - - assert_not_nil ActionMailer::Base.deliveries.first - delivered = ActionMailer::Base.deliveries.first - expected.message_id = '<123@456>' - delivered.message_id = '<123@456>' - - assert_equal expected.encoded, delivered.encoded - end - - def test_from_without_name_for_smtp - TestMailer.delivery_method = :smtp - TestMailer.from_without_name.deliver - - mail = MockSMTP.deliveries.first - assert_not_nil mail - mail, from, to = mail - - assert_equal 'system@loudthinking.com', from.to_s - end - - def test_from_with_name_for_smtp - TestMailer.delivery_method = :smtp - TestMailer.from_with_name.deliver - - mail = MockSMTP.deliveries.first - assert_not_nil mail - mail, from, to = mail - - assert_equal 'system@loudthinking.com', from - end - - def test_reply_to - expected = new_mail - - expected.to = @recipient - expected.subject = "testing reply_to" - expected.body = "Nothing to see here." - expected.from = "system@loudthinking.com" - expected.reply_to = "atraver@gmail.com" - expected.date = Time.local 2008, 5, 23 - - created = nil - assert_nothing_raised do - created = TestMailer.different_reply_to @recipient - end - assert_not_nil created - - expected.message_id = '<123@456>' - created.message_id = '<123@456>' - - assert_equal expected.encoded, created.encoded - - assert_nothing_raised do - TestMailer.different_reply_to(@recipient).deliver - end - - delivered = ActionMailer::Base.deliveries.first - assert_not_nil delivered - - expected.message_id = '<123@456>' - delivered.message_id = '<123@456>' - - assert_equal expected.encoded, delivered.encoded - end - - def test_iso_charset - expected = new_mail( "iso-8859-1" ) - expected.to = @recipient - expected.subject = encode "testing isø charsets", "iso-8859-1" - expected.body = "Nothing to see here." - expected.from = "system@loudthinking.com" - expected.cc = "nobody@loudthinking.com" - expected.bcc = "root@loudthinking.com" - expected.date = Time.local 2004, 12, 12 - - created = nil - assert_nothing_raised do - created = TestMailer.iso_charset @recipient - end - assert_not_nil created - - expected.message_id = '<123@456>' - created.message_id = '<123@456>' - - assert_equal expected.encoded, created.encoded - - assert_nothing_raised do - TestMailer.iso_charset(@recipient).deliver - end - - delivered = ActionMailer::Base.deliveries.first - assert_not_nil delivered - - expected.message_id = '<123@456>' - delivered.message_id = '<123@456>' - - assert_equal expected.encoded, delivered.encoded - end - - def test_unencoded_subject - expected = new_mail - expected.to = @recipient - expected.subject = "testing unencoded subject" - expected.body = "Nothing to see here." - expected.from = "system@loudthinking.com" - expected.cc = "nobody@loudthinking.com" - expected.bcc = "root@loudthinking.com" - expected.date = Time.local 2004, 12, 12 - - created = nil - assert_nothing_raised do - created = TestMailer.unencoded_subject @recipient - end - assert_not_nil created - - expected.message_id = '<123@456>' - created.message_id = '<123@456>' - - assert_equal expected.encoded, created.encoded - - assert_nothing_raised do - TestMailer.unencoded_subject(@recipient).deliver - end - - delivered = ActionMailer::Base.deliveries.first - assert_not_nil delivered - - expected.message_id = '<123@456>' - delivered.message_id = '<123@456>' - - assert_equal expected.encoded, delivered.encoded - end - - def test_deliveries_array - assert_not_nil ActionMailer::Base.deliveries - assert_equal 0, ActionMailer::Base.deliveries.size - TestMailer.signed_up(@recipient).deliver - assert_equal 1, ActionMailer::Base.deliveries.size - assert_not_nil ActionMailer::Base.deliveries.first - end - - def test_perform_deliveries_flag - ActionMailer::Base.perform_deliveries = false - TestMailer.signed_up(@recipient).deliver - assert_equal 0, ActionMailer::Base.deliveries.size - ActionMailer::Base.perform_deliveries = true - TestMailer.signed_up(@recipient).deliver - assert_equal 1, ActionMailer::Base.deliveries.size - end - - def test_doesnt_raise_errors_when_raise_delivery_errors_is_false - ActionMailer::Base.raise_delivery_errors = false - Mail::TestMailer.any_instance.expects(:deliver!).raises(Exception) - assert_nothing_raised { TestMailer.signed_up(@recipient).deliver } - end - - def test_performs_delivery_via_sendmail - IO.expects(:popen).once.with('/usr/sbin/sendmail -i -t -f "system@loudthinking.com" test@localhost', 'w+') - TestMailer.delivery_method = :sendmail - TestMailer.signed_up(@recipient).deliver - end - - def test_unquote_quoted_printable_subject - msg = <" - - expected = new_mail "iso-8859-1" - expected.to = quote_address_if_necessary @recipient, "iso-8859-1" - expected.subject = "testing extended headers" - expected.body = "Nothing to see here." - expected.from = quote_address_if_necessary "Grytøyr ", "iso-8859-1" - expected.cc = quote_address_if_necessary "Grytøyr ", "iso-8859-1" - expected.bcc = quote_address_if_necessary "Grytøyr ", "iso-8859-1" - expected.date = Time.local 2004, 12, 12 - - created = nil - assert_nothing_raised do - created = TestMailer.extended_headers @recipient - end - - assert_not_nil created - expected.message_id = '<123@456>' - created.message_id = '<123@456>' - - assert_equal expected.encoded, created.encoded - - assert_nothing_raised do - TestMailer.extended_headers(@recipient).deliver - end - - delivered = ActionMailer::Base.deliveries.first - assert_not_nil delivered - - expected.message_id = '<123@456>' - delivered.message_id = '<123@456>' - - assert_equal expected.encoded, delivered.encoded - end - - def test_utf8_body_is_not_quoted - @recipient = "Foo áëô îü " - expected = new_mail "utf-8" - expected.to = quote_address_if_necessary @recipient, "utf-8" - 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.date = Time.local 2004, 12, 12 - - created = TestMailer.utf8_body @recipient - assert_match(/åœö blah/, created.encoded) - end - - def test_multiple_utf8_recipients - @recipient = ["\"Foo áëô îü\" ", "\"Example Recipient\" "] - expected = new_mail "utf-8" - expected.to = quote_address_if_necessary @recipient, "utf-8" - 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.date = Time.local 2004, 12, 12 - - created = TestMailer.utf8_body @recipient - assert_match(/\nFrom: =\?utf-8\?Q\?Foo_.*?\?= \r/, created.encoded) - assert_match(/\nTo: =\?utf-8\?Q\?Foo_.*?\?= , \r\n\tExample Recipient _Google}, mail.body.to_s - end - - def test_various_newlines - mail = TestMailer.various_newlines(@recipient) - assert_equal("line #1\nline #2\nline #3\nline #4\n\n" + - "line #5\n\nline#6\n\nline #7", mail.body.to_s) - end - - def test_various_newlines_multipart - mail = TestMailer.various_newlines_multipart(@recipient) - assert_equal "line #1\nline #2\nline #3\nline #4\n\n", mail.parts[0].body.to_s - assert_equal "

line #1

\n

line #2

\n

line #3

\n

line #4

\n\n", mail.parts[1].body.to_s - assert_equal "line #1\r\nline #2\r\nline #3\r\nline #4\r\n\r\n", mail.parts[0].body.encoded - assert_equal "

line #1

\r\n

line #2

\r\n

line #3

\r\n

line #4

\r\n\r\n", mail.parts[1].body.encoded - end - - def test_headers_removed_on_smtp_delivery - TestMailer.delivery_method = :smtp - TestMailer.cc_bcc(@recipient).deliver - assert MockSMTP.deliveries[0][2].include?("root@loudthinking.com") - assert MockSMTP.deliveries[0][2].include?("nobody@loudthinking.com") - assert MockSMTP.deliveries[0][2].include?(@recipient) - assert_match %r{^Cc: nobody@loudthinking.com}, MockSMTP.deliveries[0][0] - assert_match %r{^To: #{@recipient}}, MockSMTP.deliveries[0][0] - assert_no_match %r{^Bcc: root@loudthinking.com}, MockSMTP.deliveries[0][0] - end - - def test_file_delivery_should_create_a_file - ActionMailer::Base.delivery_method = :file - tmp_location = ActionMailer::Base.file_settings[:location] - - TestMailer.cc_bcc(@recipient).deliver - assert File.exists?(tmp_location) - assert File.directory?(tmp_location) - assert File.exists?(File.join(tmp_location, @recipient)) - assert File.exists?(File.join(tmp_location, 'nobody@loudthinking.com')) - assert File.exists?(File.join(tmp_location, 'root@loudthinking.com')) - end - - def test_recursive_multipart_processing - fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email7") - mail = Mail.new(fixture) - assert_equal(2, mail.parts.length) - assert_equal(4, mail.parts.first.parts.length) - assert_equal("This is the first part.", mail.parts.first.parts.first.body.to_s) - assert_equal("test.rb", mail.parts.first.parts.second.filename) - assert_equal("flowed", mail.parts.first.parts.fourth.content_type_parameters[:format]) - assert_equal('smime.p7s', mail.parts.second.filename) - end - - def test_decode_encoded_attachment_filename - fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email8") - mail = Mail.new(fixture) - attachment = mail.attachments.last - - expected = "01 Quien Te Dij\212at. Pitbull.mp3" - - if expected.respond_to?(:force_encoding) - result = attachment.filename.dup - expected.force_encoding(Encoding::ASCII_8BIT) - result.force_encoding(Encoding::ASCII_8BIT) - assert_equal expected, result - else - assert_equal expected, attachment.filename - end - end - - def test_decode_message_with_unknown_charset - fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email10") - mail = Mail.new(fixture) - assert_nothing_raised { mail.body } - end - - def test_empty_header_values_omitted - result = TestMailer.unnamed_attachment(@recipient).encoded - assert_match %r{Content-Type: application/octet-stream;}, result - assert_match %r{Content-Disposition: attachment;}, result - end - - def test_headers_with_nonalpha_chars - mail = TestMailer.headers_with_nonalpha_chars(@recipient) - assert !mail.from_addrs.empty? - assert !mail.cc_addrs.empty? - assert !mail.bcc_addrs.empty? - assert_match(/:/, mail[:from].decoded) - assert_match(/:/, mail[:cc].decoded) - assert_match(/:/, mail[:bcc].decoded) - end - - def test_with_mail_object_deliver - mail = TestMailer.headers_with_nonalpha_chars(@recipient) - assert_nothing_raised { mail.deliver } - assert_equal 1, TestMailer.deliveries.length - end - - 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 - 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 - end - - def test_return_path_with_create - mail = TestMailer.return_path - assert_equal "another@somewhere.test", mail.return_path - end - - def test_return_path_with_deliver - TestMailer.delivery_method = :smtp - TestMailer.return_path.deliver - assert_match %r{^Return-Path: }, MockSMTP.deliveries[0][0] - assert_equal "another@somewhere.test", MockSMTP.deliveries[0][1].to_s - end - - def test_starttls_is_enabled_if_supported - TestMailer.smtp_settings.merge!(:enable_starttls_auto => true) - MockSMTP.any_instance.expects(:respond_to?).with(:enable_starttls_auto).returns(true) - MockSMTP.any_instance.expects(:enable_starttls_auto) - TestMailer.delivery_method = :smtp - TestMailer.signed_up(@recipient).deliver - end - - def test_starttls_is_disabled_if_not_supported - TestMailer.smtp_settings.merge!(:enable_starttls_auto => true) - MockSMTP.any_instance.expects(:respond_to?).with(:enable_starttls_auto).returns(false) - MockSMTP.any_instance.expects(:enable_starttls_auto).never - TestMailer.delivery_method = :smtp - TestMailer.signed_up(@recipient).deliver - end - - def test_starttls_is_not_enabled - TestMailer.smtp_settings.merge!(:enable_starttls_auto => false) - MockSMTP.any_instance.expects(:respond_to?).never - TestMailer.delivery_method = :smtp - TestMailer.signed_up(@recipient).deliver - ensure - TestMailer.smtp_settings.merge!(:enable_starttls_auto => true) - end -end - -class InheritableTemplateRootTest < ActiveSupport::TestCase - def test_attr - expected = File.expand_path("#{File.dirname(__FILE__)}/fixtures/path.with.dots") - assert_equal expected, FunkyPathMailer.template_root.to_s - - sub = Class.new(FunkyPathMailer) - assert_deprecated do - sub.template_root = 'test/path' - end - - assert_equal File.expand_path('test/path'), sub.template_root.to_s - assert_equal expected, FunkyPathMailer.template_root.to_s - end -end - -class MethodNamingTest < ActiveSupport::TestCase - class TestMailer < ActionMailer::Base - def send - render :text => 'foo' - end - end - - def setup - set_delivery_method :test - ActionMailer::Base.perform_deliveries = true - ActionMailer::Base.deliveries.clear - end - - def teardown - restore_delivery_method - end - - def test_send_method - assert_nothing_raised do - assert_emails 1 do - assert_deprecated do - TestMailer.deliver_send - end - end - end - end -end -class RespondToTest < Test::Unit::TestCase - class RespondToMailer < ActionMailer::Base; end - - def setup - set_delivery_method :test - end - - def teardown - restore_delivery_method - end - - def test_should_respond_to_new - assert RespondToMailer.respond_to?(:new) - end - - def test_should_respond_to_create_with_template_suffix - assert RespondToMailer.respond_to?(:create_any_old_template) - end - - def test_should_respond_to_deliver_with_template_suffix - assert RespondToMailer.respond_to?(:deliver_any_old_template) - end - - def test_should_not_respond_to_new_with_template_suffix - assert !RespondToMailer.respond_to?(:new_any_old_template) - end - - def test_should_not_respond_to_create_with_template_suffix_unless_it_is_separated_by_an_underscore - assert !RespondToMailer.respond_to?(:createany_old_template) - end - - def test_should_not_respond_to_deliver_with_template_suffix_unless_it_is_separated_by_an_underscore - assert !RespondToMailer.respond_to?(:deliverany_old_template) - end - - def test_should_not_respond_to_create_with_template_suffix_if_it_begins_with_a_uppercase_letter - assert !RespondToMailer.respond_to?(:create_Any_old_template) - end - - def test_should_not_respond_to_deliver_with_template_suffix_if_it_begins_with_a_uppercase_letter - assert !RespondToMailer.respond_to?(:deliver_Any_old_template) - end - - def test_should_not_respond_to_create_with_template_suffix_if_it_begins_with_a_digit - assert !RespondToMailer.respond_to?(:create_1_template) - end - - def test_should_not_respond_to_deliver_with_template_suffix_if_it_begins_with_a_digit - assert !RespondToMailer.respond_to?(:deliver_1_template) - end - - def test_should_not_respond_to_method_where_deliver_is_not_a_suffix - assert !RespondToMailer.respond_to?(:foo_deliver_template) - end - - def test_should_still_raise_exception_with_expected_message_when_calling_an_undefined_method - error = assert_raise NoMethodError do - RespondToMailer.not_a_method - end - - assert_match(/undefined method.*not_a_method/, error.message) - end -end \ No newline at end of file diff --git a/actionmailer/test/mail_test.rb b/actionmailer/test/mail_test.rb index ea6f25d157..f18dfdc156 100644 --- a/actionmailer/test/mail_test.rb +++ b/actionmailer/test/mail_test.rb @@ -8,7 +8,6 @@ class MailTest < Test::Unit::TestCase quoted_body = [expected].pack('*M') m.body = quoted_body assert_equal "something_with_underscores=\r\n", m.body.encoded - # CHANGED: body returns object, not string, Changed m.body to m.body.to_s assert_equal expected, m.body.to_s end @@ -20,5 +19,4 @@ class MailTest < Test::Unit::TestCase assert_equal 1902, mail.attachments.first.decoded.length assert_equal "application/pkcs7-signature", mail.attachments.last.mime_type end - end diff --git a/actionmailer/test/old_base/adv_attr_test.rb b/actionmailer/test/old_base/adv_attr_test.rb new file mode 100644 index 0000000000..f22d733bc5 --- /dev/null +++ b/actionmailer/test/old_base/adv_attr_test.rb @@ -0,0 +1,36 @@ +require 'abstract_unit' +require 'action_mailer/adv_attr_accessor' + +class AdvAttrTest < ActiveSupport::TestCase + class Person + cattr_reader :protected_instance_variables + @@protected_instance_variables = [] + + extend ActionMailer::AdvAttrAccessor + adv_attr_accessor :name + end + + def setup + @person = Person.new + end + + def test_adv_attr + assert_nil @person.name + @person.name 'Bob' + assert_equal 'Bob', @person.name + end + + def test_adv_attr_writer + assert_nil @person.name + @person.name = 'Bob' + assert_equal 'Bob', @person.name + end + + def test_raise_an_error_with_multiple_args + assert_raise(ArgumentError) { @person.name('x', 'y') } + end + + def test_ivar_is_added_to_protected_instnace_variables + assert Person.protected_instance_variables.include?('@name') + end +end diff --git a/actionmailer/test/old_base/asset_host_test.rb b/actionmailer/test/old_base/asset_host_test.rb new file mode 100644 index 0000000000..124032f1d9 --- /dev/null +++ b/actionmailer/test/old_base/asset_host_test.rb @@ -0,0 +1,52 @@ +require 'abstract_unit' + +class AssetHostMailer < ActionMailer::Base + def email_with_asset + recipients 'test@localhost' + subject "testing email containing asset path while asset_host is set" + from "tester@example.com" + end +end + +class AssetHostTest < Test::Unit::TestCase + def setup + set_delivery_method :test + ActionMailer::Base.perform_deliveries = true + ActionMailer::Base.deliveries.clear + end + + def teardown + restore_delivery_method + end + + def test_asset_host_as_string + ActionController::Base.asset_host = "http://www.example.com" + mail = AssetHostMailer.email_with_asset + assert_equal "\"Somelogo\"", mail.body.to_s.strip + end + + def test_asset_host_as_one_arguement_proc + ActionController::Base.asset_host = Proc.new { |source| + if source.starts_with?('/images') + "http://images.example.com" + else + "http://assets.example.com" + end + } + mail = AssetHostMailer.email_with_asset + assert_equal "\"Somelogo\"", mail.body.to_s.strip + end + + def test_asset_host_as_two_arguement_proc + ActionController::Base.asset_host = Proc.new {|source,request| + if request && request.ssl? + "https://www.example.com" + else + "http://www.example.com" + end + } + mail = nil + assert_nothing_raised { mail = AssetHostMailer.email_with_asset } + assert_equal "\"Somelogo\"", mail.body.to_s.strip + end +end \ No newline at end of file diff --git a/actionmailer/test/old_base/mail_helper_test.rb b/actionmailer/test/old_base/mail_helper_test.rb new file mode 100644 index 0000000000..a9b3cd3ce1 --- /dev/null +++ b/actionmailer/test/old_base/mail_helper_test.rb @@ -0,0 +1,94 @@ +require 'abstract_unit' + +module MailerHelper + def person_name + "Mr. Joe Person" + end +end + +class HelperMailer < ActionMailer::Base + helper MailerHelper + helper :example + + def use_helper + recipients 'test@localhost' + subject "using helpers" + from "tester@example.com" + end + + def use_example_helper + recipients 'test@localhost' + subject "using helpers" + from "tester@example.com" + + @text = "emphasize me!" + end + + def use_mail_helper + recipients 'test@localhost' + subject "using mailing helpers" + from "tester@example.com" + + @text = "But soft! What light through yonder window breaks? It is the east, " + + "and Juliet is the sun. Arise, fair sun, and kill the envious moon, " + + "which is sick and pale with grief that thou, her maid, art far more " + + "fair than she. Be not her maid, for she is envious! Her vestal " + + "livery is but sick and green, and none but fools do wear it. Cast " + + "it off!" + end + + def use_helper_method + recipients 'test@localhost' + subject "using helpers" + from "tester@example.com" + + @text = "emphasize me!" + end + + private + + def name_of_the_mailer_class + self.class.name + end + helper_method :name_of_the_mailer_class +end + +class MailerHelperTest < ActiveSupport::TestCase + def new_mail( charset="utf-8" ) + mail = Mail.new + mail.set_content_type "text", "plain", { "charset" => charset } if charset + mail + end + + def setup + set_delivery_method :test + ActionMailer::Base.perform_deliveries = true + ActionMailer::Base.deliveries.clear + end + + def teardown + restore_delivery_method + end + + def test_use_helper + mail = HelperMailer.use_helper + assert_match %r{Mr. Joe Person}, mail.encoded + end + + def test_use_example_helper + mail = HelperMailer.use_example_helper + assert_match %r{emphasize me!}, mail.encoded + end + + def test_use_helper_method + mail = HelperMailer.use_helper_method + assert_match %r{HelperMailer}, mail.encoded + end + + def test_use_mail_helper + mail = HelperMailer.use_mail_helper + assert_match %r{ But soft!}, mail.encoded + assert_match %r{east, and\r\n Juliet}, mail.encoded + end +end + diff --git a/actionmailer/test/old_base/mail_layout_test.rb b/actionmailer/test/old_base/mail_layout_test.rb new file mode 100644 index 0000000000..4038fbf339 --- /dev/null +++ b/actionmailer/test/old_base/mail_layout_test.rb @@ -0,0 +1,148 @@ +require 'abstract_unit' + +class AutoLayoutMailer < ActionMailer::Base + + def hello + recipients 'test@localhost' + subject "You have a mail" + from "tester@example.com" + end + + def spam + recipients 'test@localhost' + subject "You have a mail" + from "tester@example.com" + + @world = "Earth" + render(:inline => "Hello, <%= @world %>", :layout => 'spam') + end + + def nolayout + recipients 'test@localhost' + subject "You have a mail" + from "tester@example.com" + + @world = "Earth" + render(:inline => "Hello, <%= @world %>", :layout => false) + end + + def multipart(type = nil) + recipients 'test@localhost' + subject "You have a mail" + from "tester@example.com" + + content_type(type) if type + end +end + +class ExplicitLayoutMailer < ActionMailer::Base + layout 'spam', :except => [:logout] + + def signup + recipients 'test@localhost' + subject "You have a mail" + from "tester@example.com" + end + + def logout + recipients 'test@localhost' + subject "You have a mail" + from "tester@example.com" + end +end + +class LayoutMailerTest < Test::Unit::TestCase + def setup + set_delivery_method :test + ActionMailer::Base.perform_deliveries = true + ActionMailer::Base.deliveries.clear + end + + def teardown + restore_delivery_method + end + + def test_should_pickup_default_layout + mail = AutoLayoutMailer.hello + assert_equal "Hello from layout Inside", mail.body.to_s.strip + end + + def test_should_pickup_multipart_layout + mail = AutoLayoutMailer.multipart + # CHANGED: content_type returns an object + # assert_equal "multipart/alternative", mail.content_type + assert_equal "multipart/alternative", mail.mime_type + assert_equal 2, mail.parts.size + + # CHANGED: content_type returns an object + # assert_equal 'text/plain', mail.parts.first.content_type + assert_equal 'text/plain', mail.parts.first.mime_type + + # CHANGED: body returns an object + # assert_equal "text/plain layout - text/plain multipart", mail.parts.first.body + assert_equal "text/plain layout - text/plain multipart", mail.parts.first.body.to_s + + # CHANGED: content_type returns an object + # assert_equal 'text/html', mail.parts.last.content_type + assert_equal 'text/html', mail.parts.last.mime_type + + # CHANGED: body returns an object + # assert_equal "Hello from layout text/html multipart", mail.parts.last.body + assert_equal "Hello from layout text/html multipart", mail.parts.last.body.to_s + end + + def test_should_pickup_multipartmixed_layout + mail = AutoLayoutMailer.multipart("multipart/mixed") + # CHANGED: content_type returns an object + # assert_equal "multipart/mixed", mail.content_type + assert_equal "multipart/mixed", mail.mime_type + assert_equal 2, mail.parts.size + + # CHANGED: content_type returns an object + # assert_equal 'text/plain', mail.parts.first.content_type + assert_equal 'text/plain', mail.parts.first.mime_type + # CHANGED: body returns an object + # assert_equal "text/plain layout - text/plain multipart", mail.parts.first.body + assert_equal "text/plain layout - text/plain multipart", mail.parts.first.body.to_s + + # CHANGED: content_type returns an object + # assert_equal 'text/html', mail.parts.last.content_type + assert_equal 'text/html', mail.parts.last.mime_type + # CHANGED: body returns an object + # assert_equal "Hello from layout text/html multipart", mail.parts.last.body + assert_equal "Hello from layout text/html multipart", mail.parts.last.body.to_s + end + + def test_should_fix_multipart_layout + mail = AutoLayoutMailer.multipart("text/plain") + assert_equal "multipart/alternative", mail.mime_type + assert_equal 2, mail.parts.size + + assert_equal 'text/plain', mail.parts.first.mime_type + assert_equal "text/plain layout - text/plain multipart", mail.parts.first.body.to_s + + assert_equal 'text/html', mail.parts.last.mime_type + assert_equal "Hello from layout text/html multipart", mail.parts.last.body.to_s + end + + + def test_should_pickup_layout_given_to_render + mail = AutoLayoutMailer.spam + assert_equal "Spammer layout Hello, Earth", mail.body.to_s.strip + end + + def test_should_respect_layout_false + mail = AutoLayoutMailer.nolayout + assert_equal "Hello, Earth", mail.body.to_s.strip + end + + def test_explicit_class_layout + mail = ExplicitLayoutMailer.signup + assert_equal "Spammer layout We do not spam", mail.body.to_s.strip + end + + def test_explicit_layout_exceptions + mail = ExplicitLayoutMailer.logout + assert_equal "You logged out", mail.body.to_s.strip + end +end diff --git a/actionmailer/test/old_base/mail_render_test.rb b/actionmailer/test/old_base/mail_render_test.rb new file mode 100644 index 0000000000..804200fd36 --- /dev/null +++ b/actionmailer/test/old_base/mail_render_test.rb @@ -0,0 +1,157 @@ +require 'abstract_unit' + +class RenderMailer < ActionMailer::Base + def inline_template + recipients 'test@localhost' + subject "using helpers" + from "tester@example.com" + + @world = "Earth" + render :inline => "Hello, <%= @world %>" + end + + def file_template + recipients 'test@localhost' + subject "using helpers" + from "tester@example.com" + + @recipient = 'test@localhost' + render :file => "templates/signed_up" + end + + def implicit_body + recipients 'test@localhost' + subject "using helpers" + from "tester@example.com" + + @recipient = 'test@localhost' + render :template => "templates/signed_up" + end + + def rxml_template + recipients 'test@localhost' + subject "rendering rxml template" + from "tester@example.com" + end + + def included_subtemplate + recipients 'test@localhost' + subject "Including another template in the one being rendered" + from "tester@example.com" + end + + def mailer_accessor + recipients 'test@localhost' + subject "Mailer Accessor" + from "tester@example.com" + + render :inline => "Look, <%= mailer.subject %>!" + end + + def no_instance_variable + recipients 'test@localhost' + subject "No Instance Variable" + from "tester@example.com" + + silence_warnings do + render :inline => "Look, subject.nil? is <%= @subject.nil? %>!" + end + end + + def initialize_defaults(method_name) + super + mailer_name "test_mailer" + end +end + +class FirstMailer < ActionMailer::Base + def share + recipients 'test@localhost' + subject "using helpers" + from "tester@example.com" + end +end + +class SecondMailer < ActionMailer::Base + def share + recipients 'test@localhost' + subject "using helpers" + from "tester@example.com" + end +end + +# CHANGED: Those tests were changed because body returns an object now +# Instead of mail.body.strip, we should mail.body.to_s.strip +class RenderHelperTest < Test::Unit::TestCase + def setup + set_delivery_method :test + ActionMailer::Base.perform_deliveries = true + ActionMailer::Base.deliveries.clear + + @recipient = 'test@localhost' + end + + def teardown + restore_delivery_method + end + + def test_implicit_body + mail = RenderMailer.implicit_body + assert_equal "Hello there, \n\nMr. test@localhost", mail.body.to_s.strip + end + + def test_inline_template + mail = RenderMailer.inline_template + assert_equal "Hello, Earth", mail.body.to_s.strip + end + + def test_file_template + mail = RenderMailer.file_template + assert_equal "Hello there, \n\nMr. test@localhost", mail.body.to_s.strip + end + + def test_rxml_template + mail = RenderMailer.rxml_template.deliver + assert_equal "\n", mail.body.to_s.strip + end + + def test_included_subtemplate + mail = RenderMailer.included_subtemplate.deliver + assert_equal "Hey Ho, let's go!", mail.body.to_s.strip + end + + def test_mailer_accessor + mail = RenderMailer.mailer_accessor.deliver + assert_equal "Look, Mailer Accessor!", mail.body.to_s.strip + end + + def test_no_instance_variable + mail = RenderMailer.no_instance_variable.deliver + assert_equal "Look, subject.nil? is true!", mail.body.to_s.strip + end +end + +class FirstSecondHelperTest < Test::Unit::TestCase + def setup + set_delivery_method :test + ActionMailer::Base.perform_deliveries = true + ActionMailer::Base.deliveries.clear + + @recipient = 'test@localhost' + end + + def teardown + restore_delivery_method + end + + def test_ordering + mail = FirstMailer.share + assert_equal "first mail", mail.body.to_s.strip + mail = SecondMailer.share + assert_equal "second mail", mail.body.to_s.strip + mail = FirstMailer.share + assert_equal "first mail", mail.body.to_s.strip + mail = SecondMailer.share + assert_equal "second mail", mail.body.to_s.strip + end +end diff --git a/actionmailer/test/old_base/mail_service_test.rb b/actionmailer/test/old_base/mail_service_test.rb new file mode 100644 index 0000000000..20b0f30b84 --- /dev/null +++ b/actionmailer/test/old_base/mail_service_test.rb @@ -0,0 +1,1192 @@ +# encoding: utf-8 +require 'abstract_unit' + +class FunkyPathMailer < ActionMailer::Base + self.view_paths = "#{File.dirname(__FILE__)}/../fixtures/path.with.dots" + + def multipart_with_template_path_with_dots(recipient) + recipients recipient + subject "This path has dots" + from "Chad Fowler " + attachment :content_type => "text/plain", + :data => "dots dots dots..." + end +end + +class TestMailer < ActionMailer::Base + def signed_up(recipient) + recipients recipient + subject "[Signed up] Welcome #{recipient}" + from "system@loudthinking.com" + + @recipient = recipient + end + + def cancelled_account(recipient) + recipients recipient + subject "[Cancelled] Goodbye #{recipient}" + from "system@loudthinking.com" + sent_on Time.local(2004, 12, 12) + + render :text => "Goodbye, Mr. #{recipient}" + end + + def from_with_name + from "System " + recipients "root@loudthinking.com" + render :text => "Nothing to see here." + end + + def from_without_name + from "system@loudthinking.com" + recipients "root@loudthinking.com" + render :text => "Nothing to see here." + end + + def cc_bcc(recipient) + recipients recipient + subject "testing bcc/cc" + from "system@loudthinking.com" + sent_on Time.local(2004, 12, 12) + cc "nobody@loudthinking.com" + bcc "root@loudthinking.com" + + render :text => "Nothing to see here." + end + + def different_reply_to(recipient) + recipients recipient + subject "testing reply_to" + from "system@loudthinking.com" + sent_on Time.local(2008, 5, 23) + reply_to "atraver@gmail.com" + + render :text => "Nothing to see here." + end + + def iso_charset(recipient) + recipients recipient + subject "testing isø charsets" + from "system@loudthinking.com" + sent_on Time.local(2004, 12, 12) + cc "nobody@loudthinking.com" + bcc "root@loudthinking.com" + charset "iso-8859-1" + + render :text => "Nothing to see here." + end + + def unencoded_subject(recipient) + recipients recipient + subject "testing unencoded subject" + from "system@loudthinking.com" + sent_on Time.local(2004, 12, 12) + cc "nobody@loudthinking.com" + bcc "root@loudthinking.com" + + render :text => "Nothing to see here." + end + + def extended_headers(recipient) + recipients recipient + subject "testing extended headers" + from "Grytøyr " + sent_on Time.local(2004, 12, 12) + cc "Grytøyr " + bcc "Grytøyr " + charset "iso-8859-1" + + render :text => "Nothing to see here." + end + + def utf8_body(recipient) + recipients recipient + subject "testing utf-8 body" + from "Foo áëô îü " + sent_on Time.local(2004, 12, 12) + cc "Foo áëô îü " + bcc "Foo áëô îü " + charset "utf-8" + + render :text => "åœö blah" + end + + def multipart_with_mime_version(recipient) + recipients recipient + subject "multipart with mime_version" + from "test@example.com" + sent_on Time.local(2004, 12, 12) + mime_version "1.1" + content_type "multipart/alternative" + + part "text/plain" do |p| + p.body = render(:text => "blah") + end + + part "text/html" do |p| + p.body = render(:inline => "<%= content_tag(:b, 'blah') %>") + end + end + + def multipart_with_utf8_subject(recipient) + recipients recipient + subject "Foo áëô îü" + from "test@example.com" + charset "utf-8" + + part "text/plain" do |p| + p.body = "blah" + end + + part "text/html" do |p| + p.body = "blah" + end + end + + def explicitly_multipart_example(recipient, ct=nil) + recipients recipient + subject "multipart example" + from "test@example.com" + sent_on Time.local(2004, 12, 12) + content_type ct if ct + + part "text/html" do |p| + p.charset = "iso-8859-1" + p.body = "blah" + end + + attachment :content_type => "image/jpeg", :filename => File.join(File.dirname(__FILE__), "fixtures", "attachments", "foo.jpg"), + :data => "123456789" + + render :text => "plain text default" + end + + def implicitly_multipart_example(recipient, cs = nil, order = nil) + recipients recipient + subject "multipart example" + from "test@example.com" + sent_on Time.local(2004, 12, 12) + + @charset = cs if cs + @recipient = recipient + @implicit_parts_order = order if order + end + + def implicitly_multipart_with_utf8 + recipients "no.one@nowhere.test" + subject "Foo áëô îü" + from "some.one@somewhere.test" + template "implicitly_multipart_example" + + @recipient = "no.one@nowhere.test" + end + + def html_mail(recipient) + recipients recipient + subject "html mail" + from "test@example.com" + content_type "text/html" + + render :text => "Emphasize this" + end + + def html_mail_with_underscores(recipient) + subject "html mail with underscores" + render :text => %{_Google} + end + + def custom_template(recipient) + recipients recipient + subject "[Signed up] Welcome #{recipient}" + from "system@loudthinking.com" + sent_on Time.local(2004, 12, 12) + template "signed_up" + + @recipient = recipient + end + + def custom_templating_extension(recipient) + recipients recipient + subject "[Signed up] Welcome #{recipient}" + from "system@loudthinking.com" + sent_on Time.local(2004, 12, 12) + + @recipient = recipient + end + + def various_newlines(recipient) + recipients recipient + subject "various newlines" + from "test@example.com" + + render :text => "line #1\nline #2\rline #3\r\nline #4\r\r" + + "line #5\n\nline#6\r\n\r\nline #7" + end + + def various_newlines_multipart(recipient) + recipients recipient + subject "various newlines multipart" + from "test@example.com" + content_type "multipart/alternative" + + part :content_type => "text/plain", :body => "line #1\nline #2\rline #3\r\nline #4\r\r" + part :content_type => "text/html", :body => "

line #1

\n

line #2

\r

line #3

\r\n

line #4

\r\r" + end + + def nested_multipart(recipient) + recipients recipient + subject "nested multipart" + from "test@example.com" + content_type "multipart/mixed" + + part :content_type => "multipart/alternative", :content_disposition => "inline", "foo" => "bar" do |p| + p.part :content_type => "text/plain", :body => "test text\nline #2" + p.part :content_type => "text/html", :body => "test HTML
\nline #2" + end + + attachment :content_type => "application/octet-stream", :filename => "test.txt", :data => "test abcdefghijklmnopqstuvwxyz" + end + + def nested_multipart_with_body(recipient) + recipients recipient + subject "nested multipart with body" + from "test@example.com" + content_type "multipart/mixed" + + part :content_type => "multipart/alternative", :content_disposition => "inline", :body => "Nothing to see here." do |p| + p.part :content_type => "text/html", :body => "test HTML
" + end + end + + def attachment_with_custom_header(recipient) + recipients recipient + subject "custom header in attachment" + from "test@example.com" + content_type "multipart/related" + part :content_type => "text/html", :body => 'yo' + attachment :content_type => "image/jpeg", :filename => File.join(File.dirname(__FILE__), "fixtures", "attachments", "test.jpg"), :data => "i am not a real picture", 'Content-ID' => '' + end + + def unnamed_attachment(recipient) + recipients recipient + subject "nested multipart" + from "test@example.com" + content_type "multipart/mixed" + part :content_type => "text/plain", :body => "hullo" + attachment :content_type => "application/octet-stream", :data => "test abcdefghijklmnopqstuvwxyz" + end + + def headers_with_nonalpha_chars(recipient) + recipients recipient + subject "nonalpha chars" + from "One: Two " + cc "Three: Four " + bcc "Five: Six " + render :text => "testing" + end + + def custom_content_type_attributes + recipients "no.one@nowhere.test" + subject "custom content types" + from "some.one@somewhere.test" + content_type "text/plain; format=flowed" + render :text => "testing" + end + + def return_path + recipients "no.one@nowhere.test" + subject "return path test" + from "some.one@somewhere.test" + headers["return-path"] = "another@somewhere.test" + render :text => "testing" + end + + def subject_with_i18n(recipient) + recipients recipient + from "system@loudthinking.com" + render :text => "testing" + end + + class << self + attr_accessor :received_body + end + + def receive(mail) + self.class.received_body = mail.body + end +end + +class ActionMailerTest < Test::Unit::TestCase + include ActionMailer::Quoting + + def encode( text, charset="utf-8" ) + quoted_printable( text, charset ) + end + + def new_mail( charset="utf-8" ) + mail = Mail.new + mail.mime_version = "1.0" + if charset + mail.content_type ["text", "plain", { "charset" => charset }] + end + mail + end + + # Replacing logger work around for mocha bug. Should be fixed in mocha 0.3.3 + def setup + set_delivery_method :test + ActionMailer::Base.perform_deliveries = true + ActionMailer::Base.raise_delivery_errors = true + ActionMailer::Base.deliveries.clear + + @original_logger = TestMailer.logger + @recipient = 'test@localhost' + end + + def teardown + TestMailer.logger = @original_logger + restore_delivery_method + end + + def test_nested_parts + created = nil + assert_nothing_raised { created = TestMailer.nested_multipart(@recipient)} + assert_equal 2, created.parts.size + assert_equal 2, created.parts.first.parts.size + + 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_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 + + end + + def test_nested_parts_with_body + created = nil + TestMailer.nested_multipart_with_body(@recipient) + assert_nothing_raised { created = TestMailer.nested_multipart_with_body(@recipient)} + + assert_equal 1,created.parts.size + assert_equal 2,created.parts.first.parts.size + + assert_equal "multipart/mixed", created.mime_type + assert_equal "multipart/alternative", created.parts.first.mime_type + assert_equal "text/plain", created.parts.first.parts.first.mime_type + assert_equal "Nothing to see here.", created.parts.first.parts.first.body.to_s + assert_equal "text/html", created.parts.first.parts.second.mime_type + assert_equal "test HTML
", created.parts.first.parts.second.body.to_s + end + + def test_attachment_with_custom_header + created = nil + assert_nothing_raised { created = TestMailer.attachment_with_custom_header(@recipient) } + assert created.parts.any? { |p| p.header['content-id'].to_s == "" } + end + + def test_signed_up + Time.stubs(:now => Time.now) + + expected = new_mail + expected.to = @recipient + expected.subject = "[Signed up] Welcome #{@recipient}" + expected.body = "Hello there, \n\nMr. #{@recipient}" + expected.from = "system@loudthinking.com" + expected.date = Time.now + + created = nil + assert_nothing_raised { created = TestMailer.signed_up(@recipient) } + assert_not_nil created + + expected.message_id = '<123@456>' + created.message_id = '<123@456>' + + assert_equal expected.encoded, created.encoded + + assert_nothing_raised { TestMailer.signed_up(@recipient).deliver } + + delivered = ActionMailer::Base.deliveries.first + assert_not_nil delivered + + expected.message_id = '<123@456>' + delivered.message_id = '<123@456>' + + assert_equal expected.encoded, delivered.encoded + end + + def test_custom_template + expected = new_mail + expected.to = @recipient + expected.subject = "[Signed up] Welcome #{@recipient}" + expected.body = "Hello there, \n\nMr. #{@recipient}" + expected.from = "system@loudthinking.com" + expected.date = Time.local(2004, 12, 12) + + created = nil + assert_nothing_raised { created = TestMailer.custom_template(@recipient) } + assert_not_nil created + expected.message_id = '<123@456>' + created.message_id = '<123@456>' + assert_equal expected.encoded, created.encoded + end + + def test_custom_templating_extension + assert ActionView::Template.template_handler_extensions.include?("haml"), "haml extension was not registered" + + # N.b., custom_templating_extension.text.plain.haml is expected to be in fixtures/test_mailer directory + expected = new_mail + expected.to = @recipient + expected.subject = "[Signed up] Welcome #{@recipient}" + expected.body = "Hello there, \n\nMr. #{@recipient}" + expected.from = "system@loudthinking.com" + expected.date = Time.local(2004, 12, 12) + + # Stub the render method so no alternative renderers need be present. + ActionView::Base.any_instance.stubs(:render).returns("Hello there, \n\nMr. #{@recipient}") + + # Now that the template is registered, there should be one part. The text/plain part. + created = nil + assert_nothing_raised { created = TestMailer.custom_templating_extension(@recipient) } + assert_not_nil created + assert_equal 2, created.parts.length + assert_equal 'text/plain', created.parts[0].mime_type + assert_equal 'text/html', created.parts[1].mime_type + end + + def test_cancelled_account + expected = new_mail + expected.to = @recipient + expected.subject = "[Cancelled] Goodbye #{@recipient}" + expected.body = "Goodbye, Mr. #{@recipient}" + expected.from = "system@loudthinking.com" + expected.date = Time.local(2004, 12, 12) + + created = nil + assert_nothing_raised { created = TestMailer.cancelled_account(@recipient) } + assert_not_nil created + expected.message_id = '<123@456>' + created.message_id = '<123@456>' + assert_equal expected.encoded, created.encoded + + assert_nothing_raised { TestMailer.cancelled_account(@recipient).deliver } + assert_not_nil ActionMailer::Base.deliveries.first + delivered = ActionMailer::Base.deliveries.first + expected.message_id = '<123@456>' + delivered.message_id = '<123@456>' + + assert_equal expected.encoded, delivered.encoded + end + + def test_cc_bcc + expected = new_mail + expected.to = @recipient + expected.subject = "testing bcc/cc" + expected.body = "Nothing to see here." + expected.from = "system@loudthinking.com" + expected.cc = "nobody@loudthinking.com" + expected.bcc = "root@loudthinking.com" + expected.date = Time.local 2004, 12, 12 + + created = nil + assert_nothing_raised do + created = TestMailer.cc_bcc @recipient + end + assert_not_nil created + expected.message_id = '<123@456>' + created.message_id = '<123@456>' + assert_equal expected.encoded, created.encoded + + assert_nothing_raised do + TestMailer.cc_bcc(@recipient).deliver + end + + assert_not_nil ActionMailer::Base.deliveries.first + delivered = ActionMailer::Base.deliveries.first + expected.message_id = '<123@456>' + delivered.message_id = '<123@456>' + + assert_equal expected.encoded, delivered.encoded + end + + def test_from_without_name_for_smtp + TestMailer.delivery_method = :smtp + TestMailer.from_without_name.deliver + + mail = MockSMTP.deliveries.first + assert_not_nil mail + mail, from, to = mail + + assert_equal 'system@loudthinking.com', from.to_s + end + + def test_from_with_name_for_smtp + TestMailer.delivery_method = :smtp + TestMailer.from_with_name.deliver + + mail = MockSMTP.deliveries.first + assert_not_nil mail + mail, from, to = mail + + assert_equal 'system@loudthinking.com', from + end + + def test_reply_to + expected = new_mail + + expected.to = @recipient + expected.subject = "testing reply_to" + expected.body = "Nothing to see here." + expected.from = "system@loudthinking.com" + expected.reply_to = "atraver@gmail.com" + expected.date = Time.local 2008, 5, 23 + + created = nil + assert_nothing_raised do + created = TestMailer.different_reply_to @recipient + end + assert_not_nil created + + expected.message_id = '<123@456>' + created.message_id = '<123@456>' + + assert_equal expected.encoded, created.encoded + + assert_nothing_raised do + TestMailer.different_reply_to(@recipient).deliver + end + + delivered = ActionMailer::Base.deliveries.first + assert_not_nil delivered + + expected.message_id = '<123@456>' + delivered.message_id = '<123@456>' + + assert_equal expected.encoded, delivered.encoded + end + + def test_iso_charset + expected = new_mail( "iso-8859-1" ) + expected.to = @recipient + expected.subject = encode "testing isø charsets", "iso-8859-1" + expected.body = "Nothing to see here." + expected.from = "system@loudthinking.com" + expected.cc = "nobody@loudthinking.com" + expected.bcc = "root@loudthinking.com" + expected.date = Time.local 2004, 12, 12 + + created = nil + assert_nothing_raised do + created = TestMailer.iso_charset @recipient + end + assert_not_nil created + + expected.message_id = '<123@456>' + created.message_id = '<123@456>' + + assert_equal expected.encoded, created.encoded + + assert_nothing_raised do + TestMailer.iso_charset(@recipient).deliver + end + + delivered = ActionMailer::Base.deliveries.first + assert_not_nil delivered + + expected.message_id = '<123@456>' + delivered.message_id = '<123@456>' + + assert_equal expected.encoded, delivered.encoded + end + + def test_unencoded_subject + expected = new_mail + expected.to = @recipient + expected.subject = "testing unencoded subject" + expected.body = "Nothing to see here." + expected.from = "system@loudthinking.com" + expected.cc = "nobody@loudthinking.com" + expected.bcc = "root@loudthinking.com" + expected.date = Time.local 2004, 12, 12 + + created = nil + assert_nothing_raised do + created = TestMailer.unencoded_subject @recipient + end + assert_not_nil created + + expected.message_id = '<123@456>' + created.message_id = '<123@456>' + + assert_equal expected.encoded, created.encoded + + assert_nothing_raised do + TestMailer.unencoded_subject(@recipient).deliver + end + + delivered = ActionMailer::Base.deliveries.first + assert_not_nil delivered + + expected.message_id = '<123@456>' + delivered.message_id = '<123@456>' + + assert_equal expected.encoded, delivered.encoded + end + + def test_deliveries_array + assert_not_nil ActionMailer::Base.deliveries + assert_equal 0, ActionMailer::Base.deliveries.size + TestMailer.signed_up(@recipient).deliver + assert_equal 1, ActionMailer::Base.deliveries.size + assert_not_nil ActionMailer::Base.deliveries.first + end + + def test_perform_deliveries_flag + ActionMailer::Base.perform_deliveries = false + TestMailer.signed_up(@recipient).deliver + assert_equal 0, ActionMailer::Base.deliveries.size + ActionMailer::Base.perform_deliveries = true + TestMailer.signed_up(@recipient).deliver + assert_equal 1, ActionMailer::Base.deliveries.size + end + + def test_doesnt_raise_errors_when_raise_delivery_errors_is_false + ActionMailer::Base.raise_delivery_errors = false + Mail::TestMailer.any_instance.expects(:deliver!).raises(Exception) + assert_nothing_raised { TestMailer.signed_up(@recipient).deliver } + end + + def test_performs_delivery_via_sendmail + IO.expects(:popen).once.with('/usr/sbin/sendmail -i -t -f "system@loudthinking.com" test@localhost', 'w+') + TestMailer.delivery_method = :sendmail + TestMailer.signed_up(@recipient).deliver + end + + def test_unquote_quoted_printable_subject + msg = <" + + expected = new_mail "iso-8859-1" + expected.to = quote_address_if_necessary @recipient, "iso-8859-1" + expected.subject = "testing extended headers" + expected.body = "Nothing to see here." + expected.from = quote_address_if_necessary "Grytøyr ", "iso-8859-1" + expected.cc = quote_address_if_necessary "Grytøyr ", "iso-8859-1" + expected.bcc = quote_address_if_necessary "Grytøyr ", "iso-8859-1" + expected.date = Time.local 2004, 12, 12 + + created = nil + assert_nothing_raised do + created = TestMailer.extended_headers @recipient + end + + assert_not_nil created + expected.message_id = '<123@456>' + created.message_id = '<123@456>' + + assert_equal expected.encoded, created.encoded + + assert_nothing_raised do + TestMailer.extended_headers(@recipient).deliver + end + + delivered = ActionMailer::Base.deliveries.first + assert_not_nil delivered + + expected.message_id = '<123@456>' + delivered.message_id = '<123@456>' + + assert_equal expected.encoded, delivered.encoded + end + + def test_utf8_body_is_not_quoted + @recipient = "Foo áëô îü " + expected = new_mail "utf-8" + expected.to = quote_address_if_necessary @recipient, "utf-8" + 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.date = Time.local 2004, 12, 12 + + created = TestMailer.utf8_body @recipient + assert_match(/åœö blah/, created.encoded) + end + + def test_multiple_utf8_recipients + @recipient = ["\"Foo áëô îü\" ", "\"Example Recipient\" "] + expected = new_mail "utf-8" + expected.to = quote_address_if_necessary @recipient, "utf-8" + 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.date = Time.local 2004, 12, 12 + + created = TestMailer.utf8_body @recipient + assert_match(/\nFrom: =\?utf-8\?Q\?Foo_.*?\?= \r/, created.encoded) + assert_match(/\nTo: =\?utf-8\?Q\?Foo_.*?\?= , \r\n\tExample Recipient _Google}, mail.body.to_s + end + + def test_various_newlines + mail = TestMailer.various_newlines(@recipient) + assert_equal("line #1\nline #2\nline #3\nline #4\n\n" + + "line #5\n\nline#6\n\nline #7", mail.body.to_s) + end + + def test_various_newlines_multipart + mail = TestMailer.various_newlines_multipart(@recipient) + assert_equal "line #1\nline #2\nline #3\nline #4\n\n", mail.parts[0].body.to_s + assert_equal "

line #1

\n

line #2

\n

line #3

\n

line #4

\n\n", mail.parts[1].body.to_s + assert_equal "line #1\r\nline #2\r\nline #3\r\nline #4\r\n\r\n", mail.parts[0].body.encoded + assert_equal "

line #1

\r\n

line #2

\r\n

line #3

\r\n

line #4

\r\n\r\n", mail.parts[1].body.encoded + end + + def test_headers_removed_on_smtp_delivery + TestMailer.delivery_method = :smtp + TestMailer.cc_bcc(@recipient).deliver + assert MockSMTP.deliveries[0][2].include?("root@loudthinking.com") + assert MockSMTP.deliveries[0][2].include?("nobody@loudthinking.com") + assert MockSMTP.deliveries[0][2].include?(@recipient) + assert_match %r{^Cc: nobody@loudthinking.com}, MockSMTP.deliveries[0][0] + assert_match %r{^To: #{@recipient}}, MockSMTP.deliveries[0][0] + assert_no_match %r{^Bcc: root@loudthinking.com}, MockSMTP.deliveries[0][0] + end + + def test_file_delivery_should_create_a_file + ActionMailer::Base.delivery_method = :file + tmp_location = ActionMailer::Base.file_settings[:location] + + TestMailer.cc_bcc(@recipient).deliver + assert File.exists?(tmp_location) + assert File.directory?(tmp_location) + assert File.exists?(File.join(tmp_location, @recipient)) + assert File.exists?(File.join(tmp_location, 'nobody@loudthinking.com')) + assert File.exists?(File.join(tmp_location, 'root@loudthinking.com')) + end + + def test_recursive_multipart_processing + fixture = File.read(File.dirname(__FILE__) + "/../fixtures/raw_email7") + mail = Mail.new(fixture) + assert_equal(2, mail.parts.length) + assert_equal(4, mail.parts.first.parts.length) + assert_equal("This is the first part.", mail.parts.first.parts.first.body.to_s) + assert_equal("test.rb", mail.parts.first.parts.second.filename) + assert_equal("flowed", mail.parts.first.parts.fourth.content_type_parameters[:format]) + assert_equal('smime.p7s', mail.parts.second.filename) + end + + def test_decode_encoded_attachment_filename + fixture = File.read(File.dirname(__FILE__) + "/../fixtures/raw_email8") + mail = Mail.new(fixture) + attachment = mail.attachments.last + + expected = "01 Quien Te Dij\212at. Pitbull.mp3" + + if expected.respond_to?(:force_encoding) + result = attachment.filename.dup + expected.force_encoding(Encoding::ASCII_8BIT) + result.force_encoding(Encoding::ASCII_8BIT) + assert_equal expected, result + else + assert_equal expected, attachment.filename + end + end + + def test_decode_message_with_unknown_charset + fixture = File.read(File.dirname(__FILE__) + "/../fixtures/raw_email10") + mail = Mail.new(fixture) + assert_nothing_raised { mail.body } + end + + def test_empty_header_values_omitted + result = TestMailer.unnamed_attachment(@recipient).encoded + assert_match %r{Content-Type: application/octet-stream;}, result + assert_match %r{Content-Disposition: attachment;}, result + end + + def test_headers_with_nonalpha_chars + mail = TestMailer.headers_with_nonalpha_chars(@recipient) + assert !mail.from_addrs.empty? + assert !mail.cc_addrs.empty? + assert !mail.bcc_addrs.empty? + assert_match(/:/, mail[:from].decoded) + assert_match(/:/, mail[:cc].decoded) + assert_match(/:/, mail[:bcc].decoded) + end + + def test_with_mail_object_deliver + mail = TestMailer.headers_with_nonalpha_chars(@recipient) + assert_nothing_raised { mail.deliver } + assert_equal 1, TestMailer.deliveries.length + end + + 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 + 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 + end + + def test_return_path_with_create + mail = TestMailer.return_path + assert_equal "another@somewhere.test", mail.return_path + end + + def test_return_path_with_deliver + TestMailer.delivery_method = :smtp + TestMailer.return_path.deliver + assert_match %r{^Return-Path: }, MockSMTP.deliveries[0][0] + assert_equal "another@somewhere.test", MockSMTP.deliveries[0][1].to_s + end + + def test_starttls_is_enabled_if_supported + TestMailer.smtp_settings.merge!(:enable_starttls_auto => true) + MockSMTP.any_instance.expects(:respond_to?).with(:enable_starttls_auto).returns(true) + MockSMTP.any_instance.expects(:enable_starttls_auto) + TestMailer.delivery_method = :smtp + TestMailer.signed_up(@recipient).deliver + end + + def test_starttls_is_disabled_if_not_supported + TestMailer.smtp_settings.merge!(:enable_starttls_auto => true) + MockSMTP.any_instance.expects(:respond_to?).with(:enable_starttls_auto).returns(false) + MockSMTP.any_instance.expects(:enable_starttls_auto).never + TestMailer.delivery_method = :smtp + TestMailer.signed_up(@recipient).deliver + end + + def test_starttls_is_not_enabled + TestMailer.smtp_settings.merge!(:enable_starttls_auto => false) + MockSMTP.any_instance.expects(:respond_to?).never + TestMailer.delivery_method = :smtp + TestMailer.signed_up(@recipient).deliver + ensure + TestMailer.smtp_settings.merge!(:enable_starttls_auto => true) + end +end + +class InheritableTemplateRootTest < ActiveSupport::TestCase + def test_attr + expected = File.expand_path("#{File.dirname(__FILE__)}/../fixtures/path.with.dots") + assert_equal expected, FunkyPathMailer.template_root.to_s + + sub = Class.new(FunkyPathMailer) + assert_deprecated do + sub.template_root = 'test/path' + end + + assert_equal File.expand_path('test/path'), sub.template_root.to_s + assert_equal expected, FunkyPathMailer.template_root.to_s + end +end + +class MethodNamingTest < ActiveSupport::TestCase + class TestMailer < ActionMailer::Base + def send + render :text => 'foo' + end + end + + def setup + set_delivery_method :test + ActionMailer::Base.perform_deliveries = true + ActionMailer::Base.deliveries.clear + end + + def teardown + restore_delivery_method + end + + def test_send_method + assert_nothing_raised do + assert_emails 1 do + assert_deprecated do + TestMailer.deliver_send + end + end + end + end +end +class RespondToTest < Test::Unit::TestCase + class RespondToMailer < ActionMailer::Base; end + + def setup + set_delivery_method :test + end + + def teardown + restore_delivery_method + end + + def test_should_respond_to_new + assert RespondToMailer.respond_to?(:new) + end + + def test_should_respond_to_create_with_template_suffix + assert RespondToMailer.respond_to?(:create_any_old_template) + end + + def test_should_respond_to_deliver_with_template_suffix + assert RespondToMailer.respond_to?(:deliver_any_old_template) + end + + def test_should_not_respond_to_new_with_template_suffix + assert !RespondToMailer.respond_to?(:new_any_old_template) + end + + def test_should_not_respond_to_create_with_template_suffix_unless_it_is_separated_by_an_underscore + assert !RespondToMailer.respond_to?(:createany_old_template) + end + + def test_should_not_respond_to_deliver_with_template_suffix_unless_it_is_separated_by_an_underscore + assert !RespondToMailer.respond_to?(:deliverany_old_template) + end + + def test_should_not_respond_to_create_with_template_suffix_if_it_begins_with_a_uppercase_letter + assert !RespondToMailer.respond_to?(:create_Any_old_template) + end + + def test_should_not_respond_to_deliver_with_template_suffix_if_it_begins_with_a_uppercase_letter + assert !RespondToMailer.respond_to?(:deliver_Any_old_template) + end + + def test_should_not_respond_to_create_with_template_suffix_if_it_begins_with_a_digit + assert !RespondToMailer.respond_to?(:create_1_template) + end + + def test_should_not_respond_to_deliver_with_template_suffix_if_it_begins_with_a_digit + assert !RespondToMailer.respond_to?(:deliver_1_template) + end + + def test_should_not_respond_to_method_where_deliver_is_not_a_suffix + assert !RespondToMailer.respond_to?(:foo_deliver_template) + end + + def test_should_still_raise_exception_with_expected_message_when_calling_an_undefined_method + error = assert_raise NoMethodError do + RespondToMailer.not_a_method + end + + assert_match(/undefined method.*not_a_method/, error.message) + end +end \ No newline at end of file diff --git a/actionmailer/test/old_base/tmail_compat_test.rb b/actionmailer/test/old_base/tmail_compat_test.rb new file mode 100644 index 0000000000..7c1d9a07c1 --- /dev/null +++ b/actionmailer/test/old_base/tmail_compat_test.rb @@ -0,0 +1,25 @@ +require 'abstract_unit' + +class TmailCompatTest < ActiveSupport::TestCase + + def test_set_content_type_raises_deprecation_warning + mail = Mail.new + assert_deprecated do + assert_nothing_raised do + mail.set_content_type "text/plain" + end + end + assert_equal mail.mime_type, "text/plain" + end + + def test_transfer_encoding_raises_deprecation_warning + mail = Mail.new + assert_deprecated do + assert_nothing_raised do + mail.transfer_encoding "base64" + end + end + assert_equal mail.content_transfer_encoding, "base64" + end + +end diff --git a/actionmailer/test/old_base/url_test.rb b/actionmailer/test/old_base/url_test.rb new file mode 100644 index 0000000000..10b6a36efd --- /dev/null +++ b/actionmailer/test/old_base/url_test.rb @@ -0,0 +1,84 @@ +require 'abstract_unit' + +class WelcomeController < ActionController::Base +end + +class TestMailer < ActionMailer::Base + default_url_options[:host] = 'www.basecamphq.com' + + def signed_up_with_url(recipient) + @recipients = recipient + @subject = "[Signed up] Welcome #{recipient}" + @from = "system@loudthinking.com" + @sent_on = Time.local(2004, 12, 12) + + @recipient = recipient + @welcome_url = url_for :host => "example.com", :controller => "welcome", :action => "greeting" + end + + class < charset }] + end + mail + end + + def setup + set_delivery_method :test + ActionMailer::Base.perform_deliveries = true + ActionMailer::Base.deliveries.clear + + @recipient = 'test@localhost' + end + + def teardown + restore_delivery_method + end + + def test_signed_up_with_url + ActionController::Routing::Routes.draw do |map| + map.connect ':controller/:action/:id' + map.welcome 'welcome', :controller=>"foo", :action=>"bar" + end + + expected = new_mail + expected.to = @recipient + expected.subject = "[Signed up] Welcome #{@recipient}" + expected.body = "Hello there, \n\nMr. #{@recipient}. Please see our greeting at http://example.com/welcome/greeting http://www.basecamphq.com/welcome\n\n\"Somelogo\"" + expected.from = "system@loudthinking.com" + expected.date = Time.local(2004, 12, 12) + + created = nil + assert_nothing_raised { created = TestMailer.signed_up_with_url(@recipient) } + assert_not_nil created + + expected.message_id = '<123@456>' + created.message_id = '<123@456>' + assert_equal expected.encoded, created.encoded + + assert_nothing_raised { TestMailer.signed_up_with_url(@recipient).deliver } + assert_not_nil ActionMailer::Base.deliveries.first + delivered = ActionMailer::Base.deliveries.first + + delivered.message_id = '<123@456>' + assert_equal expected.encoded, delivered.encoded + end +end diff --git a/actionmailer/test/tmail_compat_test.rb b/actionmailer/test/tmail_compat_test.rb deleted file mode 100644 index 7c1d9a07c1..0000000000 --- a/actionmailer/test/tmail_compat_test.rb +++ /dev/null @@ -1,25 +0,0 @@ -require 'abstract_unit' - -class TmailCompatTest < ActiveSupport::TestCase - - def test_set_content_type_raises_deprecation_warning - mail = Mail.new - assert_deprecated do - assert_nothing_raised do - mail.set_content_type "text/plain" - end - end - assert_equal mail.mime_type, "text/plain" - end - - def test_transfer_encoding_raises_deprecation_warning - mail = Mail.new - assert_deprecated do - assert_nothing_raised do - mail.transfer_encoding "base64" - end - end - assert_equal mail.content_transfer_encoding, "base64" - end - -end diff --git a/actionmailer/test/url_test.rb b/actionmailer/test/url_test.rb deleted file mode 100644 index 10b6a36efd..0000000000 --- a/actionmailer/test/url_test.rb +++ /dev/null @@ -1,84 +0,0 @@ -require 'abstract_unit' - -class WelcomeController < ActionController::Base -end - -class TestMailer < ActionMailer::Base - default_url_options[:host] = 'www.basecamphq.com' - - def signed_up_with_url(recipient) - @recipients = recipient - @subject = "[Signed up] Welcome #{recipient}" - @from = "system@loudthinking.com" - @sent_on = Time.local(2004, 12, 12) - - @recipient = recipient - @welcome_url = url_for :host => "example.com", :controller => "welcome", :action => "greeting" - end - - class < charset }] - end - mail - end - - def setup - set_delivery_method :test - ActionMailer::Base.perform_deliveries = true - ActionMailer::Base.deliveries.clear - - @recipient = 'test@localhost' - end - - def teardown - restore_delivery_method - end - - def test_signed_up_with_url - ActionController::Routing::Routes.draw do |map| - map.connect ':controller/:action/:id' - map.welcome 'welcome', :controller=>"foo", :action=>"bar" - end - - expected = new_mail - expected.to = @recipient - expected.subject = "[Signed up] Welcome #{@recipient}" - expected.body = "Hello there, \n\nMr. #{@recipient}. Please see our greeting at http://example.com/welcome/greeting http://www.basecamphq.com/welcome\n\n\"Somelogo\"" - expected.from = "system@loudthinking.com" - expected.date = Time.local(2004, 12, 12) - - created = nil - assert_nothing_raised { created = TestMailer.signed_up_with_url(@recipient) } - assert_not_nil created - - expected.message_id = '<123@456>' - created.message_id = '<123@456>' - assert_equal expected.encoded, created.encoded - - assert_nothing_raised { TestMailer.signed_up_with_url(@recipient).deliver } - assert_not_nil ActionMailer::Base.deliveries.first - delivered = ActionMailer::Base.deliveries.first - - delivered.message_id = '<123@456>' - assert_equal expected.encoded, delivered.encoded - end -end -- cgit v1.2.3 From a74a655648618a6ed568b9b4ef3a17a8970e7774 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Sun, 24 Jan 2010 19:52:44 +0100 Subject: Add tests to mail helper. --- actionmailer/lib/action_mailer/base.rb | 1 - actionmailer/lib/action_mailer/mail_helper.rb | 4 +- actionmailer/test/abstract_unit.rb | 1 - actionmailer/test/delivery_methods_test.rb | 60 +++++++------- .../fixtures/helper_mailer/use_example_helper.erb | 1 - .../test/fixtures/helper_mailer/use_helper.erb | 1 - .../fixtures/helper_mailer/use_helper_method.erb | 1 - .../fixtures/helper_mailer/use_mail_helper.erb | 5 -- .../test/fixtures/helpers/example_helper.rb | 5 -- actionmailer/test/mail_helper_test.rb | 54 +++++++++++++ actionmailer/test/old_base/mail_helper_test.rb | 94 ---------------------- 11 files changed, 86 insertions(+), 141 deletions(-) delete mode 100644 actionmailer/test/fixtures/helper_mailer/use_example_helper.erb delete mode 100644 actionmailer/test/fixtures/helper_mailer/use_helper.erb delete mode 100644 actionmailer/test/fixtures/helper_mailer/use_helper_method.erb delete mode 100644 actionmailer/test/fixtures/helper_mailer/use_mail_helper.erb delete mode 100644 actionmailer/test/fixtures/helpers/example_helper.rb create mode 100644 actionmailer/test/mail_helper_test.rb delete mode 100644 actionmailer/test/old_base/mail_helper_test.rb (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 1b81cbf5af..7101bfbb70 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -256,7 +256,6 @@ module ActionMailer #:nodoc: include DeliveryMethods, Quoting abstract! - # TODO Add some sanity tests for the included modules include AbstractController::Logger include AbstractController::Rendering include AbstractController::LocalizedCache diff --git a/actionmailer/lib/action_mailer/mail_helper.rb b/actionmailer/lib/action_mailer/mail_helper.rb index 01da954b03..ab5c3469b2 100644 --- a/actionmailer/lib/action_mailer/mail_helper.rb +++ b/actionmailer/lib/action_mailer/mail_helper.rb @@ -17,12 +17,12 @@ module ActionMailer end # Access the mailer instance. - def mailer #:nodoc: + def mailer @_controller end # Access the message instance. - def message #:nodoc: + def message @_message end end diff --git a/actionmailer/test/abstract_unit.rb b/actionmailer/test/abstract_unit.rb index 781e49ae05..ce09bb5d61 100644 --- a/actionmailer/test/abstract_unit.rb +++ b/actionmailer/test/abstract_unit.rb @@ -19,7 +19,6 @@ ActionView::Template.register_template_handler :bak, lambda { |template| "Lame b FIXTURE_LOAD_PATH = File.expand_path('fixtures', File.dirname(__FILE__)) ActionMailer::Base.view_paths = FIXTURE_LOAD_PATH -$:.unshift File.join(FIXTURE_LOAD_PATH, 'helpers') class MockSMTP def self.deliveries diff --git a/actionmailer/test/delivery_methods_test.rb b/actionmailer/test/delivery_methods_test.rb index 5b2ce61ca9..145f8ba30d 100644 --- a/actionmailer/test/delivery_methods_test.rb +++ b/actionmailer/test/delivery_methods_test.rb @@ -71,7 +71,7 @@ class CustomDeliveryMethodsTest < ActiveSupport::TestCase end class MailDeliveryTest < ActiveSupport::TestCase - class DeliverMail < ActionMailer::Base + class DeliveryMailer < ActionMailer::Base DEFAULT_HEADERS = { :to => 'mikel@test.lindsaar.net', :from => 'jose@test.plataformatec.com' @@ -87,64 +87,64 @@ class MailDeliveryTest < ActiveSupport::TestCase end def teardown - DeliverMail.delivery_method = :smtp - DeliverMail.perform_deliveries = true - DeliverMail.raise_delivery_errors = true + DeliveryMailer.delivery_method = :smtp + DeliveryMailer.perform_deliveries = true + DeliveryMailer.raise_delivery_errors = true end test "ActionMailer should be told when Mail gets delivered" do - DeliverMail.deliveries.clear - DeliverMail.expects(:delivered_email).once - DeliverMail.welcome.deliver - assert_equal(1, DeliverMail.deliveries.length) + DeliveryMailer.deliveries.clear + DeliveryMailer.expects(:delivered_email).once + DeliveryMailer.welcome.deliver + assert_equal(1, DeliveryMailer.deliveries.length) end test "delivery method can be customized per instance" do - email = DeliverMail.welcome.deliver + email = DeliveryMailer.welcome.deliver assert_instance_of Mail::SMTP, email.delivery_method - email = DeliverMail.welcome(:delivery_method => :test).deliver + email = DeliveryMailer.welcome(:delivery_method => :test).deliver assert_instance_of Mail::TestMailer, email.delivery_method end test "delivery method can be customized in subclasses not changing the parent" do - DeliverMail.delivery_method = :test + DeliveryMailer.delivery_method = :test assert_equal :smtp, ActionMailer::Base.delivery_method $BREAK = true - email = DeliverMail.welcome.deliver + email = DeliveryMailer.welcome.deliver assert_instance_of Mail::TestMailer, email.delivery_method end test "non registered delivery methods raises errors" do - DeliverMail.delivery_method = :unknown + DeliveryMailer.delivery_method = :unknown assert_raise RuntimeError do - DeliverMail.welcome.deliver + DeliveryMailer.welcome.deliver end end test "does not perform deliveries if requested" do - DeliverMail.perform_deliveries = false - DeliverMail.deliveries.clear - DeliverMail.expects(:delivered_email).never - DeliverMail.welcome.deliver - assert_equal(0, DeliverMail.deliveries.length) + DeliveryMailer.perform_deliveries = false + DeliveryMailer.deliveries.clear + DeliveryMailer.expects(:delivered_email).never + DeliveryMailer.welcome.deliver + assert_equal(0, DeliveryMailer.deliveries.length) end test "raise errors on bogus deliveries" do - DeliverMail.delivery_method = BogusDelivery - DeliverMail.deliveries.clear - DeliverMail.expects(:delivered_email).never + DeliveryMailer.delivery_method = BogusDelivery + DeliveryMailer.deliveries.clear + DeliveryMailer.expects(:delivered_email).never assert_raise RuntimeError do - DeliverMail.welcome.deliver + DeliveryMailer.welcome.deliver end - assert_equal(0, DeliverMail.deliveries.length) + assert_equal(0, DeliveryMailer.deliveries.length) end test "does not raise errors on bogus deliveries if set" do - DeliverMail.delivery_method = BogusDelivery - DeliverMail.raise_delivery_errors = false - DeliverMail.deliveries.clear - DeliverMail.expects(:delivered_email).once - DeliverMail.welcome.deliver - assert_equal(1, DeliverMail.deliveries.length) + DeliveryMailer.delivery_method = BogusDelivery + DeliveryMailer.raise_delivery_errors = false + DeliveryMailer.deliveries.clear + DeliveryMailer.expects(:delivered_email).once + DeliveryMailer.welcome.deliver + assert_equal(1, DeliveryMailer.deliveries.length) end end \ No newline at end of file diff --git a/actionmailer/test/fixtures/helper_mailer/use_example_helper.erb b/actionmailer/test/fixtures/helper_mailer/use_example_helper.erb deleted file mode 100644 index fcff3bb1b4..0000000000 --- a/actionmailer/test/fixtures/helper_mailer/use_example_helper.erb +++ /dev/null @@ -1 +0,0 @@ -So, <%= example_format(@text) %> diff --git a/actionmailer/test/fixtures/helper_mailer/use_helper.erb b/actionmailer/test/fixtures/helper_mailer/use_helper.erb deleted file mode 100644 index 378777f8bb..0000000000 --- a/actionmailer/test/fixtures/helper_mailer/use_helper.erb +++ /dev/null @@ -1 +0,0 @@ -Hello, <%= person_name %>. Thanks for registering! diff --git a/actionmailer/test/fixtures/helper_mailer/use_helper_method.erb b/actionmailer/test/fixtures/helper_mailer/use_helper_method.erb deleted file mode 100644 index d5b8b285e7..0000000000 --- a/actionmailer/test/fixtures/helper_mailer/use_helper_method.erb +++ /dev/null @@ -1 +0,0 @@ -This message brought to you by <%= name_of_the_mailer_class %>. diff --git a/actionmailer/test/fixtures/helper_mailer/use_mail_helper.erb b/actionmailer/test/fixtures/helper_mailer/use_mail_helper.erb deleted file mode 100644 index 96ec49d18a..0000000000 --- a/actionmailer/test/fixtures/helper_mailer/use_mail_helper.erb +++ /dev/null @@ -1,5 +0,0 @@ -From "Romeo and Juliet": - -<%= block_format @text %> - -Good ol' Shakespeare. diff --git a/actionmailer/test/fixtures/helpers/example_helper.rb b/actionmailer/test/fixtures/helpers/example_helper.rb deleted file mode 100644 index f6a6a49ced..0000000000 --- a/actionmailer/test/fixtures/helpers/example_helper.rb +++ /dev/null @@ -1,5 +0,0 @@ -module ExampleHelper - def example_format(text) - "#{h(text)}".html_safe! - end -end diff --git a/actionmailer/test/mail_helper_test.rb b/actionmailer/test/mail_helper_test.rb new file mode 100644 index 0000000000..7cc0804323 --- /dev/null +++ b/actionmailer/test/mail_helper_test.rb @@ -0,0 +1,54 @@ +require 'abstract_unit' + +class HelperMailer < ActionMailer::Base + def use_mail_helper + @text = "But soft! What light through yonder window breaks? It is the east, " + + "and Juliet is the sun. Arise, fair sun, and kill the envious moon, " + + "which is sick and pale with grief that thou, her maid, art far more " + + "fair than she. Be not her maid, for she is envious! Her vestal " + + "livery is but sick and green, and none but fools do wear it. Cast " + + "it off!" + + mail_with_defaults do |format| + format.html { render(:inline => "<%= block_format @text %>") } + end + end + + def use_mailer + mail_with_defaults do |format| + format.html { render(:inline => "<%= mailer.message.subject %>") } + end + end + + def use_message + mail_with_defaults do |format| + format.html { render(:inline => "<%= message.subject %>") } + end + end + + protected + + def mail_with_defaults(&block) + mail(:to => "test@localhost", :from => "tester@example.com", + :subject => "using helpers", &block) + end +end + +class MailerHelperTest < ActionMailer::TestCase + def test_use_mail_helper + mail = HelperMailer.use_mail_helper + assert_match %r{ But soft!}, mail.body.encoded + assert_match %r{east, and\r\n Juliet}, mail.body.encoded + end + + def test_use_mailer + mail = HelperMailer.use_mailer + assert_match "using helpers", mail.body.encoded + end + + def test_use_message + mail = HelperMailer.use_message + assert_match "using helpers", mail.body.encoded + end +end + diff --git a/actionmailer/test/old_base/mail_helper_test.rb b/actionmailer/test/old_base/mail_helper_test.rb deleted file mode 100644 index a9b3cd3ce1..0000000000 --- a/actionmailer/test/old_base/mail_helper_test.rb +++ /dev/null @@ -1,94 +0,0 @@ -require 'abstract_unit' - -module MailerHelper - def person_name - "Mr. Joe Person" - end -end - -class HelperMailer < ActionMailer::Base - helper MailerHelper - helper :example - - def use_helper - recipients 'test@localhost' - subject "using helpers" - from "tester@example.com" - end - - def use_example_helper - recipients 'test@localhost' - subject "using helpers" - from "tester@example.com" - - @text = "emphasize me!" - end - - def use_mail_helper - recipients 'test@localhost' - subject "using mailing helpers" - from "tester@example.com" - - @text = "But soft! What light through yonder window breaks? It is the east, " + - "and Juliet is the sun. Arise, fair sun, and kill the envious moon, " + - "which is sick and pale with grief that thou, her maid, art far more " + - "fair than she. Be not her maid, for she is envious! Her vestal " + - "livery is but sick and green, and none but fools do wear it. Cast " + - "it off!" - end - - def use_helper_method - recipients 'test@localhost' - subject "using helpers" - from "tester@example.com" - - @text = "emphasize me!" - end - - private - - def name_of_the_mailer_class - self.class.name - end - helper_method :name_of_the_mailer_class -end - -class MailerHelperTest < ActiveSupport::TestCase - def new_mail( charset="utf-8" ) - mail = Mail.new - mail.set_content_type "text", "plain", { "charset" => charset } if charset - mail - end - - def setup - set_delivery_method :test - ActionMailer::Base.perform_deliveries = true - ActionMailer::Base.deliveries.clear - end - - def teardown - restore_delivery_method - end - - def test_use_helper - mail = HelperMailer.use_helper - assert_match %r{Mr. Joe Person}, mail.encoded - end - - def test_use_example_helper - mail = HelperMailer.use_example_helper - assert_match %r{emphasize me!}, mail.encoded - end - - def test_use_helper_method - mail = HelperMailer.use_helper_method - assert_match %r{HelperMailer}, mail.encoded - end - - def test_use_mail_helper - mail = HelperMailer.use_mail_helper - assert_match %r{ But soft!}, mail.encoded - assert_match %r{east, and\r\n Juliet}, mail.encoded - end -end - -- cgit v1.2.3 From 0ece244feec236f57fb2f55ea564409f25475923 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Sun, 24 Jan 2010 23:59:12 +0100 Subject: Ensure implicit multipart templates with locale works as expected. --- actionmailer/lib/action_mailer/base.rb | 5 ++++ actionmailer/test/base_test.rb | 27 ++++++++++++++++++++++ .../base_mailer/implicit_with_locale.en.html.erb | 1 + .../base_mailer/implicit_with_locale.html.erb | 1 + .../base_mailer/implicit_with_locale.pl.text.erb | 1 + .../base_mailer/implicit_with_locale.text.erb | 1 + 6 files changed, 36 insertions(+) create mode 100644 actionmailer/test/fixtures/base_mailer/implicit_with_locale.en.html.erb create mode 100644 actionmailer/test/fixtures/base_mailer/implicit_with_locale.html.erb create mode 100644 actionmailer/test/fixtures/base_mailer/implicit_with_locale.pl.text.erb create mode 100644 actionmailer/test/fixtures/base_mailer/implicit_with_locale.text.erb (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 7101bfbb70..84d50fa1f4 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -1,5 +1,8 @@ require 'active_support/core_ext/class' +require 'active_support/core_ext/object/blank' +require 'active_support/core_ext/array/uniq_by' require 'active_support/core_ext/module/delegation' +require 'active_support/core_ext/string/inflections' require 'mail' require 'action_mailer/tmail_compat' require 'action_mailer/collector' @@ -455,6 +458,8 @@ module ActionMailer #:nodoc: def each_template(&block) #:nodoc: self.class.view_paths.each do |load_paths| templates = load_paths.find_all(action_name, {}, self.class.mailer_name) + templates = templates.uniq_by { |t| t.details[:formats] } + unless templates.empty? templates.each(&block) return diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index dd17bf868b..71845d4c42 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -34,6 +34,10 @@ class BaseTest < ActiveSupport::TestCase mail(DEFAULT_HEADERS.merge(hash)) end + def implicit_with_locale(hash = {}) + mail(DEFAULT_HEADERS.merge(hash)) + end + def explicit_multipart(hash = {}) attachments['invoice.pdf'] = 'This is test File content' if hash.delete(:attachments) mail(DEFAULT_HEADERS.merge(hash)) do |format| @@ -310,6 +314,29 @@ class BaseTest < ActiveSupport::TestCase assert_equal(1, BaseMailer.deliveries.length) end + test "implicit multipart with default locale" do + email = BaseMailer.implicit_with_locale.deliver + assert_equal(2, email.parts.size) + assert_equal("multipart/alternate", email.mime_type) + assert_equal("text/plain", email.parts[0].mime_type) + assert_equal("Implicit with locale TEXT", email.parts[0].body.encoded) + assert_equal("text/html", email.parts[1].mime_type) + assert_equal("Implicit with locale EN HTML", email.parts[1].body.encoded) + end + + test "implicit multipart with other locale" do + swap I18n, :locale => :pl do + email = BaseMailer.implicit_with_locale.deliver + assert_equal(2, email.parts.size) + assert_equal("multipart/alternate", email.mime_type) + assert_equal("text/plain", email.parts[0].mime_type) + assert_equal("Implicit with locale PL TEXT", email.parts[0].body.encoded) + assert_equal("text/html", email.parts[1].mime_type) + assert_equal("Implicit with locale HTML", email.parts[1].body.encoded) + end + end + + protected # Execute the block setting the given values and restoring old values after diff --git a/actionmailer/test/fixtures/base_mailer/implicit_with_locale.en.html.erb b/actionmailer/test/fixtures/base_mailer/implicit_with_locale.en.html.erb new file mode 100644 index 0000000000..34e39c8fdb --- /dev/null +++ b/actionmailer/test/fixtures/base_mailer/implicit_with_locale.en.html.erb @@ -0,0 +1 @@ +Implicit with locale EN HTML \ No newline at end of file diff --git a/actionmailer/test/fixtures/base_mailer/implicit_with_locale.html.erb b/actionmailer/test/fixtures/base_mailer/implicit_with_locale.html.erb new file mode 100644 index 0000000000..5ce283f221 --- /dev/null +++ b/actionmailer/test/fixtures/base_mailer/implicit_with_locale.html.erb @@ -0,0 +1 @@ +Implicit with locale HTML \ No newline at end of file diff --git a/actionmailer/test/fixtures/base_mailer/implicit_with_locale.pl.text.erb b/actionmailer/test/fixtures/base_mailer/implicit_with_locale.pl.text.erb new file mode 100644 index 0000000000..c49cbae60a --- /dev/null +++ b/actionmailer/test/fixtures/base_mailer/implicit_with_locale.pl.text.erb @@ -0,0 +1 @@ +Implicit with locale PL TEXT \ No newline at end of file diff --git a/actionmailer/test/fixtures/base_mailer/implicit_with_locale.text.erb b/actionmailer/test/fixtures/base_mailer/implicit_with_locale.text.erb new file mode 100644 index 0000000000..5a18ff62cd --- /dev/null +++ b/actionmailer/test/fixtures/base_mailer/implicit_with_locale.text.erb @@ -0,0 +1 @@ +Implicit with locale TEXT \ No newline at end of file -- cgit v1.2.3 From 48faf53be19c569e85f43a4dbfa63fe81618b09f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Mon, 25 Jan 2010 00:20:38 +0100 Subject: Add some view paths tests. --- actionmailer/test/base_test.rb | 65 ++++++++++++++-------- .../fixtures/another.path/base_mailer/welcome.erb | 1 + 2 files changed, 43 insertions(+), 23 deletions(-) create mode 100644 actionmailer/test/fixtures/another.path/base_mailer/welcome.erb (limited to 'actionmailer') diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index 71845d4c42..b8d21132de 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -238,6 +238,48 @@ class BaseTest < ActiveSupport::TestCase end end + test "implicit multipart with default locale" do + email = BaseMailer.implicit_with_locale.deliver + assert_equal(2, email.parts.size) + assert_equal("multipart/alternate", email.mime_type) + assert_equal("text/plain", email.parts[0].mime_type) + assert_equal("Implicit with locale TEXT", email.parts[0].body.encoded) + assert_equal("text/html", email.parts[1].mime_type) + assert_equal("Implicit with locale EN HTML", email.parts[1].body.encoded) + end + + test "implicit multipart with other locale" do + swap I18n, :locale => :pl do + email = BaseMailer.implicit_with_locale.deliver + assert_equal(2, email.parts.size) + assert_equal("multipart/alternate", email.mime_type) + assert_equal("text/plain", email.parts[0].mime_type) + assert_equal("Implicit with locale PL TEXT", email.parts[0].body.encoded) + assert_equal("text/html", email.parts[1].mime_type) + assert_equal("Implicit with locale HTML", email.parts[1].body.encoded) + end + end + + test "implicit multipart with several view paths uses the first one with template" do + begin + BaseMailer.view_paths.unshift(File.join(FIXTURE_LOAD_PATH, "another.path")) + email = BaseMailer.welcome.deliver + assert_equal("Welcome from another path", email.body.encoded) + ensure + BaseMailer.view_paths.shift + end + end + + test "implicit multipart with inexistent templates uses the next view path" do + begin + BaseMailer.view_paths.unshift(File.join(FIXTURE_LOAD_PATH, "unknown")) + email = BaseMailer.welcome.deliver + assert_equal("Welcome", email.body.encoded) + ensure + BaseMailer.view_paths.shift + end + end + # Explicit multipart test "explicit multipart" do email = BaseMailer.explicit_multipart.deliver @@ -314,29 +356,6 @@ class BaseTest < ActiveSupport::TestCase assert_equal(1, BaseMailer.deliveries.length) end - test "implicit multipart with default locale" do - email = BaseMailer.implicit_with_locale.deliver - assert_equal(2, email.parts.size) - assert_equal("multipart/alternate", email.mime_type) - assert_equal("text/plain", email.parts[0].mime_type) - assert_equal("Implicit with locale TEXT", email.parts[0].body.encoded) - assert_equal("text/html", email.parts[1].mime_type) - assert_equal("Implicit with locale EN HTML", email.parts[1].body.encoded) - end - - test "implicit multipart with other locale" do - swap I18n, :locale => :pl do - email = BaseMailer.implicit_with_locale.deliver - assert_equal(2, email.parts.size) - assert_equal("multipart/alternate", email.mime_type) - assert_equal("text/plain", email.parts[0].mime_type) - assert_equal("Implicit with locale PL TEXT", email.parts[0].body.encoded) - assert_equal("text/html", email.parts[1].mime_type) - assert_equal("Implicit with locale HTML", email.parts[1].body.encoded) - end - end - - protected # Execute the block setting the given values and restoring old values after diff --git a/actionmailer/test/fixtures/another.path/base_mailer/welcome.erb b/actionmailer/test/fixtures/another.path/base_mailer/welcome.erb new file mode 100644 index 0000000000..ef451298e2 --- /dev/null +++ b/actionmailer/test/fixtures/another.path/base_mailer/welcome.erb @@ -0,0 +1 @@ +Welcome from another path \ No newline at end of file -- cgit v1.2.3 From e1c131863897390d04bd5515765236590747f2c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Mon, 25 Jan 2010 00:37:12 +0100 Subject: Added delivers_from. --- actionmailer/lib/action_mailer/base.rb | 14 ++++++++++++-- actionmailer/test/base_test.rb | 9 ++++++--- 2 files changed, 18 insertions(+), 5 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 84d50fa1f4..552fd7ccb8 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -273,6 +273,9 @@ module ActionMailer #:nodoc: private_class_method :new #:nodoc: + extlib_inheritable_accessor :default_from + self.default_from = nil + extlib_inheritable_accessor :default_charset self.default_charset = "utf-8" @@ -298,6 +301,12 @@ module ActionMailer #:nodoc: attr_writer :mailer_name alias :controller_path :mailer_name + # Sets who is the default sender for the e-mail + def delivers_from(value = nil) + self.default_from = value if value + self.default_from + end + # Receives a raw email, parses it into an email object, decodes it, # instantiates a new mailer, and passes the email object to the mailer # object's +receive+ method. If you want your mailer to be able to @@ -318,7 +327,7 @@ module ActionMailer #:nodoc: end # TODO The delivery should happen inside the instrument block - def delivered_email(mail) + def delivered_email(mail) #:nodoc: ActiveSupport::Notifications.instrument("action_mailer.deliver") do |payload| self.set_payload_for_mail(payload, mail) end @@ -387,8 +396,9 @@ module ActionMailer #:nodoc: charset = headers[:charset] || m.charset || self.class.default_charset.dup mime_version = headers[:mime_version] || m.mime_version || self.class.default_mime_version.dup - # Set subjects and fields quotings + # Set fields quotings headers[:subject] ||= default_subject + headers[:from] ||= self.class.default_from.dup quote_fields!(headers, charset) # Render the templates and blocks diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index b8d21132de..d8616ee3be 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -1,16 +1,14 @@ # encoding: utf-8 require 'abstract_unit' -# class Notifier < ActionMailer::Base -# delivers_from 'notifications@example.com' class BaseTest < ActiveSupport::TestCase DEFAULT_HEADERS = { :to => 'mikel@test.lindsaar.net', - :from => 'jose@test.plataformatec.com', :subject => 'The first email on new API!' } class BaseMailer < ActionMailer::Base + delivers_from 'jose@test.plataformatec.com' self.mailer_name = "base_mailer" def welcome(hash = {}) @@ -72,6 +70,11 @@ class BaseTest < ActiveSupport::TestCase assert_equal(email.subject, 'The first email on new API!') end + test "mail() with from overwrites the class level default" do + email = BaseMailer.welcome(:from => 'someone@else.com').deliver + assert_equal(email.from, ['someone@else.com']) + end + test "mail() with bcc, cc, content_type, charset, mime_version, reply_to and date" do @time = Time.now email = BaseMailer.welcome(:bcc => 'bcc@test.lindsaar.net', -- cgit v1.2.3 From 3b6f659fb6b1ffd323c0bbad36630cc97b96bd5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 25 Jan 2010 01:06:12 +0100 Subject: Add active_model/railtie back to generated boot.rb, add models back to paths, load active_support/railtie since we need it and ensure default logger is set before config. --- actionmailer/lib/action_mailer/railtie.rb | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/railtie.rb b/actionmailer/lib/action_mailer/railtie.rb index fbbcf98854..7ed1519e36 100644 --- a/actionmailer/lib/action_mailer/railtie.rb +++ b/actionmailer/lib/action_mailer/railtie.rb @@ -8,15 +8,14 @@ module ActionMailer require "action_mailer/railties/subscriber" subscriber ActionMailer::Railties::Subscriber.new + initializer "action_mailer.logger" do + ActionMailer::Base.logger ||= Rails.logger + end + initializer "action_mailer.set_configs" do |app| app.config.action_mailer.each do |k,v| ActionMailer::Base.send "#{k}=", v end end - - # TODO: ActionController::Base.logger should delegate to its own config.logger - initializer "action_mailer.logger" do - ActionMailer::Base.logger ||= Rails.logger - end end end \ No newline at end of file -- cgit v1.2.3 From e4a989e9d99b9860859ad14b5a6fca62a4009cf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Mon, 25 Jan 2010 13:39:48 +1100 Subject: Added delivery_handler method to mail and implemented in ActionMailer to deliver inside of instrumentation --- actionmailer/lib/action_mailer/base.rb | 13 ++++++++-- actionmailer/lib/action_mailer/delivery_methods.rb | 2 +- actionmailer/test/base_test.rb | 7 ++++- actionmailer/test/delivery_methods_test.rb | 30 ++++++++++++++++++---- 4 files changed, 43 insertions(+), 9 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 552fd7ccb8..4e5e1bbb29 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -326,10 +326,19 @@ module ActionMailer #:nodoc: end end - # TODO The delivery should happen inside the instrument block - def delivered_email(mail) #:nodoc: + def deliver_mail(mail) #:nodoc: ActiveSupport::Notifications.instrument("action_mailer.deliver") do |payload| self.set_payload_for_mail(payload, mail) + + if mail.perform_deliveries + begin + mail.deliver! + rescue Exception => e + raise e if mail.raise_delivery_errors + end + Mail.deliveries << mail + end + end end diff --git a/actionmailer/lib/action_mailer/delivery_methods.rb b/actionmailer/lib/action_mailer/delivery_methods.rb index 21909d5d57..7a6b410932 100644 --- a/actionmailer/lib/action_mailer/delivery_methods.rb +++ b/actionmailer/lib/action_mailer/delivery_methods.rb @@ -63,7 +63,7 @@ module ActionMailer def wrap_delivery_behavior(mail, method=nil) #:nodoc: method ||= self.delivery_method - mail.register_for_delivery_notification(self) + mail.delivery_handler = self if method.is_a?(Symbol) if klass = delivery_methods[method.to_sym] diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index d8616ee3be..81e1df3911 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -354,7 +354,12 @@ class BaseTest < ActiveSupport::TestCase test "calling deliver on the action should deliver the mail object" do BaseMailer.deliveries.clear - BaseMailer.expects(:delivered_email).once + BaseMailer.expects(:deliver_mail).once + BaseMailer.welcome.deliver + end + + test "calling deliver on the action should increment the deliveries collection" do + BaseMailer.deliveries.clear BaseMailer.welcome.deliver assert_equal(1, BaseMailer.deliveries.length) end diff --git a/actionmailer/test/delivery_methods_test.rb b/actionmailer/test/delivery_methods_test.rb index 145f8ba30d..e70e8acd9b 100644 --- a/actionmailer/test/delivery_methods_test.rb +++ b/actionmailer/test/delivery_methods_test.rb @@ -94,9 +94,8 @@ class MailDeliveryTest < ActiveSupport::TestCase test "ActionMailer should be told when Mail gets delivered" do DeliveryMailer.deliveries.clear - DeliveryMailer.expects(:delivered_email).once + DeliveryMailer.expects(:deliver_mail).once DeliveryMailer.welcome.deliver - assert_equal(1, DeliveryMailer.deliveries.length) end test "delivery method can be customized per instance" do @@ -124,7 +123,13 @@ class MailDeliveryTest < ActiveSupport::TestCase test "does not perform deliveries if requested" do DeliveryMailer.perform_deliveries = false DeliveryMailer.deliveries.clear - DeliveryMailer.expects(:delivered_email).never + Mail::Message.any_instance.expects(:deliver!).never + DeliveryMailer.welcome.deliver + end + + test "does not append the deliveries collection if told not to perform the delivery" do + DeliveryMailer.perform_deliveries = false + DeliveryMailer.deliveries.clear DeliveryMailer.welcome.deliver assert_equal(0, DeliveryMailer.deliveries.length) end @@ -132,7 +137,14 @@ class MailDeliveryTest < ActiveSupport::TestCase test "raise errors on bogus deliveries" do DeliveryMailer.delivery_method = BogusDelivery DeliveryMailer.deliveries.clear - DeliveryMailer.expects(:delivered_email).never + assert_raise RuntimeError do + DeliveryMailer.welcome.deliver + end + end + + test "does not increment the deliveries collection on error" do + DeliveryMailer.delivery_method = BogusDelivery + DeliveryMailer.deliveries.clear assert_raise RuntimeError do DeliveryMailer.welcome.deliver end @@ -140,11 +152,19 @@ class MailDeliveryTest < ActiveSupport::TestCase end test "does not raise errors on bogus deliveries if set" do + DeliveryMailer.delivery_method = BogusDelivery + DeliveryMailer.raise_delivery_errors = false + assert_nothing_raised do + DeliveryMailer.welcome.deliver + end + end + + test "increments the deliveries collection on bogus deliveries if set to ignore" do DeliveryMailer.delivery_method = BogusDelivery DeliveryMailer.raise_delivery_errors = false DeliveryMailer.deliveries.clear - DeliveryMailer.expects(:delivered_email).once DeliveryMailer.welcome.deliver assert_equal(1, DeliveryMailer.deliveries.length) end + end \ No newline at end of file -- cgit v1.2.3 From 4240369a4399b944a0652807c545ffe99d7fb0cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Mon, 25 Jan 2010 13:46:44 +1100 Subject: changed test to get TestMailer to use :file delivery method directly (as setup action was resetting delivery_method to :test on init --- actionmailer/test/old_base/mail_service_test.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/test/old_base/mail_service_test.rb b/actionmailer/test/old_base/mail_service_test.rb index 20b0f30b84..2e33abf9d6 100644 --- a/actionmailer/test/old_base/mail_service_test.rb +++ b/actionmailer/test/old_base/mail_service_test.rb @@ -967,10 +967,10 @@ EOF end def test_file_delivery_should_create_a_file - ActionMailer::Base.delivery_method = :file - tmp_location = ActionMailer::Base.file_settings[:location] + TestMailer.delivery_method = :file + tmp_location = TestMailer.file_settings[:location] - TestMailer.cc_bcc(@recipient).deliver + result = TestMailer.cc_bcc(@recipient).deliver assert File.exists?(tmp_location) assert File.directory?(tmp_location) assert File.exists?(File.join(tmp_location, @recipient)) -- cgit v1.2.3 From ace74974cf3575bbd3bf7ff4d8a83c3100fd22a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Mon, 25 Jan 2010 21:47:03 +1100 Subject: Got AM working with Mail yield on delivery_handler and updated tests --- actionmailer/actionmailer.gemspec | 2 +- actionmailer/lib/action_mailer/base.rb | 9 +-------- actionmailer/lib/action_mailer/delivery_methods.rb | 4 ++-- actionmailer/test/base_test.rb | 7 +++++++ actionmailer/test/delivery_methods_test.rb | 4 ++-- actionmailer/test/old_base/mail_service_test.rb | 8 ++++++++ actionmailer/test/old_base/url_test.rb | 2 ++ 7 files changed, 23 insertions(+), 13 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/actionmailer.gemspec b/actionmailer/actionmailer.gemspec index 4f53c709c4..a3d466c986 100644 --- a/actionmailer/actionmailer.gemspec +++ b/actionmailer/actionmailer.gemspec @@ -11,7 +11,7 @@ Gem::Specification.new do |s| s.homepage = "http://www.rubyonrails.org" s.add_dependency('actionpack', '= 3.0.pre') - s.add_dependency('mail', '~> 2.0.5') + s.add_dependency('mail', '~> 2.0.6') s.files = Dir['CHANGELOG', 'README', 'MIT-LICENSE', 'lib/**/*'] s.has_rdoc = true diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 4e5e1bbb29..47d0ffaf68 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -330,14 +330,7 @@ module ActionMailer #:nodoc: ActiveSupport::Notifications.instrument("action_mailer.deliver") do |payload| self.set_payload_for_mail(payload, mail) - if mail.perform_deliveries - begin - mail.deliver! - rescue Exception => e - raise e if mail.raise_delivery_errors - end - Mail.deliveries << mail - end + yield # Let Mail do the delivery actions end end diff --git a/actionmailer/lib/action_mailer/delivery_methods.rb b/actionmailer/lib/action_mailer/delivery_methods.rb index 7a6b410932..34bfe6000a 100644 --- a/actionmailer/lib/action_mailer/delivery_methods.rb +++ b/actionmailer/lib/action_mailer/delivery_methods.rb @@ -40,8 +40,8 @@ module ActionMailer end module ClassMethods - # Provides a list of emails that have been delivered by Mail - delegate :deliveries, :deliveries=, :to => Mail + # Provides a list of emails that have been delivered by Mail::TestMailer + delegate :deliveries, :deliveries=, :to => Mail::TestMailer # Adds a new delivery method through the given class using the given symbol # as alias and the default options supplied: diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index 81e1df3911..0705f22df8 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -363,6 +363,13 @@ class BaseTest < ActiveSupport::TestCase BaseMailer.welcome.deliver assert_equal(1, BaseMailer.deliveries.length) end + + test "calling deliver, ActionMailer should yield back to mail to let it call :do_delivery on itself" do + mail = Mail::Message.new + mail.expects(:do_delivery).once + BaseMailer.expects(:welcome).returns(mail) + BaseMailer.welcome.deliver + end protected diff --git a/actionmailer/test/delivery_methods_test.rb b/actionmailer/test/delivery_methods_test.rb index e70e8acd9b..4907ca0903 100644 --- a/actionmailer/test/delivery_methods_test.rb +++ b/actionmailer/test/delivery_methods_test.rb @@ -159,12 +159,12 @@ class MailDeliveryTest < ActiveSupport::TestCase end end - test "increments the deliveries collection on bogus deliveries if set to ignore" do + test "does not increment the deliveries collection on bogus deliveries" do DeliveryMailer.delivery_method = BogusDelivery DeliveryMailer.raise_delivery_errors = false DeliveryMailer.deliveries.clear DeliveryMailer.welcome.deliver - assert_equal(1, DeliveryMailer.deliveries.length) + assert_equal(0, DeliveryMailer.deliveries.length) end end \ No newline at end of file diff --git a/actionmailer/test/old_base/mail_service_test.rb b/actionmailer/test/old_base/mail_service_test.rb index 2e33abf9d6..fb784328bc 100644 --- a/actionmailer/test/old_base/mail_service_test.rb +++ b/actionmailer/test/old_base/mail_service_test.rb @@ -387,6 +387,8 @@ class ActionMailerTest < Test::Unit::TestCase end def test_signed_up + TestMailer.delivery_method = :test + Time.stubs(:now => Time.now) expected = new_mail @@ -533,6 +535,8 @@ class ActionMailerTest < Test::Unit::TestCase end def test_reply_to + TestMailer.delivery_method = :test + expected = new_mail expected.to = @recipient @@ -567,6 +571,8 @@ class ActionMailerTest < Test::Unit::TestCase end 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" @@ -601,6 +607,7 @@ class ActionMailerTest < Test::Unit::TestCase end def test_unencoded_subject + TestMailer.delivery_method = :test expected = new_mail expected.to = @recipient expected.subject = "testing unencoded subject" @@ -1029,6 +1036,7 @@ EOF end def test_with_mail_object_deliver + TestMailer.delivery_method = :test mail = TestMailer.headers_with_nonalpha_chars(@recipient) assert_nothing_raised { mail.deliver } assert_equal 1, TestMailer.deliveries.length diff --git a/actionmailer/test/old_base/url_test.rb b/actionmailer/test/old_base/url_test.rb index 10b6a36efd..5affb47997 100644 --- a/actionmailer/test/old_base/url_test.rb +++ b/actionmailer/test/old_base/url_test.rb @@ -54,6 +54,8 @@ class ActionMailerUrlTest < Test::Unit::TestCase end def test_signed_up_with_url + TestMailer.delivery_method = :test + ActionController::Routing::Routes.draw do |map| map.connect ':controller/:action/:id' map.welcome 'welcome', :controller=>"foo", :action=>"bar" -- cgit v1.2.3 From d5e4e9185ba09e7f461f3b62243e7b5db4d4b277 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Mon, 25 Jan 2010 21:47:24 +1100 Subject: Updated gemspec for Mail --- actionmailer/actionmailer.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionmailer') diff --git a/actionmailer/actionmailer.gemspec b/actionmailer/actionmailer.gemspec index a3d466c986..e348871c25 100644 --- a/actionmailer/actionmailer.gemspec +++ b/actionmailer/actionmailer.gemspec @@ -11,7 +11,7 @@ Gem::Specification.new do |s| s.homepage = "http://www.rubyonrails.org" s.add_dependency('actionpack', '= 3.0.pre') - s.add_dependency('mail', '~> 2.0.6') + s.add_dependency('mail', '~> 2.1.0') s.files = Dir['CHANGELOG', 'README', 'MIT-LICENSE', 'lib/**/*'] s.has_rdoc = true -- cgit v1.2.3 From ad8f5d4106c77ed1d054bf3b29bec94df557a7cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Mon, 25 Jan 2010 23:15:16 +1100 Subject: Updated to mail 2.1.1 --- actionmailer/actionmailer.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionmailer') diff --git a/actionmailer/actionmailer.gemspec b/actionmailer/actionmailer.gemspec index e348871c25..d73f86cd65 100644 --- a/actionmailer/actionmailer.gemspec +++ b/actionmailer/actionmailer.gemspec @@ -11,7 +11,7 @@ Gem::Specification.new do |s| s.homepage = "http://www.rubyonrails.org" s.add_dependency('actionpack', '= 3.0.pre') - s.add_dependency('mail', '~> 2.1.0') + s.add_dependency('mail', '~> 2.1.1') s.files = Dir['CHANGELOG', 'README', 'MIT-LICENSE', 'lib/**/*'] s.has_rdoc = true -- cgit v1.2.3 From 4a6eba3232fec13892f36fc4730bb2deef342fc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Mon, 25 Jan 2010 23:46:09 +1100 Subject: Added initial documentation for the new API --- actionmailer/CHANGELOG | 2 + actionmailer/README | 62 +++++--- actionmailer/lib/action_mailer/base.rb | 257 ++++++++++++++++++++------------- 3 files changed, 202 insertions(+), 119 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/CHANGELOG b/actionmailer/CHANGELOG index 785bf98c55..0018a2ed5d 100644 --- a/actionmailer/CHANGELOG +++ b/actionmailer/CHANGELOG @@ -1,5 +1,7 @@ *Rails 3.0 (pending)* +* Whole new API added with tests. See base.rb for full details. Old API is deprecated. + * The Mail::Message class has helped methods for all the field types that return 'common' defaults for the common use case, so to get the subject, mail.subject will give you a string, mail.date will give you a DateTime object, mail.from will give you an array of address specs (mikel@test.lindsaar.net) etc. If you want to access the field object itself, call mail[:field_name] which will return the field object you want, which you can then chain, like mail[:from].formatted * Mail#content_type now returns the content_type field as a string. If you want the mime type of a mail, then you call Mail#mime_type (eg, text/plain), if you want the parameters of the content type field, you call Mail#content_type_parameters which gives you a hash, eg {'format' => 'flowed', 'charset' => 'utf-8'} diff --git a/actionmailer/README b/actionmailer/README index 0e16ea6ec6..542996f87b 100644 --- a/actionmailer/README +++ b/actionmailer/README @@ -5,51 +5,74 @@ are used to consolidate code for sending out forgotten passwords, welcome wishes on signup, invoices for billing, and any other use case that requires a written notification to either a person or another system. +Action Mailer is in essence a wrapper around Action Controller and the +Mail gem. It provides a way to make emails using templates in the same +way that Action Controller renders views using templates. + Additionally, an Action Mailer class can be used to process incoming email, such as allowing a weblog to accept new posts from an email (which could even have been sent from a phone). == Sending emails -The framework works by setting up all the email details, except the body, -in methods on the service layer. Subject, recipients, sender, and timestamp -are all set up this way. An example of such a method: +The framework works by initializing any instance variables you want to be +available in the email template, followed by a call to +mail+ to deliver +the email. + +This can be as simple as: + + class Notifier < ActionMailer::Base + + delivers_from 'system@loudthinking.com' + + def welcome(recipient) + @recipient = recipient + mail(:to => recipient, + :subject => "[Signed up] Welcome #{recipient}") + end - def signed_up(recipient) - recipients recipient - subject "[Signed up] Welcome #{recipient}" - from "system@loudthinking.com" - body :recipient => recipient end The body of the email is created by using an Action View template (regular -ERb) that has the content of the body hash parameter available as instance variables. +ERb) that has the instance variables that are declared in the mailer action. + So the corresponding body template for the method above could look like this: Hello there, Mr. <%= @recipient %> + + Thank you for signing up! And if the recipient was given as "david@loudthinking.com", the email generated would look like this: - Date: Sun, 12 Dec 2004 00:00:00 +0100 + Date: Mon, 25 Jan 2010 22:48:09 +1100 From: system@loudthinking.com To: david@loudthinking.com + Message-ID: <4b5d84f9dd6a5_7380800b81ac29578@void.loudthinking.com.mail> Subject: [Signed up] Welcome david@loudthinking.com + Mime-Version: 1.0 + Content-Type: text/plain; + charset="US-ASCII"; + Content-Transfer-Encoding: 7bit Hello there, Mr. david@loudthinking.com -You never actually call the instance methods like signed_up directly. Instead, -you call class methods like deliver_* and create_* that are automatically -created for each instance method. So if the signed_up method sat on -ApplicationMailer, it would look like this: +In previous version of rails you would call create_method_name and +deliver_method_name. Rails 3.0 has a much simpler interface, you +simply call the method and optionally call +deliver+ on the return value. + +Calling the method returns a Mail Message object: + + message = Notifier.welcome #=> Returns a Mail::Message object + message.deliver #=> delivers the email - ApplicationMailer.create_signed_up("david@loudthinking.com") # => tmail object for testing - ApplicationMailer.deliver_signed_up("david@loudthinking.com") # sends the email - ApplicationMailer.new.signed_up("david@loudthinking.com") # won't work! +Or you can just chain the methods together like: + + Notifier.welcome.deliver # Creates the email and sends it immediately == Receiving emails @@ -103,16 +126,13 @@ The Base class has the full list of configuration options. Here's an example: Action Mailer requires that the Action Pack is either available to be required immediately or is accessible as a GEM. +Additionally, Action Mailer requires the Mail gem, http://github.com/mikel/mail == Bundled software -* tmail 0.10.8 by Minero Aoki released under LGPL - Read more on http://i.loveruby.net/en/prog/tmail.html - * Text::Format 0.63 by Austin Ziegler released under OpenSource Read more on http://www.halostatue.ca/ruby/Text__Format.html - == Download The latest version of Action Mailer can be found at diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 47d0ffaf68..51a8c07a28 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -16,46 +16,57 @@ module ActionMailer #:nodoc: # # $ script/generate mailer Notifier # - # The generated model inherits from ActionMailer::Base. Emails are defined by creating methods within the model which are then - # used to set variables to be used in the mail template, to change options on the mail, or - # to add attachments. + # The generated model inherits from ActionMailer::Base. Emails are defined by creating methods + # within the model which are then used to set variables to be used in the mail template, to + # change options on the mail, or to add attachments. # # Examples: # # class Notifier < ActionMailer::Base - # def signup_notification(recipient) - # recipients recipient.email_address_with_name - # bcc ["bcc@example.com", "Order Watcher "] - # from "system@example.com" - # subject "New account information" - # body :account => recipient + # delivers_from 'system@example.com' + # + # def welcome(recipient) + # @account = recipient + # mail { :to => recipient.email_address_with_name, + # :bcc => ["bcc@example.com", "Order Watcher "], + # :subject => "New account information" } + # end # end - # end - # - # Mailer methods have the following configuration methods available. - # - # * recipients - Takes one or more email addresses. These addresses are where your email will be delivered to. Sets the To: header. - # * subject - The subject of your email. Sets the Subject: header. - # * from - Who the email you are sending is from. Sets the From: header. - # * cc - Takes one or more email addresses. These addresses will receive a carbon copy of your email. Sets the Cc: header. - # * bcc - Takes one or more email addresses. These addresses will receive a blind carbon copy of your email. Sets the Bcc: header. - # * reply_to - Takes one or more email addresses. These addresses will be listed as the default recipients when replying to your email. Sets the Reply-To: header. - # * sent_on - The date on which the message was sent. If not set, the header will be set by the delivery agent. - # * content_type - Specify the content type of the message. Defaults to text/plain. - # * headers - Specify additional headers to be set for the message, e.g. headers 'X-Mail-Count' => 107370. - # - # When a headers 'return-path' is specified, that value will be used as the 'envelope from' - # address. Setting this is useful when you want delivery notifications sent to a different address than - # the one in from. - # + # + # Within the mailer method, you have access to the following methods: + # + # * attachments[]= - Allows you to add attachments to your email in an intuitive + # manner; attachments['filename.png'] = File.read('path/to/filename.png') + # * headers[]= - Allows you to specify non standard headers in your email such + # as headers['X-No-Spam'] = 'True' + # * mail - Allows you to specify your email to send. + # + # The hash passed to the mail method allows you to specify the most used headers in an email + # message, such as Subject, To, From, Cc, Bcc, + # Reply-To and Date. See the ActionMailer#mail method for more details. + # + # If you need other headers not listed above, use the headers['name'] = value method. + # + # The mail method, if not passed a block, will inspect your views and send all the views with + # the same name as the method, so the above action would send the +welcome.plain.erb+ view file + # as well as the +welcome.html.erb+ view file in a +multipart/alternate+ email. + # + # If you want to explicitly render only certain templates, pass a block: + # + # mail(:to => user.emai) do |format| + # format.text + # format.enriched, {:content_type => 'text/rtf'} + # format.html + # end # # = Mailer views # - # Like Action Controller, each mailer class has a corresponding view directory - # in which each method of the class looks for a template with its name. - # To define a template to be used with a mailing, create an .erb file with the same name as the method - # in your mailer model. For example, in the mailer defined above, the template at - # app/views/notifier/signup_notification.erb would be used to generate the email. + # Like Action Controller, each mailer class has a corresponding view directory in which each + # method of the class looks for a template with its name. + # + # To define a template to be used with a mailing, create an .erb file with the same + # name as the method in your mailer model. For example, in the mailer defined above, the template at + # app/views/notifier/signup_notification.text.erb would be used to generate the email. # # Variables defined in the model are accessible as instance variables in the view. # @@ -111,54 +122,13 @@ module ActionMailer #:nodoc: # Once a mailer action and template are defined, you can deliver your message or create it and save it # for delivery later: # - # Notifier.deliver_signup_notification(david) # sends the email - # mail = Notifier.create_signup_notification(david) # => a tmail object - # Notifier.deliver(mail) - # - # You never instantiate your mailer class. Rather, your delivery instance - # methods are automatically wrapped in class methods that start with the word - # deliver_ followed by the name of the mailer method that you would - # like to deliver. The signup_notification method defined above is - # delivered by invoking Notifier.deliver_signup_notification. + # Notifier.welcome(david).deliver # sends the email + # mail = Notifier.welcome(david) # => a Mail::Message object + # mail.deliver # sends the email # + # You never instantiate your mailer class. Rather, you just call the method on the class itself. # - # = HTML email - # - # To send mail as HTML, make sure your view (the .erb file) generates HTML and - # set the content type to html. - # - # class MyMailer < ActionMailer::Base - # def signup_notification(recipient) - # recipients recipient.email_address_with_name - # subject "New account information" - # from "system@example.com" - # body :account => recipient - # content_type "text/html" - # end - # end - # - # - # = Multipart email - # - # You can explicitly specify multipart messages: - # - # class ApplicationMailer < ActionMailer::Base - # def signup_notification(recipient) - # recipients recipient.email_address_with_name - # subject "New account information" - # from "system@example.com" - # content_type "multipart/alternative" - # body :account => recipient - # - # part :content_type => "text/html", - # :data => render_message("signup-as-html") - # - # part "text/plain" do |p| - # p.body = render_message("signup-as-plain") - # p.content_transfer_encoding = "base64" - # end - # end - # end + # = Multipart Emails # # Multipart messages can also be used implicitly because Action Mailer will automatically # detect and use multipart templates, where each template is named after the name of the action, followed @@ -170,11 +140,10 @@ module ActionMailer #:nodoc: # * signup_notification.text.xml.builder # * signup_notification.text.x-yaml.erb # - # Each would be rendered and added as a separate part to the message, - # with the corresponding content type. The content type for the entire - # message is automatically set to multipart/alternative, which indicates - # that the email contains multiple different representations of the same email - # body. The same body hash is passed to each template. + # Each would be rendered and added as a separate part to the message, with the corresponding content + # type. The content type for the entire message is automatically set to multipart/alternative, + # which indicates that the email contains multiple different representations of the same email + # body. The same instance variables defined in the action are passed to all email templates. # # Implicit template rendering is not performed if any attachments or parts have been added to the email. # This means that you'll have to manually add each part to the email and set the content type of the email @@ -182,31 +151,31 @@ module ActionMailer #:nodoc: # # = Attachments # - # Attachments can be added by using the +attachment+ method. - # - # Example: + # You can see above how to make a multipart HTML / Text email, to send attachments is just + # as easy: # # class ApplicationMailer < ActionMailer::Base - # # attachments - # def signup_notification(recipient) - # recipients recipient.email_address_with_name - # subject "New account information" - # from "system@example.com" - # - # attachment :content_type => "image/jpeg", - # :body => File.read("an-image.jpg") - # - # attachment "application/pdf" do |a| - # a.body = generate_your_pdf_here() - # end + # def welcome(recipient) + # attachments['free_book.pdf'] = { :data => File.read('path/to/file.pdf') } + # mail(:to => recipient, :subject => "New account information") # end # end + # + # Which will (if it had both a .text.erb and .html.erb tempalte in the view + # directory), send a complete multipart/mixed email with two parts, the first part being + # a multipart/alternate with the text and HTML email parts inside, and the second being + # a application/pdf with a Base64 encoded copy of the file.pdf book with the filename + # +free_book.pdf+. # # # = Configuration options # # These options are specified on the class level, like ActionMailer::Base.template_root = "/my/templates" # + # * delivers_from - Pass this the address that then defaults as the +from+ address on all the + # emails sent. Can be overridden on a per mail basis by passing :from => 'another@address' in + # the +mail+ method. + # # * template_root - Determines the base from which template references will be made. # # * logger - the logger is used for generating information on the mailing run if available. @@ -326,6 +295,9 @@ module ActionMailer #:nodoc: end end + # Delivers a mail object. This is actually called by the Mail::Message object + # itself through a call back when you call :deliver on the Mail::Message, + # calling +deliver_mail+ directly and passing an Mail::Message will do nothing. def deliver_mail(mail) #:nodoc: ActiveSupport::Notifications.instrument("action_mailer.deliver") do |payload| self.set_payload_for_mail(payload, mail) @@ -374,6 +346,14 @@ module ActionMailer #:nodoc: process(method_name, *args) if method_name end + # Allows you to pass random and unusual headers to the new +Mail::Message+ object + # which will add them to itself. + # + # headers['X-Special-Domain-Specific-Header'] = "SecretValue" + # + # The resulting Mail::Message will have the following in it's header: + # + # X-Special-Domain-Specific-Header: SecretValue def headers(args=nil) if args ActiveSupport::Deprecation.warn "headers(Hash) is deprecated, please do headers[key] = value instead", caller[0,2] @@ -383,10 +363,91 @@ module ActionMailer #:nodoc: end end + # Allows you to add attachments to an email, like so: + # + # mail.attachments['filename.jpg'] = File.read('/path/to/filename.jpg') + # + # If you do this, then Mail will take the file name and work out the mime type + # set the Content-Type, Content-Disposition, Content-Transfer-Encoding and + # base64 encode the contents of the attachment all for you. + # + # You can also specify overrides if you want by passing a hash instead of a string: + # + # mail.attachments['filename.jpg'] = {:mime_type => 'application/x-gzip', + # :content => File.read('/path/to/filename.jpg')} + # + # If you want to use a different encoding than Base64, you can pass an encoding in, + # but then it is up to you to pass in the content pre-encoded, and don't expect + # Mail to know how to decode this data: + # + # file_content = SpecialEncode(File.read('/path/to/filename.jpg')) + # mail.attachments['filename.jpg'] = {:mime_type => 'application/x-gzip', + # :encoding => 'SpecialEncoding', + # :content => file_content } + # + # You can also search for specific attachments: + # + # # By Filename + # mail.attachments['filename.jpg'] #=> Mail::Part object or nil + # + # # or by index + # mail.attachments[0] #=> Mail::Part (first attachment) + # def attachments @_message.attachments end + # The main method that creates the message and renders the email templates. There are + # two ways to call this method, with a block, or without a block. + # + # Both methods accept a headers hash. This hash allows you to specify the most used headers + # in an email message, these are: + # + # * :subject - The subject of the message, if this is omitted, ActionMailer will + # ask the Rails I18n class for a translated :subject in the scope of + # [:actionmailer, mailer_scope, action_name] or if this is missing, will translate the + # humanized version of the action_name + # * :to - Who the message is destined for, can be a string of addresses, or an array + # of addresses. + # * :from - Who the message is from, if missing, will use the :delivers_from + # value in the class (if it exists) + # * :cc - Who you would like to Carbon-Copy on this email, can be a string of addresses, + # or an array of addresses. + # * :bcc - Who you would like to Blind-Carbon-Copy on this email, can be a string of + # addresses, or an array of addresses. + # * :reply_to - Who to set the Reply-To header of the email to. + # * :date - The date to say the email was sent on. + # + # If you need other headers not listed above, use the headers['name'] = value method. + # + # When a :return_path is specified, that value will be used as the 'envelope from' + # address for the Mail message. Setting this is useful when you want delivery notifications + # sent to a different address than the one in :from. Mail will actually use the + # :return_path in preference to the :sender in preference to the :from + # field for the 'envelope from' value. + # + # If you do not pass a block to the +mail+ method, it will find all templates in the + # template path that match the method name that it is being called from, it will then + # create parts for each of these templates intelligently, making educated guesses + # on correct content type and sequence, and return a fully prepared Mail::Message + # ready to call :deliver on to send. + # + # If you do pass a block, you can render specific templates of your choice: + # + # mail(:to => 'mikel@test.lindsaar.net') do |format| + # format.text + # format.html + # end + # + # You can even render text directly without using a template: + # + # mail(:to => 'mikel@test.lindsaar.net') do |format| + # format.text { render :text => "Hello Mikel!" } + # format.html { render :text => "

Hello Mikel!

" } + # end + # + # Which will render a multipart/alternate email with text/plain and + # text/html parts. def mail(headers={}, &block) # Guard flag to prevent both the old and the new API from firing # Should be removed when old API is removed -- cgit v1.2.3 From f14390091c40149dcd0982ada097be5bcbb37003 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Tue, 26 Jan 2010 00:09:18 +1100 Subject: We don't support enriched yet --- actionmailer/lib/action_mailer/base.rb | 1 - 1 file changed, 1 deletion(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 51a8c07a28..6c70ce8998 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -55,7 +55,6 @@ module ActionMailer #:nodoc: # # mail(:to => user.emai) do |format| # format.text - # format.enriched, {:content_type => 'text/rtf'} # format.html # end # -- cgit v1.2.3 From 6589976533b7a6850390ed5d6526ca719e56c5ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Tue, 26 Jan 2010 01:43:41 +0100 Subject: Remove old files, add some information to docs and improve test suite. --- actionmailer/README | 2 -- actionmailer/lib/action_mailer/base.rb | 48 ++++++++++++++++++++++++---------- actionmailer/test/base_test.rb | 24 +++++++++++++++++ actionmailer/test/mail_test.rb | 22 ---------------- 4 files changed, 58 insertions(+), 38 deletions(-) delete mode 100644 actionmailer/test/mail_test.rb (limited to 'actionmailer') diff --git a/actionmailer/README b/actionmailer/README index 542996f87b..e0e2ee436a 100644 --- a/actionmailer/README +++ b/actionmailer/README @@ -22,7 +22,6 @@ the email. This can be as simple as: class Notifier < ActionMailer::Base - delivers_from 'system@loudthinking.com' def welcome(recipient) @@ -30,7 +29,6 @@ This can be as simple as: mail(:to => recipient, :subject => "[Signed up] Welcome #{recipient}") end - end The body of the email is created by using an Action View template (regular diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 6c70ce8998..65d1ba47d9 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -27,9 +27,8 @@ module ActionMailer #:nodoc: # # def welcome(recipient) # @account = recipient - # mail { :to => recipient.email_address_with_name, - # :bcc => ["bcc@example.com", "Order Watcher "], - # :subject => "New account information" } + # mail(:to => recipient.email_address_with_name, + # :bcc => ["bcc@example.com", "Order Watcher "]) # end # end # @@ -37,13 +36,15 @@ module ActionMailer #:nodoc: # # * attachments[]= - Allows you to add attachments to your email in an intuitive # manner; attachments['filename.png'] = File.read('path/to/filename.png') + # # * headers[]= - Allows you to specify non standard headers in your email such # as headers['X-No-Spam'] = 'True' + # # * mail - Allows you to specify your email to send. # # The hash passed to the mail method allows you to specify the most used headers in an email # message, such as Subject, To, From, Cc, Bcc, - # Reply-To and Date. See the ActionMailer#mail method for more details. + # Reply-To and Date. See the ActionMailer#mail method for more details. # # If you need other headers not listed above, use the headers['name'] = value method. # @@ -58,6 +59,20 @@ module ActionMailer #:nodoc: # format.html # end # + # The block syntax is useful if also need to specify information specific to a part: + # + # mail(:to => user.emai) do |format| + # format.text(:content_transfer_encoding => "base64") + # format.html + # end + # + # Or even to renderize a special view: + # + # mail(:to => user.emai) do |format| + # format.text + # format.html { render "some_other_template" } + # end + # # = Mailer views # # Like Action Controller, each mailer class has a corresponding view directory in which each @@ -79,9 +94,9 @@ module ActionMailer #:nodoc: # You got a new note! # <%= truncate(@note.body, 25) %> # - # If you need to access the subject, from or the recipients in the view, you can do that through mailer object: + # If you need to access the subject, from or the recipients in the view, you can do that through message object: # - # You got a new note from <%= mailer.from %>! + # You got a new note from <%= message.from %>! # <%= truncate(@note.body, 25) %> # # @@ -137,7 +152,7 @@ module ActionMailer #:nodoc: # * signup_notification.text.plain.erb # * signup_notification.text.html.erb # * signup_notification.text.xml.builder - # * signup_notification.text.x-yaml.erb + # * signup_notification.text.yaml.erb # # Each would be rendered and added as a separate part to the message, with the corresponding content # type. The content type for the entire message is automatically set to multipart/alternative, @@ -174,8 +189,6 @@ module ActionMailer #:nodoc: # * delivers_from - Pass this the address that then defaults as the +from+ address on all the # emails sent. Can be overridden on a per mail basis by passing :from => 'another@address' in # the +mail+ method. - # - # * template_root - Determines the base from which template references will be made. # # * logger - the logger is used for generating information on the mailing run if available. # Can be set to nil for no logging. Compatible with both Ruby's own Logger and Log4r loggers. @@ -300,9 +313,7 @@ module ActionMailer #:nodoc: def deliver_mail(mail) #:nodoc: ActiveSupport::Notifications.instrument("action_mailer.deliver") do |payload| self.set_payload_for_mail(payload, mail) - yield # Let Mail do the delivery actions - end end @@ -399,7 +410,7 @@ module ActionMailer #:nodoc: # The main method that creates the message and renders the email templates. There are # two ways to call this method, with a block, or without a block. # - # Both methods accept a headers hash. This hash allows you to specify the most used headers + # Both methods accept a headers hash. This hash allows you to specify the most used headers # in an email message, these are: # # * :subject - The subject of the message, if this is omitted, ActionMailer will @@ -419,7 +430,7 @@ module ActionMailer #:nodoc: # # If you need other headers not listed above, use the headers['name'] = value method. # - # When a :return_path is specified, that value will be used as the 'envelope from' + # When a :return_path is specified as header, that value will be used as the 'envelope from' # address for the Mail message. Setting this is useful when you want delivery notifications # sent to a different address than the one in :from. Mail will actually use the # :return_path in preference to the :sender in preference to the :from @@ -447,6 +458,14 @@ module ActionMailer #:nodoc: # # Which will render a multipart/alternate email with text/plain and # text/html parts. + # + # The block syntax also allows you to customize the part headers if desired: + # + # mail(:to => 'mikel@test.lindsaar.net') do |format| + # format.text(:content_transfer_encoding => "base64") + # format.html + # end + # def mail(headers={}, &block) # Guard flag to prevent both the old and the new API from firing # Should be removed when old API is removed @@ -541,7 +560,8 @@ module ActionMailer #:nodoc: def create_parts_from_responses(m, responses, charset) #:nodoc: if responses.size == 1 && !m.has_attachments? - m.body = responses[0][:body] + headers = responses[0] + headers.each { |k,v| m[k] = v } return responses[0][:content_type] elsif responses.size > 1 && m.has_attachments? container = Mail::Part.new diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index 0705f22df8..856b5b2d3c 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -56,6 +56,13 @@ class BaseTest < ActiveSupport::TestCase format.any(:text, :html){ render :text => "Format with any!" } end end + + def custom_block(include_html=false) + mail(DEFAULT_HEADERS) do |format| + format.text(:content_transfer_encoding => "base64"){ render "welcome" } + format.html{ render "welcome" } if include_html + end + end end test "method call to mail does not raise error" do @@ -337,6 +344,23 @@ class BaseTest < ActiveSupport::TestCase assert_equal("Format with any!", email.parts[1].body.encoded) end + test "explicit multipart with options" do + email = BaseMailer.custom_block(true).deliver + assert_equal(2, email.parts.size) + assert_equal("multipart/alternate", email.mime_type) + assert_equal("text/plain", email.parts[0].mime_type) + assert_equal("base64", email.parts[0].content_transfer_encoding) + assert_equal("text/html", email.parts[1].mime_type) + assert_equal("7bit", email.parts[1].content_transfer_encoding) + end + + test "explicit multipart with one part is rendered as body" do + email = BaseMailer.custom_block.deliver + assert_equal(0, email.parts.size) + assert_equal("text/plain", email.mime_type) + assert_equal("base64", email.content_transfer_encoding) + end + # Class level API with method missing test "should respond to action methods" do assert BaseMailer.respond_to?(:welcome) diff --git a/actionmailer/test/mail_test.rb b/actionmailer/test/mail_test.rb deleted file mode 100644 index f18dfdc156..0000000000 --- a/actionmailer/test/mail_test.rb +++ /dev/null @@ -1,22 +0,0 @@ -require 'abstract_unit' - -class MailTest < Test::Unit::TestCase - def test_body - m = Mail.new - expected = 'something_with_underscores' - m.content_transfer_encoding = 'quoted-printable' - quoted_body = [expected].pack('*M') - m.body = quoted_body - assert_equal "something_with_underscores=\r\n", m.body.encoded - assert_equal expected, m.body.to_s - end - - def test_nested_attachments_are_recognized_correctly - fixture = File.read("#{File.dirname(__FILE__)}/fixtures/raw_email_with_nested_attachment") - mail = Mail.new(fixture) - assert_equal 2, mail.attachments.length - assert_equal "image/png", mail.attachments.first.mime_type - assert_equal 1902, mail.attachments.first.decoded.length - assert_equal "application/pkcs7-signature", mail.attachments.last.mime_type - end -end -- cgit v1.2.3 From 74a5889abef1212d373ea994f1c93daedee8932c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Tue, 26 Jan 2010 11:49:32 +1100 Subject: Refactor content type setting, added tests to ensure boundary exists on multipart and fixed typo --- actionmailer/lib/action_mailer/base.rb | 31 ++++++++++++++++++++++--------- actionmailer/test/base_test.rb | 23 ++++++++++++++--------- 2 files changed, 36 insertions(+), 18 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 6c70ce8998..782e9d2c46 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -49,7 +49,7 @@ module ActionMailer #:nodoc: # # The mail method, if not passed a block, will inspect your views and send all the views with # the same name as the method, so the above action would send the +welcome.plain.erb+ view file - # as well as the +welcome.html.erb+ view file in a +multipart/alternate+ email. + # as well as the +welcome.html.erb+ view file in a +multipart/alternative+ email. # # If you want to explicitly render only certain templates, pass a block: # @@ -162,7 +162,7 @@ module ActionMailer #:nodoc: # # Which will (if it had both a .text.erb and .html.erb tempalte in the view # directory), send a complete multipart/mixed email with two parts, the first part being - # a multipart/alternate with the text and HTML email parts inside, and the second being + # a multipart/alternative with the text and HTML email parts inside, and the second being # a application/pdf with a Base64 encoded copy of the file.pdf book with the filename # +free_book.pdf+. # @@ -445,7 +445,7 @@ module ActionMailer #:nodoc: # format.html { render :text => "

Hello Mikel!

" } # end # - # Which will render a multipart/alternate email with text/plain and + # Which will render a multipart/alternative email with text/plain and # text/html parts. def mail(headers={}, &block) # Guard flag to prevent both the old and the new API from firing @@ -465,10 +465,11 @@ module ActionMailer #:nodoc: # Render the templates and blocks responses, sort_order = collect_responses_and_sort_order(headers, &block) - content_type ||= create_parts_from_responses(m, responses, charset) + + create_parts_from_responses(m, responses, charset) # Tidy up content type, charset, mime version and sort order - m.content_type = content_type + m.content_type = set_content_type(m, content_type) m.charset = charset m.mime_version = mime_version sort_order = headers[:parts_order] || sort_order || self.class.default_implicit_parts_order.dup @@ -485,6 +486,20 @@ module ActionMailer #:nodoc: protected + def set_content_type(m, user_content_type) + params = m.content_type_parameters || {} + case + when user_content_type.present? + user_content_type + when m.has_attachments? + ["multipart", "mixed", params] + when m.multipart? + ["multipart", "alternative", params] + else + self.class.default_content_type.dup + end + end + def default_subject #:nodoc: mailer_scope = self.class.mailer_name.gsub('/', '.') I18n.t(:subject, :scope => [:actionmailer, mailer_scope, action_name], :default => action_name.humanize) @@ -543,16 +558,14 @@ module ActionMailer #:nodoc: if responses.size == 1 && !m.has_attachments? m.body = responses[0][:body] return responses[0][:content_type] - elsif responses.size > 1 && m.has_attachments? + elsif responses.size > 1 && m.has_attachments? container = Mail::Part.new - container.content_type = "multipart/alternate" + container.content_type = "multipart/alternative" responses.each { |r| insert_part(container, r, charset) } m.add_part(container) else responses.each { |r| insert_part(m, r, charset) } end - - m.has_attachments? ? "multipart/mixed" : "multipart/alternate" end def insert_part(container, response, charset) #:nodoc: diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index 0705f22df8..14feef5a00 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -200,7 +200,7 @@ class BaseTest < ActiveSupport::TestCase test "implicit multipart" do email = BaseMailer.implicit_multipart.deliver assert_equal(2, email.parts.size) - assert_equal("multipart/alternate", email.mime_type) + assert_equal("multipart/alternative", email.mime_type) assert_equal("text/plain", email.parts[0].mime_type) assert_equal("TEXT Implicit Multipart", email.parts[0].body.encoded) assert_equal("text/html", email.parts[1].mime_type) @@ -223,7 +223,7 @@ class BaseTest < ActiveSupport::TestCase test "implicit multipart with attachments creates nested parts" do email = BaseMailer.implicit_multipart(:attachments => true).deliver assert_equal("application/pdf", email.parts[0].mime_type) - assert_equal("multipart/alternate", email.parts[1].mime_type) + assert_equal("multipart/alternative", email.parts[1].mime_type) assert_equal("text/plain", email.parts[1].parts[0].mime_type) assert_equal("TEXT Implicit Multipart", email.parts[1].parts[0].body.encoded) assert_equal("text/html", email.parts[1].parts[1].mime_type) @@ -235,7 +235,7 @@ class BaseTest < ActiveSupport::TestCase swap BaseMailer, :default_implicit_parts_order => order do email = BaseMailer.implicit_multipart(:attachments => true).deliver assert_equal("application/pdf", email.parts[0].mime_type) - assert_equal("multipart/alternate", email.parts[1].mime_type) + assert_equal("multipart/alternative", email.parts[1].mime_type) assert_equal("text/plain", email.parts[1].parts[1].mime_type) assert_equal("text/html", email.parts[1].parts[0].mime_type) end @@ -244,7 +244,7 @@ class BaseTest < ActiveSupport::TestCase test "implicit multipart with default locale" do email = BaseMailer.implicit_with_locale.deliver assert_equal(2, email.parts.size) - assert_equal("multipart/alternate", email.mime_type) + assert_equal("multipart/alternative", email.mime_type) assert_equal("text/plain", email.parts[0].mime_type) assert_equal("Implicit with locale TEXT", email.parts[0].body.encoded) assert_equal("text/html", email.parts[1].mime_type) @@ -255,7 +255,7 @@ class BaseTest < ActiveSupport::TestCase swap I18n, :locale => :pl do email = BaseMailer.implicit_with_locale.deliver assert_equal(2, email.parts.size) - assert_equal("multipart/alternate", email.mime_type) + assert_equal("multipart/alternative", email.mime_type) assert_equal("text/plain", email.parts[0].mime_type) assert_equal("Implicit with locale PL TEXT", email.parts[0].body.encoded) assert_equal("text/html", email.parts[1].mime_type) @@ -287,7 +287,7 @@ class BaseTest < ActiveSupport::TestCase test "explicit multipart" do email = BaseMailer.explicit_multipart.deliver assert_equal(2, email.parts.size) - assert_equal("multipart/alternate", email.mime_type) + assert_equal("multipart/alternative", email.mime_type) assert_equal("text/plain", email.parts[0].mime_type) assert_equal("TEXT Explicit Multipart", email.parts[0].body.encoded) assert_equal("text/html", email.parts[1].mime_type) @@ -310,7 +310,7 @@ class BaseTest < ActiveSupport::TestCase test "explicit multipart with attachments creates nested parts" do email = BaseMailer.explicit_multipart(:attachments => true).deliver assert_equal("application/pdf", email.parts[0].mime_type) - assert_equal("multipart/alternate", email.parts[1].mime_type) + assert_equal("multipart/alternative", email.parts[1].mime_type) assert_equal("text/plain", email.parts[1].parts[0].mime_type) assert_equal("TEXT Explicit Multipart", email.parts[1].parts[0].body.encoded) assert_equal("text/html", email.parts[1].parts[1].mime_type) @@ -320,7 +320,7 @@ class BaseTest < ActiveSupport::TestCase test "explicit multipart with templates" do email = BaseMailer.explicit_multipart_templates.deliver assert_equal(2, email.parts.size) - assert_equal("multipart/alternate", email.mime_type) + assert_equal("multipart/alternative", email.mime_type) assert_equal("text/html", email.parts[0].mime_type) assert_equal("HTML Explicit Multipart Templates", email.parts[0].body.encoded) assert_equal("text/plain", email.parts[1].mime_type) @@ -330,7 +330,7 @@ class BaseTest < ActiveSupport::TestCase test "explicit multipart with any" do email = BaseMailer.explicit_multipart_with_any.deliver assert_equal(2, email.parts.size) - assert_equal("multipart/alternate", email.mime_type) + assert_equal("multipart/alternative", email.mime_type) assert_equal("text/plain", email.parts[0].mime_type) assert_equal("Format with any!", email.parts[0].body.encoded) assert_equal("text/html", email.parts[1].mime_type) @@ -370,6 +370,11 @@ class BaseTest < ActiveSupport::TestCase BaseMailer.expects(:welcome).returns(mail) BaseMailer.welcome.deliver end + + test "explicit multipart should be multipart" do + mail = BaseMailer.explicit_multipart + assert_not_nil(mail.content_type_parameters[:boundary]) + end protected -- cgit v1.2.3 From c02391f8f97182e818d22a0f0ec4a5589d2fff15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Tue, 26 Jan 2010 01:54:23 +0100 Subject: Fix small typo. --- actionmailer/test/base_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionmailer') diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index 83707137e1..4b8427fb92 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -347,7 +347,7 @@ class BaseTest < ActiveSupport::TestCase test "explicit multipart with options" do email = BaseMailer.custom_block(true).deliver assert_equal(2, email.parts.size) - assert_equal("multipart/alternate", email.mime_type) + assert_equal("multipart/alternative", email.mime_type) assert_equal("text/plain", email.parts[0].mime_type) assert_equal("base64", email.parts[0].content_transfer_encoding) assert_equal("text/html", email.parts[1].mime_type) -- cgit v1.2.3 From 0b05acd42439b197f71e168354020393cbf42b4f Mon Sep 17 00:00:00 2001 From: Mikel Lindsaar Date: Tue, 26 Jan 2010 17:08:55 +1100 Subject: Implementing class level :defaults hash, instead of delivers_from et al --- actionmailer/lib/action_mailer/base.rb | 39 ++++++++++++++++++++++------------ actionmailer/test/base_test.rb | 26 ++++++++++++++++++++--- 2 files changed, 49 insertions(+), 16 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 44df30b1ba..5adf4973b5 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -254,8 +254,8 @@ module ActionMailer #:nodoc: private_class_method :new #:nodoc: - extlib_inheritable_accessor :default_from - self.default_from = nil + extlib_inheritable_accessor :defaults + self.defaults = {} extlib_inheritable_accessor :default_charset self.default_charset = "utf-8" @@ -276,18 +276,13 @@ module ActionMailer #:nodoc: self.default_implicit_parts_order = [ "text/plain", "text/enriched", "text/html" ] class << self + def mailer_name @mailer_name ||= name.underscore end attr_writer :mailer_name alias :controller_path :mailer_name - # Sets who is the default sender for the e-mail - def delivers_from(value = nil) - self.default_from = value if value - self.default_from - end - # Receives a raw email, parses it into an email object, decodes it, # instantiates a new mailer, and passes the email object to the mailer # object's +receive+ method. If you want your mailer to be able to @@ -419,8 +414,7 @@ module ActionMailer #:nodoc: # humanized version of the action_name # * :to - Who the message is destined for, can be a string of addresses, or an array # of addresses. - # * :from - Who the message is from, if missing, will use the :delivers_from - # value in the class (if it exists) + # * :from - Who the message is from # * :cc - Who you would like to Carbon-Copy on this email, can be a string of addresses, # or an array of addresses. # * :bcc - Who you would like to Blind-Carbon-Copy on this email, can be a string of @@ -428,6 +422,15 @@ module ActionMailer #:nodoc: # * :reply_to - Who to set the Reply-To header of the email to. # * :date - The date to say the email was sent on. # + # You can set default values for any of the above headers (except :date) by using the defaults + # class method: + # + # class Notifier + # self.defaults = {:from => 'no-reply@test.lindsaar.net', + # :bcc => 'email_logger@test.lindsaar.net', + # :reply_to => 'bounces@test.lindsaar.net' } + # end + # # If you need other headers not listed above, use the headers['name'] = value method. # # When a :return_path is specified as header, that value will be used as the 'envelope from' @@ -478,8 +481,8 @@ module ActionMailer #:nodoc: mime_version = headers[:mime_version] || m.mime_version || self.class.default_mime_version.dup # Set fields quotings - headers[:subject] ||= default_subject - headers[:from] ||= self.class.default_from.dup + headers = set_defaults(headers) + quote_fields!(headers, charset) # Render the templates and blocks @@ -519,9 +522,19 @@ module ActionMailer #:nodoc: end end + def set_defaults(headers) + headers[:subject] ||= default_subject + headers[:to] ||= self.class.defaults[:to].to_s.dup + headers[:from] ||= self.class.defaults[:from].to_s.dup + headers[:cc] ||= self.class.defaults[:cc].to_s.dup + headers[:bcc] ||= self.class.defaults[:bcc].to_s.dup + headers[:reply_to] ||= self.class.defaults[:reply_to].to_s.dup + headers + end + def default_subject #:nodoc: mailer_scope = self.class.mailer_name.gsub('/', '.') - I18n.t(:subject, :scope => [:actionmailer, mailer_scope, action_name], :default => action_name.humanize) + self.class.defaults[:subject] || I18n.t(:subject, :scope => [:actionmailer, mailer_scope, action_name], :default => action_name.humanize) end # TODO: Move this into Mail diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index 4b8427fb92..8a54455633 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -8,9 +8,18 @@ class BaseTest < ActiveSupport::TestCase } class BaseMailer < ActionMailer::Base - delivers_from 'jose@test.plataformatec.com' + + self.defaults = {:to => 'system@test.lindsaar.net', + :from => 'jose@test.plataformatec.com', + :reply_to => 'mikel@test.lindsaar.net', + :subject => 'Default Subject!'} + self.mailer_name = "base_mailer" + def empty(hash = {}) + mail(hash) + end + def welcome(hash = {}) headers['X-SPAM'] = "Not SPAM" mail(DEFAULT_HEADERS.merge(hash)) @@ -77,9 +86,19 @@ class BaseTest < ActiveSupport::TestCase assert_equal(email.subject, 'The first email on new API!') end + test "mail() should pull the defaults from the class if nothing is specified" do + email = BaseMailer.empty.deliver + assert_equal(['system@test.lindsaar.net'], email.to) + assert_equal(['jose@test.plataformatec.com'], email.from) + assert_equal(['mikel@test.lindsaar.net'], email.reply_to) + assert_equal('Default Subject!', email.subject) + end + test "mail() with from overwrites the class level default" do - email = BaseMailer.welcome(:from => 'someone@else.com').deliver - assert_equal(email.from, ['someone@else.com']) + email = BaseMailer.welcome(:from => 'someone@example.com', + :to => 'another@example.org').deliver + assert_equal(['someone@example.com'], email.from) + assert_equal(['another@example.org'], email.to) end test "mail() with bcc, cc, content_type, charset, mime_version, reply_to and date" do @@ -195,6 +214,7 @@ class BaseTest < ActiveSupport::TestCase end test "subject gets default from I18n" do + BaseMailer.defaults[:subject] = nil email = BaseMailer.welcome(:subject => nil).deliver assert_equal "Welcome", email.subject -- cgit v1.2.3 From e297eed4f21a57234ea28fe3dc9265ed8793dba1 Mon Sep 17 00:00:00 2001 From: Mikel Lindsaar Date: Tue, 26 Jan 2010 17:11:36 +1100 Subject: Fixing up expectations in base_test.rb --- actionmailer/test/base_test.rb | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index 8a54455633..20a35ddc73 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -81,9 +81,9 @@ class BaseTest < ActiveSupport::TestCase # Basic mail usage without block test "mail() should set the headers of the mail message" do email = BaseMailer.welcome.deliver - assert_equal(email.to, ['mikel@test.lindsaar.net']) - assert_equal(email.from, ['jose@test.plataformatec.com']) - assert_equal(email.subject, 'The first email on new API!') + assert_equal(['mikel@test.lindsaar.net'], email.to) + assert_equal(['jose@test.plataformatec.com'], email.from) + assert_equal('The first email on new API!', email.subject) end test "mail() should pull the defaults from the class if nothing is specified" do @@ -110,13 +110,13 @@ class BaseTest < ActiveSupport::TestCase :mime_version => '2.0', :reply_to => 'reply-to@test.lindsaar.net', :date => @time).deliver - assert_equal(email.bcc, ['bcc@test.lindsaar.net']) - assert_equal(email.cc, ['cc@test.lindsaar.net']) - assert_equal(email.content_type, 'multipart/mixed') - assert_equal(email.charset, 'iso-8559-1') - assert_equal(email.mime_version, '2.0') - assert_equal(email.reply_to, ['reply-to@test.lindsaar.net']) - assert_equal(email.date, @time) + assert_equal(['bcc@test.lindsaar.net'], email.bcc) + assert_equal(['cc@test.lindsaar.net'], email.cc) + assert_equal('multipart/mixed', email.content_type) + assert_equal('iso-8559-1', email.charset) + assert_equal('2.0', email.mime_version) + assert_equal(['reply-to@test.lindsaar.net'], email.reply_to) + assert_equal(@time, email.date) end test "mail() renders the template using the method being processed" do -- cgit v1.2.3 From 9dd65c368b40093cfc686956a48c18b78abacf7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Tue, 26 Jan 2010 11:21:20 +0100 Subject: Make defaults accept a hash. --- actionmailer/lib/action_mailer/base.rb | 78 ++++++++++++++++--------------- actionmailer/test/base_test.rb | 85 +++++++++++++++++----------------- 2 files changed, 84 insertions(+), 79 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 5adf4973b5..dbaf1424ed 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -254,8 +254,13 @@ module ActionMailer #:nodoc: private_class_method :new #:nodoc: - extlib_inheritable_accessor :defaults - self.defaults = {} + extlib_inheritable_accessor :default_params + self.default_params = { + :mime_version => "1.0", + :charset => "utf-8", + :content_type => "text/plain", + :parts_order => [ "text/plain", "text/enriched", "text/html" ] + } extlib_inheritable_accessor :default_charset self.default_charset = "utf-8" @@ -283,6 +288,11 @@ module ActionMailer #:nodoc: attr_writer :mailer_name alias :controller_path :mailer_name + def defaults(value=nil) + self.default_params.merge!(value) if value + self.default_params + end + # Receives a raw email, parses it into an email object, decodes it, # instantiates a new mailer, and passes the email object to the mailer # object's +receive+ method. If you want your mailer to be able to @@ -425,10 +435,10 @@ module ActionMailer #:nodoc: # You can set default values for any of the above headers (except :date) by using the defaults # class method: # - # class Notifier - # self.defaults = {:from => 'no-reply@test.lindsaar.net', - # :bcc => 'email_logger@test.lindsaar.net', - # :reply_to => 'bounces@test.lindsaar.net' } + # class Notifier < ActionMailer::Base + # self.defaults :from => 'no-reply@test.lindsaar.net', + # :bcc => 'email_logger@test.lindsaar.net', + # :reply_to => 'bounces@test.lindsaar.net' # end # # If you need other headers not listed above, use the headers['name'] = value method. @@ -475,40 +485,46 @@ module ActionMailer #:nodoc: @mail_was_called = true m = @_message - # Give preference to headers and fallback to the ones set in mail - content_type = headers[:content_type] || m.content_type - charset = headers[:charset] || m.charset || self.class.default_charset.dup - mime_version = headers[:mime_version] || m.mime_version || self.class.default_mime_version.dup + # At the beginning, do not consider class default for parts order neither content_type + content_type = headers[:content_type] + parts_order = headers[:parts_order] - # Set fields quotings - headers = set_defaults(headers) + # Merge defaults from class + headers = headers.reverse_merge(self.class.defaults) + charset = headers[:charset] + # Quote fields + headers[:subject] ||= default_i18n_subject quote_fields!(headers, charset) # Render the templates and blocks - responses, sort_order = collect_responses_and_sort_order(headers, &block) - + responses, explicit_order = collect_responses_and_sort_order(headers, &block) create_parts_from_responses(m, responses, charset) - # Tidy up content type, charset, mime version and sort order - m.content_type = set_content_type(m, content_type) + # Finally setup content type and parts order + m.content_type = set_content_type(m, content_type, headers[:content_type]) m.charset = charset - m.mime_version = mime_version - sort_order = headers[:parts_order] || sort_order || self.class.default_implicit_parts_order.dup if m.multipart? - m.body.set_sort_order(sort_order) + parts_order ||= explicit_order || headers[:parts_order] + m.body.set_sort_order(parts_order) m.body.sort_parts! end - # Finaly set delivery behavior configured in class + # Set configure delivery behavior wrap_delivery_behavior!(headers[:delivery_method]) + + # Remove headers already treated and assign all others + headers.except!(:subject, :to, :from, :cc, :bcc, :reply_to) + headers.except!(:body, :parts_order, :content_type, :charset, :delivery_method) + headers.each { |k, v| m[k] = v } + m end protected - def set_content_type(m, user_content_type) + def set_content_type(m, user_content_type, class_default) params = m.content_type_parameters || {} case when user_content_type.present? @@ -518,23 +534,13 @@ module ActionMailer #:nodoc: when m.multipart? ["multipart", "alternative", params] else - self.class.default_content_type.dup + class_default end end - def set_defaults(headers) - headers[:subject] ||= default_subject - headers[:to] ||= self.class.defaults[:to].to_s.dup - headers[:from] ||= self.class.defaults[:from].to_s.dup - headers[:cc] ||= self.class.defaults[:cc].to_s.dup - headers[:bcc] ||= self.class.defaults[:bcc].to_s.dup - headers[:reply_to] ||= self.class.defaults[:reply_to].to_s.dup - headers - end - - def default_subject #:nodoc: + def default_i18n_subject #:nodoc: mailer_scope = self.class.mailer_name.gsub('/', '.') - self.class.defaults[:subject] || I18n.t(:subject, :scope => [:actionmailer, mailer_scope, action_name], :default => action_name.humanize) + I18n.t(:subject, :scope => [:actionmailer, mailer_scope, action_name], :default => action_name.humanize) end # TODO: Move this into Mail @@ -546,7 +552,6 @@ module ActionMailer #:nodoc: m.cc ||= quote_address_if_necessary(headers[:cc], charset) if headers[:cc] m.bcc ||= quote_address_if_necessary(headers[:bcc], charset) if headers[:bcc] m.reply_to ||= quote_address_if_necessary(headers[:reply_to], charset) if headers[:reply_to] - m.date ||= headers[:date] if headers[:date] end def collect_responses_and_sort_order(headers) #:nodoc: @@ -588,8 +593,7 @@ module ActionMailer #:nodoc: def create_parts_from_responses(m, responses, charset) #:nodoc: if responses.size == 1 && !m.has_attachments? - headers = responses[0] - headers.each { |k,v| m[k] = v } + responses[0].each { |k,v| m[k] = v } return responses[0][:content_type] elsif responses.size > 1 && m.has_attachments? container = Mail::Part.new diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index 20a35ddc73..7abdf7f4f8 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -2,72 +2,61 @@ require 'abstract_unit' class BaseTest < ActiveSupport::TestCase - DEFAULT_HEADERS = { - :to => 'mikel@test.lindsaar.net', - :subject => 'The first email on new API!' - } - class BaseMailer < ActionMailer::Base - - self.defaults = {:to => 'system@test.lindsaar.net', - :from => 'jose@test.plataformatec.com', - :reply_to => 'mikel@test.lindsaar.net', - :subject => 'Default Subject!'} - self.mailer_name = "base_mailer" - def empty(hash = {}) - mail(hash) - end + self.defaults :to => 'system@test.lindsaar.net', + :from => 'jose@test.plataformatec.com', + :reply_to => 'mikel@test.lindsaar.net' def welcome(hash = {}) headers['X-SPAM'] = "Not SPAM" - mail(DEFAULT_HEADERS.merge(hash)) + mail({:subject => "The first email on new API!"}.merge!(hash)) end def attachment_with_content(hash = {}) attachments['invoice.pdf'] = 'This is test File content' - mail(DEFAULT_HEADERS.merge(hash)) + mail(hash) end def attachment_with_hash attachments['invoice.jpg'] = { :data => "you smiling", :mime_type => "image/x-jpg", :transfer_encoding => "base64" } - mail(DEFAULT_HEADERS) + mail end def implicit_multipart(hash = {}) attachments['invoice.pdf'] = 'This is test File content' if hash.delete(:attachments) - mail(DEFAULT_HEADERS.merge(hash)) + mail(hash) end def implicit_with_locale(hash = {}) - mail(DEFAULT_HEADERS.merge(hash)) + mail(hash) end def explicit_multipart(hash = {}) attachments['invoice.pdf'] = 'This is test File content' if hash.delete(:attachments) - mail(DEFAULT_HEADERS.merge(hash)) do |format| + mail(hash) do |format| format.text { render :text => "TEXT Explicit Multipart" } format.html { render :text => "HTML Explicit Multipart" } end end def explicit_multipart_templates(hash = {}) - mail(DEFAULT_HEADERS.merge(hash)) do |format| + mail(hash) do |format| format.html format.text end end def explicit_multipart_with_any(hash = {}) - mail(DEFAULT_HEADERS.merge(hash)) do |format| + mail(hash) do |format| format.any(:text, :html){ render :text => "Format with any!" } end end def custom_block(include_html=false) - mail(DEFAULT_HEADERS) do |format| + mail do |format| format.text(:content_transfer_encoding => "base64"){ render "welcome" } format.html{ render "welcome" } if include_html end @@ -81,19 +70,11 @@ class BaseTest < ActiveSupport::TestCase # Basic mail usage without block test "mail() should set the headers of the mail message" do email = BaseMailer.welcome.deliver - assert_equal(['mikel@test.lindsaar.net'], email.to) + assert_equal(['system@test.lindsaar.net'], email.to) assert_equal(['jose@test.plataformatec.com'], email.from) assert_equal('The first email on new API!', email.subject) end - test "mail() should pull the defaults from the class if nothing is specified" do - email = BaseMailer.empty.deliver - assert_equal(['system@test.lindsaar.net'], email.to) - assert_equal(['jose@test.plataformatec.com'], email.from) - assert_equal(['mikel@test.lindsaar.net'], email.reply_to) - assert_equal('Default Subject!', email.subject) - end - test "mail() with from overwrites the class level default" do email = BaseMailer.welcome(:from => 'someone@example.com', :to => 'another@example.org').deliver @@ -184,7 +165,7 @@ class BaseTest < ActiveSupport::TestCase # Defaults values test "uses default charset from class" do - swap BaseMailer, :default_charset => "US-ASCII" do + with_default BaseMailer, :charset => "US-ASCII" do email = BaseMailer.welcome.deliver assert_equal("US-ASCII", email.charset) @@ -194,7 +175,7 @@ class BaseTest < ActiveSupport::TestCase end test "uses default content type from class" do - swap BaseMailer, :default_content_type => "text/html" do + with_default BaseMailer, :content_type => "text/html" do email = BaseMailer.welcome.deliver assert_equal("text/html", email.mime_type) @@ -204,7 +185,7 @@ class BaseTest < ActiveSupport::TestCase end test "uses default mime version from class" do - swap BaseMailer, :default_mime_version => "2.0" do + with_default BaseMailer, :mime_version => "2.0" do email = BaseMailer.welcome.deliver assert_equal("2.0", email.mime_version) @@ -213,6 +194,13 @@ class BaseTest < ActiveSupport::TestCase end end + test "uses default headers from class" do + with_default BaseMailer, "X-SPAM" => "Not spam" do + email = BaseMailer.welcome.deliver + assert_equal("Not spam", email["X-SPAM"].decoded) + end + end + test "subject gets default from I18n" do BaseMailer.defaults[:subject] = nil email = BaseMailer.welcome(:subject => nil).deliver @@ -236,7 +224,7 @@ class BaseTest < ActiveSupport::TestCase test "implicit multipart with sort order" do order = ["text/html", "text/plain"] - swap BaseMailer, :default_implicit_parts_order => order do + with_default BaseMailer, :parts_order => order do email = BaseMailer.implicit_multipart.deliver assert_equal("text/html", email.parts[0].mime_type) assert_equal("text/plain", email.parts[1].mime_type) @@ -259,7 +247,7 @@ class BaseTest < ActiveSupport::TestCase test "implicit multipart with attachments and sort order" do order = ["text/html", "text/plain"] - swap BaseMailer, :default_implicit_parts_order => order do + with_default BaseMailer, :parts_order => order do email = BaseMailer.implicit_multipart(:attachments => true).deliver assert_equal("application/pdf", email.parts[0].mime_type) assert_equal("multipart/alternative", email.parts[1].mime_type) @@ -323,7 +311,7 @@ class BaseTest < ActiveSupport::TestCase test "explicit multipart does not sort order" do order = ["text/html", "text/plain"] - swap BaseMailer, :default_implicit_parts_order => order do + with_default BaseMailer, :parts_order => order do email = BaseMailer.explicit_multipart.deliver assert_equal("text/plain", email.parts[0].mime_type) assert_equal("text/html", email.parts[1].mime_type) @@ -424,17 +412,30 @@ class BaseTest < ActiveSupport::TestCase # Execute the block setting the given values and restoring old values after # the block is executed. - def swap(object, new_values) + def swap(klass, new_values) old_values = {} new_values.each do |key, value| - old_values[key] = object.send key - object.send :"#{key}=", value + old_values[key] = klass.send key + klass.send :"#{key}=", value end yield ensure old_values.each do |key, value| - object.send :"#{key}=", value + klass.send :"#{key}=", value end end + def with_default(klass, new_values) + hash = klass.defaults + old_values = {} + new_values.each do |key, value| + old_values[key] = hash[key] + hash[key] = value + end + yield + ensure + old_values.each do |key, value| + hash[key] = value + end + end end \ No newline at end of file -- cgit v1.2.3 From 39a1b06f13221e00ab38dff960155cb5fe9eaabb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Tue, 26 Jan 2010 11:46:42 +0100 Subject: Deprecate old defaults API. --- actionmailer/lib/action_mailer/base.rb | 31 +++++----------------- actionmailer/lib/action_mailer/delivery_methods.rb | 5 +++- actionmailer/lib/action_mailer/deprecated_api.rb | 29 ++++++++++++++++++-- actionmailer/lib/action_mailer/old_api.rb | 10 ++++--- 4 files changed, 43 insertions(+), 32 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index dbaf1424ed..95c45ec54b 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -262,24 +262,6 @@ module ActionMailer #:nodoc: :parts_order => [ "text/plain", "text/enriched", "text/html" ] } - extlib_inheritable_accessor :default_charset - self.default_charset = "utf-8" - - extlib_inheritable_accessor :default_content_type - self.default_content_type = "text/plain" - - extlib_inheritable_accessor :default_mime_version - self.default_mime_version = "1.0" - - # This specifies the order that the parts of a multipart email will be. Usually you put - # text/plain at the top so someone without a MIME capable email reader can read the plain - # text of your email first. - # - # Any content type that is not listed here will be inserted in the order you add them to - # the email after the content types you list here. - extlib_inheritable_accessor :default_implicit_parts_order - self.default_implicit_parts_order = [ "text/plain", "text/enriched", "text/html" ] - class << self def mailer_name @@ -498,7 +480,7 @@ module ActionMailer #:nodoc: quote_fields!(headers, charset) # Render the templates and blocks - responses, explicit_order = collect_responses_and_sort_order(headers, &block) + responses, explicit_order = collect_responses_and_parts_order(headers, &block) create_parts_from_responses(m, responses, charset) # Finally setup content type and parts order @@ -554,18 +536,18 @@ module ActionMailer #:nodoc: m.reply_to ||= quote_address_if_necessary(headers[:reply_to], charset) if headers[:reply_to] end - def collect_responses_and_sort_order(headers) #:nodoc: - responses, sort_order = [], nil + def collect_responses_and_parts_order(headers) #:nodoc: + responses, parts_order = [], nil if block_given? collector = ActionMailer::Collector.new(self) { render(action_name) } yield(collector) - sort_order = collector.responses.map { |r| r[:content_type] } + parts_order = collector.responses.map { |r| r[:content_type] } responses = collector.responses elsif headers[:body] responses << { :body => headers[:body], - :content_type => self.class.default_content_type.dup + :content_type => self.class.defaults[:content_type] || "text/plain" } else each_template do |template| @@ -576,7 +558,7 @@ module ActionMailer #:nodoc: end end - [responses, sort_order] + [responses, parts_order] end def each_template(&block) #:nodoc: @@ -594,7 +576,6 @@ module ActionMailer #:nodoc: def create_parts_from_responses(m, responses, charset) #:nodoc: if responses.size == 1 && !m.has_attachments? responses[0].each { |k,v| m[k] = v } - return responses[0][:content_type] elsif responses.size > 1 && m.has_attachments? container = Mail::Part.new container.content_type = "multipart/alternative" diff --git a/actionmailer/lib/action_mailer/delivery_methods.rb b/actionmailer/lib/action_mailer/delivery_methods.rb index 34bfe6000a..f6321a240c 100644 --- a/actionmailer/lib/action_mailer/delivery_methods.rb +++ b/actionmailer/lib/action_mailer/delivery_methods.rb @@ -65,7 +65,10 @@ module ActionMailer method ||= self.delivery_method mail.delivery_handler = self - if method.is_a?(Symbol) + case method + when NilClass + raise "Delivery method cannot be nil" + when Symbol if klass = delivery_methods[method.to_sym] mail.delivery_method(klass, send(:"#{method}_settings")) else diff --git a/actionmailer/lib/action_mailer/deprecated_api.rb b/actionmailer/lib/action_mailer/deprecated_api.rb index 0eb8d85676..61101c26a1 100644 --- a/actionmailer/lib/action_mailer/deprecated_api.rb +++ b/actionmailer/lib/action_mailer/deprecated_api.rb @@ -5,8 +5,25 @@ module ActionMailer module DeprecatedApi #:nodoc: extend ActiveSupport::Concern - module ClassMethods + included do + [:charset, :content_type, :mime_version, :implicit_parts_order].each do |method| + class_eval <<-FILE, __FILE__, __LINE__ + 1 + def self.default_#{method} + @@default_#{method} + end + + def self.default_#{method}=(value) + ActiveSupport::Deprecation.warn "ActionMailer::Base.default_#{method}=value is deprecated, " << + "use defaults :#{method} => value instead" + @@default_#{method} = value + end + + @@default_#{method} = nil + FILE + end + end + module ClassMethods # Deliver the given mail object directly. This can be used to deliver # a preconstructed mail object, like: # @@ -99,7 +116,15 @@ module ActionMailer end private - + + def initialize_defaults(*) + @charset ||= self.class.default_charset.try(:dup) + @content_type ||= self.class.default_content_type.try(:dup) + @implicit_parts_order ||= self.class.default_implicit_parts_order.try(:dup) + @mime_version ||= self.class.default_mime_version.try(:dup) + super + end + def create_parts if @body.is_a?(Hash) && !@body.empty? ActiveSupport::Deprecation.warn "Giving a hash to body is deprecated, please use instance variables instead", caller[0,2] diff --git a/actionmailer/lib/action_mailer/old_api.rb b/actionmailer/lib/action_mailer/old_api.rb index f5b077ab98..22c3c518b1 100644 --- a/actionmailer/lib/action_mailer/old_api.rb +++ b/actionmailer/lib/action_mailer/old_api.rb @@ -1,3 +1,5 @@ +require 'active_support/core_ext/object/try' + module ActionMailer module OldApi #:nodoc: extend ActiveSupport::Concern @@ -185,10 +187,10 @@ module ActionMailer # mailer. Subclasses may override this method to provide different # defaults. def initialize_defaults(method_name) - @charset ||= self.class.default_charset.dup - @content_type ||= self.class.default_content_type.dup - @implicit_parts_order ||= self.class.default_implicit_parts_order.dup - @mime_version ||= self.class.default_mime_version.dup if self.class.default_mime_version + @charset ||= self.class.defaults[:charset].try(:dup) + @content_type ||= self.class.defaults[:content_type].try(:dup) + @implicit_parts_order ||= self.class.defaults[:parts_order].try(:dup) + @mime_version ||= self.class.defaults[:mime_version].try(:dup) @mailer_name ||= self.class.mailer_name.dup @template ||= method_name -- cgit v1.2.3 From 9520166f70b84dd56640b7dbe8e3737c91e04bd9 Mon Sep 17 00:00:00 2001 From: Mikel Lindsaar Date: Wed, 27 Jan 2010 00:06:19 +1100 Subject: Fixed up being able to pass random headers in with headers, or mail. Also, undeprecated headers(hash) as this works now too --- actionmailer/lib/action_mailer/base.rb | 31 +++++++++++++++++++----------- actionmailer/test/base_test.rb | 35 +++++++++++++++++++++++++++++----- 2 files changed, 50 insertions(+), 16 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index dbaf1424ed..c01ca876dc 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -40,13 +40,17 @@ module ActionMailer #:nodoc: # * headers[]= - Allows you to specify non standard headers in your email such # as headers['X-No-Spam'] = 'True' # + # * headers(hash) - Allows you to specify multiple headers in your email such + # as headers({'X-No-Spam' => 'True', 'In-Reply-To' => '1234@message.id'}) + # # * mail - Allows you to specify your email to send. # - # The hash passed to the mail method allows you to specify the most used headers in an email - # message, such as Subject, To, From, Cc, Bcc, - # Reply-To and Date. See the ActionMailer#mail method for more details. - # - # If you need other headers not listed above, use the headers['name'] = value method. + # The hash passed to the mail method allows you to specify any header that a Mail::Message + # will accept (any valid Email header including optional fields). Obviously if you specify + # the same header in the headers method and then again in the mail method, the last one + # will over write the first, unless you are specifying a header field that can appear more + # than once per RFC, in which case, both will be inserted (X-value headers for example can + # appear multiple times.) # # The mail method, if not passed a block, will inspect your views and send all the views with # the same name as the method, so the above action would send the +welcome.plain.erb+ view file @@ -263,13 +267,13 @@ module ActionMailer #:nodoc: } extlib_inheritable_accessor :default_charset - self.default_charset = "utf-8" + self.default_charset = self.default_params[:charset] extlib_inheritable_accessor :default_content_type - self.default_content_type = "text/plain" + self.default_content_type = self.default_params[:content_type] extlib_inheritable_accessor :default_mime_version - self.default_mime_version = "1.0" + self.default_mime_version = self.default_params[:mime_version] # This specifies the order that the parts of a multipart email will be. Usually you put # text/plain at the top so someone without a MIME capable email reader can read the plain @@ -278,7 +282,7 @@ module ActionMailer #:nodoc: # Any content type that is not listed here will be inserted in the order you add them to # the email after the content types you list here. extlib_inheritable_accessor :default_implicit_parts_order - self.default_implicit_parts_order = [ "text/plain", "text/enriched", "text/html" ] + self.default_implicit_parts_order = self.default_params[:parts_order] class << self @@ -366,13 +370,18 @@ module ActionMailer #:nodoc: # # headers['X-Special-Domain-Specific-Header'] = "SecretValue" # + # You can also pass a hash into headers of header field names and values, which + # will then be set on the Mail::Message object: + # + # headers {'X-Special-Domain-Specific-Header' => "SecretValue", + # 'In-Reply-To' => incoming.message_id } + # # The resulting Mail::Message will have the following in it's header: # # X-Special-Domain-Specific-Header: SecretValue def headers(args=nil) if args - ActiveSupport::Deprecation.warn "headers(Hash) is deprecated, please do headers[key] = value instead", caller[0,2] - @headers = args + @_message.headers(args) else @_message end diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index 7abdf7f4f8..9a39204998 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -5,15 +5,24 @@ class BaseTest < ActiveSupport::TestCase class BaseMailer < ActionMailer::Base self.mailer_name = "base_mailer" - self.defaults :to => 'system@test.lindsaar.net', - :from => 'jose@test.plataformatec.com', - :reply_to => 'mikel@test.lindsaar.net' + defaults({:to => 'system@test.lindsaar.net', + :from => 'jose@test.plataformatec.com', + :reply_to => 'mikel@test.lindsaar.net'}) def welcome(hash = {}) headers['X-SPAM'] = "Not SPAM" mail({:subject => "The first email on new API!"}.merge!(hash)) end + def simple(hash = {}) + mail(hash) + end + + def simple_with_headers(hash = {}) + headers hash + mail + end + def attachment_with_content(hash = {}) attachments['invoice.pdf'] = 'This is test File content' mail(hash) @@ -194,9 +203,9 @@ class BaseTest < ActiveSupport::TestCase end end - test "uses default headers from class" do + test "uses random default headers from class" do with_default BaseMailer, "X-SPAM" => "Not spam" do - email = BaseMailer.welcome.deliver + email = BaseMailer.simple assert_equal("Not spam", email["X-SPAM"].decoded) end end @@ -407,6 +416,22 @@ class BaseTest < ActiveSupport::TestCase mail = BaseMailer.explicit_multipart assert_not_nil(mail.content_type_parameters[:boundary]) end + + test "can pass random headers in as a hash" do + hash = {'X-Special-Domain-Specific-Header' => "SecretValue", + 'In-Reply-To' => '1234@mikel.me.com' } + mail = BaseMailer.simple_with_headers(hash) + assert_equal('SecretValue', mail['X-Special-Domain-Specific-Header'].decoded) + assert_equal('1234@mikel.me.com', mail['In-Reply-To'].decoded) + end + + test "can pass random headers in as a hash to mail" do + hash = {'X-Special-Domain-Specific-Header' => "SecretValue", + 'In-Reply-To' => '1234@mikel.me.com' } + mail = BaseMailer.simple(hash) + assert_equal('SecretValue', mail['X-Special-Domain-Specific-Header'].decoded) + assert_equal('1234@mikel.me.com', mail['In-Reply-To'].decoded) + end protected -- cgit v1.2.3 From 21dcc20ed29053c8ffd4d3a5a68a40f6e225512b Mon Sep 17 00:00:00 2001 From: Mikel Lindsaar Date: Wed, 27 Jan 2010 00:18:40 +1100 Subject: Fixed up documentation to reflect code change and cleaned up tests of spurious #deliver calls --- actionmailer/lib/action_mailer/base.rb | 40 +++++++++--------- actionmailer/test/base_test.rb | 77 +++++++++++++++++----------------- 2 files changed, 58 insertions(+), 59 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index c01ca876dc..868d785129 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -23,7 +23,7 @@ module ActionMailer #:nodoc: # Examples: # # class Notifier < ActionMailer::Base - # delivers_from 'system@example.com' + # defaults({:from => 'system@example.com'}) # # def welcome(recipient) # @account = recipient @@ -190,9 +190,14 @@ module ActionMailer #:nodoc: # # These options are specified on the class level, like ActionMailer::Base.template_root = "/my/templates" # - # * delivers_from - Pass this the address that then defaults as the +from+ address on all the - # emails sent. Can be overridden on a per mail basis by passing :from => 'another@address' in - # the +mail+ method. + # * defaults - This is a class wide hash of :key => value pairs containing + # default values for the specified header fields of the Mail::Message. You can + # specify a default for any valid header for Mail::Message and it will be used if + # you do not override it. The defaults set by Action Mailer are: + # * :mime_version => "1.0" + # * :charset => "utf-8", + # * :content_type => "text/plain", + # * :parts_order => [ "text/plain", "text/enriched", "text/html" ] # # * logger - the logger is used for generating information on the mailing run if available. # Can be set to nil for no logging. Compatible with both Ruby's own Logger and Log4r loggers. @@ -226,20 +231,19 @@ module ActionMailer #:nodoc: # * deliveries - Keeps an array of all the emails sent out through the Action Mailer with delivery_method :test. Most useful # for unit and functional testing. # - # * default_charset - The default charset used for the body and to encode the subject. Defaults to UTF-8. You can also - # pick a different charset from inside a method with +charset+. + # * default_charset - This is now deprecated, use the +defaults+ method above to + # set the default +:charset+. # - # * default_content_type - The default content type used for the main part of the message. Defaults to "text/plain". You - # can also pick a different content type from inside a method with +content_type+. + # * default_content_type - This is now deprecated, use the +defaults+ method above + # to set the default +:content_type+. # - # * default_mime_version - The default mime version used for the message. Defaults to 1.0. You - # can also pick a different value from inside a method with +mime_version+. + # * default_mime_version - This is now deprecated, use the +defaults+ method above + # to set the default +:mime_version+. # - # * default_implicit_parts_order - When a message is built implicitly (i.e. multiple parts are assembled from templates - # which specify the content type in their filenames) this variable controls how the parts are ordered. Defaults to - # ["text/html", "text/enriched", "text/plain"]. Items that appear first in the array have higher priority in the mail client - # and appear last in the mime encoded message. You can also pick a different order from inside a method with - # +implicit_parts_order+. + # * default_implicit_parts_order - This is now deprecated, use the +defaults+ method above + # to set the default +:parts_order+. Parts Order is used when a message is built implicitly + # (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 abstract! @@ -275,12 +279,6 @@ module ActionMailer #:nodoc: extlib_inheritable_accessor :default_mime_version self.default_mime_version = self.default_params[:mime_version] - # This specifies the order that the parts of a multipart email will be. Usually you put - # text/plain at the top so someone without a MIME capable email reader can read the plain - # text of your email first. - # - # Any content type that is not listed here will be inserted in the order you add them to - # the email after the content types you list here. extlib_inheritable_accessor :default_implicit_parts_order self.default_implicit_parts_order = self.default_params[:parts_order] diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index 9a39204998..6900e77178 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -73,12 +73,12 @@ class BaseTest < ActiveSupport::TestCase end test "method call to mail does not raise error" do - assert_nothing_raised { BaseMailer.welcome.deliver } + assert_nothing_raised { BaseMailer.welcome } end # Basic mail usage without block test "mail() should set the headers of the mail message" do - email = BaseMailer.welcome.deliver + email = BaseMailer.welcome assert_equal(['system@test.lindsaar.net'], email.to) assert_equal(['jose@test.plataformatec.com'], email.from) assert_equal('The first email on new API!', email.subject) @@ -86,7 +86,7 @@ class BaseTest < ActiveSupport::TestCase test "mail() with from overwrites the class level default" do email = BaseMailer.welcome(:from => 'someone@example.com', - :to => 'another@example.org').deliver + :to => 'another@example.org') assert_equal(['someone@example.com'], email.from) assert_equal(['another@example.org'], email.to) end @@ -99,7 +99,7 @@ class BaseTest < ActiveSupport::TestCase :charset => 'iso-8559-1', :mime_version => '2.0', :reply_to => 'reply-to@test.lindsaar.net', - :date => @time).deliver + :date => @time) assert_equal(['bcc@test.lindsaar.net'], email.bcc) assert_equal(['cc@test.lindsaar.net'], email.cc) assert_equal('multipart/mixed', email.content_type) @@ -110,50 +110,50 @@ class BaseTest < ActiveSupport::TestCase end test "mail() renders the template using the method being processed" do - email = BaseMailer.welcome.deliver + email = BaseMailer.welcome assert_equal("Welcome", email.body.encoded) end test "can pass in :body to the mail method hash" do - email = BaseMailer.welcome(:body => "Hello there").deliver + email = BaseMailer.welcome(:body => "Hello there") assert_equal("text/plain", email.mime_type) assert_equal("Hello there", email.body.encoded) end # Custom headers test "custom headers" do - email = BaseMailer.welcome.deliver + email = BaseMailer.welcome assert_equal("Not SPAM", email['X-SPAM'].decoded) end # Attachments test "attachment with content" do - email = BaseMailer.attachment_with_content.deliver + email = BaseMailer.attachment_with_content assert_equal(1, email.attachments.length) assert_equal('invoice.pdf', email.attachments[0].filename) assert_equal('This is test File content', email.attachments['invoice.pdf'].decoded) end test "attachment gets content type from filename" do - email = BaseMailer.attachment_with_content.deliver + email = BaseMailer.attachment_with_content assert_equal('invoice.pdf', email.attachments[0].filename) end test "attachment with hash" do - email = BaseMailer.attachment_with_hash.deliver + email = BaseMailer.attachment_with_hash assert_equal(1, email.attachments.length) assert_equal('invoice.jpg', email.attachments[0].filename) assert_equal("\312\213\254\232)b", email.attachments['invoice.jpg'].decoded) end test "sets mime type to multipart/mixed when attachment is included" do - email = BaseMailer.attachment_with_content.deliver + email = BaseMailer.attachment_with_content assert_equal(1, email.attachments.length) assert_equal("multipart/mixed", email.mime_type) end test "adds the rendered template as part" do - email = BaseMailer.attachment_with_content.deliver + email = BaseMailer.attachment_with_content assert_equal(2, email.parts.length) assert_equal("multipart/mixed", email.mime_type) assert_equal("text/html", email.parts[0].mime_type) @@ -163,7 +163,7 @@ class BaseTest < ActiveSupport::TestCase end test "adds the given :body as part" do - email = BaseMailer.attachment_with_content(:body => "I'm the eggman").deliver + email = BaseMailer.attachment_with_content(:body => "I'm the eggman") assert_equal(2, email.parts.length) assert_equal("multipart/mixed", email.mime_type) assert_equal("text/plain", email.parts[0].mime_type) @@ -175,30 +175,30 @@ class BaseTest < ActiveSupport::TestCase # Defaults values test "uses default charset from class" do with_default BaseMailer, :charset => "US-ASCII" do - email = BaseMailer.welcome.deliver + email = BaseMailer.welcome assert_equal("US-ASCII", email.charset) - email = BaseMailer.welcome(:charset => "iso-8559-1").deliver + email = BaseMailer.welcome(:charset => "iso-8559-1") assert_equal("iso-8559-1", email.charset) end end test "uses default content type from class" do with_default BaseMailer, :content_type => "text/html" do - email = BaseMailer.welcome.deliver + email = BaseMailer.welcome assert_equal("text/html", email.mime_type) - email = BaseMailer.welcome(:content_type => "text/plain").deliver + email = BaseMailer.welcome(:content_type => "text/plain") assert_equal("text/plain", email.mime_type) end end test "uses default mime version from class" do with_default BaseMailer, :mime_version => "2.0" do - email = BaseMailer.welcome.deliver + email = BaseMailer.welcome assert_equal("2.0", email.mime_version) - email = BaseMailer.welcome(:mime_version => "1.0").deliver + email = BaseMailer.welcome(:mime_version => "1.0") assert_equal("1.0", email.mime_version) end end @@ -212,17 +212,17 @@ class BaseTest < ActiveSupport::TestCase test "subject gets default from I18n" do BaseMailer.defaults[:subject] = nil - email = BaseMailer.welcome(:subject => nil).deliver + email = BaseMailer.welcome(:subject => nil) assert_equal "Welcome", email.subject I18n.backend.store_translations('en', :actionmailer => {:base_mailer => {:welcome => {:subject => "New Subject!"}}}) - email = BaseMailer.welcome(:subject => nil).deliver + email = BaseMailer.welcome(:subject => nil) assert_equal "New Subject!", email.subject end # Implicit multipart test "implicit multipart" do - email = BaseMailer.implicit_multipart.deliver + email = BaseMailer.implicit_multipart assert_equal(2, email.parts.size) assert_equal("multipart/alternative", email.mime_type) assert_equal("text/plain", email.parts[0].mime_type) @@ -234,18 +234,18 @@ class BaseTest < ActiveSupport::TestCase test "implicit multipart with sort order" do order = ["text/html", "text/plain"] with_default BaseMailer, :parts_order => order do - email = BaseMailer.implicit_multipart.deliver + email = BaseMailer.implicit_multipart assert_equal("text/html", email.parts[0].mime_type) assert_equal("text/plain", email.parts[1].mime_type) - email = BaseMailer.implicit_multipart(:parts_order => order.reverse).deliver + email = BaseMailer.implicit_multipart(:parts_order => order.reverse) assert_equal("text/plain", email.parts[0].mime_type) assert_equal("text/html", email.parts[1].mime_type) end end test "implicit multipart with attachments creates nested parts" do - email = BaseMailer.implicit_multipart(:attachments => true).deliver + email = BaseMailer.implicit_multipart(:attachments => true) assert_equal("application/pdf", email.parts[0].mime_type) assert_equal("multipart/alternative", email.parts[1].mime_type) assert_equal("text/plain", email.parts[1].parts[0].mime_type) @@ -257,7 +257,7 @@ class BaseTest < ActiveSupport::TestCase test "implicit multipart with attachments and sort order" do order = ["text/html", "text/plain"] with_default BaseMailer, :parts_order => order do - email = BaseMailer.implicit_multipart(:attachments => true).deliver + email = BaseMailer.implicit_multipart(:attachments => true) assert_equal("application/pdf", email.parts[0].mime_type) assert_equal("multipart/alternative", email.parts[1].mime_type) assert_equal("text/plain", email.parts[1].parts[1].mime_type) @@ -266,7 +266,7 @@ class BaseTest < ActiveSupport::TestCase end test "implicit multipart with default locale" do - email = BaseMailer.implicit_with_locale.deliver + email = BaseMailer.implicit_with_locale assert_equal(2, email.parts.size) assert_equal("multipart/alternative", email.mime_type) assert_equal("text/plain", email.parts[0].mime_type) @@ -277,7 +277,7 @@ class BaseTest < ActiveSupport::TestCase test "implicit multipart with other locale" do swap I18n, :locale => :pl do - email = BaseMailer.implicit_with_locale.deliver + email = BaseMailer.implicit_with_locale assert_equal(2, email.parts.size) assert_equal("multipart/alternative", email.mime_type) assert_equal("text/plain", email.parts[0].mime_type) @@ -290,7 +290,7 @@ class BaseTest < ActiveSupport::TestCase test "implicit multipart with several view paths uses the first one with template" do begin BaseMailer.view_paths.unshift(File.join(FIXTURE_LOAD_PATH, "another.path")) - email = BaseMailer.welcome.deliver + email = BaseMailer.welcome assert_equal("Welcome from another path", email.body.encoded) ensure BaseMailer.view_paths.shift @@ -300,7 +300,7 @@ class BaseTest < ActiveSupport::TestCase test "implicit multipart with inexistent templates uses the next view path" do begin BaseMailer.view_paths.unshift(File.join(FIXTURE_LOAD_PATH, "unknown")) - email = BaseMailer.welcome.deliver + email = BaseMailer.welcome assert_equal("Welcome", email.body.encoded) ensure BaseMailer.view_paths.shift @@ -309,7 +309,7 @@ class BaseTest < ActiveSupport::TestCase # Explicit multipart test "explicit multipart" do - email = BaseMailer.explicit_multipart.deliver + email = BaseMailer.explicit_multipart assert_equal(2, email.parts.size) assert_equal("multipart/alternative", email.mime_type) assert_equal("text/plain", email.parts[0].mime_type) @@ -321,18 +321,18 @@ class BaseTest < ActiveSupport::TestCase test "explicit multipart does not sort order" do order = ["text/html", "text/plain"] with_default BaseMailer, :parts_order => order do - email = BaseMailer.explicit_multipart.deliver + email = BaseMailer.explicit_multipart assert_equal("text/plain", email.parts[0].mime_type) assert_equal("text/html", email.parts[1].mime_type) - email = BaseMailer.explicit_multipart(:parts_order => order.reverse).deliver + email = BaseMailer.explicit_multipart(:parts_order => order.reverse) assert_equal("text/plain", email.parts[0].mime_type) assert_equal("text/html", email.parts[1].mime_type) end end test "explicit multipart with attachments creates nested parts" do - email = BaseMailer.explicit_multipart(:attachments => true).deliver + email = BaseMailer.explicit_multipart(:attachments => true) assert_equal("application/pdf", email.parts[0].mime_type) assert_equal("multipart/alternative", email.parts[1].mime_type) assert_equal("text/plain", email.parts[1].parts[0].mime_type) @@ -342,7 +342,7 @@ class BaseTest < ActiveSupport::TestCase end test "explicit multipart with templates" do - email = BaseMailer.explicit_multipart_templates.deliver + email = BaseMailer.explicit_multipart_templates assert_equal(2, email.parts.size) assert_equal("multipart/alternative", email.mime_type) assert_equal("text/html", email.parts[0].mime_type) @@ -352,7 +352,7 @@ class BaseTest < ActiveSupport::TestCase end test "explicit multipart with any" do - email = BaseMailer.explicit_multipart_with_any.deliver + email = BaseMailer.explicit_multipart_with_any assert_equal(2, email.parts.size) assert_equal("multipart/alternative", email.mime_type) assert_equal("text/plain", email.parts[0].mime_type) @@ -362,7 +362,8 @@ class BaseTest < ActiveSupport::TestCase end test "explicit multipart with options" do - email = BaseMailer.custom_block(true).deliver + email = BaseMailer.custom_block(true) + email.ready_to_send! assert_equal(2, email.parts.size) assert_equal("multipart/alternative", email.mime_type) assert_equal("text/plain", email.parts[0].mime_type) @@ -372,7 +373,7 @@ class BaseTest < ActiveSupport::TestCase end test "explicit multipart with one part is rendered as body" do - email = BaseMailer.custom_block.deliver + email = BaseMailer.custom_block assert_equal(0, email.parts.size) assert_equal("text/plain", email.mime_type) assert_equal("base64", email.content_transfer_encoding) -- cgit v1.2.3 From ccea6ab07d38c5bc2de341c3f08d199ef55bccc6 Mon Sep 17 00:00:00 2001 From: Mikel Lindsaar Date: Wed, 27 Jan 2010 00:37:22 +1100 Subject: Fixing up tests and docs to use defaults :from => 'name' instead of defaults({:from => 'name'}) --- actionmailer/lib/action_mailer/base.rb | 3 ++- actionmailer/test/base_test.rb | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index f677ab629e..669e49c91c 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -23,7 +23,8 @@ module ActionMailer #:nodoc: # Examples: # # class Notifier < ActionMailer::Base - # defaults({:from => 'system@example.com'}) + # defaults :from => 'no-reply@example.com', + # :return_path => 'system@example.com' # # def welcome(recipient) # @account = recipient diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index 6900e77178..0709c92326 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -5,9 +5,9 @@ class BaseTest < ActiveSupport::TestCase class BaseMailer < ActionMailer::Base self.mailer_name = "base_mailer" - defaults({:to => 'system@test.lindsaar.net', - :from => 'jose@test.plataformatec.com', - :reply_to => 'mikel@test.lindsaar.net'}) + defaults :to => 'system@test.lindsaar.net', + :from => 'jose@test.plataformatec.com', + :reply_to => 'mikel@test.lindsaar.net' def welcome(hash = {}) headers['X-SPAM'] = "Not SPAM" -- cgit v1.2.3 From 05c4ad9d3f6ff8d0017f4bca9b52e552629c4813 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim=20and=20Mikel=20Lindsaar?= Date: Tue, 26 Jan 2010 16:00:24 +0100 Subject: Tidy up tests and docs. --- actionmailer/lib/action_mailer/base.rb | 4 ++-- actionmailer/test/base_test.rb | 37 +++++++++++++++++----------------- 2 files changed, 21 insertions(+), 20 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 669e49c91c..b230e34631 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -360,8 +360,8 @@ module ActionMailer #:nodoc: # You can also pass a hash into headers of header field names and values, which # will then be set on the Mail::Message object: # - # headers {'X-Special-Domain-Specific-Header' => "SecretValue", - # 'In-Reply-To' => incoming.message_id } + # headers 'X-Special-Domain-Specific-Header' => "SecretValue", + # 'In-Reply-To' => incoming.message_id # # The resulting Mail::Message will have the following in it's header: # diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index 0709c92326..4a65363e3e 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -79,7 +79,7 @@ class BaseTest < ActiveSupport::TestCase # Basic mail usage without block test "mail() should set the headers of the mail message" do email = BaseMailer.welcome - assert_equal(['system@test.lindsaar.net'], email.to) + assert_equal(['system@test.lindsaar.net'], email.to) assert_equal(['jose@test.plataformatec.com'], email.from) assert_equal('The first email on new API!', email.subject) end @@ -126,6 +126,22 @@ class BaseTest < ActiveSupport::TestCase assert_equal("Not SPAM", email['X-SPAM'].decoded) end + test "can pass random headers in as a hash to mail" do + hash = {'X-Special-Domain-Specific-Header' => "SecretValue", + 'In-Reply-To' => '1234@mikel.me.com' } + mail = BaseMailer.simple(hash) + assert_equal('SecretValue', mail['X-Special-Domain-Specific-Header'].decoded) + assert_equal('1234@mikel.me.com', mail['In-Reply-To'].decoded) + end + + test "can pass random headers in as a hash" do + hash = {'X-Special-Domain-Specific-Header' => "SecretValue", + 'In-Reply-To' => '1234@mikel.me.com' } + mail = BaseMailer.simple_with_headers(hash) + assert_equal('SecretValue', mail['X-Special-Domain-Specific-Header'].decoded) + assert_equal('1234@mikel.me.com', mail['In-Reply-To'].decoded) + end + # Attachments test "attachment with content" do email = BaseMailer.attachment_with_content @@ -397,7 +413,8 @@ class BaseTest < ActiveSupport::TestCase test "calling deliver on the action should deliver the mail object" do BaseMailer.deliveries.clear BaseMailer.expects(:deliver_mail).once - BaseMailer.welcome.deliver + mail = BaseMailer.welcome.deliver + assert_instance_of Mail::Message, mail end test "calling deliver on the action should increment the deliveries collection" do @@ -417,22 +434,6 @@ class BaseTest < ActiveSupport::TestCase mail = BaseMailer.explicit_multipart assert_not_nil(mail.content_type_parameters[:boundary]) end - - test "can pass random headers in as a hash" do - hash = {'X-Special-Domain-Specific-Header' => "SecretValue", - 'In-Reply-To' => '1234@mikel.me.com' } - mail = BaseMailer.simple_with_headers(hash) - assert_equal('SecretValue', mail['X-Special-Domain-Specific-Header'].decoded) - assert_equal('1234@mikel.me.com', mail['In-Reply-To'].decoded) - end - - test "can pass random headers in as a hash to mail" do - hash = {'X-Special-Domain-Specific-Header' => "SecretValue", - 'In-Reply-To' => '1234@mikel.me.com' } - mail = BaseMailer.simple(hash) - assert_equal('SecretValue', mail['X-Special-Domain-Specific-Header'].decoded) - assert_equal('1234@mikel.me.com', mail['In-Reply-To'].decoded) - end protected -- cgit v1.2.3 From 48a3985dd77160b34fc3ac35a75d850d8a2711f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 26 Jan 2010 16:18:29 +0100 Subject: Also include translation in ActionMailer. --- actionmailer/lib/action_mailer/base.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index b230e34631..2288a30691 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -255,6 +255,7 @@ module ActionMailer #:nodoc: include AbstractController::Layouts include AbstractController::Helpers include AbstractController::UrlFor + include AbstractController::Translation helper ActionMailer::MailHelper -- cgit v1.2.3 From 9f7190187cd755345557009a0b0ca9eec679b415 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 26 Jan 2010 09:27:21 -0600 Subject: Failing AM test for nested layouts --- .../test/fixtures/nested/layouts/spam.html.erb | 1 + .../fixtures/nested_layout_mailer/signup.html.erb | 1 + actionmailer/test/old_base/mail_layout_test.rb | 19 +++++++++++++++++-- 3 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 actionmailer/test/fixtures/nested/layouts/spam.html.erb create mode 100644 actionmailer/test/fixtures/nested_layout_mailer/signup.html.erb (limited to 'actionmailer') diff --git a/actionmailer/test/fixtures/nested/layouts/spam.html.erb b/actionmailer/test/fixtures/nested/layouts/spam.html.erb new file mode 100644 index 0000000000..7a24b19b7f --- /dev/null +++ b/actionmailer/test/fixtures/nested/layouts/spam.html.erb @@ -0,0 +1 @@ +Nested Spammer layout <%= yield %> \ No newline at end of file diff --git a/actionmailer/test/fixtures/nested_layout_mailer/signup.html.erb b/actionmailer/test/fixtures/nested_layout_mailer/signup.html.erb new file mode 100644 index 0000000000..4789e888c6 --- /dev/null +++ b/actionmailer/test/fixtures/nested_layout_mailer/signup.html.erb @@ -0,0 +1 @@ +We do not spam \ No newline at end of file diff --git a/actionmailer/test/old_base/mail_layout_test.rb b/actionmailer/test/old_base/mail_layout_test.rb index 4038fbf339..2abd3ece92 100644 --- a/actionmailer/test/old_base/mail_layout_test.rb +++ b/actionmailer/test/old_base/mail_layout_test.rb @@ -1,7 +1,7 @@ require 'abstract_unit' class AutoLayoutMailer < ActionMailer::Base - + def hello recipients 'test@localhost' subject "You have a mail" @@ -51,6 +51,16 @@ class ExplicitLayoutMailer < ActionMailer::Base end end +class NestedLayoutMailer < ActionMailer::Base + layout 'nested/layouts/spam' + + def signup + recipients 'test@localhost' + subject "You have a mail" + from "tester@example.com" + end +end + class LayoutMailerTest < Test::Unit::TestCase def setup set_delivery_method :test @@ -77,7 +87,7 @@ class LayoutMailerTest < Test::Unit::TestCase # CHANGED: content_type returns an object # assert_equal 'text/plain', mail.parts.first.content_type assert_equal 'text/plain', mail.parts.first.mime_type - + # CHANGED: body returns an object # assert_equal "text/plain layout - text/plain multipart", mail.parts.first.body assert_equal "text/plain layout - text/plain multipart", mail.parts.first.body.to_s @@ -145,4 +155,9 @@ class LayoutMailerTest < Test::Unit::TestCase mail = ExplicitLayoutMailer.logout assert_equal "You logged out", mail.body.to_s.strip end + + def test_nested_class_layout + mail = NestedLayoutMailer.signup + assert_equal "Nested Spammer layout We do not spam", mail.body.to_s.strip + end end -- cgit v1.2.3 From 31b538df6457ba723668afc62e85056e3bca9413 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 26 Jan 2010 09:37:20 -0600 Subject: Failing AM test for legacy multipart alternative rendering --- .../test_mailer/multipart_alternative.html.erb | 1 + .../test_mailer/multipart_alternative.plain.erb | 1 + actionmailer/test/old_base/mail_render_test.rb | 37 ++++++++++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 actionmailer/test/fixtures/test_mailer/multipart_alternative.html.erb create mode 100644 actionmailer/test/fixtures/test_mailer/multipart_alternative.plain.erb (limited to 'actionmailer') diff --git a/actionmailer/test/fixtures/test_mailer/multipart_alternative.html.erb b/actionmailer/test/fixtures/test_mailer/multipart_alternative.html.erb new file mode 100644 index 0000000000..73ea14f82f --- /dev/null +++ b/actionmailer/test/fixtures/test_mailer/multipart_alternative.html.erb @@ -0,0 +1 @@ +foo <%= @foo %> \ No newline at end of file diff --git a/actionmailer/test/fixtures/test_mailer/multipart_alternative.plain.erb b/actionmailer/test/fixtures/test_mailer/multipart_alternative.plain.erb new file mode 100644 index 0000000000..779fe4c1ea --- /dev/null +++ b/actionmailer/test/fixtures/test_mailer/multipart_alternative.plain.erb @@ -0,0 +1 @@ +foo: <%= @foo %> \ No newline at end of file diff --git a/actionmailer/test/old_base/mail_render_test.rb b/actionmailer/test/old_base/mail_render_test.rb index 804200fd36..7ba55b1bd2 100644 --- a/actionmailer/test/old_base/mail_render_test.rb +++ b/actionmailer/test/old_base/mail_render_test.rb @@ -62,6 +62,33 @@ class RenderMailer < ActionMailer::Base super mailer_name "test_mailer" end + + def multipart_alternative + recipients 'test@localhost' + subject 'multipart/alternative' + from 'tester@example.com' + + build_multipart_message(:foo => "bar") + end + + private + def build_multipart_message(assigns = {}) + content_type "multipart/alternative" + + part "text/plain" do |p| + p.body = build_body_part('plain', assigns, :layout => false) + end + + part "text/html" do |p| + p.body = build_body_part('html', assigns) + p.transfer_encoding = "base64" + end + end + + def build_body_part(content_type, assigns, options = {}) + render "#{template}.#{content_type}", :body => assigns + # render options.merge(:file => "#{template}.#{content_type}", :body => assigns) + end end class FirstMailer < ActionMailer::Base @@ -129,6 +156,16 @@ class RenderHelperTest < Test::Unit::TestCase mail = RenderMailer.no_instance_variable.deliver assert_equal "Look, subject.nil? is true!", mail.body.to_s.strip end + + def test_legacy_multipart_alternative + mail = RenderMailer.multipart_alternative.deliver + assert_equal(2, email.parts.size) + assert_equal("multipart/alternative", email.mime_type) + assert_equal("text/plain", email.parts[0].mime_type) + assert_equal("foo: bar", email.parts[0].body.encoded) + assert_equal("text/html", email.parts[1].mime_type) + assert_equal("foo bar", email.parts[1].body.encoded) + end end class FirstSecondHelperTest < Test::Unit::TestCase -- cgit v1.2.3 From af43674c1cc73630736537a73e79a24ac2bef995 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 26 Jan 2010 19:15:20 +0100 Subject: Fix failing tests on AM about render(:body => Hash). --- actionmailer/lib/action_mailer/deprecated_api.rb | 6 ++- actionmailer/lib/action_mailer/old_api.rb | 8 +--- actionmailer/test/old_base/mail_layout_test.rb | 4 +- actionmailer/test/old_base/mail_render_test.rb | 47 +++++------------------- actionmailer/test/old_base/mail_service_test.rb | 37 +++++++++---------- actionmailer/test/subscriber_test.rb | 2 +- 6 files changed, 36 insertions(+), 68 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/deprecated_api.rb b/actionmailer/lib/action_mailer/deprecated_api.rb index 61101c26a1..36eec1087e 100644 --- a/actionmailer/lib/action_mailer/deprecated_api.rb +++ b/actionmailer/lib/action_mailer/deprecated_api.rb @@ -93,10 +93,12 @@ module ActionMailer def render(*args) options = args.last.is_a?(Hash) ? args.last : {} - if options[:body] + + if options[:body].is_a?(Hash) ActiveSupport::Deprecation.warn(':body in render deprecated. Please use instance ' << 'variables as assigns instead', caller[0,1]) - body options.delete(:body) + + options[:body].each { |k,v| instance_variable_set(:"@#{k}", v) } end super end diff --git a/actionmailer/lib/action_mailer/old_api.rb b/actionmailer/lib/action_mailer/old_api.rb index 22c3c518b1..4694958222 100644 --- a/actionmailer/lib/action_mailer/old_api.rb +++ b/actionmailer/lib/action_mailer/old_api.rb @@ -204,12 +204,8 @@ module ActionMailer def create_parts if String === @body - self.response_body = @body - end - - if String === response_body - @parts.unshift create_inline_part(response_body) - else + @parts.unshift create_inline_part(@body) + elsif @parts.empty? || @parts.all? { |p| p.content_disposition =~ /^attachment/ } self.class.view_paths.first.find_all(@template, {}, @mailer_name).each do |template| @parts << create_inline_part(render_to_body(:_template => template), template.mime_type) end diff --git a/actionmailer/test/old_base/mail_layout_test.rb b/actionmailer/test/old_base/mail_layout_test.rb index 2abd3ece92..c69252efa9 100644 --- a/actionmailer/test/old_base/mail_layout_test.rb +++ b/actionmailer/test/old_base/mail_layout_test.rb @@ -14,7 +14,7 @@ class AutoLayoutMailer < ActionMailer::Base from "tester@example.com" @world = "Earth" - render(:inline => "Hello, <%= @world %>", :layout => 'spam') + body render(:inline => "Hello, <%= @world %>", :layout => 'spam') end def nolayout @@ -23,7 +23,7 @@ class AutoLayoutMailer < ActionMailer::Base from "tester@example.com" @world = "Earth" - render(:inline => "Hello, <%= @world %>", :layout => false) + body render(:inline => "Hello, <%= @world %>", :layout => false) end def multipart(type = nil) diff --git a/actionmailer/test/old_base/mail_render_test.rb b/actionmailer/test/old_base/mail_render_test.rb index 7ba55b1bd2..4213c2a173 100644 --- a/actionmailer/test/old_base/mail_render_test.rb +++ b/actionmailer/test/old_base/mail_render_test.rb @@ -7,7 +7,7 @@ class RenderMailer < ActionMailer::Base from "tester@example.com" @world = "Earth" - render :inline => "Hello, <%= @world %>" + body render(:inline => "Hello, <%= @world %>") end def file_template @@ -16,16 +16,7 @@ class RenderMailer < ActionMailer::Base from "tester@example.com" @recipient = 'test@localhost' - render :file => "templates/signed_up" - end - - def implicit_body - recipients 'test@localhost' - subject "using helpers" - from "tester@example.com" - - @recipient = 'test@localhost' - render :template => "templates/signed_up" + body render(:file => "templates/signed_up") end def rxml_template @@ -40,21 +31,13 @@ class RenderMailer < ActionMailer::Base from "tester@example.com" end - def mailer_accessor - recipients 'test@localhost' - subject "Mailer Accessor" - from "tester@example.com" - - render :inline => "Look, <%= mailer.subject %>!" - end - def no_instance_variable recipients 'test@localhost' subject "No Instance Variable" from "tester@example.com" silence_warnings do - render :inline => "Look, subject.nil? is <%= @subject.nil? %>!" + body render(:inline => "Look, subject.nil? is <%= @subject.nil? %>!") end end @@ -81,13 +64,11 @@ class RenderMailer < ActionMailer::Base part "text/html" do |p| p.body = build_body_part('html', assigns) - p.transfer_encoding = "base64" end end def build_body_part(content_type, assigns, options = {}) render "#{template}.#{content_type}", :body => assigns - # render options.merge(:file => "#{template}.#{content_type}", :body => assigns) end end @@ -122,11 +103,6 @@ class RenderHelperTest < Test::Unit::TestCase restore_delivery_method end - def test_implicit_body - mail = RenderMailer.implicit_body - assert_equal "Hello there, \n\nMr. test@localhost", mail.body.to_s.strip - end - def test_inline_template mail = RenderMailer.inline_template assert_equal "Hello, Earth", mail.body.to_s.strip @@ -147,11 +123,6 @@ class RenderHelperTest < Test::Unit::TestCase assert_equal "Hey Ho, let's go!", mail.body.to_s.strip end - def test_mailer_accessor - mail = RenderMailer.mailer_accessor.deliver - assert_equal "Look, Mailer Accessor!", mail.body.to_s.strip - end - def test_no_instance_variable mail = RenderMailer.no_instance_variable.deliver assert_equal "Look, subject.nil? is true!", mail.body.to_s.strip @@ -159,12 +130,12 @@ class RenderHelperTest < Test::Unit::TestCase def test_legacy_multipart_alternative mail = RenderMailer.multipart_alternative.deliver - assert_equal(2, email.parts.size) - assert_equal("multipart/alternative", email.mime_type) - assert_equal("text/plain", email.parts[0].mime_type) - assert_equal("foo: bar", email.parts[0].body.encoded) - assert_equal("text/html", email.parts[1].mime_type) - assert_equal("foo bar", email.parts[1].body.encoded) + assert_equal(2, mail.parts.size) + assert_equal("multipart/alternative", mail.mime_type) + assert_equal("text/plain", mail.parts[0].mime_type) + assert_equal("foo: bar", mail.parts[0].body.encoded) + assert_equal("text/html", mail.parts[1].mime_type) + assert_equal("foo bar", mail.parts[1].body.encoded) end end diff --git a/actionmailer/test/old_base/mail_service_test.rb b/actionmailer/test/old_base/mail_service_test.rb index fb784328bc..70dafaf33c 100644 --- a/actionmailer/test/old_base/mail_service_test.rb +++ b/actionmailer/test/old_base/mail_service_test.rb @@ -27,20 +27,19 @@ class TestMailer < ActionMailer::Base subject "[Cancelled] Goodbye #{recipient}" from "system@loudthinking.com" sent_on Time.local(2004, 12, 12) - - render :text => "Goodbye, Mr. #{recipient}" + body "Goodbye, Mr. #{recipient}" end def from_with_name from "System " recipients "root@loudthinking.com" - render :text => "Nothing to see here." + body "Nothing to see here." end def from_without_name from "system@loudthinking.com" recipients "root@loudthinking.com" - render :text => "Nothing to see here." + body "Nothing to see here." end def cc_bcc(recipient) @@ -51,7 +50,7 @@ class TestMailer < ActionMailer::Base cc "nobody@loudthinking.com" bcc "root@loudthinking.com" - render :text => "Nothing to see here." + body "Nothing to see here." end def different_reply_to(recipient) @@ -61,7 +60,7 @@ class TestMailer < ActionMailer::Base sent_on Time.local(2008, 5, 23) reply_to "atraver@gmail.com" - render :text => "Nothing to see here." + body "Nothing to see here." end def iso_charset(recipient) @@ -73,7 +72,7 @@ class TestMailer < ActionMailer::Base bcc "root@loudthinking.com" charset "iso-8859-1" - render :text => "Nothing to see here." + body "Nothing to see here." end def unencoded_subject(recipient) @@ -84,7 +83,7 @@ class TestMailer < ActionMailer::Base cc "nobody@loudthinking.com" bcc "root@loudthinking.com" - render :text => "Nothing to see here." + body "Nothing to see here." end def extended_headers(recipient) @@ -96,7 +95,7 @@ class TestMailer < ActionMailer::Base bcc "Grytøyr " charset "iso-8859-1" - render :text => "Nothing to see here." + body "Nothing to see here." end def utf8_body(recipient) @@ -108,7 +107,7 @@ class TestMailer < ActionMailer::Base bcc "Foo áëô îü " charset "utf-8" - render :text => "åœö blah" + body "åœö blah" end def multipart_with_mime_version(recipient) @@ -158,7 +157,7 @@ class TestMailer < ActionMailer::Base attachment :content_type => "image/jpeg", :filename => File.join(File.dirname(__FILE__), "fixtures", "attachments", "foo.jpg"), :data => "123456789" - render :text => "plain text default" + body "plain text default" end def implicitly_multipart_example(recipient, cs = nil, order = nil) @@ -187,12 +186,12 @@ class TestMailer < ActionMailer::Base from "test@example.com" content_type "text/html" - render :text => "Emphasize this" + body "Emphasize this" end def html_mail_with_underscores(recipient) subject "html mail with underscores" - render :text => %{_Google} + body %{_Google} end def custom_template(recipient) @@ -219,7 +218,7 @@ class TestMailer < ActionMailer::Base subject "various newlines" from "test@example.com" - render :text => "line #1\nline #2\rline #3\r\nline #4\r\r" + + body "line #1\nline #2\rline #3\r\nline #4\r\r" + "line #5\n\nline#6\r\n\r\nline #7" end @@ -282,7 +281,7 @@ class TestMailer < ActionMailer::Base from "One: Two " cc "Three: Four " bcc "Five: Six " - render :text => "testing" + body "testing" end def custom_content_type_attributes @@ -290,7 +289,7 @@ class TestMailer < ActionMailer::Base subject "custom content types" from "some.one@somewhere.test" content_type "text/plain; format=flowed" - render :text => "testing" + body "testing" end def return_path @@ -298,13 +297,13 @@ class TestMailer < ActionMailer::Base subject "return path test" from "some.one@somewhere.test" headers["return-path"] = "another@somewhere.test" - render :text => "testing" + body "testing" end def subject_with_i18n(recipient) recipients recipient from "system@loudthinking.com" - render :text => "testing" + body "testing" end class << self @@ -1111,7 +1110,7 @@ end class MethodNamingTest < ActiveSupport::TestCase class TestMailer < ActionMailer::Base def send - render :text => 'foo' + body 'foo' end end diff --git a/actionmailer/test/subscriber_test.rb b/actionmailer/test/subscriber_test.rb index 6c347b8392..3d1736d64f 100644 --- a/actionmailer/test/subscriber_test.rb +++ b/actionmailer/test/subscriber_test.rb @@ -11,7 +11,7 @@ class AMSubscriberTest < ActionMailer::TestCase recipients "somewhere@example.com" subject "basic" from "basic@example.com" - render :text => "Hello world" + body "Hello world" end def receive(mail) -- cgit v1.2.3 From 9f63c4b26e6afe04849dc906b52177ba5221e3b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 26 Jan 2010 19:50:59 +0100 Subject: Bring AM tests back to green again. --- actionmailer/test/fixtures/nested/layouts/spam.html.erb | 1 - actionmailer/test/old_base/mail_layout_test.rb | 15 --------------- actionmailer/test/old_base/mail_render_test.rb | 4 +++- 3 files changed, 3 insertions(+), 17 deletions(-) delete mode 100644 actionmailer/test/fixtures/nested/layouts/spam.html.erb (limited to 'actionmailer') diff --git a/actionmailer/test/fixtures/nested/layouts/spam.html.erb b/actionmailer/test/fixtures/nested/layouts/spam.html.erb deleted file mode 100644 index 7a24b19b7f..0000000000 --- a/actionmailer/test/fixtures/nested/layouts/spam.html.erb +++ /dev/null @@ -1 +0,0 @@ -Nested Spammer layout <%= yield %> \ No newline at end of file diff --git a/actionmailer/test/old_base/mail_layout_test.rb b/actionmailer/test/old_base/mail_layout_test.rb index c69252efa9..5679aa5a64 100644 --- a/actionmailer/test/old_base/mail_layout_test.rb +++ b/actionmailer/test/old_base/mail_layout_test.rb @@ -51,16 +51,6 @@ class ExplicitLayoutMailer < ActionMailer::Base end end -class NestedLayoutMailer < ActionMailer::Base - layout 'nested/layouts/spam' - - def signup - recipients 'test@localhost' - subject "You have a mail" - from "tester@example.com" - end -end - class LayoutMailerTest < Test::Unit::TestCase def setup set_delivery_method :test @@ -155,9 +145,4 @@ class LayoutMailerTest < Test::Unit::TestCase mail = ExplicitLayoutMailer.logout assert_equal "You logged out", mail.body.to_s.strip end - - def test_nested_class_layout - mail = NestedLayoutMailer.signup - assert_equal "Nested Spammer layout We do not spam", mail.body.to_s.strip - end end diff --git a/actionmailer/test/old_base/mail_render_test.rb b/actionmailer/test/old_base/mail_render_test.rb index 4213c2a173..405d43d7d3 100644 --- a/actionmailer/test/old_base/mail_render_test.rb +++ b/actionmailer/test/old_base/mail_render_test.rb @@ -68,7 +68,9 @@ class RenderMailer < ActionMailer::Base end def build_body_part(content_type, assigns, options = {}) - render "#{template}.#{content_type}", :body => assigns + ActiveSupport::Deprecation.silence do + render "#{template}.#{content_type}", :body => assigns + end end end -- cgit v1.2.3 From b6b3db6734af8d5b42c7bdcea7c73923a5b88463 Mon Sep 17 00:00:00 2001 From: Mikel Lindsaar Date: Thu, 28 Jan 2010 00:24:30 +1100 Subject: Fixed bug on HTML only emails getting set to text/plain --- actionmailer/lib/action_mailer/base.rb | 2 +- actionmailer/test/base_test.rb | 18 ++++++++++++++++++ .../test/fixtures/base_mailer/html_only.html.erb | 1 + .../test/fixtures/base_mailer/plain_text_only.text.erb | 1 + 4 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 actionmailer/test/fixtures/base_mailer/html_only.html.erb create mode 100644 actionmailer/test/fixtures/base_mailer/plain_text_only.text.erb (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 2288a30691..3fbf004a0d 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -531,7 +531,7 @@ module ActionMailer #:nodoc: when m.multipart? ["multipart", "alternative", params] else - class_default + m.content_type || class_default end end diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index 4a65363e3e..b7af86b622 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -17,6 +17,14 @@ class BaseTest < ActiveSupport::TestCase def simple(hash = {}) mail(hash) end + + def html_only(hash = {}) + mail(hash) + end + + def plain_text_only(hash = {}) + mail(hash) + end def simple_with_headers(hash = {}) headers hash @@ -434,6 +442,16 @@ class BaseTest < ActiveSupport::TestCase mail = BaseMailer.explicit_multipart assert_not_nil(mail.content_type_parameters[:boundary]) end + + test "should set a content type if only has an html part" do + mail = BaseMailer.html_only + assert_equal('text/html', mail.mime_type) + end + + test "should set a content type if only has an plain text part" do + mail = BaseMailer.plain_text_only + assert_equal('text/plain', mail.mime_type) + end protected diff --git a/actionmailer/test/fixtures/base_mailer/html_only.html.erb b/actionmailer/test/fixtures/base_mailer/html_only.html.erb new file mode 100644 index 0000000000..9c99a008e7 --- /dev/null +++ b/actionmailer/test/fixtures/base_mailer/html_only.html.erb @@ -0,0 +1 @@ +

Testing

\ No newline at end of file diff --git a/actionmailer/test/fixtures/base_mailer/plain_text_only.text.erb b/actionmailer/test/fixtures/base_mailer/plain_text_only.text.erb new file mode 100644 index 0000000000..0a90125685 --- /dev/null +++ b/actionmailer/test/fixtures/base_mailer/plain_text_only.text.erb @@ -0,0 +1 @@ +Testing \ No newline at end of file -- cgit v1.2.3 From 32ce2bb37fcc4f41322d69d74d686d08c0bb39c7 Mon Sep 17 00:00:00 2001 From: Mikel Lindsaar Date: Thu, 28 Jan 2010 11:33:58 +1100 Subject: Updated mail requirement to 2.1.2 --- actionmailer/actionmailer.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionmailer') diff --git a/actionmailer/actionmailer.gemspec b/actionmailer/actionmailer.gemspec index d73f86cd65..b0ec3d798e 100644 --- a/actionmailer/actionmailer.gemspec +++ b/actionmailer/actionmailer.gemspec @@ -11,7 +11,7 @@ Gem::Specification.new do |s| s.homepage = "http://www.rubyonrails.org" s.add_dependency('actionpack', '= 3.0.pre') - s.add_dependency('mail', '~> 2.1.1') + s.add_dependency('mail', '~> 2.1.2') s.files = Dir['CHANGELOG', 'README', 'MIT-LICENSE', 'lib/**/*'] s.has_rdoc = true -- cgit v1.2.3 From a06a5a64ba8f7d7b11025d136013b48a01ccdcc8 Mon Sep 17 00:00:00 2001 From: Mikel Lindsaar Date: Thu, 28 Jan 2010 12:08:14 +1100 Subject: Unvendor'd text-format, now requires text-format gem --- actionmailer/CHANGELOG | 2 + actionmailer/actionmailer.gemspec | 1 + actionmailer/lib/action_mailer.rb | 2 +- .../vendor/text-format-0.6.3/text/format.rb | 1467 -------------------- .../lib/action_mailer/vendor/text_format.rb | 10 - 5 files changed, 4 insertions(+), 1478 deletions(-) delete mode 100755 actionmailer/lib/action_mailer/vendor/text-format-0.6.3/text/format.rb delete mode 100644 actionmailer/lib/action_mailer/vendor/text_format.rb (limited to 'actionmailer') diff --git a/actionmailer/CHANGELOG b/actionmailer/CHANGELOG index 0018a2ed5d..4ee6bd4620 100644 --- a/actionmailer/CHANGELOG +++ b/actionmailer/CHANGELOG @@ -1,5 +1,7 @@ *Rails 3.0 (pending)* +* Unvendor'd text-format, now requires text-format gem + * Whole new API added with tests. See base.rb for full details. Old API is deprecated. * The Mail::Message class has helped methods for all the field types that return 'common' defaults for the common use case, so to get the subject, mail.subject will give you a string, mail.date will give you a DateTime object, mail.from will give you an array of address specs (mikel@test.lindsaar.net) etc. If you want to access the field object itself, call mail[:field_name] which will return the field object you want, which you can then chain, like mail[:from].formatted diff --git a/actionmailer/actionmailer.gemspec b/actionmailer/actionmailer.gemspec index b0ec3d798e..abbb542293 100644 --- a/actionmailer/actionmailer.gemspec +++ b/actionmailer/actionmailer.gemspec @@ -12,6 +12,7 @@ Gem::Specification.new do |s| s.add_dependency('actionpack', '= 3.0.pre') s.add_dependency('mail', '~> 2.1.2') + s.add_dependency('text-format', '~> 1.0.0') s.files = Dir['CHANGELOG', 'README', 'MIT-LICENSE', 'lib/**/*'] s.has_rdoc = true diff --git a/actionmailer/lib/action_mailer.rb b/actionmailer/lib/action_mailer.rb index 8339826197..17f63aca25 100644 --- a/actionmailer/lib/action_mailer.rb +++ b/actionmailer/lib/action_mailer.rb @@ -45,5 +45,5 @@ end module Text extend ActiveSupport::Autoload - autoload :Format, 'action_mailer/vendor/text_format' + autoload :Format, 'text/format' end diff --git a/actionmailer/lib/action_mailer/vendor/text-format-0.6.3/text/format.rb b/actionmailer/lib/action_mailer/vendor/text-format-0.6.3/text/format.rb deleted file mode 100755 index 81cc7906d8..0000000000 --- a/actionmailer/lib/action_mailer/vendor/text-format-0.6.3/text/format.rb +++ /dev/null @@ -1,1467 +0,0 @@ -#-- -# Text::Format for Ruby -# Version 0.63 -# -# Copyright (c) 2002 - 2003 Austin Ziegler -# -# $Id: format.rb,v 1.1.1.1 2004/10/14 11:59:57 webster132 Exp $ -# -# ========================================================================== -# Revision History :: -# YYYY.MM.DD Change ID Developer -# Description -# -------------------------------------------------------------------------- -# 2002.10.18 Austin Ziegler -# Fixed a minor problem with tabs not being counted. Changed -# abbreviations from Hash to Array to better suit Ruby's -# capabilities. Fixed problems with the way that Array arguments -# are handled in calls to the major object types, excepting in -# Text::Format#expand and Text::Format#unexpand (these will -# probably need to be fixed). -# 2002.10.30 Austin Ziegler -# Fixed the ordering of the <=> for binary tests. Fixed -# Text::Format#expand and Text::Format#unexpand to handle array -# arguments better. -# 2003.01.24 Austin Ziegler -# Fixed a problem with Text::Format::RIGHT_FILL handling where a -# single word is larger than #columns. Removed Comparable -# capabilities (<=> doesn't make sense; == does). Added Symbol -# equivalents for the Hash initialization. Hash initialization has -# been modified so that values are set as follows (Symbols are -# highest priority; strings are middle; defaults are lowest): -# @columns = arg[:columns] || arg['columns'] || @columns -# Added #hard_margins, #split_rules, #hyphenator, and #split_words. -# 2003.02.07 Austin Ziegler -# Fixed the installer for proper case-sensitive handling. -# 2003.03.28 Austin Ziegler -# Added the ability for a hyphenator to receive the formatter -# object. Fixed a bug for strings matching /\A\s*\Z/ failing -# entirely. Fixed a test case failing under 1.6.8. -# 2003.04.04 Austin Ziegler -# Handle the case of hyphenators returning nil for first/rest. -# 2003.09.17 Austin Ziegler -# Fixed a problem where #paragraphs(" ") was raising -# NoMethodError. -# -# ========================================================================== -#++ - -module Text #:nodoc: - # Text::Format for Ruby is copyright 2002 - 2005 by Austin Ziegler. It - # is available under Ruby's licence, the Perl Artistic licence, or the - # GNU GPL version 2 (or at your option, any later version). As a - # special exception, for use with official Rails (provided by the - # rubyonrails.org development team) and any project created with - # official Rails, the following alternative MIT-style licence may be - # used: - # - # == Text::Format Licence for Rails and Rails Applications - # Permission is hereby granted, free of charge, to any person - # obtaining a copy of this software and associated documentation files - # (the "Software"), to deal in the Software without restriction, - # including without limitation the rights to use, copy, modify, merge, - # publish, distribute, sublicense, and/or sell copies of the Software, - # and to permit persons to whom the Software is furnished to do so, - # subject to the following conditions: - # - # * The names of its contributors may not be used to endorse or - # promote products derived from this software without specific prior - # written permission. - # - # The above copyright notice and this permission notice shall be - # included in all copies or substantial portions of the Software. - # - # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - # SOFTWARE. - class Format - VERSION = '0.63' - - # Local abbreviations. More can be added with Text::Format.abbreviations - ABBREV = [ 'Mr', 'Mrs', 'Ms', 'Jr', 'Sr' ] - - # Formatting values - LEFT_ALIGN = 0 - RIGHT_ALIGN = 1 - RIGHT_FILL = 2 - JUSTIFY = 3 - - # Word split modes (only applies when #hard_margins is true). - SPLIT_FIXED = 1 - SPLIT_CONTINUATION = 2 - SPLIT_HYPHENATION = 4 - SPLIT_CONTINUATION_FIXED = SPLIT_CONTINUATION | SPLIT_FIXED - SPLIT_HYPHENATION_FIXED = SPLIT_HYPHENATION | SPLIT_FIXED - SPLIT_HYPHENATION_CONTINUATION = SPLIT_HYPHENATION | SPLIT_CONTINUATION - SPLIT_ALL = SPLIT_HYPHENATION | SPLIT_CONTINUATION | SPLIT_FIXED - - # Words forcibly split by Text::Format will be stored as split words. - # This class represents a word forcibly split. - class SplitWord - # The word that was split. - attr_reader :word - # The first part of the word that was split. - attr_reader :first - # The remainder of the word that was split. - attr_reader :rest - - def initialize(word, first, rest) #:nodoc: - @word = word - @first = first - @rest = rest - end - end - - private - LEQ_RE = /[.?!]['"]?$/ - - def brk_re(i) #:nodoc: - %r/((?:\S+\s+){#{i}})(.+)/ - end - - def posint(p) #:nodoc: - p.to_i.abs - end - - public - # Compares two Text::Format objects. All settings of the objects are - # compared *except* #hyphenator. Generated results (e.g., #split_words) - # are not compared, either. - def ==(o) - (@text == o.text) && - (@columns == o.columns) && - (@left_margin == o.left_margin) && - (@right_margin == o.right_margin) && - (@hard_margins == o.hard_margins) && - (@split_rules == o.split_rules) && - (@first_indent == o.first_indent) && - (@body_indent == o.body_indent) && - (@tag_text == o.tag_text) && - (@tabstop == o.tabstop) && - (@format_style == o.format_style) && - (@extra_space == o.extra_space) && - (@tag_paragraph == o.tag_paragraph) && - (@nobreak == o.nobreak) && - (@abbreviations == o.abbreviations) && - (@nobreak_regex == o.nobreak_regex) - end - - # The text to be manipulated. Note that value is optional, but if the - # formatting functions are called without values, this text is what will - # be formatted. - # - # *Default*:: [] - # Used in:: All methods - attr_accessor :text - - # The total width of the format area. The margins, indentation, and text - # are formatted into this space. - # - # COLUMNS - # <--------------------------------------------------------------> - # <-----------><------><---------------------------><------------> - # left margin indent text is formatted into here right margin - # - # *Default*:: 72 - # Used in:: #format, #paragraphs, - # #center - attr_reader :columns - - # The total width of the format area. The margins, indentation, and text - # are formatted into this space. The value provided is silently - # converted to a positive integer. - # - # COLUMNS - # <--------------------------------------------------------------> - # <-----------><------><---------------------------><------------> - # left margin indent text is formatted into here right margin - # - # *Default*:: 72 - # Used in:: #format, #paragraphs, - # #center - def columns=(c) - @columns = posint(c) - end - - # The number of spaces used for the left margin. - # - # columns - # <--------------------------------------------------------------> - # <-----------><------><---------------------------><------------> - # LEFT MARGIN indent text is formatted into here right margin - # - # *Default*:: 0 - # Used in:: #format, #paragraphs, - # #center - attr_reader :left_margin - - # The number of spaces used for the left margin. The value provided is - # silently converted to a positive integer value. - # - # columns - # <--------------------------------------------------------------> - # <-----------><------><---------------------------><------------> - # LEFT MARGIN indent text is formatted into here right margin - # - # *Default*:: 0 - # Used in:: #format, #paragraphs, - # #center - def left_margin=(left) - @left_margin = posint(left) - end - - # The number of spaces used for the right margin. - # - # columns - # <--------------------------------------------------------------> - # <-----------><------><---------------------------><------------> - # left margin indent text is formatted into here RIGHT MARGIN - # - # *Default*:: 0 - # Used in:: #format, #paragraphs, - # #center - attr_reader :right_margin - - # The number of spaces used for the right margin. The value provided is - # silently converted to a positive integer value. - # - # columns - # <--------------------------------------------------------------> - # <-----------><------><---------------------------><------------> - # left margin indent text is formatted into here RIGHT MARGIN - # - # *Default*:: 0 - # Used in:: #format, #paragraphs, - # #center - def right_margin=(r) - @right_margin = posint(r) - end - - # The number of spaces to indent the first line of a paragraph. - # - # columns - # <--------------------------------------------------------------> - # <-----------><------><---------------------------><------------> - # left margin INDENT text is formatted into here right margin - # - # *Default*:: 4 - # Used in:: #format, #paragraphs - attr_reader :first_indent - - # The number of spaces to indent the first line of a paragraph. The - # value provided is silently converted to a positive integer value. - # - # columns - # <--------------------------------------------------------------> - # <-----------><------><---------------------------><------------> - # left margin INDENT text is formatted into here right margin - # - # *Default*:: 4 - # Used in:: #format, #paragraphs - def first_indent=(f) - @first_indent = posint(f) - end - - # The number of spaces to indent all lines after the first line of a - # paragraph. - # - # columns - # <--------------------------------------------------------------> - # <-----------><------><---------------------------><------------> - # left margin INDENT text is formatted into here right margin - # - # *Default*:: 0 - # Used in:: #format, #paragraphs - attr_reader :body_indent - - # The number of spaces to indent all lines after the first line of - # a paragraph. The value provided is silently converted to a - # positive integer value. - # - # columns - # <--------------------------------------------------------------> - # <-----------><------><---------------------------><------------> - # left margin INDENT text is formatted into here right margin - # - # *Default*:: 0 - # Used in:: #format, #paragraphs - def body_indent=(b) - @body_indent = posint(b) - end - - # Normally, words larger than the format area will be placed on a line - # by themselves. Setting this to +true+ will force words larger than the - # format area to be split into one or more "words" each at most the size - # of the format area. The first line and the original word will be - # placed into #split_words. Note that this will cause the - # output to look *similar* to a #format_style of JUSTIFY. (Lines will be - # filled as much as possible.) - # - # *Default*:: +false+ - # Used in:: #format, #paragraphs - attr_accessor :hard_margins - - # An array of words split during formatting if #hard_margins is set to - # +true+. - # #split_words << Text::Format::SplitWord.new(word, first, rest) - attr_reader :split_words - - # The object responsible for hyphenating. It must respond to - # #hyphenate_to(word, size) or #hyphenate_to(word, size, formatter) and - # return an array of the word split into two parts; if there is a - # hyphenation mark to be applied, responsibility belongs to the - # hyphenator object. The size is the MAXIMUM size permitted, including - # any hyphenation marks. If the #hyphenate_to method has an arity of 3, - # the formatter will be provided to the method. This allows the - # hyphenator to make decisions about the hyphenation based on the - # formatting rules. - # - # *Default*:: +nil+ - # Used in:: #format, #paragraphs - attr_reader :hyphenator - - # The object responsible for hyphenating. It must respond to - # #hyphenate_to(word, size) and return an array of the word hyphenated - # into two parts. The size is the MAXIMUM size permitted, including any - # hyphenation marks. - # - # *Default*:: +nil+ - # Used in:: #format, #paragraphs - def hyphenator=(h) - raise ArgumentError, "#{h.inspect} is not a valid hyphenator." unless h.respond_to?(:hyphenate_to) - arity = h.method(:hyphenate_to).arity - raise ArgumentError, "#{h.inspect} must have exactly two or three arguments." unless [2, 3].include?(arity) - @hyphenator = h - @hyphenator_arity = arity - end - - # Specifies the split mode; used only when #hard_margins is set to - # +true+. Allowable values are: - # [+SPLIT_FIXED+] The word will be split at the number of - # characters needed, with no marking at all. - # repre - # senta - # ion - # [+SPLIT_CONTINUATION+] The word will be split at the number of - # characters needed, with a C-style continuation - # character. If a word is the only item on a - # line and it cannot be split into an - # appropriate size, SPLIT_FIXED will be used. - # repr\ - # esen\ - # tati\ - # on - # [+SPLIT_HYPHENATION+] The word will be split according to the - # hyphenator specified in #hyphenator. If there - # is no #hyphenator specified, works like - # SPLIT_CONTINUATION. The example is using - # TeX::Hyphen. If a word is the only item on a - # line and it cannot be split into an - # appropriate size, SPLIT_CONTINUATION mode will - # be used. - # rep- - # re- - # sen- - # ta- - # tion - # - # *Default*:: Text::Format::SPLIT_FIXED - # Used in:: #format, #paragraphs - attr_reader :split_rules - - # Specifies the split mode; used only when #hard_margins is set to - # +true+. Allowable values are: - # [+SPLIT_FIXED+] The word will be split at the number of - # characters needed, with no marking at all. - # repre - # senta - # ion - # [+SPLIT_CONTINUATION+] The word will be split at the number of - # characters needed, with a C-style continuation - # character. - # repr\ - # esen\ - # tati\ - # on - # [+SPLIT_HYPHENATION+] The word will be split according to the - # hyphenator specified in #hyphenator. If there - # is no #hyphenator specified, works like - # SPLIT_CONTINUATION. The example is using - # TeX::Hyphen as the #hyphenator. - # rep- - # re- - # sen- - # ta- - # tion - # - # These values can be bitwise ORed together (e.g., SPLIT_FIXED | - # SPLIT_CONTINUATION) to provide fallback split methods. In the - # example given, an attempt will be made to split the word using the - # rules of SPLIT_CONTINUATION; if there is not enough room, the word - # will be split with the rules of SPLIT_FIXED. These combinations are - # also available as the following values: - # * +SPLIT_CONTINUATION_FIXED+ - # * +SPLIT_HYPHENATION_FIXED+ - # * +SPLIT_HYPHENATION_CONTINUATION+ - # * +SPLIT_ALL+ - # - # *Default*:: Text::Format::SPLIT_FIXED - # Used in:: #format, #paragraphs - def split_rules=(s) - raise ArgumentError, "Invalid value provided for split_rules." if ((s < SPLIT_FIXED) || (s > SPLIT_ALL)) - @split_rules = s - end - - # Indicates whether sentence terminators should be followed by a single - # space (+false+), or two spaces (+true+). - # - # *Default*:: +false+ - # Used in:: #format, #paragraphs - attr_accessor :extra_space - - # Defines the current abbreviations as an array. This is only used if - # extra_space is turned on. - # - # If one is abbreviating "President" as "Pres." (abbreviations = - # ["Pres"]), then the results of formatting will be as illustrated in - # the table below: - # - # extra_space | include? | !include? - # true | Pres. Lincoln | Pres. Lincoln - # false | Pres. Lincoln | Pres. Lincoln - # - # *Default*:: {} - # Used in:: #format, #paragraphs - attr_accessor :abbreviations - - # Indicates whether the formatting of paragraphs should be done with - # tagged paragraphs. Useful only with #tag_text. - # - # *Default*:: +false+ - # Used in:: #format, #paragraphs - attr_accessor :tag_paragraph - - # The array of text to be placed before each paragraph when - # #tag_paragraph is +true+. When #format() is called, - # only the first element of the array is used. When #paragraphs - # is called, then each entry in the array will be used once, with - # corresponding paragraphs. If the tag elements are exhausted before the - # text is exhausted, then the remaining paragraphs will not be tagged. - # Regardless of indentation settings, a blank line will be inserted - # between all paragraphs when #tag_paragraph is +true+. - # - # *Default*:: [] - # Used in:: #format, #paragraphs - attr_accessor :tag_text - - # Indicates whether or not the non-breaking space feature should be - # used. - # - # *Default*:: +false+ - # Used in:: #format, #paragraphs - attr_accessor :nobreak - - # A hash which holds the regular expressions on which spaces should not - # be broken. The hash is set up such that the key is the first word and - # the value is the second word. - # - # For example, if +nobreak_regex+ contains the following hash: - # - # { '^Mrs?\.$' => '\S+$', '^\S+$' => '^(?:S|J)r\.$'} - # - # Then "Mr. Jones", "Mrs. Jones", and "Jones Jr." would not be broken. - # If this simple matching algorithm indicates that there should not be a - # break at the current end of line, then a backtrack is done until there - # are two words on which line breaking is permitted. If two such words - # are not found, then the end of the line will be broken *regardless*. - # If there is a single word on the current line, then no backtrack is - # done and the word is stuck on the end. - # - # *Default*:: {} - # Used in:: #format, #paragraphs - attr_accessor :nobreak_regex - - # Indicates the number of spaces that a single tab represents. - # - # *Default*:: 8 - # Used in:: #expand, #unexpand, - # #paragraphs - attr_reader :tabstop - - # Indicates the number of spaces that a single tab represents. - # - # *Default*:: 8 - # Used in:: #expand, #unexpand, - # #paragraphs - def tabstop=(t) - @tabstop = posint(t) - end - - # Specifies the format style. Allowable values are: - # [+LEFT_ALIGN+] Left justified, ragged right. - # |A paragraph that is| - # |left aligned.| - # [+RIGHT_ALIGN+] Right justified, ragged left. - # |A paragraph that is| - # | right aligned.| - # [+RIGHT_FILL+] Left justified, right ragged, filled to width by - # spaces. (Essentially the same as +LEFT_ALIGN+ except - # that lines are padded on the right.) - # |A paragraph that is| - # |left aligned. | - # [+JUSTIFY+] Fully justified, words filled to width by spaces, - # except the last line. - # |A paragraph that| - # |is justified.| - # - # *Default*:: Text::Format::LEFT_ALIGN - # Used in:: #format, #paragraphs - attr_reader :format_style - - # Specifies the format style. Allowable values are: - # [+LEFT_ALIGN+] Left justified, ragged right. - # |A paragraph that is| - # |left aligned.| - # [+RIGHT_ALIGN+] Right justified, ragged left. - # |A paragraph that is| - # | right aligned.| - # [+RIGHT_FILL+] Left justified, right ragged, filled to width by - # spaces. (Essentially the same as +LEFT_ALIGN+ except - # that lines are padded on the right.) - # |A paragraph that is| - # |left aligned. | - # [+JUSTIFY+] Fully justified, words filled to width by spaces. - # |A paragraph that| - # |is justified.| - # - # *Default*:: Text::Format::LEFT_ALIGN - # Used in:: #format, #paragraphs - def format_style=(fs) - raise ArgumentError, "Invalid value provided for format_style." if ((fs < LEFT_ALIGN) || (fs > JUSTIFY)) - @format_style = fs - end - - # Indicates that the format style is left alignment. - # - # *Default*:: +true+ - # Used in:: #format, #paragraphs - def left_align? - return @format_style == LEFT_ALIGN - end - - # Indicates that the format style is right alignment. - # - # *Default*:: +false+ - # Used in:: #format, #paragraphs - def right_align? - return @format_style == RIGHT_ALIGN - end - - # Indicates that the format style is right fill. - # - # *Default*:: +false+ - # Used in:: #format, #paragraphs - def right_fill? - return @format_style == RIGHT_FILL - end - - # Indicates that the format style is full justification. - # - # *Default*:: +false+ - # Used in:: #format, #paragraphs - def justify? - return @format_style == JUSTIFY - end - - # The default implementation of #hyphenate_to implements - # SPLIT_CONTINUATION. - def hyphenate_to(word, size) - [word[0 .. (size - 2)] + "\\", word[(size - 1) .. -1]] - end - - private - def __do_split_word(word, size) #:nodoc: - [word[0 .. (size - 1)], word[size .. -1]] - end - - def __format(to_wrap) #:nodoc: - words = to_wrap.split(/\s+/).compact - words.shift if words[0].nil? or words[0].empty? - to_wrap = [] - - abbrev = false - width = @columns - @first_indent - @left_margin - @right_margin - indent_str = ' ' * @first_indent - first_line = true - line = words.shift - abbrev = __is_abbrev(line) unless line.nil? || line.empty? - - while w = words.shift - if (w.size + line.size < (width - 1)) || - ((line !~ LEQ_RE || abbrev) && (w.size + line.size < width)) - line << " " if (line =~ LEQ_RE) && (not abbrev) - line << " #{w}" - else - line, w = __do_break(line, w) if @nobreak - line, w = __do_hyphenate(line, w, width) if @hard_margins - if w.index(/\s+/) - w, *w2 = w.split(/\s+/) - words.unshift(w2) - words.flatten! - end - to_wrap << __make_line(line, indent_str, width, w.nil?) unless line.nil? - if first_line - first_line = false - width = @columns - @body_indent - @left_margin - @right_margin - indent_str = ' ' * @body_indent - end - line = w - end - - abbrev = __is_abbrev(w) unless w.nil? - end - - loop do - break if line.nil? or line.empty? - line, w = __do_hyphenate(line, w, width) if @hard_margins - to_wrap << __make_line(line, indent_str, width, w.nil?) - line = w - end - - if (@tag_paragraph && (to_wrap.size > 0)) then - clr = %r{`(\w+)'}.match([caller(1)].flatten[0])[1] - clr = "" if clr.nil? - - if ((not @tag_text[0].nil?) && (@tag_cur.size < 1) && - (clr != "__paragraphs")) then - @tag_cur = @tag_text[0] - end - - fchar = /(\S)/.match(to_wrap[0])[1] - white = to_wrap[0].index(fchar) - if ((white - @left_margin - 1) > @tag_cur.size) then - white = @tag_cur.size + @left_margin - to_wrap[0].gsub!(/^ {#{white}}/, "#{' ' * @left_margin}#{@tag_cur}") - else - to_wrap.unshift("#{' ' * @left_margin}#{@tag_cur}\n") - end - end - to_wrap.join('') - end - - # format lines in text into paragraphs with each element of @wrap a - # paragraph; uses Text::Format.format for the formatting - def __paragraphs(to_wrap) #:nodoc: - if ((@first_indent == @body_indent) || @tag_paragraph) then - p_end = "\n" - else - p_end = '' - end - - cnt = 0 - ret = [] - to_wrap.each do |tw| - @tag_cur = @tag_text[cnt] if @tag_paragraph - @tag_cur = '' if @tag_cur.nil? - line = __format(tw) - ret << "#{line}#{p_end}" if (not line.nil?) && (line.size > 0) - cnt += 1 - end - - ret[-1].chomp! unless ret.empty? - ret.join('') - end - - # center text using spaces on left side to pad it out empty lines - # are preserved - def __center(to_center) #:nodoc: - tabs = 0 - width = @columns - @left_margin - @right_margin - centered = [] - to_center.each do |tc| - s = tc.strip - tabs = s.count("\t") - tabs = 0 if tabs.nil? - ct = ((width - s.size - (tabs * @tabstop) + tabs) / 2) - ct = (width - @left_margin - @right_margin) - ct - centered << "#{s.rjust(ct)}\n" - end - centered.join('') - end - - # expand tabs to spaces should be similar to Text::Tabs::expand - def __expand(to_expand) #:nodoc: - expanded = [] - to_expand.split("\n").each { |te| expanded << te.gsub(/\t/, ' ' * @tabstop) } - expanded.join('') - end - - def __unexpand(to_unexpand) #:nodoc: - unexpanded = [] - to_unexpand.split("\n").each { |tu| unexpanded << tu.gsub(/ {#{@tabstop}}/, "\t") } - unexpanded.join('') - end - - def __is_abbrev(word) #:nodoc: - # remove period if there is one. - w = word.gsub(/\.$/, '') unless word.nil? - return true if (!@extra_space || ABBREV.include?(w) || @abbreviations.include?(w)) - false - end - - def __make_line(line, indent, width, last = false) #:nodoc: - lmargin = " " * @left_margin - fill = " " * (width - line.size) if right_fill? && (line.size <= width) - - if (justify? && ((not line.nil?) && (not line.empty?)) && line =~ /\S+\s+\S+/ && !last) - spaces = width - line.size - words = line.split(/(\s+)/) - ws = spaces / (words.size / 2) - spaces = spaces % (words.size / 2) if ws > 0 - words.reverse.each do |rw| - next if (rw =~ /^\S/) - rw.sub!(/^/, " " * ws) - next unless (spaces > 0) - rw.sub!(/^/, " ") - spaces -= 1 - end - line = words.join('') - end - line = "#{lmargin}#{indent}#{line}#{fill}\n" unless line.nil? - if right_align? && (not line.nil?) - line.sub(/^/, " " * (@columns - @right_margin - (line.size - 1))) - else - line - end - end - - def __do_hyphenate(line, next_line, width) #:nodoc: - rline = line.dup rescue line - rnext = next_line.dup rescue next_line - loop do - if rline.size == width - break - elsif rline.size > width - words = rline.strip.split(/\s+/) - word = words[-1].dup - size = width - rline.size + word.size - if (size <= 0) - words[-1] = nil - rline = words.join(' ').strip - rnext = "#{word} #{rnext}".strip - next - end - - first = rest = nil - - if ((@split_rules & SPLIT_HYPHENATION) != 0) - if @hyphenator_arity == 2 - first, rest = @hyphenator.hyphenate_to(word, size) - else - first, rest = @hyphenator.hyphenate_to(word, size, self) - end - end - - if ((@split_rules & SPLIT_CONTINUATION) != 0) and first.nil? - first, rest = self.hyphenate_to(word, size) - end - - if ((@split_rules & SPLIT_FIXED) != 0) and first.nil? - first.nil? or @split_rules == SPLIT_FIXED - first, rest = __do_split_word(word, size) - end - - if first.nil? - words[-1] = nil - rest = word - else - words[-1] = first - @split_words << SplitWord.new(word, first, rest) - end - rline = words.join(' ').strip - rnext = "#{rest} #{rnext}".strip - break - else - break if rnext.nil? or rnext.empty? or rline.nil? or rline.empty? - words = rnext.split(/\s+/) - word = words.shift - size = width - rline.size - 1 - - if (size <= 0) - rnext = "#{word} #{words.join(' ')}".strip - break - end - - first = rest = nil - - if ((@split_rules & SPLIT_HYPHENATION) != 0) - if @hyphenator_arity == 2 - first, rest = @hyphenator.hyphenate_to(word, size) - else - first, rest = @hyphenator.hyphenate_to(word, size, self) - end - end - - first, rest = self.hyphenate_to(word, size) if ((@split_rules & SPLIT_CONTINUATION) != 0) and first.nil? - - first, rest = __do_split_word(word, size) if ((@split_rules & SPLIT_FIXED) != 0) and first.nil? - - if (rline.size + (first ? first.size : 0)) < width - @split_words << SplitWord.new(word, first, rest) - rline = "#{rline} #{first}".strip - rnext = "#{rest} #{words.join(' ')}".strip - end - break - end - end - [rline, rnext] - end - - def __do_break(line, next_line) #:nodoc: - no_brk = false - words = [] - words = line.split(/\s+/) unless line.nil? - last_word = words[-1] - - @nobreak_regex.each { |k, v| no_brk = ((last_word =~ /#{k}/) and (next_line =~ /#{v}/)) } - - if no_brk && words.size > 1 - i = words.size - while i > 0 - no_brk = false - @nobreak_regex.each { |k, v| no_brk = ((words[i + 1] =~ /#{k}/) && (words[i] =~ /#{v}/)) } - i -= 1 - break if not no_brk - end - if i > 0 - l = brk_re(i).match(line) - line.sub!(brk_re(i), l[1]) - next_line = "#{l[2]} #{next_line}" - line.sub!(/\s+$/, '') - end - end - [line, next_line] - end - - def __create(arg = nil, &block) #:nodoc: - # Format::Text.new(text-to-wrap) - @text = arg unless arg.nil? - # Defaults - @columns = 72 - @tabstop = 8 - @first_indent = 4 - @body_indent = 0 - @format_style = LEFT_ALIGN - @left_margin = 0 - @right_margin = 0 - @extra_space = false - @text = Array.new if @text.nil? - @tag_paragraph = false - @tag_text = Array.new - @tag_cur = "" - @abbreviations = Array.new - @nobreak = false - @nobreak_regex = Hash.new - @split_words = Array.new - @hard_margins = false - @split_rules = SPLIT_FIXED - @hyphenator = self - @hyphenator_arity = self.method(:hyphenate_to).arity - - instance_eval(&block) unless block.nil? - end - - public - # Formats text into a nice paragraph format. The text is separated - # into words and then reassembled a word at a time using the settings - # of this Format object. If a word is larger than the number of - # columns available for formatting, then that word will appear on the - # line by itself. - # - # If +to_wrap+ is +nil+, then the value of #text will be - # worked on. - def format(to_wrap = nil) - to_wrap = @text if to_wrap.nil? - if to_wrap.class == Array - __format(to_wrap[0]) - else - __format(to_wrap) - end - end - - # Considers each element of text (provided or internal) as a paragraph. - # If #first_indent is the same as #body_indent, then - # paragraphs will be separated by a single empty line in the result; - # otherwise, the paragraphs will follow immediately after each other. - # Uses #format to do the heavy lifting. - def paragraphs(to_wrap = nil) - to_wrap = @text if to_wrap.nil? - __paragraphs([to_wrap].flatten) - end - - # Centers the text, preserving empty lines and tabs. - def center(to_center = nil) - to_center = @text if to_center.nil? - __center([to_center].flatten) - end - - # Replaces all tab characters in the text with #tabstop spaces. - def expand(to_expand = nil) - to_expand = @text if to_expand.nil? - if to_expand.class == Array - to_expand.collect { |te| __expand(te) } - else - __expand(to_expand) - end - end - - # Replaces all occurrences of #tabstop consecutive spaces - # with a tab character. - def unexpand(to_unexpand = nil) - to_unexpand = @text if to_unexpand.nil? - if to_unexpand.class == Array - to_unexpand.collect { |te| v << __unexpand(te) } - else - __unexpand(to_unexpand) - end - end - - # This constructor takes advantage of a technique for Ruby object - # construction introduced by Andy Hunt and Dave Thomas (see reference), - # where optional values are set using commands in a block. - # - # Text::Format.new { - # columns = 72 - # left_margin = 0 - # right_margin = 0 - # first_indent = 4 - # body_indent = 0 - # format_style = Text::Format::LEFT_ALIGN - # extra_space = false - # abbreviations = {} - # tag_paragraph = false - # tag_text = [] - # nobreak = false - # nobreak_regex = {} - # tabstop = 8 - # text = nil - # } - # - # As shown above, +arg+ is optional. If +arg+ is specified and is a - # +String+, then arg is used as the default value of #text. - # Alternately, an existing Text::Format object can be used or a Hash can - # be used. With all forms, a block can be specified. - # - # *Reference*:: "Object Construction and Blocks" - # - # - def initialize(arg = nil, &block) - @text = nil - case arg - when Text::Format - __create(arg.text) do - @columns = arg.columns - @tabstop = arg.tabstop - @first_indent = arg.first_indent - @body_indent = arg.body_indent - @format_style = arg.format_style - @left_margin = arg.left_margin - @right_margin = arg.right_margin - @extra_space = arg.extra_space - @tag_paragraph = arg.tag_paragraph - @tag_text = arg.tag_text - @abbreviations = arg.abbreviations - @nobreak = arg.nobreak - @nobreak_regex = arg.nobreak_regex - @text = arg.text - @hard_margins = arg.hard_margins - @split_words = arg.split_words - @split_rules = arg.split_rules - @hyphenator = arg.hyphenator - end - instance_eval(&block) unless block.nil? - when Hash - __create do - @columns = arg[:columns] || arg['columns'] || @columns - @tabstop = arg[:tabstop] || arg['tabstop'] || @tabstop - @first_indent = arg[:first_indent] || arg['first_indent'] || @first_indent - @body_indent = arg[:body_indent] || arg['body_indent'] || @body_indent - @format_style = arg[:format_style] || arg['format_style'] || @format_style - @left_margin = arg[:left_margin] || arg['left_margin'] || @left_margin - @right_margin = arg[:right_margin] || arg['right_margin'] || @right_margin - @extra_space = arg[:extra_space] || arg['extra_space'] || @extra_space - @text = arg[:text] || arg['text'] || @text - @tag_paragraph = arg[:tag_paragraph] || arg['tag_paragraph'] || @tag_paragraph - @tag_text = arg[:tag_text] || arg['tag_text'] || @tag_text - @abbreviations = arg[:abbreviations] || arg['abbreviations'] || @abbreviations - @nobreak = arg[:nobreak] || arg['nobreak'] || @nobreak - @nobreak_regex = arg[:nobreak_regex] || arg['nobreak_regex'] || @nobreak_regex - @hard_margins = arg[:hard_margins] || arg['hard_margins'] || @hard_margins - @split_rules = arg[:split_rules] || arg['split_rules'] || @split_rules - @hyphenator = arg[:hyphenator] || arg['hyphenator'] || @hyphenator - end - instance_eval(&block) unless block.nil? - when String - __create(arg, &block) - when NilClass - __create(&block) - else - raise TypeError - end - end - end -end - -if __FILE__ == $0 - require 'test/unit' - - class TestText__Format < Test::Unit::TestCase #:nodoc: - attr_accessor :format_o - - GETTYSBURG = <<-'EOS' - Four score and seven years ago our fathers brought forth on this - continent a new nation, conceived in liberty and dedicated to the - proposition that all men are created equal. Now we are engaged in - a great civil war, testing whether that nation or any nation so - conceived and so dedicated can long endure. We are met on a great - battlefield of that war. We have come to dedicate a portion of - that field as a final resting-place for those who here gave their - lives that that nation might live. It is altogether fitting and - proper that we should do this. But in a larger sense, we cannot - dedicate, we cannot consecrate, we cannot hallow this ground. - The brave men, living and dead who struggled here have consecrated - it far above our poor power to add or detract. The world will - little note nor long remember what we say here, but it can never - forget what they did here. It is for us the living rather to be - dedicated here to the unfinished work which they who fought here - have thus far so nobly advanced. It is rather for us to be here - dedicated to the great task remaining before us--that from these - honored dead we take increased devotion to that cause for which - they gave the last full measure of devotion--that we here highly - resolve that these dead shall not have died in vain, that this - nation under God shall have a new birth of freedom, and that - government of the people, by the people, for the people shall - not perish from the earth. - - -- Pres. Abraham Lincoln, 19 November 1863 - EOS - - FIVE_COL = "Four \nscore\nand s\neven \nyears\nago o\nur fa\nthers\nbroug\nht fo\nrth o\nn thi\ns con\ntinen\nt a n\new na\ntion,\nconce\nived \nin li\nberty\nand d\nedica\nted t\no the\npropo\nsitio\nn tha\nt all\nmen a\nre cr\neated\nequal\n. Now\nwe ar\ne eng\naged \nin a \ngreat\ncivil\nwar, \ntesti\nng wh\nether\nthat \nnatio\nn or \nany n\nation\nso co\nnceiv\ned an\nd so \ndedic\nated \ncan l\nong e\nndure\n. We \nare m\net on\na gre\nat ba\nttlef\nield \nof th\nat wa\nr. We\nhave \ncome \nto de\ndicat\ne a p\nortio\nn of \nthat \nfield\nas a \nfinal\nresti\nng-pl\nace f\nor th\nose w\nho he\nre ga\nve th\neir l\nives \nthat \nthat \nnatio\nn mig\nht li\nve. I\nt is \naltog\nether\nfitti\nng an\nd pro\nper t\nhat w\ne sho\nuld d\no thi\ns. Bu\nt in \na lar\nger s\nense,\nwe ca\nnnot \ndedic\nate, \nwe ca\nnnot \nconse\ncrate\n, we \ncanno\nt hal\nlow t\nhis g\nround\n. The\nbrave\nmen, \nlivin\ng and\ndead \nwho s\ntrugg\nled h\nere h\nave c\nonsec\nrated\nit fa\nr abo\nve ou\nr poo\nr pow\ner to\nadd o\nr det\nract.\nThe w\norld \nwill \nlittl\ne not\ne nor\nlong \nremem\nber w\nhat w\ne say\nhere,\nbut i\nt can\nnever\nforge\nt wha\nt the\ny did\nhere.\nIt is\nfor u\ns the\nlivin\ng rat\nher t\no be \ndedic\nated \nhere \nto th\ne unf\ninish\ned wo\nrk wh\nich t\nhey w\nho fo\nught \nhere \nhave \nthus \nfar s\no nob\nly ad\nvance\nd. It\nis ra\nther \nfor u\ns to \nbe he\nre de\ndicat\ned to\nthe g\nreat \ntask \nremai\nning \nbefor\ne us-\n-that\nfrom \nthese\nhonor\ned de\nad we\ntake \nincre\nased \ndevot\nion t\no tha\nt cau\nse fo\nr whi\nch th\ney ga\nve th\ne las\nt ful\nl mea\nsure \nof de\nvotio\nn--th\nat we\nhere \nhighl\ny res\nolve \nthat \nthese\ndead \nshall\nnot h\nave d\nied i\nn vai\nn, th\nat th\nis na\ntion \nunder\nGod s\nhall \nhave \na new\nbirth\nof fr\needom\n, and\nthat \ngover\nnment\nof th\ne peo\nple, \nby th\ne peo\nple, \nfor t\nhe pe\nople \nshall\nnot p\nerish\nfrom \nthe e\narth.\n-- Pr\nes. A\nbraha\nm Lin\ncoln,\n19 No\nvembe\nr 186\n3 \n" - - FIVE_CNT = "Four \nscore\nand \nseven\nyears\nago \nour \nfath\\\ners \nbrou\\\nght \nforth\non t\\\nhis \ncont\\\ninent\na new\nnati\\\non, \nconc\\\neived\nin l\\\niber\\\nty a\\\nnd d\\\nedic\\\nated \nto t\\\nhe p\\\nropo\\\nsiti\\\non t\\\nhat \nall \nmen \nare \ncrea\\\nted \nequa\\\nl. N\\\now we\nare \nenga\\\nged \nin a \ngreat\ncivil\nwar, \ntest\\\ning \nwhet\\\nher \nthat \nnati\\\non or\nany \nnati\\\non so\nconc\\\neived\nand \nso d\\\nedic\\\nated \ncan \nlong \nendu\\\nre. \nWe a\\\nre m\\\net on\na gr\\\neat \nbatt\\\nlefi\\\neld \nof t\\\nhat \nwar. \nWe h\\\nave \ncome \nto d\\\nedic\\\nate a\nport\\\nion \nof t\\\nhat \nfield\nas a \nfinal\nrest\\\ning-\\\nplace\nfor \nthose\nwho \nhere \ngave \ntheir\nlives\nthat \nthat \nnati\\\non m\\\night \nlive.\nIt is\nalto\\\ngeth\\\ner f\\\nitti\\\nng a\\\nnd p\\\nroper\nthat \nwe s\\\nhould\ndo t\\\nhis. \nBut \nin a \nlarg\\\ner s\\\nense,\nwe c\\\nannot\ndedi\\\ncate,\nwe c\\\nannot\ncons\\\necra\\\nte, \nwe c\\\nannot\nhall\\\now t\\\nhis \ngrou\\\nnd. \nThe \nbrave\nmen, \nlivi\\\nng a\\\nnd d\\\nead \nwho \nstru\\\nggled\nhere \nhave \ncons\\\necra\\\nted \nit f\\\nar a\\\nbove \nour \npoor \npower\nto a\\\ndd or\ndetr\\\nact. \nThe \nworld\nwill \nlitt\\\nle n\\\note \nnor \nlong \nreme\\\nmber \nwhat \nwe s\\\nay h\\\nere, \nbut \nit c\\\nan n\\\never \nforg\\\net w\\\nhat \nthey \ndid \nhere.\nIt is\nfor \nus t\\\nhe l\\\niving\nrath\\\ner to\nbe d\\\nedic\\\nated \nhere \nto t\\\nhe u\\\nnfin\\\nished\nwork \nwhich\nthey \nwho \nfoug\\\nht h\\\nere \nhave \nthus \nfar \nso n\\\nobly \nadva\\\nnced.\nIt is\nrath\\\ner f\\\nor us\nto be\nhere \ndedi\\\ncated\nto t\\\nhe g\\\nreat \ntask \nrema\\\nining\nbefo\\\nre u\\\ns--t\\\nhat \nfrom \nthese\nhono\\\nred \ndead \nwe t\\\nake \nincr\\\neased\ndevo\\\ntion \nto t\\\nhat \ncause\nfor \nwhich\nthey \ngave \nthe \nlast \nfull \nmeas\\\nure \nof d\\\nevot\\\nion-\\\n-that\nwe h\\\nere \nhigh\\\nly r\\\nesol\\\nve t\\\nhat \nthese\ndead \nshall\nnot \nhave \ndied \nin v\\\nain, \nthat \nthis \nnati\\\non u\\\nnder \nGod \nshall\nhave \na new\nbirth\nof f\\\nreed\\\nom, \nand \nthat \ngove\\\nrnme\\\nnt of\nthe \npeop\\\nle, \nby t\\\nhe p\\\neopl\\\ne, f\\\nor t\\\nhe p\\\neople\nshall\nnot \nperi\\\nsh f\\\nrom \nthe \neart\\\nh. --\nPres.\nAbra\\\nham \nLinc\\\noln, \n19 N\\\novem\\\nber \n1863 \n" - - # Tests both abbreviations and abbreviations= - def test_abbreviations - abbr = [" Pres. Abraham Lincoln\n", " Pres. Abraham Lincoln\n"] - assert_nothing_raised { @format_o = Text::Format.new } - assert_equal([], @format_o.abbreviations) - assert_nothing_raised { @format_o.abbreviations = [ 'foo', 'bar' ] } - assert_equal([ 'foo', 'bar' ], @format_o.abbreviations) - assert_equal(abbr[0], @format_o.format(abbr[0])) - assert_nothing_raised { @format_o.extra_space = true } - assert_equal(abbr[1], @format_o.format(abbr[0])) - assert_nothing_raised { @format_o.abbreviations = [ "Pres" ] } - assert_equal([ "Pres" ], @format_o.abbreviations) - assert_equal(abbr[0], @format_o.format(abbr[0])) - assert_nothing_raised { @format_o.extra_space = false } - assert_equal(abbr[0], @format_o.format(abbr[0])) - end - - # Tests both body_indent and body_indent= - def test_body_indent - assert_nothing_raised { @format_o = Text::Format.new } - assert_equal(0, @format_o.body_indent) - assert_nothing_raised { @format_o.body_indent = 7 } - assert_equal(7, @format_o.body_indent) - assert_nothing_raised { @format_o.body_indent = -3 } - assert_equal(3, @format_o.body_indent) - assert_nothing_raised { @format_o.body_indent = "9" } - assert_equal(9, @format_o.body_indent) - assert_nothing_raised { @format_o.body_indent = "-2" } - assert_equal(2, @format_o.body_indent) - assert_match(/^ [^ ]/, @format_o.format(GETTYSBURG).split("\n")[1]) - end - - # Tests both columns and columns= - def test_columns - assert_nothing_raised { @format_o = Text::Format.new } - assert_equal(72, @format_o.columns) - assert_nothing_raised { @format_o.columns = 7 } - assert_equal(7, @format_o.columns) - assert_nothing_raised { @format_o.columns = -3 } - assert_equal(3, @format_o.columns) - assert_nothing_raised { @format_o.columns = "9" } - assert_equal(9, @format_o.columns) - assert_nothing_raised { @format_o.columns = "-2" } - assert_equal(2, @format_o.columns) - assert_nothing_raised { @format_o.columns = 40 } - assert_equal(40, @format_o.columns) - assert_match(/this continent$/, - @format_o.format(GETTYSBURG).split("\n")[1]) - end - - # Tests both extra_space and extra_space= - def test_extra_space - assert_nothing_raised { @format_o = Text::Format.new } - assert(!@format_o.extra_space) - assert_nothing_raised { @format_o.extra_space = true } - assert(@format_o.extra_space) - # The behaviour of extra_space is tested in test_abbreviations. There - # is no need to reproduce it here. - end - - # Tests both first_indent and first_indent= - def test_first_indent - assert_nothing_raised { @format_o = Text::Format.new } - assert_equal(4, @format_o.first_indent) - assert_nothing_raised { @format_o.first_indent = 7 } - assert_equal(7, @format_o.first_indent) - assert_nothing_raised { @format_o.first_indent = -3 } - assert_equal(3, @format_o.first_indent) - assert_nothing_raised { @format_o.first_indent = "9" } - assert_equal(9, @format_o.first_indent) - assert_nothing_raised { @format_o.first_indent = "-2" } - assert_equal(2, @format_o.first_indent) - assert_match(/^ [^ ]/, @format_o.format(GETTYSBURG).split("\n")[0]) - end - - def test_format_style - assert_nothing_raised { @format_o = Text::Format.new } - assert_equal(Text::Format::LEFT_ALIGN, @format_o.format_style) - assert_match(/^November 1863$/, - @format_o.format(GETTYSBURG).split("\n")[-1]) - assert_nothing_raised { - @format_o.format_style = Text::Format::RIGHT_ALIGN - } - assert_equal(Text::Format::RIGHT_ALIGN, @format_o.format_style) - assert_match(/^ +November 1863$/, - @format_o.format(GETTYSBURG).split("\n")[-1]) - assert_nothing_raised { - @format_o.format_style = Text::Format::RIGHT_FILL - } - assert_equal(Text::Format::RIGHT_FILL, @format_o.format_style) - assert_match(/^November 1863 +$/, - @format_o.format(GETTYSBURG).split("\n")[-1]) - assert_nothing_raised { @format_o.format_style = Text::Format::JUSTIFY } - assert_equal(Text::Format::JUSTIFY, @format_o.format_style) - assert_match(/^of freedom, and that government of the people, by the people, for the$/, - @format_o.format(GETTYSBURG).split("\n")[-3]) - assert_raise(ArgumentError) { @format_o.format_style = 33 } - end - - def test_tag_paragraph - assert_nothing_raised { @format_o = Text::Format.new } - assert(!@format_o.tag_paragraph) - assert_nothing_raised { @format_o.tag_paragraph = true } - assert(@format_o.tag_paragraph) - assert_not_equal(@format_o.paragraphs([GETTYSBURG, GETTYSBURG]), - Text::Format.new.paragraphs([GETTYSBURG, GETTYSBURG])) - end - - def test_tag_text - assert_nothing_raised { @format_o = Text::Format.new } - assert_equal([], @format_o.tag_text) - assert_equal(@format_o.format(GETTYSBURG), - Text::Format.new.format(GETTYSBURG)) - assert_nothing_raised { - @format_o.tag_paragraph = true - @format_o.tag_text = ["Gettysburg Address", "---"] - } - assert_not_equal(@format_o.format(GETTYSBURG), - Text::Format.new.format(GETTYSBURG)) - assert_not_equal(@format_o.paragraphs([GETTYSBURG, GETTYSBURG]), - Text::Format.new.paragraphs([GETTYSBURG, GETTYSBURG])) - assert_not_equal(@format_o.paragraphs([GETTYSBURG, GETTYSBURG, - GETTYSBURG]), - Text::Format.new.paragraphs([GETTYSBURG, GETTYSBURG, - GETTYSBURG])) - end - - def test_justify? - assert_nothing_raised { @format_o = Text::Format.new } - assert(!@format_o.justify?) - assert_nothing_raised { - @format_o.format_style = Text::Format::RIGHT_ALIGN - } - assert(!@format_o.justify?) - assert_nothing_raised { - @format_o.format_style = Text::Format::RIGHT_FILL - } - assert(!@format_o.justify?) - assert_nothing_raised { - @format_o.format_style = Text::Format::JUSTIFY - } - assert(@format_o.justify?) - # The format testing is done in test_format_style - end - - def test_left_align? - assert_nothing_raised { @format_o = Text::Format.new } - assert(@format_o.left_align?) - assert_nothing_raised { - @format_o.format_style = Text::Format::RIGHT_ALIGN - } - assert(!@format_o.left_align?) - assert_nothing_raised { - @format_o.format_style = Text::Format::RIGHT_FILL - } - assert(!@format_o.left_align?) - assert_nothing_raised { @format_o.format_style = Text::Format::JUSTIFY } - assert(!@format_o.left_align?) - # The format testing is done in test_format_style - end - - def test_left_margin - assert_nothing_raised { @format_o = Text::Format.new } - assert_equal(0, @format_o.left_margin) - assert_nothing_raised { @format_o.left_margin = -3 } - assert_equal(3, @format_o.left_margin) - assert_nothing_raised { @format_o.left_margin = "9" } - assert_equal(9, @format_o.left_margin) - assert_nothing_raised { @format_o.left_margin = "-2" } - assert_equal(2, @format_o.left_margin) - assert_nothing_raised { @format_o.left_margin = 7 } - assert_equal(7, @format_o.left_margin) - assert_nothing_raised { - ft = @format_o.format(GETTYSBURG).split("\n") - assert_match(/^ {11}Four score/, ft[0]) - assert_match(/^ {7}November/, ft[-1]) - } - end - - def test_hard_margins - assert_nothing_raised { @format_o = Text::Format.new } - assert(!@format_o.hard_margins) - assert_nothing_raised { - @format_o.hard_margins = true - @format_o.columns = 5 - @format_o.first_indent = 0 - @format_o.format_style = Text::Format::RIGHT_FILL - } - assert(@format_o.hard_margins) - assert_equal(FIVE_COL, @format_o.format(GETTYSBURG)) - assert_nothing_raised { - @format_o.split_rules |= Text::Format::SPLIT_CONTINUATION - assert_equal(Text::Format::SPLIT_CONTINUATION_FIXED, - @format_o.split_rules) - } - assert_equal(FIVE_CNT, @format_o.format(GETTYSBURG)) - end - - # Tests both nobreak and nobreak_regex, since one is only useful - # with the other. - def test_nobreak - assert_nothing_raised { @format_o = Text::Format.new } - assert(!@format_o.nobreak) - assert(@format_o.nobreak_regex.empty?) - assert_nothing_raised { - @format_o.nobreak = true - @format_o.nobreak_regex = { '^this$' => '^continent$' } - @format_o.columns = 77 - } - assert(@format_o.nobreak) - assert_equal({ '^this$' => '^continent$' }, @format_o.nobreak_regex) - assert_match(/^this continent/, - @format_o.format(GETTYSBURG).split("\n")[1]) - end - - def test_right_align? - assert_nothing_raised { @format_o = Text::Format.new } - assert(!@format_o.right_align?) - assert_nothing_raised { - @format_o.format_style = Text::Format::RIGHT_ALIGN - } - assert(@format_o.right_align?) - assert_nothing_raised { - @format_o.format_style = Text::Format::RIGHT_FILL - } - assert(!@format_o.right_align?) - assert_nothing_raised { @format_o.format_style = Text::Format::JUSTIFY } - assert(!@format_o.right_align?) - # The format testing is done in test_format_style - end - - def test_right_fill? - assert_nothing_raised { @format_o = Text::Format.new } - assert(!@format_o.right_fill?) - assert_nothing_raised { - @format_o.format_style = Text::Format::RIGHT_ALIGN - } - assert(!@format_o.right_fill?) - assert_nothing_raised { - @format_o.format_style = Text::Format::RIGHT_FILL - } - assert(@format_o.right_fill?) - assert_nothing_raised { - @format_o.format_style = Text::Format::JUSTIFY - } - assert(!@format_o.right_fill?) - # The format testing is done in test_format_style - end - - def test_right_margin - assert_nothing_raised { @format_o = Text::Format.new } - assert_equal(0, @format_o.right_margin) - assert_nothing_raised { @format_o.right_margin = -3 } - assert_equal(3, @format_o.right_margin) - assert_nothing_raised { @format_o.right_margin = "9" } - assert_equal(9, @format_o.right_margin) - assert_nothing_raised { @format_o.right_margin = "-2" } - assert_equal(2, @format_o.right_margin) - assert_nothing_raised { @format_o.right_margin = 7 } - assert_equal(7, @format_o.right_margin) - assert_nothing_raised { - ft = @format_o.format(GETTYSBURG).split("\n") - assert_match(/^ {4}Four score.*forth on$/, ft[0]) - assert_match(/^November/, ft[-1]) - } - end - - def test_tabstop - assert_nothing_raised { @format_o = Text::Format.new } - assert_equal(8, @format_o.tabstop) - assert_nothing_raised { @format_o.tabstop = 7 } - assert_equal(7, @format_o.tabstop) - assert_nothing_raised { @format_o.tabstop = -3 } - assert_equal(3, @format_o.tabstop) - assert_nothing_raised { @format_o.tabstop = "9" } - assert_equal(9, @format_o.tabstop) - assert_nothing_raised { @format_o.tabstop = "-2" } - assert_equal(2, @format_o.tabstop) - end - - def test_text - assert_nothing_raised { @format_o = Text::Format.new } - assert_equal([], @format_o.text) - assert_nothing_raised { @format_o.text = "Test Text" } - assert_equal("Test Text", @format_o.text) - assert_nothing_raised { @format_o.text = ["Line 1", "Line 2"] } - assert_equal(["Line 1", "Line 2"], @format_o.text) - end - - def test_s_new - # new(NilClass) { block } - assert_nothing_raised do - @format_o = Text::Format.new { - self.text = "Test 1, 2, 3" - } - end - assert_equal("Test 1, 2, 3", @format_o.text) - - # new(Hash Symbols) - assert_nothing_raised { @format_o = Text::Format.new(:columns => 72) } - assert_equal(72, @format_o.columns) - - # new(Hash String) - assert_nothing_raised { @format_o = Text::Format.new('columns' => 72) } - assert_equal(72, @format_o.columns) - - # new(Hash) { block } - assert_nothing_raised do - @format_o = Text::Format.new('columns' => 80) { - self.text = "Test 4, 5, 6" - } - end - assert_equal("Test 4, 5, 6", @format_o.text) - assert_equal(80, @format_o.columns) - - # new(Text::Format) - assert_nothing_raised do - fo = Text::Format.new(@format_o) - assert(fo == @format_o) - end - - # new(Text::Format) { block } - assert_nothing_raised do - fo = Text::Format.new(@format_o) { self.columns = 79 } - assert(fo != @format_o) - end - - # new(String) - assert_nothing_raised { @format_o = Text::Format.new("Test A, B, C") } - assert_equal("Test A, B, C", @format_o.text) - - # new(String) { block } - assert_nothing_raised do - @format_o = Text::Format.new("Test X, Y, Z") { self.columns = -5 } - end - assert_equal("Test X, Y, Z", @format_o.text) - assert_equal(5, @format_o.columns) - end - - def test_center - assert_nothing_raised { @format_o = Text::Format.new } - assert_nothing_raised do - ct = @format_o.center(GETTYSBURG.split("\n")).split("\n") - assert_match(/^ Four score and seven years ago our fathers brought forth on this/, ct[0]) - assert_match(/^ not perish from the earth./, ct[-3]) - end - end - - def test_expand - assert_nothing_raised { @format_o = Text::Format.new } - assert_equal(" ", @format_o.expand("\t ")) - assert_nothing_raised { @format_o.tabstop = 4 } - assert_equal(" ", @format_o.expand("\t ")) - end - - def test_unexpand - assert_nothing_raised { @format_o = Text::Format.new } - assert_equal("\t ", @format_o.unexpand(" ")) - assert_nothing_raised { @format_o.tabstop = 4 } - assert_equal("\t ", @format_o.unexpand(" ")) - end - - def test_space_only - assert_equal("", Text::Format.new.format(" ")) - assert_equal("", Text::Format.new.format("\n")) - assert_equal("", Text::Format.new.format(" ")) - assert_equal("", Text::Format.new.format(" \n")) - assert_equal("", Text::Format.new.paragraphs("\n")) - assert_equal("", Text::Format.new.paragraphs(" ")) - assert_equal("", Text::Format.new.paragraphs(" ")) - assert_equal("", Text::Format.new.paragraphs(" \n")) - assert_equal("", Text::Format.new.paragraphs(["\n"])) - assert_equal("", Text::Format.new.paragraphs([" "])) - assert_equal("", Text::Format.new.paragraphs([" "])) - assert_equal("", Text::Format.new.paragraphs([" \n"])) - end - - def test_splendiferous - h = nil - test = "This is a splendiferous test" - assert_nothing_raised { @format_o = Text::Format.new(:columns => 6, :left_margin => 0, :indent => 0, :first_indent => 0) } - assert_match(/^splendiferous$/, @format_o.format(test)) - assert_nothing_raised { @format_o.hard_margins = true } - assert_match(/^lendif$/, @format_o.format(test)) - assert_nothing_raised { h = Object.new } - assert_nothing_raised do - @format_o.split_rules = Text::Format::SPLIT_HYPHENATION - class << h #:nodoc: - def hyphenate_to(word, size) - return ["", word] if size < 2 - [word[0 ... size], word[size .. -1]] - end - end - @format_o.hyphenator = h - end - assert_match(/^iferou$/, @format_o.format(test)) - assert_nothing_raised { h = Object.new } - assert_nothing_raised do - class << h #:nodoc: - def hyphenate_to(word, size, formatter) - return ["", word] if word.size < formatter.columns - [word[0 ... size], word[size .. -1]] - end - end - @format_o.hyphenator = h - end - assert_match(/^ferous$/, @format_o.format(test)) - end - end -end diff --git a/actionmailer/lib/action_mailer/vendor/text_format.rb b/actionmailer/lib/action_mailer/vendor/text_format.rb deleted file mode 100644 index c6c8c394d0..0000000000 --- a/actionmailer/lib/action_mailer/vendor/text_format.rb +++ /dev/null @@ -1,10 +0,0 @@ -# Prefer gems to the bundled libs. -require 'rubygems' - -begin - gem 'text-format', '>= 0.6.3' -rescue Gem::LoadError - $:.unshift "#{File.dirname(__FILE__)}/text-format-0.6.3" -end - -require 'text/format' -- cgit v1.2.3 From 030ab357f94d4f3624e0997b4aeb972681180186 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Wed, 27 Jan 2010 17:11:29 -0800 Subject: Remove unbundle changelogs --- actionmailer/CHANGELOG | 2 -- 1 file changed, 2 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/CHANGELOG b/actionmailer/CHANGELOG index 4ee6bd4620..0018a2ed5d 100644 --- a/actionmailer/CHANGELOG +++ b/actionmailer/CHANGELOG @@ -1,7 +1,5 @@ *Rails 3.0 (pending)* -* Unvendor'd text-format, now requires text-format gem - * Whole new API added with tests. See base.rb for full details. Old API is deprecated. * The Mail::Message class has helped methods for all the field types that return 'common' defaults for the common use case, so to get the subject, mail.subject will give you a string, mail.date will give you a DateTime object, mail.from will give you an array of address specs (mikel@test.lindsaar.net) etc. If you want to access the field object itself, call mail[:field_name] which will return the field object you want, which you can then chain, like mail[:from].formatted -- cgit v1.2.3 From 8c60acbea22645278bb43a4fa575b298cea7671a Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Wed, 27 Jan 2010 18:37:01 -0800 Subject: Expected attachment encoding is binary --- actionmailer/test/base_test.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index b7af86b622..9e1a4c22c6 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -167,7 +167,9 @@ class BaseTest < ActiveSupport::TestCase email = BaseMailer.attachment_with_hash assert_equal(1, email.attachments.length) assert_equal('invoice.jpg', email.attachments[0].filename) - assert_equal("\312\213\254\232)b", email.attachments['invoice.jpg'].decoded) + expected = "\312\213\254\232)b" + expected.force_encoding(Encoding::BINARY) if '1.9'.respond_to?(:force_encoding) + assert_equal expected, email.attachments['invoice.jpg'].decoded end test "sets mime type to multipart/mixed when attachment is included" do @@ -483,4 +485,4 @@ class BaseTest < ActiveSupport::TestCase hash[key] = value end end -end \ No newline at end of file +end -- cgit v1.2.3 From 187b3b0b4808c2daf015699dfa1e5a78605072a7 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Wed, 27 Jan 2010 19:08:36 -0800 Subject: Fix time comparison. Mail#date returns DateTime not Time. --- actionmailer/test/base_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionmailer') diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index 9e1a4c22c6..86db3afc15 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -100,7 +100,7 @@ class BaseTest < ActiveSupport::TestCase end test "mail() with bcc, cc, content_type, charset, mime_version, reply_to and date" do - @time = Time.now + @time = Time.now.beginning_of_day.to_datetime email = BaseMailer.welcome(:bcc => 'bcc@test.lindsaar.net', :cc => 'cc@test.lindsaar.net', :content_type => 'multipart/mixed', -- cgit v1.2.3 From 452bb1e48d7fa3dd4b2684d9d8ba3091200d59fe Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Wed, 27 Jan 2010 19:37:47 -0800 Subject: Rename 'defaults' class method to 'default' to reflect that it's a declaration --- actionmailer/lib/action_mailer/base.rb | 28 ++++++++++++------------ actionmailer/lib/action_mailer/deprecated_api.rb | 4 ++-- actionmailer/lib/action_mailer/old_api.rb | 10 ++++----- actionmailer/test/base_test.rb | 10 ++++----- 4 files changed, 26 insertions(+), 26 deletions(-) (limited to 'actionmailer') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 3fbf004a0d..6246530bf0 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -23,8 +23,8 @@ module ActionMailer #:nodoc: # Examples: # # class Notifier < ActionMailer::Base - # defaults :from => 'no-reply@example.com', - # :return_path => 'system@example.com' + # default :from => 'no-reply@example.com', + # :return_path => 'system@example.com' # # def welcome(recipient) # @account = recipient @@ -191,7 +191,7 @@ module ActionMailer #:nodoc: # # These options are specified on the class level, like ActionMailer::Base.template_root = "/my/templates" # - # * defaults - This is a class wide hash of :key => value pairs containing + # * default - This is a class wide hash of :key => value pairs containing # default values for the specified header fields of the Mail::Message. You can # specify a default for any valid header for Mail::Message and it will be used if # you do not override it. The defaults set by Action Mailer are: @@ -232,16 +232,16 @@ module ActionMailer #:nodoc: # * deliveries - Keeps an array of all the emails sent out through the Action Mailer with delivery_method :test. Most useful # for unit and functional testing. # - # * default_charset - This is now deprecated, use the +defaults+ method above to + # * default_charset - This is now deprecated, use the +default+ method above to # set the default +:charset+. # - # * default_content_type - This is now deprecated, use the +defaults+ method above + # * default_content_type - This is now deprecated, use the +default+ method above # to set the default +:content_type+. # - # * default_mime_version - This is now deprecated, use the +defaults+ method above + # * default_mime_version - This is now deprecated, use the +default+ method above # to set the default +:mime_version+. # - # * default_implicit_parts_order - This is now deprecated, use the +defaults+ method above + # * default_implicit_parts_order - This is now deprecated, use the +default+ method above # to set the default +:parts_order+. Parts Order is used when a message is built implicitly # (i.e. multiple parts are assembled from templates which specify the content type in their # filenames) this variable controls how the parts are ordered. @@ -280,7 +280,7 @@ module ActionMailer #:nodoc: attr_writer :mailer_name alias :controller_path :mailer_name - def defaults(value=nil) + def default(value=nil) self.default_params.merge!(value) if value self.default_params end @@ -429,13 +429,13 @@ module ActionMailer #:nodoc: # * :reply_to - Who to set the Reply-To header of the email to. # * :date - The date to say the email was sent on. # - # You can set default values for any of the above headers (except :date) by using the defaults + # You can set default values for any of the above headers (except :date) by using the default # class method: # # class Notifier < ActionMailer::Base - # self.defaults :from => 'no-reply@test.lindsaar.net', - # :bcc => 'email_logger@test.lindsaar.net', - # :reply_to => 'bounces@test.lindsaar.net' + # self.default :from => 'no-reply@test.lindsaar.net', + # :bcc => 'email_logger@test.lindsaar.net', + # :reply_to => 'bounces@test.lindsaar.net' # end # # If you need other headers not listed above, use the headers['name'] = value method. @@ -487,7 +487,7 @@ module ActionMailer #:nodoc: parts_order = headers[:parts_order] # Merge defaults from class - headers = headers.reverse_merge(self.class.defaults) + headers = headers.reverse_merge(self.class.default) charset = headers[:charset] # Quote fields @@ -562,7 +562,7 @@ module ActionMailer #:nodoc: elsif headers[:body] responses << { :body => headers[:body], - :content_type => self.class.defaults[:content_type] || "text/plain" + :content_type => self.class.default[:content_type] || "text/plain" } else each_template do |template| diff --git a/actionmailer/lib/action_mailer/deprecated_api.rb b/actionmailer/lib/action_mailer/deprecated_api.rb index 36eec1087e..54ad18f796 100644 --- a/actionmailer/lib/action_mailer/deprecated_api.rb +++ b/actionmailer/lib/action_mailer/deprecated_api.rb @@ -14,7 +14,7 @@ module ActionMailer def self.default_#{method}=(value) ActiveSupport::Deprecation.warn "ActionMailer::Base.default_#{method}=value is deprecated, " << - "use defaults :#{method} => value instead" + "use default :#{method} => value instead" @@default_#{method} = value end @@ -136,4 +136,4 @@ module ActionMailer end end -end \ No newline at end of file +end diff --git a/actionmailer/lib/action_mailer/old_api.rb b/actionmailer/lib/action_mailer/old_api.rb index 4694958222..936ceb0dd6 100644 --- a/actionmailer/lib/action_mailer/old_api.rb +++ b/actionmailer/lib/action_mailer/old_api.rb @@ -187,10 +187,10 @@ module ActionMailer # mailer. Subclasses may override this method to provide different # defaults. def initialize_defaults(method_name) - @charset ||= self.class.defaults[:charset].try(:dup) - @content_type ||= self.class.defaults[:content_type].try(:dup) - @implicit_parts_order ||= self.class.defaults[:parts_order].try(:dup) - @mime_version ||= self.class.defaults[:mime_version].try(:dup) + @charset ||= self.class.default[:charset].try(:dup) + @content_type ||= self.class.default[:content_type].try(:dup) + @implicit_parts_order ||= self.class.default[:parts_order].try(:dup) + @mime_version ||= self.class.default[:mime_version].try(:dup) @mailer_name ||= self.class.mailer_name.dup @template ||= method_name @@ -245,4 +245,4 @@ module ActionMailer end end end -end \ No newline at end of file +end diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index 86db3afc15..03e3f81acd 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -5,9 +5,9 @@ class BaseTest < ActiveSupport::TestCase class BaseMailer < ActionMailer::Base self.mailer_name = "base_mailer" - defaults :to => 'system@test.lindsaar.net', - :from => 'jose@test.plataformatec.com', - :reply_to => 'mikel@test.lindsaar.net' + default :to => 'system@test.lindsaar.net', + :from => 'jose@test.plataformatec.com', + :reply_to => 'mikel@test.lindsaar.net' def welcome(hash = {}) headers['X-SPAM'] = "Not SPAM" @@ -237,7 +237,7 @@ class BaseTest < ActiveSupport::TestCase end test "subject gets default from I18n" do - BaseMailer.defaults[:subject] = nil + BaseMailer.default[:subject] = nil email = BaseMailer.welcome(:subject => nil) assert_equal "Welcome", email.subject @@ -473,7 +473,7 @@ class BaseTest < ActiveSupport::TestCase end def with_default(klass, new_values) - hash = klass.defaults + hash = klass.default old_values = {} new_values.each do |key, value| old_values[key] = hash[key] -- cgit v1.2.3