diff options
-rw-r--r-- | actionmailer/actionmailer.gemspec | 2 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer.rb | 1 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer/base.rb | 91 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer/delivery_method.rb | 56 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer/delivery_method/file.rb | 21 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer/delivery_method/sendmail.rb | 22 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer/delivery_method/smtp.rb | 30 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer/delivery_method/test.rb | 12 | ||||
-rw-r--r-- | actionmailer/test/abstract_unit.rb | 6 | ||||
-rw-r--r-- | actionmailer/test/delivery_method_test.rb | 63 | ||||
-rw-r--r-- | actionmailer/test/mail_layout_test.rb | 1 | ||||
-rw-r--r-- | actionmailer/test/mail_service_test.rb | 25 | ||||
-rw-r--r-- | actionmailer/test/test_helper_test.rb | 2 |
13 files changed, 134 insertions, 198 deletions
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 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 diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index a8233512ab..5ece35e69b 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -354,24 +354,48 @@ module ActionMailer #:nodoc: # Alias controller_path to mailer_name so render :partial in views work. alias :controller_path :mailer_name - class << self - attr_writer :mailer_name + superclass_delegating_accessor :delivery_method + self.delivery_method = :smtp - 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 + class << self def mailer_name @mailer_name ||= name.underscore end - alias :controller_path :mailer_name + attr_writer :mailer_name - def delivery_method=(method_name) - @delivery_method = ActionMailer::DeliveryMethod.lookup_method(method_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) || super + matches_dynamic_method?(method_symbol) || matches_settings_method?(method_symbol) || super end def method_missing(method_symbol, *parameters) #:nodoc: @@ -382,6 +406,13 @@ 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 @@ -413,7 +444,24 @@ 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, get_delivery_settings(delivery_method) + 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 def template_root @@ -438,6 +486,14 @@ 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) @@ -522,19 +578,7 @@ module ActionMailer #:nodoc: # object (from the <tt>create!</tt> 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 @@ -566,6 +610,7 @@ 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 @template ||= method_name @parts ||= [] 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 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_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" diff --git a/actionmailer/test/mail_service_test.rb b/actionmailer/test/mail_service_test.rb index f87d9b2e5b..7b5f8b1ffc 100644 --- a/actionmailer/test/mail_service_test.rb +++ b/actionmailer/test/mail_service_test.rb @@ -545,7 +545,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 @@ -674,15 +674,12 @@ 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) + IO.expects(:popen).once.with('/usr/sbin/sendmail -i -t test@localhost', 'w+') ActionMailer::Base.delivery_method = :sendmail TestMailer.deliver_signed_up(@recipient) end @@ -1072,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 @@ -1093,7 +1085,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 @@ -1101,7 +1093,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 @@ -1109,13 +1101,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 - MockSMTP.any_instance.expects(:enable_starttls_auto).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 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 |