aboutsummaryrefslogtreecommitdiffstats
path: root/actionmailer/lib/action_mailer
diff options
context:
space:
mode:
Diffstat (limited to 'actionmailer/lib/action_mailer')
-rw-r--r--actionmailer/lib/action_mailer/base.rb79
-rw-r--r--actionmailer/lib/action_mailer/delivery_job.rb2
-rw-r--r--actionmailer/lib/action_mailer/delivery_methods.rb3
-rw-r--r--actionmailer/lib/action_mailer/gem_version.rb2
-rw-r--r--actionmailer/lib/action_mailer/inline_preview_interceptor.rb61
-rw-r--r--actionmailer/lib/action_mailer/log_subscriber.rb10
-rw-r--r--actionmailer/lib/action_mailer/mail_helper.rb14
-rw-r--r--actionmailer/lib/action_mailer/message_delivery.rb12
-rw-r--r--actionmailer/lib/action_mailer/preview.rb14
-rw-r--r--actionmailer/lib/action_mailer/railtie.rb5
-rw-r--r--actionmailer/lib/action_mailer/test_case.rb10
-rw-r--r--actionmailer/lib/action_mailer/test_helper.rb6
12 files changed, 155 insertions, 63 deletions
diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb
index d5d124cbb8..4c5d959e32 100644
--- a/actionmailer/lib/action_mailer/base.rb
+++ b/actionmailer/lib/action_mailer/base.rb
@@ -21,11 +21,11 @@ module ActionMailer
# the mailer views, options on the mail itself such as the <tt>:from</tt> address, and attachments.
#
# class ApplicationMailer < ActionMailer::Base
- # default from: 'from@exmaple.com'
+ # default from: 'from@example.com'
# layout 'mailer'
# end
#
- # class Notifier < ApplicationMailer
+ # class NotifierMailer < ApplicationMailer
# default from: 'no-reply@example.com',
# return_path: 'system@example.com'
#
@@ -58,7 +58,7 @@ module ActionMailer
#
# 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.text.erb+ view
- # file as well as the +welcome.text.html.erb+ view file in a +multipart/alternative+ email.
+ # file 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:
#
@@ -88,7 +88,7 @@ module ActionMailer
#
# To define a template to be used with a mailing, create an <tt>.erb</tt> file with the same
# name as the method in your mailer model. For example, in the mailer defined above, the template at
- # <tt>app/views/notifier/welcome.text.erb</tt> would be used to generate the email.
+ # <tt>app/views/notifier_mailer/welcome.text.erb</tt> would be used to generate the email.
#
# Variables defined in the methods of your mailer model are accessible as instance variables in their
# corresponding view.
@@ -132,27 +132,32 @@ 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 create it and save it
- # for delivery later:
+ # Once a mailer action and template are defined, you can deliver your message or defer its creation and
+ # delivery for later:
+ #
+ # NotifierMailer.welcome(User.first).deliver_now # sends the email
+ # mail = NotifierMailer.welcome(User.first) # => an ActionMailer::MessageDelivery object
+ # mail.deliver_now # generates and sends the email now
#
- # Notifier.welcome(User.first).deliver_now # sends the email
- # mail = Notifier.welcome(User.first) # => an ActionMailer::MessageDelivery object
- # mail.deliver_now # sends the email
+ # The <tt>ActionMailer::MessageDelivery</tt> class is a wrapper around a delegate that will call
+ # your method to generate the mail. If you want direct access to delegator, or <tt>Mail::Message</tt>,
+ # you can call the <tt>message</tt> method on the <tt>ActionMailer::MessageDelivery</tt> object.
#
- # The <tt>ActionMailer::MessageDelivery</tt> class is a wrapper around a <tt>Mail::Message</tt> object. If
- # you want direct access to the <tt>Mail::Message</tt> object you can call the <tt>message</tt> method on
- # the <tt>ActionMailer::MessageDelivery</tt> object.
+ # NotifierMailer.welcome(User.first).message # => a Mail::Message object
#
- # Notifier.welcome(User.first).message # => a Mail::Message object
+ # Action Mailer is nicely integrated with Active Job so you can generate and send emails in the background
+ # (example: outside of the request-response cycle, so the user doesn't have to wait on it):
#
- # Action Mailer is nicely integrated with Active Job so you can send emails in the background (example: outside
- # of the request-response cycle, so the user doesn't have to wait on it):
+ # NotifierMailer.welcome(User.first).deliver_later # enqueue the email sending to Active Job
#
- # Notifier.welcome(User.first).deliver_later # enqueue the email sending to Active Job
+ # Note that <tt>deliver_later</tt> will execute your method from the background job.
#
# You never instantiate your mailer class. Rather, you just call the method you defined on the class itself.
+ # All instance methods are expected to return a message object to be sent.
#
# = Multipart Emails
#
@@ -179,7 +184,7 @@ module ActionMailer
#
# Sending attachment in emails is easy:
#
- # class Notifier < ApplicationMailer
+ # class NotifierMailer < ApplicationMailer
# def welcome(recipient)
# attachments['free_book.pdf'] = File.read('path/to/file.pdf')
# mail(to: recipient, subject: "New account information")
@@ -195,7 +200,7 @@ module ActionMailer
# If you need to send attachments with no content, you need to create an empty view for it,
# or add an empty body parameter like this:
#
- # class Notifier < ApplicationMailer
+ # class NotifierMailer < ApplicationMailer
# def welcome(recipient)
# attachments['free_book.pdf'] = File.read('path/to/file.pdf')
# mail(to: recipient, subject: "New account information", body: "")
@@ -207,7 +212,7 @@ module ActionMailer
# You can also specify that a file should be displayed inline with other HTML. This is useful
# if you want to display a corporate logo or a photo.
#
- # class Notifier < ApplicationMailer
+ # class NotifierMailer < ApplicationMailer
# def welcome(recipient)
# attachments.inline['photo.png'] = File.read('path/to/photo.png')
# mail(to: recipient, subject: "Here is what we look like")
@@ -246,7 +251,7 @@ module ActionMailer
# Action Mailer provides some intelligent defaults for your emails, these are usually specified in a
# default method inside the class definition:
#
- # class Notifier < ApplicationMailer
+ # class NotifierMailer < ApplicationMailer
# default sender: 'system@example.com'
# end
#
@@ -254,8 +259,8 @@ module ActionMailer
# <tt>ActionMailer::Base</tt> sets the following:
#
# * <tt>mime_version: "1.0"</tt>
- # * <tt>charset: "UTF-8",</tt>
- # * <tt>content_type: "text/plain",</tt>
+ # * <tt>charset: "UTF-8"</tt>
+ # * <tt>content_type: "text/plain"</tt>
# * <tt>parts_order: [ "text/plain", "text/enriched", "text/html" ]</tt>
#
# <tt>parts_order</tt> and <tt>charset</tt> are not actually valid <tt>Mail::Message</tt> header fields,
@@ -264,7 +269,7 @@ module ActionMailer
# As you can pass in any header, you need to either quote the header as a string, or pass it in as
# an underscored symbol, so the following will work:
#
- # class Notifier < ApplicationMailer
+ # class NotifierMailer < ApplicationMailer
# default 'Content-Transfer-Encoding' => '7bit',
# content_description: 'This is a description'
# end
@@ -272,7 +277,7 @@ module ActionMailer
# Finally, Action Mailer also supports passing <tt>Proc</tt> objects into the default hash, so you
# can define methods that evaluate as the message is being generated:
#
- # class Notifier < ApplicationMailer
+ # class NotifierMailer < ApplicationMailer
# default 'X-Special-Header' => Proc.new { my_method }
#
# private
@@ -283,7 +288,7 @@ module ActionMailer
# end
#
# Note that the proc is evaluated right at the start of the mail message generation, so if you
- # set something in the defaults using a proc, and then set the same thing inside of your
+ # set something in the default using a proc, and then set the same thing inside of your
# mailer method, it will get over written by the mailer method.
#
# It is also possible to set these default options that will be used in all mailers through
@@ -297,7 +302,7 @@ module ActionMailer
# This may be useful, for example, when you want to add default inline attachments for all
# messages sent out by a certain mailer class:
#
- # class Notifier < ApplicationMailer
+ # class NotifierMailer < ApplicationMailer
# before_action :add_inline_attachment!
#
# def welcome
@@ -316,8 +321,9 @@ module ActionMailer
# callbacks in the same manner that you would use callbacks in classes that
# inherit from <tt>ActionController::Base</tt>.
#
- # Note that unless you have a specific reason to do so, you should prefer using before_action
- # rather than after_action in your Action Mailer classes so that headers are parsed properly.
+ # Note that unless you have a specific reason to do so, you should prefer
+ # using <tt>before_action</tt> rather than <tt>after_action</tt> in your
+ # Action Mailer classes so that headers are parsed properly.
#
# = Previewing emails
#
@@ -325,9 +331,9 @@ module ActionMailer
# <tt>ActionMailer::Base.preview_path</tt>. Since most emails do something interesting
# with database data, you'll need to write some scenarios to load messages with fake data:
#
- # class NotifierPreview < ActionMailer::Preview
+ # class NotifierMailerPreview < ActionMailer::Preview
# def welcome
- # Notifier.welcome(User.first)
+ # NotifierMailer.welcome(User.first)
# end
# end
#
@@ -376,8 +382,8 @@ module ActionMailer
# * <tt>:password</tt> - If your mail server requires authentication, set the password in this setting.
# * <tt>:authentication</tt> - If your mail server requires authentication, you need to specify the
# authentication type here.
- # This is a symbol and one of <tt>:plain</tt> (will send the password in the clear), <tt>:login</tt> (will
- # send password Base64 encoded) or <tt>:cram_md5</tt> (combines a Challenge/Response mechanism to exchange
+ # This is a symbol and one of <tt>:plain</tt> (will send the password Base64 encoded), <tt>:login</tt> (will
+ # send the password Base64 encoded) or <tt>:cram_md5</tt> (combines a Challenge/Response mechanism to exchange
# information and a cryptographic Message Digest 5 algorithm to hash important information)
# * <tt>:enable_starttls_auto</tt> - Detects if STARTTLS is enabled in your SMTP server and starts
# to use it. Defaults to <tt>true</tt>.
@@ -409,6 +415,8 @@ 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>.
class Base < AbstractController::Base
include DeliveryMethods
include Previews
@@ -433,7 +441,6 @@ module ActionMailer
helper ActionMailer::MailHelper
- private_class_method :new #:nodoc:
private_class_method :find_class #:nodoc:
class_attribute :default_params
@@ -577,11 +584,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:
@@ -598,6 +604,7 @@ module ActionMailer
class NullMail #:nodoc:
def body; '' end
+ def header; {} end
def respond_to?(string, include_all=false)
true
@@ -818,7 +825,7 @@ module ActionMailer
# Set configure delivery behavior
wrap_delivery_behavior!(headers.delete(:delivery_method), headers.delete(:delivery_method_options))
- # Assign all headers except parts_order, content_type and body
+ # Assign all headers except parts_order, content_type, body, template_name, and template_path
assignable = headers.except(:parts_order, :content_type, :body, :template_name, :template_path)
assignable.each { |k, v| m[k] = v }
diff --git a/actionmailer/lib/action_mailer/delivery_job.rb b/actionmailer/lib/action_mailer/delivery_job.rb
index e864ab7a4d..52772af2d3 100644
--- a/actionmailer/lib/action_mailer/delivery_job.rb
+++ b/actionmailer/lib/action_mailer/delivery_job.rb
@@ -4,7 +4,7 @@ module ActionMailer
# The <tt>ActionMailer::DeliveryJob</tt> class is used when you
# want to send emails outside of the request-response cycle.
class DeliveryJob < ActiveJob::Base # :nodoc:
- queue_as :mailers
+ queue_as { ActionMailer::Base.deliver_later_queue_name }
def perform(mailer, mail_method, delivery_method, *args) #:nodoc:
mailer.constantize.public_send(mail_method, *args).send(delivery_method)
diff --git a/actionmailer/lib/action_mailer/delivery_methods.rb b/actionmailer/lib/action_mailer/delivery_methods.rb
index aedcd81e52..4758b55a2a 100644
--- a/actionmailer/lib/action_mailer/delivery_methods.rb
+++ b/actionmailer/lib/action_mailer/delivery_methods.rb
@@ -16,6 +16,9 @@ module ActionMailer
cattr_accessor :perform_deliveries
self.perform_deliveries = true
+ cattr_accessor :deliver_later_queue_name
+ self.deliver_later_queue_name = :mailers
+
self.delivery_methods = {}.freeze
self.delivery_method = :smtp
diff --git a/actionmailer/lib/action_mailer/gem_version.rb b/actionmailer/lib/action_mailer/gem_version.rb
index ac79788cf0..b35d2ed965 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
diff --git a/actionmailer/lib/action_mailer/inline_preview_interceptor.rb b/actionmailer/lib/action_mailer/inline_preview_interceptor.rb
new file mode 100644
index 0000000000..6d02b39225
--- /dev/null
+++ b/actionmailer/lib/action_mailer/inline_preview_interceptor.rb
@@ -0,0 +1,61 @@
+require 'base64'
+
+module ActionMailer
+ # Implements a mailer preview interceptor that converts image tag src attributes
+ # that use inline cid: style urls to data: style urls so that they are visible
+ # when previewing a HTML email in a web browser.
+ #
+ # This interceptor is enabled by default. To disable it, delete it from the
+ # <tt>ActionMailer::Base.preview_interceptors</tt> array:
+ #
+ # ActionMailer::Base.preview_interceptors.delete(ActionMailer::InlinePreviewInterceptor)
+ #
+ class InlinePreviewInterceptor
+ PATTERN = /src=(?:"cid:[^"]+"|'cid:[^']+')/i
+
+ include Base64
+
+ def self.previewing_email(message) #:nodoc:
+ new(message).transform!
+ end
+
+ def initialize(message) #:nodoc:
+ @message = message
+ end
+
+ def transform! #:nodoc:
+ return message if html_part.blank?
+
+ html_source.gsub!(PATTERN) do |match|
+ if part = find_part(match[9..-2])
+ %[src="#{data_url(part)}"]
+ else
+ match
+ end
+ end
+
+ message
+ end
+
+ private
+ def message
+ @message
+ end
+
+ def html_part
+ @html_part ||= message.html_part
+ end
+
+ def html_source
+ html_part.body.raw_source
+ end
+
+ def data_url(part)
+ "data:#{part.mime_type};base64,#{strict_encode64(part.body.raw_source)}"
+ end
+
+ def find_part(cid)
+ message.all_parts.find{ |p| p.attachment? && p.cid == cid }
+ end
+ end
+end
diff --git a/actionmailer/lib/action_mailer/log_subscriber.rb b/actionmailer/lib/action_mailer/log_subscriber.rb
index 5b57c75ec3..2867bf90fb 100644
--- a/actionmailer/lib/action_mailer/log_subscriber.rb
+++ b/actionmailer/lib/action_mailer/log_subscriber.rb
@@ -2,13 +2,13 @@ require 'active_support/log_subscriber'
module ActionMailer
# Implements the ActiveSupport::LogSubscriber for logging notifications when
- # email is delivered and received.
+ # email is delivered or received.
class LogSubscriber < ActiveSupport::LogSubscriber
# An email was delivered.
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/mail_helper.rb b/actionmailer/lib/action_mailer/mail_helper.rb
index cc7935a7e0..239974e7b1 100644
--- a/actionmailer/lib/action_mailer/mail_helper.rb
+++ b/actionmailer/lib/action_mailer/mail_helper.rb
@@ -4,7 +4,17 @@ module ActionMailer
# attachments list.
module MailHelper
# Take the text and format it, indented two spaces for each line, and
- # wrapped at 72 columns.
+ # wrapped at 72 columns:
+ #
+ # text = <<-TEXT
+ # This is
+ # the paragraph.
+ #
+ # * item1 * item2
+ # TEXT
+ #
+ # block_format text
+ # # => " This is the paragraph.\n\n * item1\n * item2\n"
def block_format(text)
formatted = text.split(/\n\r?\n/).collect { |paragraph|
format_paragraph(paragraph)
@@ -33,6 +43,8 @@ module ActionMailer
end
# Returns +text+ wrapped at +len+ columns and indented +indent+ spaces.
+ # By default column length +len+ equals 72 characters and indent
+ # +indent+ equal two spaces.
#
# my_text = 'Here is a sample text with more than 40 characters'
#
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 6fd3b0b120..0b37f405ee 100644
--- a/actionmailer/lib/action_mailer/preview.rb
+++ b/actionmailer/lib/action_mailer/preview.rb
@@ -21,7 +21,7 @@ module ActionMailer
# :nodoc:
mattr_accessor :preview_interceptors, instance_writer: false
- self.preview_interceptors = []
+ self.preview_interceptors = [ActionMailer::InlinePreviewInterceptor]
end
module ClassMethods
@@ -70,7 +70,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
@@ -86,27 +86,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 524e6e3af1..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
@@ -34,13 +34,13 @@ module ActionMailer
original_count = ActionMailer::Base.deliveries.size
yield
new_count = ActionMailer::Base.deliveries.size
- assert_equal original_count + number, new_count, "#{number} emails expected, but #{new_count - original_count} were sent"
+ assert_equal number, new_count - original_count, "#{number} emails expected, but #{new_count - original_count} were sent"
else
assert_equal number, ActionMailer::Base.deliveries.size
end
end
- # Assert that no emails have been sent.
+ # Asserts that no emails have been sent.
#
# def test_emails
# assert_no_emails