diff options
Diffstat (limited to 'actionmailer')
22 files changed, 261 insertions, 184 deletions
diff --git a/actionmailer/CHANGELOG.md b/actionmailer/CHANGELOG.md index 7c1b0b215a..e74e0bc20a 100644 --- a/actionmailer/CHANGELOG.md +++ b/actionmailer/CHANGELOG.md @@ -1,3 +1,10 @@ +## Rails 5.0.0.beta1 (December 18, 2015) ## + +* `config.force_ssl = true` will set + `config.action_mailer.default_url_options = { protocol: 'https' }`. + + *Andrew Kampjes* + * Add `config.action_mailer.deliver_later_queue_name` configuration to set the mailer queue name. @@ -53,7 +60,7 @@ *Carlos Souza* -* Remove deprecate `*_path` helpers in email views. +* Remove deprecated `*_path` helpers in email views. *Rafael Mendonça França* diff --git a/actionmailer/MIT-LICENSE b/actionmailer/MIT-LICENSE index 3ec7a617cf..8573eb1225 100644 --- a/actionmailer/MIT-LICENSE +++ b/actionmailer/MIT-LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2015 David Heinemeier Hansson +Copyright (c) 2004-2016 David Heinemeier Hansson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/actionmailer/README.rdoc b/actionmailer/README.rdoc index e5c2ed8c77..397ebe4201 100644 --- a/actionmailer/README.rdoc +++ b/actionmailer/README.rdoc @@ -146,7 +146,7 @@ The Base class has the full list of configuration options. Here's an example: The latest version of Action Mailer can be installed with RubyGems: - % gem install actionmailer + $ gem install actionmailer Source code can be downloaded as part of the Rails project on GitHub @@ -173,4 +173,3 @@ Bug reports can be filed for the Ruby on Rails project here: Feature requests should be discussed on the rails-core mailing list here: * https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core - diff --git a/actionmailer/actionmailer.gemspec b/actionmailer/actionmailer.gemspec index 782b208ef4..fa6043fdd7 100644 --- a/actionmailer/actionmailer.gemspec +++ b/actionmailer/actionmailer.gemspec @@ -13,7 +13,7 @@ Gem::Specification.new do |s| s.author = 'David Heinemeier Hansson' s.email = 'david@loudthinking.com' - s.homepage = 'http://www.rubyonrails.org' + s.homepage = 'http://rubyonrails.org' s.files = Dir['CHANGELOG.md', 'README.rdoc', 'MIT-LICENSE', 'lib/**/*'] s.require_path = 'lib' diff --git a/actionmailer/lib/action_mailer.rb b/actionmailer/lib/action_mailer.rb index 291a8c1e34..55c017e338 100644 --- a/actionmailer/lib/action_mailer.rb +++ b/actionmailer/lib/action_mailer.rb @@ -1,5 +1,5 @@ #-- -# Copyright (c) 2004-2015 David Heinemeier Hansson +# Copyright (c) 2004-2016 David Heinemeier Hansson # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -49,3 +49,10 @@ module ActionMailer autoload :MessageDelivery autoload :DeliveryJob end + +autoload :Mime, 'action_dispatch/http/mime_type' + +ActiveSupport.on_load(:action_view) do + ActionView::Base.default_formats ||= Mime::SET.symbols + ActionView::Template::Types.delegate_to Mime +end diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 7022c04a9a..bb3cb1be45 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -132,6 +132,8 @@ module ActionMailer # # config.action_mailer.default_url_options = { host: "example.com" } # + # By default when <tt>config.force_ssl</tt> is true, URLs generated for hosts will use the HTTPS protocol. + # # = Sending mail # # Once a mailer action and template are defined, you can deliver your message or defer its creation and @@ -414,7 +416,7 @@ module ActionMailer # * <tt>deliveries</tt> - Keeps an array of all the emails sent out through the Action Mailer with # <tt>delivery_method :test</tt>. Most useful for unit and functional testing. # - # * <tt>deliver_later_queue_name</tt> - The name of the queue used with <tt>deliver_later</tt> + # * <tt>deliver_later_queue_name</tt> - The name of the queue used with <tt>deliver_later</tt>. class Base < AbstractController::Base include DeliveryMethods include Previews @@ -439,8 +441,6 @@ module ActionMailer helper ActionMailer::MailHelper - private_class_method :new #:nodoc: - class_attribute :default_params self.default_params = { mime_version: "1.0", @@ -464,30 +464,26 @@ module ActionMailer # Either a class, string or symbol can be passed in as the Observer. # If a string or symbol is passed in it will be camelized and constantized. def register_observer(observer) - delivery_observer = case observer - when String, Symbol - observer.to_s.camelize.constantize - else - observer - end - - Mail.register_observer(delivery_observer) + Mail.register_observer(observer_class_for(observer)) end # Register an Interceptor which will be called before mail is sent. # Either a class, string or symbol can be passed in as the Interceptor. # If a string or symbol is passed in it will be camelized and constantized. def register_interceptor(interceptor) - delivery_interceptor = case interceptor - when String, Symbol - interceptor.to_s.camelize.constantize - else - interceptor - end - - Mail.register_interceptor(delivery_interceptor) + Mail.register_interceptor(observer_class_for(interceptor)) end + def observer_class_for(value) # :nodoc: + case value + when String, Symbol + value.to_s.camelize.constantize + else + value + end + end + private :observer_class_for + # Returns the name of current mailer. This method is also being used as a path for a view lookup. # If this is an anonymous mailer, this method will return +anonymous+ instead. def mailer_name @@ -545,10 +541,6 @@ module ActionMailer end end - def respond_to?(method, include_private = false) #:nodoc: - super || action_methods.include?(method.to_s) - end - protected def set_payload_for_mail(payload, mail) #:nodoc: @@ -570,6 +562,12 @@ module ActionMailer super end end + + private + + def respond_to_missing?(method, include_all = false) #:nodoc: + action_methods.include?(method.to_s) + end end attr_internal :message @@ -578,11 +576,10 @@ module ActionMailer # 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) + def initialize super() @_mail_was_called = false @_message = Mail.new - process(method_name, *args) if method_name end def process(method_name, *args) #:nodoc: @@ -661,18 +658,18 @@ module ActionMailer # # 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. + # If you do this, then Mail will take the file name and work out the mime type. + # It will also set the Content-Type, Content-Disposition, Content-Transfer-Encoding + # and encode the contents of the attachment in Base64. # # 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: + # If you want to use encoding other than Base64 then you will need to pass encoding + # type along with the pre-encoded content as Mail doesn't know how to decode the + # data: # # file_content = SpecialEncode(File.read('/path/to/filename.jpg')) # mail.attachments['filename.jpg'] = {mime_type: 'application/x-gzip', @@ -797,52 +794,40 @@ module ActionMailer # end # def mail(headers = {}, &block) - return @_message if @_mail_was_called && headers.blank? && !block - - m = @_message + return message if @_mail_was_called && headers.blank? && !block # At the beginning, do not consider class default for content_type content_type = headers[:content_type] - # Call all the procs (if any) - default_values = {} - self.class.default.each do |k,v| - default_values[k] = v.is_a?(Proc) ? instance_eval(&v) : v - end - - # Handle defaults - headers = headers.reverse_merge(default_values) - headers[:subject] ||= default_i18n_subject + headers = apply_defaults(headers) # Apply charset at the beginning so all fields are properly quoted - m.charset = charset = headers[:charset] + message.charset = charset = headers[:charset] # Set configure delivery behavior - wrap_delivery_behavior!(headers.delete(:delivery_method), headers.delete(:delivery_method_options)) + wrap_delivery_behavior!(headers[:delivery_method], headers[:delivery_method_options]) - # Assign all headers except parts_order, content_type and body - assignable = headers.except(:parts_order, :content_type, :body, :template_name, :template_path) - assignable.each { |k, v| m[k] = v } + assign_headers_to_message(message, headers) # Render the templates and blocks responses = collect_responses(headers, &block) @_mail_was_called = true - create_parts_from_responses(m, responses) + create_parts_from_responses(message, responses) # Setup content type, reapply charset and handle parts order - m.content_type = set_content_type(m, content_type, headers[:content_type]) - m.charset = charset + message.content_type = set_content_type(message, content_type, headers[:content_type]) + message.charset = charset - if m.multipart? - m.body.set_sort_order(headers[:parts_order]) - m.body.sort_parts! + if message.multipart? + message.body.set_sort_order(headers[:parts_order]) + message.body.sort_parts! end - m + message end - protected + protected # Used by #mail to set the content type of the message. # @@ -880,36 +865,61 @@ module ActionMailer I18n.t(:subject, interpolations.merge(scope: [mailer_scope, action_name], default: action_name.humanize)) end - def collect_responses(headers) #:nodoc: - responses = [] + # Emails do not support relative path links. + def self.supports_path? + false + end + + private + + def apply_defaults(headers) + default_values = self.class.default.map do |key, value| + [ + key, + value.is_a?(Proc) ? instance_eval(&value) : value + ] + end.to_h + + headers_with_defaults = headers.reverse_merge(default_values) + headers_with_defaults[:subject] ||= default_i18n_subject + headers_with_defaults + end + def assign_headers_to_message(message, headers) + assignable = headers.except(:parts_order, :content_type, :body, :template_name, + :template_path, :delivery_method, :delivery_method_options) + assignable.each { |k, v| message[k] = v } + end + + def collect_responses(headers) if block_given? collector = ActionMailer::Collector.new(lookup_context) { render(action_name) } yield(collector) - responses = collector.responses + collector.responses elsif headers[:body] - responses << { + [{ body: headers.delete(:body), content_type: self.class.default[:content_type] || "text/plain" - } + }] else - templates_path = headers.delete(:template_path) || self.class.mailer_name - templates_name = headers.delete(:template_name) || action_name + collect_responses_from_templates(headers) + end + end - each_template(Array(templates_path), templates_name) do |template| - self.formats = template.formats + def collect_responses_from_templates(headers) + templates_path = headers[:template_path] || self.class.mailer_name + templates_name = headers[:template_name] || action_name - responses << { - body: render(template: template), - content_type: template.type.to_s - } - end + each_template(Array(templates_path), templates_name).map do |template| + self.formats = template.formats + { + body: render(template: template), + content_type: template.type.to_s + } end - - responses end - def each_template(paths, name, &block) #:nodoc: + def each_template(paths, name, &block) templates = lookup_context.find_all(name, paths) if templates.empty? raise ActionView::MissingTemplate.new(paths, name, paths, false, 'mailer') @@ -918,7 +928,7 @@ module ActionMailer end end - def create_parts_from_responses(m, responses) #:nodoc: + def create_parts_from_responses(m, responses) if responses.size == 1 && !m.has_attachments? responses[0].each { |k,v| m[k] = v } elsif responses.size > 1 && m.has_attachments? @@ -931,17 +941,12 @@ module ActionMailer end end - def insert_part(container, response, charset) #:nodoc: + def insert_part(container, response, charset) response[:charset] ||= charset part = Mail::Part.new(response) container.add_part(part) end - # Emails do not support relative path links. - def self.supports_path? - false - end - ActiveSupport.run_load_hooks(:action_mailer, self) end end diff --git a/actionmailer/lib/action_mailer/gem_version.rb b/actionmailer/lib/action_mailer/gem_version.rb index ac79788cf0..175122e00a 100644 --- a/actionmailer/lib/action_mailer/gem_version.rb +++ b/actionmailer/lib/action_mailer/gem_version.rb @@ -1,5 +1,5 @@ module ActionMailer - # Returns the version of the currently loaded Action Mailer as a <tt>Gem::Version</tt> + # Returns the version of the currently loaded Action Mailer as a <tt>Gem::Version</tt>. def self.gem_version Gem::Version.new VERSION::STRING end @@ -8,7 +8,7 @@ module ActionMailer MAJOR = 5 MINOR = 0 TINY = 0 - PRE = "alpha" + PRE = "beta1" STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".") end diff --git a/actionmailer/lib/action_mailer/log_subscriber.rb b/actionmailer/lib/action_mailer/log_subscriber.rb index c2f671fdac..2867bf90fb 100644 --- a/actionmailer/lib/action_mailer/log_subscriber.rb +++ b/actionmailer/lib/action_mailer/log_subscriber.rb @@ -8,7 +8,7 @@ module ActionMailer def deliver(event) info do recipients = Array(event.payload[:to]).join(', ') - "\nSent mail to #{recipients} (#{event.duration.round(1)}ms)" + "Sent mail to #{recipients} (#{event.duration.round(1)}ms)" end debug { event.payload[:mail] } @@ -16,7 +16,7 @@ module ActionMailer # An email was received. def receive(event) - info { "\nReceived mail (#{event.duration.round(1)}ms)" } + info { "Received mail (#{event.duration.round(1)}ms)" } debug { event.payload[:mail] } end @@ -25,11 +25,11 @@ module ActionMailer debug do mailer = event.payload[:mailer] action = event.payload[:action] - "\n#{mailer}##{action}: processed outbound mail in #{event.duration.round(1)}ms" + "#{mailer}##{action}: processed outbound mail in #{event.duration.round(1)}ms" end end - # Use the logger configured for ActionMailer::Base + # Use the logger configured for ActionMailer::Base. def logger ActionMailer::Base.logger end diff --git a/actionmailer/lib/action_mailer/message_delivery.rb b/actionmailer/lib/action_mailer/message_delivery.rb index ff2cb0fd01..5fcb5a0c88 100644 --- a/actionmailer/lib/action_mailer/message_delivery.rb +++ b/actionmailer/lib/action_mailer/message_delivery.rb @@ -21,7 +21,11 @@ module ActionMailer end def __getobj__ #:nodoc: - @obj ||= @mailer.send(:new, @mail_method, *@args).message + @obj ||= begin + mailer = @mailer.new + mailer.process @mail_method, *@args + mailer.message + end end def __setobj__(obj) #:nodoc: @@ -60,9 +64,9 @@ module ActionMailer # # Options: # - # * <tt>:wait</tt> - Enqueue the email to be delivered with a delay - # * <tt>:wait_until</tt> - Enqueue the email to be delivered at (after) a specific date / time - # * <tt>:queue</tt> - Enqueue the email on the specified queue + # * <tt>:wait</tt> - Enqueue the email to be delivered with a delay. + # * <tt>:wait_until</tt> - Enqueue the email to be delivered at (after) a specific date / time. + # * <tt>:queue</tt> - Enqueue the email on the specified queue. def deliver_later(options={}) enqueue_delivery :deliver_now, options end diff --git a/actionmailer/lib/action_mailer/preview.rb b/actionmailer/lib/action_mailer/preview.rb index 25ad7ee721..aab92fe8db 100644 --- a/actionmailer/lib/action_mailer/preview.rb +++ b/actionmailer/lib/action_mailer/preview.rb @@ -52,7 +52,7 @@ module ActionMailer extend ActiveSupport::DescendantsTracker class << self - # Returns all mailer preview classes + # Returns all mailer preview classes. def all load_previews if descendants.empty? descendants @@ -68,27 +68,27 @@ module ActionMailer message end - # Returns all of the available email previews + # Returns all of the available email previews. def emails public_instance_methods(false).map(&:to_s).sort end - # Returns true if the email exists + # Returns true if the email exists. def email_exists?(email) emails.include?(email) end - # Returns true if the preview exists + # Returns true if the preview exists. def exists?(preview) all.any?{ |p| p.preview_name == preview } end - # Find a mailer preview by its underscored class name + # Find a mailer preview by its underscored class name. def find(preview) all.find{ |p| p.preview_name == preview } end - # Returns the underscored name of the mailer preview without the suffix + # Returns the underscored name of the mailer preview without the suffix. def preview_name name.sub(/Preview$/, '').underscore end diff --git a/actionmailer/lib/action_mailer/railtie.rb b/actionmailer/lib/action_mailer/railtie.rb index bebcf4de01..fa707021c7 100644 --- a/actionmailer/lib/action_mailer/railtie.rb +++ b/actionmailer/lib/action_mailer/railtie.rb @@ -16,6 +16,11 @@ module ActionMailer paths = app.config.paths options = app.config.action_mailer + if app.config.force_ssl + options.default_url_options ||= {} + options.default_url_options[:protocol] ||= 'https' + end + options.assets_dir ||= paths["public"].first options.javascripts_dir ||= paths["public/javascripts"].first options.stylesheets_dir ||= paths["public/stylesheets"].first diff --git a/actionmailer/lib/action_mailer/test_case.rb b/actionmailer/lib/action_mailer/test_case.rb index 766215ce96..0aa15e31ba 100644 --- a/actionmailer/lib/action_mailer/test_case.rb +++ b/actionmailer/lib/action_mailer/test_case.rb @@ -57,28 +57,28 @@ module ActionMailer protected - def initialize_test_deliveries + def initialize_test_deliveries # :nodoc: set_delivery_method :test @old_perform_deliveries = ActionMailer::Base.perform_deliveries ActionMailer::Base.perform_deliveries = true end - def restore_test_deliveries + def restore_test_deliveries # :nodoc: restore_delivery_method ActionMailer::Base.perform_deliveries = @old_perform_deliveries ActionMailer::Base.deliveries.clear end - def set_delivery_method(method) + def set_delivery_method(method) # :nodoc: @old_delivery_method = ActionMailer::Base.delivery_method ActionMailer::Base.delivery_method = method end - def restore_delivery_method + def restore_delivery_method # :nodoc: ActionMailer::Base.delivery_method = @old_delivery_method end - def set_expected_mail + def set_expected_mail # :nodoc: @expected = Mail.new @expected.content_type ["text", "plain", { "charset" => charset }] @expected.mime_version = '1.0' diff --git a/actionmailer/lib/action_mailer/test_helper.rb b/actionmailer/lib/action_mailer/test_helper.rb index 4d03a616d2..e423aac389 100644 --- a/actionmailer/lib/action_mailer/test_helper.rb +++ b/actionmailer/lib/action_mailer/test_helper.rb @@ -2,7 +2,7 @@ require 'active_job' module ActionMailer # Provides helper methods for testing Action Mailer, including #assert_emails - # and #assert_no_emails + # and #assert_no_emails. module TestHelper include ActiveJob::TestHelper @@ -40,7 +40,7 @@ module ActionMailer end end - # Assert that no emails have been sent. + # Asserts that no emails have been sent. # # def test_emails # assert_no_emails diff --git a/actionmailer/lib/rails/generators/mailer/mailer_generator.rb b/actionmailer/lib/rails/generators/mailer/mailer_generator.rb index 3ec7d3d896..5a5c9d32bb 100644 --- a/actionmailer/lib/rails/generators/mailer/mailer_generator.rb +++ b/actionmailer/lib/rails/generators/mailer/mailer_generator.rb @@ -9,9 +9,6 @@ module Rails def create_mailer_file template "mailer.rb", File.join('app/mailers', class_path, "#{file_name}_mailer.rb") - if self.behavior == :invoke - template "application_mailer.rb", 'app/mailers/application_mailer.rb' - end end hook_for :template_engine, :test_framework diff --git a/actionmailer/lib/rails/generators/mailer/templates/application_mailer.rb b/actionmailer/lib/rails/generators/mailer/templates/application_mailer.rb deleted file mode 100644 index d25d8892dd..0000000000 --- a/actionmailer/lib/rails/generators/mailer/templates/application_mailer.rb +++ /dev/null @@ -1,4 +0,0 @@ -class ApplicationMailer < ActionMailer::Base - default from: "from@example.com" - layout 'mailer' -end diff --git a/actionmailer/test/abstract_unit.rb b/actionmailer/test/abstract_unit.rb index 706249a2f6..285b2cfcb5 100644 --- a/actionmailer/test/abstract_unit.rb +++ b/actionmailer/test/abstract_unit.rb @@ -8,7 +8,14 @@ silence_warnings do Encoding.default_external = "UTF-8" end +module Rails + def self.root + File.expand_path('../', File.dirname(__FILE__)) + end +end + require 'active_support/testing/autorun' +require 'active_support/testing/method_call_assertions' require 'action_mailer' require 'action_mailer/test_case' @@ -25,12 +32,6 @@ I18n.enforce_available_locales = false FIXTURE_LOAD_PATH = File.expand_path('fixtures', File.dirname(__FILE__)) ActionMailer::Base.view_paths = FIXTURE_LOAD_PATH -module Rails - def self.root - File.expand_path('../', File.dirname(__FILE__)) - end -end - # Skips the current run on Rubinius using Minitest::Assertions#skip def rubinius_skip(message = '') skip message if RUBY_ENGINE == 'rbx' @@ -40,4 +41,6 @@ def jruby_skip(message = '') skip message if defined?(JRUBY_VERSION) end -require 'mocha/setup' # FIXME: stop using mocha +class ActiveSupport::TestCase + include ActiveSupport::Testing::MethodCallAssertions +end diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index 59c5638f96..50f2c71737 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -449,6 +449,13 @@ class BaseTest < ActiveSupport::TestCase assert_equal("Format with any!", email.parts[1].body.encoded) end + test 'explicit without specifying format with format.any' do + error = assert_raises(ArgumentError) do + BaseMailer.explicit_without_specifying_format_with_any.parts + end + assert_equal "You have to supply at least one format", error.message + end + test "explicit multipart with format(Hash)" do email = BaseMailer.explicit_multipart_with_options(true) email.ready_to_send! @@ -505,9 +512,10 @@ class BaseTest < ActiveSupport::TestCase end test "calling deliver on the action should deliver the mail object" do - BaseMailer.expects(:deliver_mail).once - mail = BaseMailer.welcome.deliver_now - assert_equal 'The first email on new API!', mail.subject + assert_called(BaseMailer, :deliver_mail) do + mail = BaseMailer.welcome.deliver_now + assert_equal 'The first email on new API!', mail.subject + end end test "calling deliver on the action should increment the deliveries collection if using the test mailer" do @@ -517,9 +525,11 @@ class BaseTest < ActiveSupport::TestCase 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 + assert_called(mail, :do_delivery) do + assert_called(BaseMailer, :welcome, returns: mail) do + BaseMailer.welcome.deliver + end + end end # Rendering @@ -607,8 +617,9 @@ class BaseTest < ActiveSupport::TestCase mail_side_effects do ActionMailer::Base.register_observer(MyObserver) mail = BaseMailer.welcome - MyObserver.expects(:delivered_email).with(mail) - mail.deliver_now + assert_called_with(MyObserver, :delivered_email, [mail]) do + mail.deliver_now + end end end @@ -616,8 +627,9 @@ class BaseTest < ActiveSupport::TestCase mail_side_effects do ActionMailer::Base.register_observer("BaseTest::MyObserver") mail = BaseMailer.welcome - MyObserver.expects(:delivered_email).with(mail) - mail.deliver_now + assert_called_with(MyObserver, :delivered_email, [mail]) do + mail.deliver_now + end end end @@ -625,8 +637,9 @@ class BaseTest < ActiveSupport::TestCase mail_side_effects do ActionMailer::Base.register_observer(:"base_test/my_observer") mail = BaseMailer.welcome - MyObserver.expects(:delivered_email).with(mail) - mail.deliver_now + assert_called_with(MyObserver, :delivered_email, [mail]) do + mail.deliver_now + end end end @@ -634,9 +647,11 @@ class BaseTest < ActiveSupport::TestCase mail_side_effects do ActionMailer::Base.register_observers("BaseTest::MyObserver", MySecondObserver) mail = BaseMailer.welcome - MyObserver.expects(:delivered_email).with(mail) - MySecondObserver.expects(:delivered_email).with(mail) - mail.deliver_now + assert_called_with(MyObserver, :delivered_email, [mail]) do + assert_called_with(MySecondObserver, :delivered_email, [mail]) do + mail.deliver_now + end + end end end @@ -654,8 +669,9 @@ class BaseTest < ActiveSupport::TestCase mail_side_effects do ActionMailer::Base.register_interceptor(MyInterceptor) mail = BaseMailer.welcome - MyInterceptor.expects(:delivering_email).with(mail) - mail.deliver_now + assert_called_with(MyInterceptor, :delivering_email, [mail]) do + mail.deliver_now + end end end @@ -663,8 +679,9 @@ class BaseTest < ActiveSupport::TestCase mail_side_effects do ActionMailer::Base.register_interceptor("BaseTest::MyInterceptor") mail = BaseMailer.welcome - MyInterceptor.expects(:delivering_email).with(mail) - mail.deliver_now + assert_called_with(MyInterceptor, :delivering_email, [mail]) do + mail.deliver_now + end end end @@ -672,8 +689,9 @@ class BaseTest < ActiveSupport::TestCase mail_side_effects do ActionMailer::Base.register_interceptor(:"base_test/my_interceptor") mail = BaseMailer.welcome - MyInterceptor.expects(:delivering_email).with(mail) - mail.deliver_now + assert_called_with(MyInterceptor, :delivering_email, [mail]) do + mail.deliver_now + end end end @@ -681,18 +699,21 @@ class BaseTest < ActiveSupport::TestCase mail_side_effects do ActionMailer::Base.register_interceptors("BaseTest::MyInterceptor", MySecondInterceptor) mail = BaseMailer.welcome - MyInterceptor.expects(:delivering_email).with(mail) - MySecondInterceptor.expects(:delivering_email).with(mail) - mail.deliver_now + assert_called_with(MyInterceptor, :delivering_email, [mail]) do + assert_called_with(MySecondInterceptor, :delivering_email, [mail]) do + mail.deliver_now + end + end end end test "being able to put proc's into the defaults hash and they get evaluated on mail sending" do mail1 = ProcMailer.welcome['X-Proc-Method'] yesterday = 1.day.ago - Time.stubs(:now).returns(yesterday) - mail2 = ProcMailer.welcome['X-Proc-Method'] - assert(mail1.to_s.to_i > mail2.to_s.to_i) + Time.stub(:now, yesterday) do + mail2 = ProcMailer.welcome['X-Proc-Method'] + assert(mail1.to_s.to_i > mail2.to_s.to_i) + end end test 'default values which have to_proc (e.g. symbols) should not be considered procs' do @@ -877,33 +898,50 @@ class BasePreviewInterceptorsTest < ActiveSupport::TestCase test "you can register a preview interceptor to the mail object that gets passed the mail object before previewing" do ActionMailer::Base.register_preview_interceptor(MyInterceptor) mail = BaseMailer.welcome - BaseMailerPreview.any_instance.stubs(:welcome).returns(mail) - MyInterceptor.expects(:previewing_email).with(mail) - BaseMailerPreview.call(:welcome) + stub_any_instance(BaseMailerPreview) do |instance| + instance.stub(:welcome, mail) do + assert_called_with(MyInterceptor, :previewing_email, [mail]) do + BaseMailerPreview.call(:welcome) + end + end + end end test "you can register a preview interceptor using its stringified name to the mail object that gets passed the mail object before previewing" do ActionMailer::Base.register_preview_interceptor("BasePreviewInterceptorsTest::MyInterceptor") mail = BaseMailer.welcome - BaseMailerPreview.any_instance.stubs(:welcome).returns(mail) - MyInterceptor.expects(:previewing_email).with(mail) - BaseMailerPreview.call(:welcome) + stub_any_instance(BaseMailerPreview) do |instance| + instance.stub(:welcome, mail) do + assert_called_with(MyInterceptor, :previewing_email, [mail]) do + BaseMailerPreview.call(:welcome) + end + end + end end test "you can register an interceptor using its symbolized underscored name to the mail object that gets passed the mail object before previewing" do ActionMailer::Base.register_preview_interceptor(:"base_preview_interceptors_test/my_interceptor") mail = BaseMailer.welcome - BaseMailerPreview.any_instance.stubs(:welcome).returns(mail) - MyInterceptor.expects(:previewing_email).with(mail) - BaseMailerPreview.call(:welcome) + stub_any_instance(BaseMailerPreview) do |instance| + instance.stub(:welcome, mail) do + assert_called_with(MyInterceptor, :previewing_email, [mail]) do + BaseMailerPreview.call(:welcome) + end + end + end end test "you can register multiple preview interceptors to the mail object that both get passed the mail object before previewing" do ActionMailer::Base.register_preview_interceptors("BasePreviewInterceptorsTest::MyInterceptor", MySecondInterceptor) mail = BaseMailer.welcome - BaseMailerPreview.any_instance.stubs(:welcome).returns(mail) - MyInterceptor.expects(:previewing_email).with(mail) - MySecondInterceptor.expects(:previewing_email).with(mail) - BaseMailerPreview.call(:welcome) + stub_any_instance(BaseMailerPreview) do |instance| + instance.stub(:welcome, mail) do + assert_called_with(MyInterceptor, :previewing_email, [mail]) do + assert_called_with(MySecondInterceptor, :previewing_email, [mail]) do + BaseMailerPreview.call(:welcome) + end + end + end + end end end diff --git a/actionmailer/test/delivery_methods_test.rb b/actionmailer/test/delivery_methods_test.rb index 78507ce7dc..2786fe0d07 100644 --- a/actionmailer/test/delivery_methods_test.rb +++ b/actionmailer/test/delivery_methods_test.rb @@ -31,8 +31,8 @@ class DefaultsDeliveryMethodsTest < ActiveSupport::TestCase assert_equal settings, ActionMailer::Base.smtp_settings end - test "default file delivery settings" do - settings = {location: "#{Dir.tmpdir}/mails"} + test "default file delivery settings (with Rails.root)" do + settings = {location: "#{Rails.root}/tmp/mails"} assert_equal settings, ActionMailer::Base.file_settings end @@ -102,16 +102,21 @@ class MailDeliveryTest < ActiveSupport::TestCase end test "ActionMailer should be told when Mail gets delivered" do - DeliveryMailer.expects(:deliver_mail).once - DeliveryMailer.welcome.deliver_now + DeliveryMailer.delivery_method = :test + assert_called(DeliveryMailer, :deliver_mail) do + DeliveryMailer.welcome.deliver_now + end end test "delivery method can be customized per instance" do - Mail::SMTP.any_instance.expects(:deliver!) - email = DeliveryMailer.welcome.deliver_now - assert_instance_of Mail::SMTP, email.delivery_method - email = DeliveryMailer.welcome(delivery_method: :test).deliver_now - assert_instance_of Mail::TestMailer, email.delivery_method + stub_any_instance(Mail::SMTP, instance: Mail::SMTP.new({})) do |instance| + assert_called(instance, :deliver!) do + email = DeliveryMailer.welcome.deliver_now + assert_instance_of Mail::SMTP, email.delivery_method + email = DeliveryMailer.welcome(delivery_method: :test).deliver_now + assert_instance_of Mail::TestMailer, email.delivery_method + end + end end test "delivery method can be customized in subclasses not changing the parent" do @@ -160,24 +165,29 @@ class MailDeliveryTest < ActiveSupport::TestCase test "non registered delivery methods raises errors" do DeliveryMailer.delivery_method = :unknown - assert_raise RuntimeError do + error = assert_raise RuntimeError do DeliveryMailer.welcome.deliver_now end + assert_equal "Invalid delivery method :unknown", error.message end test "undefined delivery methods raises errors" do DeliveryMailer.delivery_method = nil - assert_raise RuntimeError do + error = assert_raise RuntimeError do DeliveryMailer.welcome.deliver_now end + assert_equal "Delivery method cannot be nil", error.message end test "does not perform deliveries if requested" do old_perform_deliveries = DeliveryMailer.perform_deliveries begin DeliveryMailer.perform_deliveries = false - Mail::Message.any_instance.expects(:deliver!).never - DeliveryMailer.welcome.deliver_now + stub_any_instance(Mail::Message) do |instance| + assert_not_called(instance, :deliver!) do + DeliveryMailer.welcome.deliver_now + end + end ensure DeliveryMailer.perform_deliveries = old_perform_deliveries end diff --git a/actionmailer/test/fixtures/async_mailer/welcome.erb b/actionmailer/test/fixtures/async_mailer/welcome.erb deleted file mode 100644 index 01f3f00c63..0000000000 --- a/actionmailer/test/fixtures/async_mailer/welcome.erb +++ /dev/null @@ -1 +0,0 @@ -Welcome
\ No newline at end of file diff --git a/actionmailer/test/i18n_with_controller_test.rb b/actionmailer/test/i18n_with_controller_test.rb index 5ffde06a80..6124ffeb52 100644 --- a/actionmailer/test/i18n_with_controller_test.rb +++ b/actionmailer/test/i18n_with_controller_test.rb @@ -1,7 +1,6 @@ require 'abstract_unit' require 'action_view' require 'action_controller' -require 'active_support/deprecation' class I18nTestMailer < ActionMailer::Base configure do |c| @@ -53,12 +52,15 @@ class ActionMailerI18nWithControllerTest < ActionDispatch::IntegrationTest end def test_send_mail - Mail::SMTP.any_instance.expects(:deliver!) - with_translation 'de', email_subject: '[Anmeldung] Willkommen' do - ActiveSupport::Deprecation.silence do - get '/test/send_mail' + stub_any_instance(Mail::SMTP, instance: Mail::SMTP.new({})) do |instance| + assert_called(instance, :deliver!) do + with_translation 'de', email_subject: '[Anmeldung] Willkommen' do + ActiveSupport::Deprecation.silence do + get '/test/send_mail' + end + assert_equal "Mail sent - Subject: [Anmeldung] Willkommen", @response.body + end end - assert_equal "Mail sent - Subject: [Anmeldung] Willkommen", @response.body end end diff --git a/actionmailer/test/mailers/base_mailer.rb b/actionmailer/test/mailers/base_mailer.rb index bd991e209e..8c2225ce60 100644 --- a/actionmailer/test/mailers/base_mailer.rb +++ b/actionmailer/test/mailers/base_mailer.rb @@ -80,6 +80,12 @@ class BaseMailer < ActionMailer::Base end end + def explicit_without_specifying_format_with_any(hash = {}) + mail(hash) do |format| + format.any + end + end + def explicit_multipart_with_options(include_html = false) mail do |format| format.text(content_transfer_encoding: "base64"){ render "welcome" } diff --git a/actionmailer/test/message_delivery_test.rb b/actionmailer/test/message_delivery_test.rb index 862ce26187..b834cdd08c 100644 --- a/actionmailer/test/message_delivery_test.rb +++ b/actionmailer/test/message_delivery_test.rb @@ -1,6 +1,5 @@ require 'abstract_unit' require 'active_job' -require 'minitest/mock' require 'mailers/delayed_mailer' class MessageDeliveryTest < ActiveSupport::TestCase |