mirror of https://github.com/rails/rails
Merge remote branch 'mikel/master'
This commit is contained in:
commit
abad097016
|
@ -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'}
|
||||
|
|
|
@ -5,51 +5,72 @@ 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.
|
||||
|
||||
def signed_up(recipient)
|
||||
recipients recipient
|
||||
subject "[Signed up] Welcome #{recipient}"
|
||||
from "system@loudthinking.com"
|
||||
body :recipient => recipient
|
||||
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
|
||||
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 <tt>create_method_name</tt> and
|
||||
<tt>deliver_method_name</tt>. Rails 3.0 has a much simpler interface, you
|
||||
simply call the method and optionally call +deliver+ on the return value.
|
||||
|
||||
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!
|
||||
Calling the method returns a Mail Message object:
|
||||
|
||||
message = Notifier.welcome #=> Returns a Mail::Message object
|
||||
message.deliver #=> delivers the email
|
||||
|
||||
Or you can just chain the methods together like:
|
||||
|
||||
Notifier.welcome.deliver # Creates the email and sends it immediately
|
||||
|
||||
== Receiving emails
|
||||
|
||||
|
@ -103,16 +124,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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.1.1')
|
||||
|
||||
s.files = Dir['CHANGELOG', 'README', 'MIT-LICENSE', 'lib/**/*']
|
||||
s.has_rdoc = true
|
||||
|
|
|
@ -31,10 +31,12 @@ module ActionMailer
|
|||
extend ::ActiveSupport::Autoload
|
||||
|
||||
autoload :AdvAttrAccessor
|
||||
autoload :Collector
|
||||
autoload :Base
|
||||
autoload :DeliveryMethod
|
||||
autoload :DeprecatedBody
|
||||
autoload :DeliveryMethods
|
||||
autoload :DeprecatedApi
|
||||
autoload :MailHelper
|
||||
autoload :OldApi
|
||||
autoload :Quoting
|
||||
autoload :TestCase
|
||||
autoload :TestHelper
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
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'
|
||||
|
||||
module ActionMailer #:nodoc:
|
||||
# Action Mailer allows you to send email from your application using a mailer model and views.
|
||||
|
@ -11,46 +16,71 @@ 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 <watcher@example.com>"]
|
||||
# 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 <watcher@example.com>"])
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# Within the mailer method, you have access to the following methods:
|
||||
#
|
||||
# * <tt>attachments[]=</tt> - Allows you to add attachments to your email in an intuitive
|
||||
# manner; <tt>attachments['filename.png'] = File.read('path/to/filename.png')</tt>
|
||||
#
|
||||
# Mailer methods have the following configuration methods available.
|
||||
# * <tt>headers[]=</tt> - Allows you to specify non standard headers in your email such
|
||||
# as <tt>headers['X-No-Spam'] = 'True'</tt>
|
||||
#
|
||||
# * <tt>recipients</tt> - Takes one or more email addresses. These addresses are where your email will be delivered to. Sets the <tt>To:</tt> header.
|
||||
# * <tt>subject</tt> - The subject of your email. Sets the <tt>Subject:</tt> header.
|
||||
# * <tt>from</tt> - Who the email you are sending is from. Sets the <tt>From:</tt> header.
|
||||
# * <tt>cc</tt> - Takes one or more email addresses. These addresses will receive a carbon copy of your email. Sets the <tt>Cc:</tt> header.
|
||||
# * <tt>bcc</tt> - Takes one or more email addresses. These addresses will receive a blind carbon copy of your email. Sets the <tt>Bcc:</tt> header.
|
||||
# * <tt>reply_to</tt> - Takes one or more email addresses. These addresses will be listed as the default recipients when replying to your email. Sets the <tt>Reply-To:</tt> header.
|
||||
# * <tt>sent_on</tt> - The date on which the message was sent. If not set, the header will be set by the delivery agent.
|
||||
# * <tt>content_type</tt> - Specify the content type of the message. Defaults to <tt>text/plain</tt>.
|
||||
# * <tt>headers</tt> - Specify additional headers to be set for the message, e.g. <tt>headers 'X-Mail-Count' => 107370</tt>.
|
||||
# * <tt>mail</tt> - 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 <tt>Subject</tt>, <tt>To</tt>, <tt>From</tt>, <tt>Cc</tt>, <tt>Bcc</tt>,
|
||||
# <tt>Reply-To</tt> and <tt>Date</tt>. See the <tt>ActionMailer#mail</tt> method for more details.
|
||||
#
|
||||
# If you need other headers not listed above, use the <tt>headers['name'] = value</tt> method.
|
||||
#
|
||||
# When a <tt>headers 'return-path'</tt> 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 <tt>from</tt>.
|
||||
# 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/alternative+ email.
|
||||
#
|
||||
# If you want to explicitly render only certain templates, pass a block:
|
||||
#
|
||||
# mail(:to => user.emai) do |format|
|
||||
# format.text
|
||||
# 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 method of the class looks for a template with its name.
|
||||
# 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/signup_notification.erb</tt> 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 <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/signup_notification.text.erb</tt> would be used to generate the email.
|
||||
#
|
||||
# Variables defined in the model are accessible as instance variables in the view.
|
||||
#
|
||||
|
@ -64,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) %>
|
||||
#
|
||||
#
|
||||
|
@ -106,54 +136,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)
|
||||
# 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, your delivery instance
|
||||
# methods are automatically wrapped in class methods that start with the word
|
||||
# <tt>deliver_</tt> followed by the name of the mailer method that you would
|
||||
# like to deliver. The <tt>signup_notification</tt> method defined above is
|
||||
# delivered by invoking <tt>Notifier.deliver_signup_notification</tt>.
|
||||
# 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 <tt>.erb</tt> 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
|
||||
|
@ -163,13 +152,12 @@ 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 <tt>multipart/alternative</tt>, 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 <tt>multipart/alternative</tt>,
|
||||
# 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
|
||||
|
@ -177,32 +165,30 @@ 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 <tt>.text.erb</tt> and <tt>.html.erb</tt> tempalte in the view
|
||||
# directory), send a complete <tt>multipart/mixed</tt> email with two parts, the first part being
|
||||
# a <tt>multipart/alternative</tt> with the text and HTML email parts inside, and the second being
|
||||
# a <tt>application/pdf</tt> 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 <tt>ActionMailer::Base.template_root = "/my/templates"</tt>
|
||||
#
|
||||
# * <tt>template_root</tt> - Determines the base from which template references will be made.
|
||||
# * <tt>delivers_from</tt> - 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 <tt>:from => 'another@address'</tt> in
|
||||
# the +mail+ method.
|
||||
#
|
||||
# * <tt>logger</tt> - 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.
|
||||
|
@ -251,8 +237,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
|
||||
include Quoting
|
||||
extend AdvAttrAccessor
|
||||
include DeliveryMethods, Quoting
|
||||
abstract!
|
||||
|
||||
include AbstractController::Logger
|
||||
include AbstractController::Rendering
|
||||
|
@ -262,27 +248,23 @@ module ActionMailer #:nodoc:
|
|||
include AbstractController::UrlFor
|
||||
|
||||
helper ActionMailer::MailHelper
|
||||
include ActionMailer::DeprecatedBody
|
||||
|
||||
include ActionMailer::OldApi
|
||||
include ActionMailer::DeprecatedApi
|
||||
|
||||
private_class_method :new #:nodoc:
|
||||
|
||||
@@raise_delivery_errors = true
|
||||
cattr_accessor :raise_delivery_errors
|
||||
extlib_inheritable_accessor :default_from
|
||||
self.default_from = nil
|
||||
|
||||
@@perform_deliveries = true
|
||||
cattr_accessor :perform_deliveries
|
||||
extlib_inheritable_accessor :default_charset
|
||||
self.default_charset = "utf-8"
|
||||
|
||||
@@deliveries = []
|
||||
cattr_accessor :deliveries
|
||||
extlib_inheritable_accessor :default_content_type
|
||||
self.default_content_type = "text/plain"
|
||||
|
||||
@@default_charset = "utf-8"
|
||||
cattr_accessor :default_charset
|
||||
|
||||
@@default_content_type = "text/plain"
|
||||
cattr_accessor :default_content_type
|
||||
|
||||
@@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
|
||||
|
@ -290,101 +272,20 @@ 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
|
||||
|
||||
@@protected_instance_variables = %w(@parts @mail)
|
||||
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 <tt>text/plain</tt>
|
||||
# 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
|
||||
attr_reader :mail
|
||||
|
||||
# Alias controller_path to mailer_name so render :partial in views work.
|
||||
alias :controller_path :mailer_name
|
||||
extlib_inheritable_accessor :default_implicit_parts_order
|
||||
self.default_implicit_parts_order = [ "text/plain", "text/enriched", "text/html" ]
|
||||
|
||||
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
|
||||
attr_writer :mailer_name
|
||||
alias :controller_path :mailer_name
|
||||
|
||||
def delivery_method=(method_name)
|
||||
@delivery_method = ActionMailer::DeliveryMethod.lookup_method(method_name)
|
||||
end
|
||||
|
||||
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).mail
|
||||
when 'deliver' then new(match[2], *parameters).deliver!
|
||||
when 'new' then nil
|
||||
else super
|
||||
end
|
||||
else
|
||||
super
|
||||
end
|
||||
# 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,
|
||||
|
@ -406,26 +307,24 @@ 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)
|
||||
new.deliver!(mail)
|
||||
# Delivers a mail object. This is actually called by the <tt>Mail::Message</tt> object
|
||||
# itself through a call back when you call <tt>:deliver</tt> 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)
|
||||
yield # Let Mail do the delivery actions
|
||||
end
|
||||
end
|
||||
|
||||
def template_root
|
||||
self.view_paths && self.view_paths.first
|
||||
def respond_to?(method, *args) #:nodoc:
|
||||
super || action_methods.include?(method.to_s)
|
||||
end
|
||||
|
||||
# Should template root overwrite the whole view_paths?
|
||||
def template_root=(root)
|
||||
self.view_paths = ActionView::Base.process_view_paths(root)
|
||||
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
|
||||
|
@ -436,229 +335,264 @@ module ActionMailer #:nodoc:
|
|||
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
|
||||
|
||||
# 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.
|
||||
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
|
||||
|
||||
# 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) }
|
||||
def method_missing(method, *args) #:nodoc:
|
||||
if action_methods.include?(method.to_s)
|
||||
new(method, *args).message
|
||||
else
|
||||
super
|
||||
end
|
||||
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
|
||||
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
|
||||
|
||||
# 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
|
||||
# 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]
|
||||
@headers = args
|
||||
else
|
||||
@_message
|
||||
end
|
||||
end
|
||||
|
||||
# Delivers a Mail object. By default, it delivers the cached mail
|
||||
# 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
|
||||
|
||||
ActiveSupport::Notifications.instrument("action_mailer.deliver",
|
||||
:template => template, :mailer => self.class.name) do |payload|
|
||||
|
||||
self.class.set_payload_for_mail(payload, mail)
|
||||
|
||||
begin
|
||||
self.delivery_method.perform_delivery(mail) if perform_deliveries
|
||||
rescue Exception => e # Net::SMTP errors or sendmail pipe errors
|
||||
raise e if raise_delivery_errors
|
||||
end
|
||||
end
|
||||
|
||||
mail
|
||||
# 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
|
||||
|
||||
private
|
||||
# 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:
|
||||
#
|
||||
# * <tt>:subject</tt> - The subject of the message, if this is omitted, ActionMailer will
|
||||
# ask the Rails I18n class for a translated <tt>:subject</tt> in the scope of
|
||||
# <tt>[:actionmailer, mailer_scope, action_name]</tt> or if this is missing, will translate the
|
||||
# humanized version of the <tt>action_name</tt>
|
||||
# * <tt>:to</tt> - Who the message is destined for, can be a string of addresses, or an array
|
||||
# of addresses.
|
||||
# * <tt>:from</tt> - Who the message is from, if missing, will use the <tt>:delivers_from</tt>
|
||||
# value in the class (if it exists)
|
||||
# * <tt>:cc</tt> - Who you would like to Carbon-Copy on this email, can be a string of addresses,
|
||||
# or an array of addresses.
|
||||
# * <tt>:bcc</tt> - Who you would like to Blind-Carbon-Copy on this email, can be a string of
|
||||
# addresses, or an array of addresses.
|
||||
# * <tt>:reply_to</tt> - Who to set the Reply-To header of the email to.
|
||||
# * <tt>:date</tt> - The date to say the email was sent on.
|
||||
#
|
||||
# If you need other headers not listed above, use the <tt>headers['name'] = value</tt> method.
|
||||
#
|
||||
# When a <tt>:return_path</tt> 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 <tt>:from</tt>. Mail will actually use the
|
||||
# <tt>:return_path</tt> in preference to the <tt>:sender</tt> in preference to the <tt>:from</tt>
|
||||
# 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 <tt>:deliver</tt> 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 => "<h1>Hello Mikel!</h1>" }
|
||||
# end
|
||||
#
|
||||
# Which will render a <tt>multipart/alternative</tt> email with <tt>text/plain</tt> and
|
||||
# <tt>text/html</tt> 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
|
||||
@mail_was_called = true
|
||||
m = @_message
|
||||
|
||||
# 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
|
||||
# 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 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
|
||||
# Set fields quotings
|
||||
headers[:subject] ||= default_subject
|
||||
headers[:from] ||= self.class.default_from.dup
|
||||
quote_fields!(headers, charset)
|
||||
|
||||
@mailer_name ||= self.class.mailer_name.dup
|
||||
@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
|
||||
# Render the templates and blocks
|
||||
responses, sort_order = collect_responses_and_sort_order(headers, &block)
|
||||
|
||||
def split_content_type(ct) #:nodoc:
|
||||
ct.to_s.split("/")
|
||||
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)
|
||||
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
|
||||
|
||||
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)]
|
||||
# Finaly set delivery behavior configured in class
|
||||
wrap_delivery_behavior!(headers[:delivery_method])
|
||||
m
|
||||
end
|
||||
|
||||
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)
|
||||
end
|
||||
|
||||
# TODO: Move this into Mail
|
||||
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
|
||||
each_template do |template|
|
||||
responses << {
|
||||
:body => render_to_body(:_template => template),
|
||||
:content_type => template.mime_type.to_s
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
[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)
|
||||
templates = templates.uniq_by { |t| t.details[:formats] }
|
||||
|
||||
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?
|
||||
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
|
||||
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
|
||||
end
|
||||
|
||||
def insert_part(container, response, charset) #:nodoc:
|
||||
response[:charset] ||= charset
|
||||
part = Mail::Part.new(response)
|
||||
container.add_part(part)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
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_reader :responses
|
||||
|
||||
def initialize(context, &block)
|
||||
@context = context
|
||||
@responses = []
|
||||
@default_render = block
|
||||
@default_formats = context.formats
|
||||
end
|
||||
|
||||
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.dup, &block) }
|
||||
end
|
||||
alias :all :any
|
||||
|
||||
def custom(mime, options={}, &block)
|
||||
options.reverse_merge!(:content_type => mime.to_s)
|
||||
@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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,87 @@
|
|||
require 'tmpdir'
|
||||
|
||||
module 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
|
||||
|
||||
included do
|
||||
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
|
||||
|
||||
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
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
# 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:
|
||||
#
|
||||
# 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
|
||||
|
||||
send(:"#{symbol}_settings=", default_options)
|
||||
self.delivery_methods[symbol.to_sym] = klass
|
||||
end
|
||||
|
||||
def wrap_delivery_behavior(mail, method=nil) #:nodoc:
|
||||
method ||= self.delivery_method
|
||||
mail.delivery_handler = self
|
||||
|
||||
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
|
||||
mail.delivery_method(method)
|
||||
end
|
||||
|
||||
mail.perform_deliveries = perform_deliveries
|
||||
mail.raise_delivery_errors = raise_delivery_errors
|
||||
end
|
||||
end
|
||||
|
||||
def wrap_delivery_behavior!(*args) #:nodoc:
|
||||
self.class.wrap_delivery_behavior(message, *args)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,112 @@
|
|||
module ActionMailer
|
||||
# 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
|
||||
|
||||
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, show_warning=true)
|
||||
if show_warning
|
||||
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
|
||||
wrap_delivery_behavior(mail)
|
||||
mail.deliver
|
||||
mail
|
||||
end
|
||||
|
||||
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)
|
||||
if match = matches_dynamic_method?(method_symbol)
|
||||
case match[1]
|
||||
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).message.deliver
|
||||
else super
|
||||
end
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
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
|
||||
end
|
||||
|
||||
# Delivers a Mail object. By default, it delivers the cached mail
|
||||
# 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 = @_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!
|
||||
|
||||
def render(*args)
|
||||
options = args.last.is_a?(Hash) ? args.last : {}
|
||||
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
|
||||
|
||||
# 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(*args)
|
||||
ActiveSupport::Deprecation.warn "render_message is deprecated, use render instead", caller[0,2]
|
||||
render(*args)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
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
|
||||
|
||||
end
|
||||
end
|
|
@ -1,46 +0,0 @@
|
|||
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.
|
||||
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[: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)
|
||||
end
|
||||
end
|
||||
|
||||
def create_parts
|
||||
if String === @body && !defined?(@assigns_set)
|
||||
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
|
||||
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
|
|
@ -17,8 +17,13 @@ module ActionMailer
|
|||
end
|
||||
|
||||
# Access the mailer instance.
|
||||
def mailer #:nodoc:
|
||||
def mailer
|
||||
@_controller
|
||||
end
|
||||
|
||||
# Access the message instance.
|
||||
def message
|
||||
@_message
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,250 @@
|
|||
module ActionMailer
|
||||
module OldApi #: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 <tt>text/plain</tt>
|
||||
# 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
|
||||
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)
|
||||
@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
|
||||
if String === @body
|
||||
self.response_body = @body
|
||||
end
|
||||
|
||||
if String === response_body
|
||||
@parts.unshift create_inline_part(response_body)
|
||||
else
|
||||
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
|
||||
|
||||
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)
|
||||
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)
|
||||
ct.to_s.split("/")
|
||||
end
|
||||
|
||||
def parse_content_type(defaults=nil)
|
||||
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
|
|
@ -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
|
||||
|
|
|
@ -58,7 +58,6 @@ module ActionMailer
|
|||
end
|
||||
end
|
||||
|
||||
# TODO: Deprecate this
|
||||
module Test
|
||||
module Unit
|
||||
class TestCase
|
||||
|
|
|
@ -2,19 +2,27 @@ 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,2])
|
||||
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,2])
|
||||
content_transfer_encoding(value)
|
||||
else
|
||||
old_transfer_encoding
|
||||
end
|
||||
end
|
||||
|
||||
def original_filename
|
||||
ActiveSupport::Deprecation.warn('Message#original_filename is deprecated, ' <<
|
||||
'please call Message#filename', caller[0,2])
|
||||
filename
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -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,14 +17,10 @@ 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' }
|
||||
FIXTURE_LOAD_PATH = File.expand_path('fixtures', File.dirname(__FILE__))
|
||||
ActionMailer::Base.view_paths = FIXTURE_LOAD_PATH
|
||||
|
||||
$:.unshift "#{File.dirname(__FILE__)}/fixtures/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
|
||||
|
@ -49,19 +44,11 @@ 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(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
|
||||
ActionMailer::Base.delivery_method = @old_delivery_method
|
||||
end
|
||||
end
|
|
@ -0,0 +1,420 @@
|
|||
# encoding: utf-8
|
||||
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
|
||||
delivers_from 'jose@test.plataformatec.com'
|
||||
self.mailer_name = "base_mailer"
|
||||
|
||||
def welcome(hash = {})
|
||||
headers['X-SPAM'] = "Not SPAM"
|
||||
mail(DEFAULT_HEADERS.merge(hash))
|
||||
end
|
||||
|
||||
def attachment_with_content(hash = {})
|
||||
attachments['invoice.pdf'] = 'This is test File content'
|
||||
mail(DEFAULT_HEADERS.merge(hash))
|
||||
end
|
||||
|
||||
def attachment_with_hash
|
||||
attachments['invoice.jpg'] = { :data => "you smiling", :mime_type => "image/x-jpg",
|
||||
:transfer_encoding => "base64" }
|
||||
mail(DEFAULT_HEADERS)
|
||||
end
|
||||
|
||||
def implicit_multipart(hash = {})
|
||||
attachments['invoice.pdf'] = 'This is test File content' if hash.delete(:attachments)
|
||||
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|
|
||||
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|
|
||||
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
|
||||
|
||||
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
|
||||
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.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!')
|
||||
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',
|
||||
: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')
|
||||
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
|
||||
|
||||
test "mail() renders the template using the method being processed" do
|
||||
email = BaseMailer.welcome.deliver
|
||||
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
|
||||
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
|
||||
assert_equal("Not SPAM", email['X-SPAM'].decoded)
|
||||
end
|
||||
|
||||
# Attachments
|
||||
test "attachment with content" do
|
||||
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.attachment_with_content.deliver
|
||||
assert_equal('invoice.pdf', email.attachments[0].filename)
|
||||
end
|
||||
|
||||
test "attachment with hash" do
|
||||
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.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.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)
|
||||
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.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)
|
||||
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
|
||||
email = BaseMailer.welcome.deliver
|
||||
assert_equal("US-ASCII", email.charset)
|
||||
|
||||
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.welcome.deliver
|
||||
assert_equal("text/html", email.mime_type)
|
||||
|
||||
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.welcome.deliver
|
||||
assert_equal("2.0", email.mime_version)
|
||||
|
||||
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.welcome(:subject => nil).deliver
|
||||
assert_equal "Welcome", email.subject
|
||||
|
||||
I18n.backend.store_translations('en', :actionmailer => {:base_mailer => {:welcome => {:subject => "New Subject!"}}})
|
||||
email = BaseMailer.welcome(:subject => nil).deliver
|
||||
assert_equal "New Subject!", email.subject
|
||||
end
|
||||
|
||||
# Implicit multipart
|
||||
test "implicit multipart" do
|
||||
email = BaseMailer.implicit_multipart.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("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 with sort order" do
|
||||
order = ["text/html", "text/plain"]
|
||||
swap BaseMailer, :default_implicit_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)
|
||||
|
||||
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.implicit_multipart(:attachments => true).deliver
|
||||
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)
|
||||
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 "implicit multipart with attachments and sort order" do
|
||||
order = ["text/html", "text/plain"]
|
||||
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/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
|
||||
end
|
||||
|
||||
test "implicit multipart with default locale" do
|
||||
email = BaseMailer.implicit_with_locale.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("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/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)
|
||||
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
|
||||
assert_equal(2, email.parts.size)
|
||||
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)
|
||||
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.explicit_multipart.deliver
|
||||
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
|
||||
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
|
||||
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)
|
||||
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
|
||||
|
||||
test "explicit multipart with templates" do
|
||||
email = BaseMailer.explicit_multipart_templates.deliver
|
||||
assert_equal(2, email.parts.size)
|
||||
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)
|
||||
assert_equal("TEXT Explicit Multipart Templates", email.parts[1].body.encoded)
|
||||
end
|
||||
|
||||
test "explicit multipart with any" do
|
||||
email = BaseMailer.explicit_multipart_with_any.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("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
|
||||
|
||||
test "explicit multipart with options" do
|
||||
email = BaseMailer.custom_block(true).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("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)
|
||||
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
|
||||
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(: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
|
||||
|
||||
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
|
||||
|
||||
test "explicit multipart should be multipart" do
|
||||
mail = BaseMailer.explicit_multipart
|
||||
assert_not_nil(mail.content_type_parameters[:boundary])
|
||||
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
|
|
@ -1,101 +0,0 @@
|
|||
require 'abstract_unit'
|
||||
|
||||
class DefaultDeliveryMethodMailer < ActionMailer::Base
|
||||
end
|
||||
|
||||
class NonDefaultDeliveryMethodMailer < ActionMailer::Base
|
||||
self.delivery_method = :sendmail
|
||||
end
|
||||
|
||||
class FileDeliveryMethodMailer < ActionMailer::Base
|
||||
self.delivery_method = :file
|
||||
end
|
||||
|
||||
class CustomDeliveryMethod
|
||||
attr_accessor :custom_deliveries
|
||||
def initialize()
|
||||
@customer_deliveries = []
|
||||
end
|
||||
|
||||
def self.perform_delivery(mail)
|
||||
self.custom_deliveries << mail
|
||||
end
|
||||
end
|
||||
|
||||
class CustomerDeliveryMailer < ActionMailer::Base
|
||||
self.delivery_method = CustomDeliveryMethod.new
|
||||
end
|
||||
|
||||
class ActionMailerBase_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_instance_of ActionMailer::DeliveryMethod::Smtp, ActionMailer::Base.delivery_method
|
||||
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_instance_of ActionMailer::DeliveryMethod::Smtp, DefaultDeliveryMethodMailer.delivery_method
|
||||
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_instance_of ActionMailer::DeliveryMethod::Sendmail, NonDefaultDeliveryMethodMailer.delivery_method
|
||||
end
|
||||
end
|
||||
|
||||
class FileDeliveryMethodMailer_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_instance_of ActionMailer::DeliveryMethod::File, FileDeliveryMethodMailer.delivery_method
|
||||
end
|
||||
|
||||
def test_should_default_location_to_the_tmpdir
|
||||
assert_equal "#{Dir.tmpdir}/mails", ActionMailer::Base.file_settings[:location]
|
||||
end
|
||||
end
|
||||
|
||||
class CustomDeliveryMethodMailer_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_instance_of CustomDeliveryMethod, CustomerDeliveryMailer.delivery_method
|
||||
end
|
||||
end
|
|
@ -0,0 +1,170 @@
|
|||
require 'abstract_unit'
|
||||
require 'mail'
|
||||
|
||||
class MyCustomDelivery
|
||||
end
|
||||
|
||||
class BogusDelivery
|
||||
def initialize(*)
|
||||
end
|
||||
|
||||
def deliver!(mail)
|
||||
raise "failed"
|
||||
end
|
||||
end
|
||||
|
||||
class DefaultsDeliveryMethodsTest < ActiveSupport::TestCase
|
||||
test "default smtp settings" do
|
||||
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
|
||||
|
||||
test "default file delivery settings" do
|
||||
settings = {:location => "#{Dir.tmpdir}/mails"}
|
||||
assert_equal settings, ActionMailer::Base.file_settings
|
||||
end
|
||||
|
||||
test "default sendmail settings" do
|
||||
settings = {:location => '/usr/sbin/sendmail',
|
||||
:arguments => '-i -t'}
|
||||
assert_equal settings, ActionMailer::Base.sendmail_settings
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
test "allow to add custom delivery method" do
|
||||
ActionMailer::Base.delivery_method = :custom
|
||||
assert_equal :custom, ActionMailer::Base.delivery_method
|
||||
end
|
||||
|
||||
test "allow to customize custom settings" do
|
||||
ActionMailer::Base.custom_settings = { :foo => :bar }
|
||||
assert_equal Hash[:foo => :bar], ActionMailer::Base.custom_settings
|
||||
end
|
||||
|
||||
test "respond to custom settings" do
|
||||
assert_respond_to ActionMailer::Base, :custom_settings
|
||||
assert_respond_to ActionMailer::Base, :custom_settings=
|
||||
end
|
||||
|
||||
test "does not respond to unknown settings" do
|
||||
assert_raise NoMethodError do
|
||||
ActionMailer::Base.another_settings
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class MailDeliveryTest < ActiveSupport::TestCase
|
||||
class DeliveryMailer < 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
|
||||
DeliveryMailer.delivery_method = :smtp
|
||||
DeliveryMailer.perform_deliveries = true
|
||||
DeliveryMailer.raise_delivery_errors = true
|
||||
end
|
||||
|
||||
test "ActionMailer should be told when Mail gets delivered" do
|
||||
DeliveryMailer.deliveries.clear
|
||||
DeliveryMailer.expects(:deliver_mail).once
|
||||
DeliveryMailer.welcome.deliver
|
||||
end
|
||||
|
||||
test "delivery method can be customized per instance" do
|
||||
email = DeliveryMailer.welcome.deliver
|
||||
assert_instance_of Mail::SMTP, email.delivery_method
|
||||
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
|
||||
DeliveryMailer.delivery_method = :test
|
||||
assert_equal :smtp, ActionMailer::Base.delivery_method
|
||||
$BREAK = true
|
||||
email = DeliveryMailer.welcome.deliver
|
||||
assert_instance_of Mail::TestMailer, email.delivery_method
|
||||
end
|
||||
|
||||
test "non registered delivery methods raises errors" do
|
||||
DeliveryMailer.delivery_method = :unknown
|
||||
assert_raise RuntimeError do
|
||||
DeliveryMailer.welcome.deliver
|
||||
end
|
||||
end
|
||||
|
||||
test "does not perform deliveries if requested" do
|
||||
DeliveryMailer.perform_deliveries = false
|
||||
DeliveryMailer.deliveries.clear
|
||||
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
|
||||
|
||||
test "raise errors on bogus deliveries" do
|
||||
DeliveryMailer.delivery_method = BogusDelivery
|
||||
DeliveryMailer.deliveries.clear
|
||||
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
|
||||
assert_equal(0, DeliveryMailer.deliveries.length)
|
||||
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 "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(0, DeliveryMailer.deliveries.length)
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1 @@
|
|||
Welcome from another path
|
|
@ -0,0 +1 @@
|
|||
Attachment with content
|
|
@ -0,0 +1 @@
|
|||
HTML Explicit Multipart Templates
|
|
@ -0,0 +1 @@
|
|||
TEXT Explicit Multipart Templates
|
|
@ -0,0 +1 @@
|
|||
HTML Implicit Multipart
|
|
@ -0,0 +1 @@
|
|||
TEXT Implicit Multipart
|
|
@ -0,0 +1 @@
|
|||
Implicit with locale EN HTML
|
|
@ -0,0 +1 @@
|
|||
Implicit with locale HTML
|
|
@ -0,0 +1 @@
|
|||
Implicit with locale PL TEXT
|
|
@ -0,0 +1 @@
|
|||
Implicit with locale TEXT
|
|
@ -0,0 +1 @@
|
|||
Welcome
|
|
@ -1 +0,0 @@
|
|||
So, <%= example_format(@text) %>
|
|
@ -1 +0,0 @@
|
|||
Hello, <%= person_name %>. Thanks for registering!
|
|
@ -1 +0,0 @@
|
|||
This message brought to you by <%= name_of_the_mailer_class %>.
|
|
@ -1,5 +0,0 @@
|
|||
From "Romeo and Juliet":
|
||||
|
||||
<%= block_format @text %>
|
||||
|
||||
Good ol' Shakespeare.
|
|
@ -1,5 +0,0 @@
|
|||
module ExampleHelper
|
||||
def example_format(text)
|
||||
"<em><strong><small>#{h(text)}</small></strong></em>".html_safe!
|
||||
end
|
||||
end
|
|
@ -1,2 +0,0 @@
|
|||
body: <%= @body %>
|
||||
bar: <%= @bar %>
|
|
@ -1,96 +1,54 @@
|
|||
require 'abstract_unit'
|
||||
|
||||
module MailerHelper
|
||||
def person_name
|
||||
"Mr. Joe Person"
|
||||
end
|
||||
end
|
||||
|
||||
class HelperMailer < ActionMailer::Base
|
||||
helper MailerHelper
|
||||
helper :example
|
||||
|
||||
def use_helper(recipient)
|
||||
recipients recipient
|
||||
subject "using helpers"
|
||||
from "tester@example.com"
|
||||
end
|
||||
|
||||
def use_example_helper(recipient)
|
||||
recipients recipient
|
||||
subject "using helpers"
|
||||
from "tester@example.com"
|
||||
|
||||
@text = "emphasize me!"
|
||||
end
|
||||
|
||||
def use_mail_helper(recipient)
|
||||
recipients recipient
|
||||
subject "using mailing helpers"
|
||||
from "tester@example.com"
|
||||
|
||||
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!"
|
||||
end
|
||||
|
||||
def use_helper_method(recipient)
|
||||
recipients recipient
|
||||
subject "using helpers"
|
||||
from "tester@example.com"
|
||||
|
||||
@text = "emphasize me!"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def name_of_the_mailer_class
|
||||
self.class.name
|
||||
mail_with_defaults do |format|
|
||||
format.html { render(:inline => "<%= block_format @text %>") }
|
||||
end
|
||||
helper_method :name_of_the_mailer_class
|
||||
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 < Test::Unit::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 = []
|
||||
|
||||
@recipient = 'test@localhost'
|
||||
end
|
||||
|
||||
def teardown
|
||||
restore_delivery_method
|
||||
end
|
||||
|
||||
def test_use_helper
|
||||
mail = HelperMailer.create_use_helper(@recipient)
|
||||
assert_match %r{Mr. Joe Person}, mail.encoded
|
||||
end
|
||||
|
||||
def test_use_example_helper
|
||||
mail = HelperMailer.create_use_example_helper(@recipient)
|
||||
assert_match %r{<em><strong><small>emphasize me!}, mail.encoded
|
||||
end
|
||||
|
||||
def test_use_helper_method
|
||||
mail = HelperMailer.create_use_helper_method(@recipient)
|
||||
assert_match %r{HelperMailer}, mail.encoded
|
||||
end
|
||||
|
||||
class MailerHelperTest < ActionMailer::TestCase
|
||||
def test_use_mail_helper
|
||||
mail = HelperMailer.create_use_mail_helper(@recipient)
|
||||
assert_match %r{ But soft!}, mail.encoded
|
||||
assert_match %r{east, and\r\n Juliet}, mail.encoded
|
||||
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
|
||||
|
||||
|
|
|
@ -1,24 +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
|
||||
# CHANGED: body returns object, not string, Changed m.body to m.body.to_s
|
||||
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
|
|
@ -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
|
||||
|
@ -12,9 +12,7 @@ class AssetHostTest < Test::Unit::TestCase
|
|||
def setup
|
||||
set_delivery_method :test
|
||||
ActionMailer::Base.perform_deliveries = true
|
||||
ActionMailer::Base.deliveries = []
|
||||
|
||||
@recipient = 'test@localhost'
|
||||
ActionMailer::Base.deliveries.clear
|
||||
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 "<img alt=\"Somelogo\" src=\"http://www.example.com/images/somelogo.png\" />", 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 "<img alt=\"Somelogo\" src=\"http://images.example.com/images/somelogo.png\" />", 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 "<img alt=\"Somelogo\" src=\"http://www.example.com/images/somelogo.png\" />", mail.body.to_s.strip
|
||||
end
|
||||
end
|
|
@ -1,14 +1,15 @@
|
|||
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"
|
||||
|
||||
|
@ -16,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"
|
||||
|
||||
|
@ -25,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"
|
||||
|
||||
|
@ -37,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
|
||||
|
@ -54,9 +55,7 @@ class LayoutMailerTest < Test::Unit::TestCase
|
|||
def setup
|
||||
set_delivery_method :test
|
||||
ActionMailer::Base.perform_deliveries = true
|
||||
ActionMailer::Base.deliveries = []
|
||||
|
||||
@recipient = 'test@localhost'
|
||||
ActionMailer::Base.deliveries.clear
|
||||
end
|
||||
|
||||
def teardown
|
||||
|
@ -64,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
|
||||
|
@ -93,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
|
||||
|
@ -115,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
|
||||
|
||||
|
@ -128,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
|
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<test/>", 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
|
||||
|
@ -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
|
||||
|
@ -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
|
|
@ -2,7 +2,7 @@
|
|||
require 'abstract_unit'
|
||||
|
||||
class FunkyPathMailer < ActionMailer::Base
|
||||
self.template_root = "#{File.dirname(__FILE__)}/fixtures/path.with.dots"
|
||||
self.view_paths = "#{File.dirname(__FILE__)}/../fixtures/path.with.dots"
|
||||
|
||||
def multipart_with_template_path_with_dots(recipient)
|
||||
recipients recipient
|
||||
|
@ -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,17 +297,10 @@ 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
|
||||
|
||||
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"
|
||||
|
@ -344,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'
|
||||
|
@ -357,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
|
||||
|
||||
|
@ -373,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
|
||||
|
@ -389,11 +382,13 @@ 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 == "<test@test.com>" }
|
||||
end
|
||||
|
||||
def test_signed_up
|
||||
TestMailer.delivery_method = :test
|
||||
|
||||
Time.stubs(:now => Time.now)
|
||||
|
||||
expected = new_mail
|
||||
|
@ -404,7 +399,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>'
|
||||
|
@ -412,7 +407,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
|
||||
|
@ -423,15 +418,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
|
||||
|
@ -441,7 +427,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>'
|
||||
|
@ -464,7 +450,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
|
||||
|
@ -480,13 +466,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>'
|
||||
|
@ -507,7 +493,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>'
|
||||
|
@ -515,7 +501,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
|
||||
|
@ -527,8 +513,8 @@ class ActionMailerTest < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_from_without_name_for_smtp
|
||||
ActionMailer::Base.delivery_method = :smtp
|
||||
TestMailer.deliver_from_without_name
|
||||
TestMailer.delivery_method = :smtp
|
||||
TestMailer.from_without_name.deliver
|
||||
|
||||
mail = MockSMTP.deliveries.first
|
||||
assert_not_nil mail
|
||||
|
@ -538,17 +524,19 @@ class ActionMailerTest < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_from_with_name_for_smtp
|
||||
ActionMailer::Base.delivery_method = :smtp
|
||||
TestMailer.deliver_from_with_name
|
||||
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.addresses.first
|
||||
assert_equal 'system@loudthinking.com', from
|
||||
end
|
||||
|
||||
def test_reply_to
|
||||
TestMailer.delivery_method = :test
|
||||
|
||||
expected = new_mail
|
||||
|
||||
expected.to = @recipient
|
||||
|
@ -560,7 +548,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
|
||||
|
||||
|
@ -570,7 +558,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
|
||||
|
@ -583,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"
|
||||
|
@ -594,7 +584,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
|
||||
|
||||
|
@ -604,7 +594,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
|
||||
|
@ -617,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"
|
||||
|
@ -628,7 +619,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
|
||||
|
||||
|
@ -638,7 +629,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
|
||||
|
@ -650,41 +641,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
|
||||
TestMailer.delivery_method.expects(:perform_delivery).raises(Exception)
|
||||
assert_nothing_raised { TestMailer.deliver_signed_up(@recipient) }
|
||||
Mail::TestMailer.any_instance.expects(:deliver!).raises(Exception)
|
||||
assert_nothing_raised { TestMailer.signed_up(@recipient).deliver }
|
||||
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
|
||||
TestMailer.deliver_signed_up(@recipient)
|
||||
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
|
||||
|
@ -769,7 +752,7 @@ EOF
|
|||
|
||||
created = nil
|
||||
assert_nothing_raised do
|
||||
created = TestMailer.create_extended_headers @recipient
|
||||
created = TestMailer.extended_headers @recipient
|
||||
end
|
||||
|
||||
assert_not_nil created
|
||||
|
@ -779,7 +762,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
|
||||
|
@ -802,7 +785,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
|
||||
|
||||
|
@ -817,82 +800,82 @@ 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_.*?\?= <extended@example.net>\r/, created.encoded)
|
||||
assert_match(/\nTo: =\?utf-8\?Q\?Foo_.*?\?= <extended@example.net>, \r\n\tExample Recipient <me/, created.encoded)
|
||||
end
|
||||
|
||||
def test_receive_decodes_base64_encoded_mail
|
||||
fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email")
|
||||
fixture = File.read(File.dirname(__FILE__) + "/../fixtures/raw_email")
|
||||
TestMailer.receive(fixture)
|
||||
assert_match(/Jamis/, TestMailer.received_body.to_s)
|
||||
end
|
||||
|
||||
def test_receive_attachments
|
||||
fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email2")
|
||||
fixture = File.read(File.dirname(__FILE__) + "/../fixtures/raw_email2")
|
||||
mail = Mail.new(fixture)
|
||||
attachment = mail.attachments.last
|
||||
assert_equal "smime.p7s", attachment.original_filename
|
||||
assert_equal "smime.p7s", attachment.filename
|
||||
assert_equal "application/pkcs7-signature", mail.parts.last.mime_type
|
||||
end
|
||||
|
||||
def test_decode_attachment_without_charset
|
||||
fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email3")
|
||||
fixture = File.read(File.dirname(__FILE__) + "/../fixtures/raw_email3")
|
||||
mail = Mail.new(fixture)
|
||||
attachment = mail.attachments.last
|
||||
assert_equal 1026, attachment.read.length
|
||||
end
|
||||
|
||||
def test_attachment_using_content_location
|
||||
fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email12")
|
||||
fixture = File.read(File.dirname(__FILE__) + "/../fixtures/raw_email12")
|
||||
mail = Mail.new(fixture)
|
||||
assert_equal 1, mail.attachments.length
|
||||
assert_equal "Photo25.jpg", mail.attachments.first.original_filename
|
||||
assert_equal "Photo25.jpg", mail.attachments.first.filename
|
||||
end
|
||||
|
||||
def test_attachment_with_text_type
|
||||
fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email13")
|
||||
fixture = File.read(File.dirname(__FILE__) + "/../fixtures/raw_email13")
|
||||
mail = Mail.new(fixture)
|
||||
assert mail.has_attachments?
|
||||
assert_equal 1, mail.attachments.length
|
||||
assert_equal "hello.rb", mail.attachments.first.original_filename
|
||||
assert_equal "hello.rb", mail.attachments.first.filename
|
||||
end
|
||||
|
||||
def test_decode_part_without_content_type
|
||||
fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email4")
|
||||
fixture = File.read(File.dirname(__FILE__) + "/../fixtures/raw_email4")
|
||||
mail = Mail.new(fixture)
|
||||
assert_nothing_raised { mail.body }
|
||||
end
|
||||
|
||||
def test_decode_message_without_content_type
|
||||
fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email5")
|
||||
fixture = File.read(File.dirname(__FILE__) + "/../fixtures/raw_email5")
|
||||
mail = Mail.new(fixture)
|
||||
assert_nothing_raised { mail.body }
|
||||
end
|
||||
|
||||
def test_decode_message_with_incorrect_charset
|
||||
fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email6")
|
||||
fixture = File.read(File.dirname(__FILE__) + "/../fixtures/raw_email6")
|
||||
mail = Mail.new(fixture)
|
||||
assert_nothing_raised { mail.body }
|
||||
end
|
||||
|
||||
def test_multipart_with_mime_version
|
||||
mail = TestMailer.create_multipart_with_mime_version(@recipient)
|
||||
mail = TestMailer.multipart_with_mime_version(@recipient)
|
||||
assert_equal "1.1", mail.mime_version
|
||||
end
|
||||
|
||||
def test_multipart_with_utf8_subject
|
||||
mail = TestMailer.create_multipart_with_utf8_subject(@recipient)
|
||||
mail = TestMailer.multipart_with_utf8_subject(@recipient)
|
||||
assert_match(/\nSubject: =\?utf-8\?Q\?Foo_.*?\?=/, mail.encoded)
|
||||
end
|
||||
|
||||
def test_implicitly_multipart_with_utf8
|
||||
mail = TestMailer.create_implicitly_multipart_with_utf8
|
||||
mail = TestMailer.implicitly_multipart_with_utf8
|
||||
assert_match(/\nSubject: =\?utf-8\?Q\?Foo_.*?\?=/, mail.encoded)
|
||||
end
|
||||
|
||||
def test_explicitly_multipart_messages
|
||||
mail = TestMailer.create_explicitly_multipart_example(@recipient)
|
||||
mail = TestMailer.explicitly_multipart_example(@recipient)
|
||||
assert_equal 3, mail.parts.length
|
||||
assert_equal 'multipart/mixed', mail.mime_type
|
||||
assert_equal "text/plain", mail.parts[0].mime_type
|
||||
|
@ -901,6 +884,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
|
||||
|
@ -908,13 +892,13 @@ EOF
|
|||
end
|
||||
|
||||
def test_explicitly_multipart_with_content_type
|
||||
mail = TestMailer.create_explicitly_multipart_example(@recipient, "multipart/alternative")
|
||||
mail = TestMailer.explicitly_multipart_example(@recipient, "multipart/alternative")
|
||||
assert_equal 3, mail.parts.length
|
||||
assert_equal "multipart/alternative", mail.mime_type
|
||||
end
|
||||
|
||||
def test_explicitly_multipart_with_invalid_content_type
|
||||
mail = TestMailer.create_explicitly_multipart_example(@recipient, "text/xml")
|
||||
mail = TestMailer.explicitly_multipart_example(@recipient, "text/xml")
|
||||
assert_equal 3, mail.parts.length
|
||||
assert_equal 'multipart/mixed', mail.mime_type
|
||||
end
|
||||
|
@ -922,7 +906,7 @@ EOF
|
|||
def test_implicitly_multipart_messages
|
||||
assert ActionView::Template.template_handler_extensions.include?("bak"), "bak extension was not registered"
|
||||
|
||||
mail = TestMailer.create_implicitly_multipart_example(@recipient)
|
||||
mail = TestMailer.implicitly_multipart_example(@recipient)
|
||||
assert_equal 3, mail.parts.length
|
||||
assert_equal "1.0", mail.mime_version.to_s
|
||||
assert_equal "multipart/alternative", mail.mime_type
|
||||
|
@ -937,7 +921,7 @@ EOF
|
|||
def test_implicitly_multipart_messages_with_custom_order
|
||||
assert ActionView::Template.template_handler_extensions.include?("bak"), "bak extension was not registered"
|
||||
|
||||
mail = TestMailer.create_implicitly_multipart_example(@recipient, nil, ["application/x-yaml", "text/plain"])
|
||||
mail = TestMailer.implicitly_multipart_example(@recipient, nil, ["application/x-yaml", "text/plain"])
|
||||
assert_equal 3, mail.parts.length
|
||||
assert_equal "application/x-yaml", mail.parts[0].mime_type
|
||||
assert_equal "text/plain", mail.parts[1].mime_type
|
||||
|
@ -945,7 +929,7 @@ EOF
|
|||
end
|
||||
|
||||
def test_implicitly_multipart_messages_with_charset
|
||||
mail = TestMailer.create_implicitly_multipart_example(@recipient, 'iso-8859-1')
|
||||
mail = TestMailer.implicitly_multipart_example(@recipient, 'iso-8859-1')
|
||||
|
||||
assert_equal "multipart/alternative", mail.header['content-type'].content_type
|
||||
|
||||
|
@ -955,23 +939,23 @@ EOF
|
|||
end
|
||||
|
||||
def test_html_mail
|
||||
mail = TestMailer.create_html_mail(@recipient)
|
||||
mail = TestMailer.html_mail(@recipient)
|
||||
assert_equal "text/html", mail.mime_type
|
||||
end
|
||||
|
||||
def test_html_mail_with_underscores
|
||||
mail = TestMailer.create_html_mail_with_underscores(@recipient)
|
||||
mail = TestMailer.html_mail_with_underscores(@recipient)
|
||||
assert_equal %{<a href="http://google.com" target="_blank">_Google</a>}, 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 "<p>line #1</p>\n<p>line #2</p>\n<p>line #3</p>\n<p>line #4</p>\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
|
||||
|
@ -979,8 +963,8 @@ EOF
|
|||
end
|
||||
|
||||
def test_headers_removed_on_smtp_delivery
|
||||
ActionMailer::Base.delivery_method = :smtp
|
||||
TestMailer.deliver_cc_bcc(@recipient)
|
||||
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)
|
||||
|
@ -990,10 +974,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.deliver_cc_bcc(@recipient)
|
||||
result = TestMailer.cc_bcc(@recipient).deliver
|
||||
assert File.exists?(tmp_location)
|
||||
assert File.directory?(tmp_location)
|
||||
assert File.exists?(File.join(tmp_location, @recipient))
|
||||
|
@ -1002,7 +986,7 @@ EOF
|
|||
end
|
||||
|
||||
def test_recursive_multipart_processing
|
||||
fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email7")
|
||||
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)
|
||||
|
@ -1013,36 +997,36 @@ EOF
|
|||
end
|
||||
|
||||
def test_decode_encoded_attachment_filename
|
||||
fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email8")
|
||||
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.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
|
||||
|
||||
def test_decode_message_with_unknown_charset
|
||||
fixture = File.read(File.dirname(__FILE__) + "/fixtures/raw_email10")
|
||||
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.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
|
||||
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?
|
||||
|
@ -1051,88 +1035,80 @@ 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
|
||||
TestMailer.delivery_method = :test
|
||||
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
|
||||
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
|
||||
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.delivery_method = :smtp
|
||||
TestMailer.return_path.deliver
|
||||
assert_match %r{^Return-Path: <another@somewhere.test>}, MockSMTP.deliveries[0][0]
|
||||
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.smtp_settings[: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.deliver_signed_up(@recipient)
|
||||
TestMailer.delivery_method = :smtp
|
||||
TestMailer.signed_up(@recipient).deliver
|
||||
end
|
||||
|
||||
def test_starttls_is_disabled_if_not_supported
|
||||
ActionMailer::Base.smtp_settings[: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.deliver_signed_up(@recipient)
|
||||
TestMailer.delivery_method = :smtp
|
||||
TestMailer.signed_up(@recipient).deliver
|
||||
end
|
||||
|
||||
def test_starttls_is_not_enabled
|
||||
ActionMailer::Base.smtp_settings[:enable_starttls_auto] = false
|
||||
TestMailer.smtp_settings.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)
|
||||
TestMailer.delivery_method = :smtp
|
||||
TestMailer.signed_up(@recipient).deliver
|
||||
ensure
|
||||
ActionMailer::Base.smtp_settings[:enable_starttls_auto] = true
|
||||
TestMailer.smtp_settings.merge!(:enable_starttls_auto => true)
|
||||
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")
|
||||
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
|
||||
end
|
||||
end
|
||||
|
||||
class MethodNamingTest < Test::Unit::TestCase
|
||||
class MethodNamingTest < ActiveSupport::TestCase
|
||||
class TestMailer < ActionMailer::Base
|
||||
def send
|
||||
render :text => 'foo'
|
||||
|
@ -1142,7 +1118,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
|
||||
|
@ -1152,12 +1128,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
|
||||
|
||||
|
@ -1220,4 +1197,4 @@ class RespondToTest < Test::Unit::TestCase
|
|||
|
||||
assert_match(/undefined method.*not_a_method/, error.message)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,21 +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
|
||||
STDERR.expects(:puts) # Deprecation warning
|
||||
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
|
||||
STDERR.expects(:puts) # Deprecation warning
|
||||
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
|
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -67,14 +69,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
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ module AbstractController
|
|||
|
||||
autoload :Base
|
||||
autoload :Callbacks
|
||||
autoload :Collector
|
||||
autoload :Helpers
|
||||
autoload :Layouts
|
||||
autoload :LocalizedCache
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
module AbstractController
|
||||
module Collector
|
||||
def self.generate_method_for_mime(mime)
|
||||
sym = mime.is_a?(Symbol) ? mime : mime.to_sym
|
||||
const = sym.to_s.upcase
|
||||
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
||||
def #{sym}(*args, &block) # def html(*args, &block)
|
||||
custom(Mime::#{const}, *args, &block) # custom(Mime::HTML, *args, &block)
|
||||
end # end
|
||||
RUBY
|
||||
end
|
||||
|
||||
Mime::SET.each do |mime|
|
||||
generate_method_for_mime(mime)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def method_missing(symbol, &block)
|
||||
mime_constant = Mime.const_get(symbol.to_s.upcase)
|
||||
|
||||
if Mime::SET.include?(mime_constant)
|
||||
AbstractController::Collector.generate_method_for_mime(mime_constant)
|
||||
send(symbol, &block)
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -41,10 +41,6 @@ module AbstractController
|
|||
# Mostly abstracts the fact that calling render twice is a DoubleRenderError.
|
||||
# Delegates render_to_body and sticks the result in self.response_body.
|
||||
def render(*args, &block)
|
||||
if response_body
|
||||
raise AbstractController::DoubleRenderError
|
||||
end
|
||||
|
||||
options = _normalize_options(*args, &block)
|
||||
self.response_body = render_to_body(options)
|
||||
end
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
require 'abstract_controller/collector'
|
||||
|
||||
module ActionController #:nodoc:
|
||||
module MimeResponds #:nodoc:
|
||||
extend ActiveSupport::Concern
|
||||
|
@ -265,6 +267,7 @@ module ActionController #:nodoc:
|
|||
end
|
||||
|
||||
class Collector #:nodoc:
|
||||
include AbstractController::Collector
|
||||
attr_accessor :order
|
||||
|
||||
def initialize(&block)
|
||||
|
@ -289,32 +292,6 @@ module ActionController #:nodoc:
|
|||
def response_for(mime)
|
||||
@responses[mime] || @responses[Mime::ALL] || @default_response
|
||||
end
|
||||
|
||||
def self.generate_method_for_mime(mime)
|
||||
sym = mime.is_a?(Symbol) ? mime : mime.to_sym
|
||||
const = sym.to_s.upcase
|
||||
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
||||
def #{sym}(&block) # def html(&block)
|
||||
custom(Mime::#{const}, &block) # custom(Mime::HTML, &block)
|
||||
end # end
|
||||
RUBY
|
||||
end
|
||||
|
||||
Mime::SET.each do |mime|
|
||||
generate_method_for_mime(mime)
|
||||
end
|
||||
|
||||
def method_missing(symbol, &block)
|
||||
mime_constant = Mime.const_get(symbol.to_s.upcase)
|
||||
|
||||
if Mime::SET.include?(mime_constant)
|
||||
self.class.generate_method_for_mime(mime_constant)
|
||||
send(symbol, &block)
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -13,6 +13,10 @@ module ActionController
|
|||
end
|
||||
|
||||
def render(*args)
|
||||
if response_body
|
||||
raise ::AbstractController::DoubleRenderError
|
||||
end
|
||||
|
||||
args << {} unless args.last.is_a?(Hash)
|
||||
super(*args)
|
||||
self.content_type ||= args.last[:_template].mime_type.to_s
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
require 'abstract_unit'
|
||||
|
||||
module AbstractController
|
||||
module Testing
|
||||
class MyCollector
|
||||
include Collector
|
||||
attr_accessor :responses
|
||||
|
||||
def initialize
|
||||
@responses = []
|
||||
end
|
||||
|
||||
def custom(mime, *args, &block)
|
||||
@responses << [mime, args, block]
|
||||
end
|
||||
end
|
||||
|
||||
class TestCollector < ActiveSupport::TestCase
|
||||
test "responds to default mime types" do
|
||||
collector = MyCollector.new
|
||||
assert_respond_to collector, :html
|
||||
assert_respond_to collector, :text
|
||||
end
|
||||
|
||||
test "does not respond to unknown mime types" do
|
||||
collector = MyCollector.new
|
||||
assert !collector.respond_to?(:unknown)
|
||||
end
|
||||
|
||||
test "register mime types on method missing" do
|
||||
AbstractController::Collector.send(:remove_method, :js)
|
||||
collector = MyCollector.new
|
||||
assert !collector.respond_to?(:js)
|
||||
collector.js
|
||||
assert_respond_to collector, :js
|
||||
end
|
||||
|
||||
test "does not register unknown mime types" do
|
||||
collector = MyCollector.new
|
||||
assert_raise NameError do
|
||||
collector.unknown
|
||||
end
|
||||
end
|
||||
|
||||
test "generated methods call custom with args received" do
|
||||
collector = MyCollector.new
|
||||
collector.html
|
||||
collector.text(:foo)
|
||||
collector.js(:bar) { :baz }
|
||||
assert_equal [Mime::HTML, [], nil], collector.responses[0]
|
||||
assert_equal [Mime::TEXT, [:foo], nil], collector.responses[1]
|
||||
assert_equal [Mime::JS, [:bar]], collector.responses[2][0,2]
|
||||
assert_equal :baz, collector.responses[2][2].call
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,5 +1,6 @@
|
|||
require 'active_support/core_ext/array/wrap'
|
||||
require 'active_support/core_ext/array/access'
|
||||
require 'active_support/core_ext/array/uniq_by'
|
||||
require 'active_support/core_ext/array/conversions'
|
||||
require 'active_support/core_ext/array/extract_options'
|
||||
require 'active_support/core_ext/array/grouping'
|
||||
|
|
|
@ -13,19 +13,6 @@ class Array
|
|||
default_two_words_connector = I18n.translate(:'support.array.two_words_connector', :locale => options[:locale])
|
||||
default_last_word_connector = I18n.translate(:'support.array.last_word_connector', :locale => options[:locale])
|
||||
|
||||
# Try to emulate to_sentences previous to 2.3
|
||||
if options.has_key?(:connector) || options.has_key?(:skip_last_comma)
|
||||
::ActiveSupport::Deprecation.warn(":connector has been deprecated. Use :words_connector instead", caller) if options.has_key? :connector
|
||||
::ActiveSupport::Deprecation.warn(":skip_last_comma has been deprecated. Use :last_word_connector instead", caller) if options.has_key? :skip_last_comma
|
||||
|
||||
skip_last_comma = options.delete :skip_last_comma
|
||||
if connector = options.delete(:connector)
|
||||
options[:last_word_connector] ||= skip_last_comma ? connector : ", #{connector}"
|
||||
else
|
||||
options[:last_word_connector] ||= skip_last_comma ? default_two_words_connector : default_last_word_connector
|
||||
end
|
||||
end
|
||||
|
||||
options.assert_valid_keys(:words_connector, :two_words_connector, :last_word_connector, :locale)
|
||||
options.reverse_merge! :words_connector => default_words_connector, :two_words_connector => default_two_words_connector, :last_word_connector => default_last_word_connector
|
||||
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
class Array
|
||||
# Return an unique array based on the criteria given as a proc.
|
||||
#
|
||||
# [1, 2, 3, 4].uniq_by { |i| i.odd? }
|
||||
# #=> [1, 2]
|
||||
#
|
||||
def uniq_by
|
||||
hash, array = {}, []
|
||||
each { |i| hash[yield(i)] ||= (array << i) }
|
||||
array
|
||||
end
|
||||
|
||||
# Same as uniq_by, but modifies self.
|
||||
def uniq_by!
|
||||
replace(uniq_by{ |i| yield(i) })
|
||||
end
|
||||
end
|
|
@ -1,17 +1,16 @@
|
|||
class Hash
|
||||
# Returns a new hash with +self+ and +other_hash+ merged recursively.
|
||||
def deep_merge(other_hash)
|
||||
target = dup
|
||||
other_hash.each_pair do |k,v|
|
||||
tv = target[k]
|
||||
target[k] = tv.is_a?(Hash) && v.is_a?(Hash) ? tv.deep_merge(v) : v
|
||||
end
|
||||
target
|
||||
dup.deep_merge!(other_hash)
|
||||
end
|
||||
|
||||
# Returns a new hash with +self+ and +other_hash+ merged recursively.
|
||||
# Modifies the receiver in place.
|
||||
def deep_merge!(other_hash)
|
||||
replace(deep_merge(other_hash))
|
||||
other_hash.each_pair do |k,v|
|
||||
tv = self[k]
|
||||
self[k] = tv.is_a?(Hash) && v.is_a?(Hash) ? tv.deep_merge(v) : v
|
||||
end
|
||||
self
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
class Hash
|
||||
# Return a new hash with all keys converted to strings.
|
||||
def stringify_keys
|
||||
inject({}) do |options, (key, value)|
|
||||
options[key.to_s] = value
|
||||
options
|
||||
end
|
||||
dup.stringify_keys!
|
||||
end
|
||||
|
||||
# Destructively convert all keys to strings.
|
||||
|
@ -18,16 +15,16 @@ class Hash
|
|||
# Return a new hash with all keys converted to symbols, as long as
|
||||
# they respond to +to_sym+.
|
||||
def symbolize_keys
|
||||
inject({}) do |options, (key, value)|
|
||||
options[(key.to_sym rescue key) || key] = value
|
||||
options
|
||||
end
|
||||
dup.symbolize_keys!
|
||||
end
|
||||
|
||||
# Destructively convert all keys to symbols, as long as they respond
|
||||
# to +to_sym+.
|
||||
def symbolize_keys!
|
||||
self.replace(self.symbolize_keys)
|
||||
keys.each do |key|
|
||||
self[(key.to_sym rescue key) || key] = delete(key)
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
alias_method :to_options, :symbolize_keys
|
||||
|
|
|
@ -52,8 +52,6 @@ class ArrayExtToParamTests < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
class ArrayExtToSentenceTests < Test::Unit::TestCase
|
||||
include ActiveSupport::Testing::Deprecation
|
||||
|
||||
def test_plain_array_to_sentence
|
||||
assert_equal "", [].to_sentence
|
||||
assert_equal "one", ['one'].to_sentence
|
||||
|
@ -62,28 +60,12 @@ class ArrayExtToSentenceTests < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_to_sentence_with_words_connector
|
||||
assert_deprecated(":connector has been deprecated. Use :words_connector instead") do
|
||||
assert_equal "one, two, three", ['one', 'two', 'three'].to_sentence(:connector => '')
|
||||
end
|
||||
|
||||
assert_deprecated(":connector has been deprecated. Use :words_connector instead") do
|
||||
assert_equal "one, two, and three", ['one', 'two', 'three'].to_sentence(:connector => 'and ')
|
||||
end
|
||||
|
||||
assert_equal "one two, and three", ['one', 'two', 'three'].to_sentence(:words_connector => ' ')
|
||||
assert_equal "one & two, and three", ['one', 'two', 'three'].to_sentence(:words_connector => ' & ')
|
||||
assert_equal "onetwo, and three", ['one', 'two', 'three'].to_sentence(:words_connector => nil)
|
||||
end
|
||||
|
||||
def test_to_sentence_with_last_word_connector
|
||||
assert_deprecated(":skip_last_comma has been deprecated. Use :last_word_connector instead") do
|
||||
assert_equal "one, two and three", ['one', 'two', 'three'].to_sentence(:skip_last_comma => true)
|
||||
end
|
||||
|
||||
assert_deprecated(":skip_last_comma has been deprecated. Use :last_word_connector instead") do
|
||||
assert_equal "one, two, and three", ['one', 'two', 'three'].to_sentence(:skip_last_comma => false)
|
||||
end
|
||||
|
||||
assert_equal "one, two, and also three", ['one', 'two', 'three'].to_sentence(:last_word_connector => ', and also ')
|
||||
assert_equal "one, twothree", ['one', 'two', 'three'].to_sentence(:last_word_connector => nil)
|
||||
assert_equal "one, two three", ['one', 'two', 'three'].to_sentence(:last_word_connector => ' ')
|
||||
|
@ -320,6 +302,28 @@ class ArrayExtractOptionsTests < Test::Unit::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
class ArrayUniqByTests < Test::Unit::TestCase
|
||||
def test_uniq_by
|
||||
assert_equal [1,2], [1,2,3,4].uniq_by { |i| i.odd? }
|
||||
assert_equal [1,2], [1,2,3,4].uniq_by(&:even?)
|
||||
assert_equal (-5..0).to_a, (-5..5).to_a.uniq_by{ |i| i**2 }
|
||||
end
|
||||
|
||||
def test_uniq_by!
|
||||
a = [1,2,3,4]
|
||||
a.uniq_by! { |i| i.odd? }
|
||||
assert_equal [1,2], a
|
||||
|
||||
a = [1,2,3,4]
|
||||
a.uniq_by! { |i| i.even? }
|
||||
assert_equal [1,2], a
|
||||
|
||||
a = (-5..5).to_a
|
||||
a.uniq_by! { |i| i**2 }
|
||||
assert_equal (-5..0).to_a, a
|
||||
end
|
||||
end
|
||||
|
||||
class ArrayExtRandomTests < Test::Unit::TestCase
|
||||
def test_random_element_from_array
|
||||
assert_nil [].rand
|
||||
|
|
|
@ -12,7 +12,7 @@ module Erb
|
|||
def create_view_files
|
||||
actions.each do |action|
|
||||
@action, @path = action, File.join(file_path, action)
|
||||
template "view.erb", File.join("app/views", "#{@path}.erb")
|
||||
template "view.text.erb", File.join("app/views", "#{@path}.text.erb")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
<%= class_name %>#<%= @action %>
|
||||
|
||||
Find me in app/views/<%= @path %>
|
|
@ -0,0 +1,3 @@
|
|||
<%= class_name %>#<%= @action %>
|
||||
|
||||
<%%= @greeting %>, find me in app/views/<%= @path %>
|
|
@ -1,14 +1,15 @@
|
|||
class <%= class_name %> < ActionMailer::Base
|
||||
delivers_from "from@example.com"
|
||||
<% for action in actions -%>
|
||||
|
||||
def <%= action %>(sent_at = Time.now)
|
||||
subject '<%= class_name %>#<%= action %>'
|
||||
recipients ''
|
||||
from ''
|
||||
sent_on sent_at
|
||||
|
||||
body :greeting => 'Hi,'
|
||||
# Subject can be set in your I18n file at config/locales/en.yml
|
||||
# with the following lookup:
|
||||
#
|
||||
# en.actionmailer.<%= file_name %>.<%= action %>.subject
|
||||
#
|
||||
def <%= action %>
|
||||
@greeting = "Hi"
|
||||
mail(:to => "to@example.com")
|
||||
end
|
||||
|
||||
<% end -%>
|
||||
end
|
||||
end
|
|
@ -6,8 +6,8 @@ module Rails
|
|||
class ResourceGenerator < ModelGenerator #metagenerator
|
||||
include ResourceHelpers
|
||||
|
||||
hook_for :resource_controller, :required => true do |base, controller|
|
||||
base.invoke controller, [ base.controller_name, base.options[:actions] ]
|
||||
hook_for :resource_controller, :required => true do |controller|
|
||||
invoke controller, [ controller_name, options[:actions] ]
|
||||
end
|
||||
|
||||
class_option :actions, :type => :array, :banner => "ACTION ACTION", :default => [],
|
||||
|
|
|
@ -18,9 +18,9 @@ module Rails
|
|||
|
||||
hook_for :template_engine, :test_framework, :as => :scaffold
|
||||
|
||||
# Invoke the helper using the controller (pluralized) name.
|
||||
hook_for :helper, :as => :scaffold do |base, invoked|
|
||||
base.invoke invoked, [ base.controller_name ]
|
||||
# Invoke the helper using the controller name (pluralized)
|
||||
hook_for :helper, :as => :scaffold do |invoked|
|
||||
invoke invoked, [ controller_name ]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
<%= class_name %>#<%= @action %>
|
||||
|
||||
Find me in app/views/<%= @path %>
|
||||
Hi, find me in app/views/<%= @path %>
|
||||
|
|
|
@ -3,11 +3,13 @@ require 'test_helper'
|
|||
class <%= class_name %>Test < ActionMailer::TestCase
|
||||
<% for action in actions -%>
|
||||
test "<%= action %>" do
|
||||
@expected.subject = '<%= class_name %>#<%= action %>'
|
||||
@expected.body = read_fixture('<%= action %>')
|
||||
@expected.subject = <%= action.to_s.humanize.inspect %>
|
||||
@expected.to = "to@example.com"
|
||||
@expected.from = "from@example.com"
|
||||
@expected.body = read_fixture("<%= action %>")
|
||||
@expected.date = Time.now
|
||||
|
||||
assert_equal @expected.encoded, <%= class_name %>.create_<%= action %>(@expected.date).encoded
|
||||
assert_equal @expected, <%= class_name %>.<%= action %>
|
||||
end
|
||||
|
||||
<% end -%>
|
||||
|
|
|
@ -6,17 +6,9 @@ module Rails
|
|||
class NamedBase < Base
|
||||
argument :name, :type => :string
|
||||
|
||||
no_tasks {
|
||||
attr_reader :class_name, :singular_name, :plural_name, :table_name,
|
||||
:class_path, :file_path, :class_nesting_depth
|
||||
|
||||
alias :file_name :singular_name
|
||||
}
|
||||
|
||||
def initialize(args, *options) #:nodoc:
|
||||
# Unfreeze name in case it's given as a frozen string
|
||||
args[0] = args[0].dup if args[0].is_a?(String) && args[0].frozen?
|
||||
|
||||
super
|
||||
assign_names!(self.name)
|
||||
parse_attributes! if respond_to?(:attributes)
|
||||
|
@ -24,28 +16,48 @@ module Rails
|
|||
|
||||
protected
|
||||
|
||||
def assign_names!(given_name) #:nodoc:
|
||||
base_name, @class_path, @file_path, class_nesting, @class_nesting_depth = extract_modules(given_name)
|
||||
class_name_without_nesting, @singular_name, @plural_name = inflect_names(base_name)
|
||||
attr_reader :class_path, :file_name
|
||||
alias :singular_name :file_name
|
||||
|
||||
@table_name = if pluralize_table_names?
|
||||
plural_name
|
||||
else
|
||||
singular_name
|
||||
end
|
||||
|
||||
if class_nesting.empty?
|
||||
@class_name = class_name_without_nesting
|
||||
else
|
||||
@table_name = class_nesting.underscore << "_" << @table_name
|
||||
@class_name = "#{class_nesting}::#{class_name_without_nesting}"
|
||||
end
|
||||
|
||||
@table_name.gsub!('/', '_')
|
||||
def file_path
|
||||
@file_path ||= (class_path + [file_name]).join('/')
|
||||
end
|
||||
|
||||
# Convert attributes hash into an array with GeneratedAttribute objects.
|
||||
#
|
||||
def class_name
|
||||
@class_name ||= (class_path + [file_name]).map!{ |m| m.camelize }.join('::')
|
||||
end
|
||||
|
||||
def plural_name
|
||||
@plural_name ||= singular_name.pluralize
|
||||
end
|
||||
|
||||
def i18n_scope
|
||||
@i18n_scope ||= file_path.gsub('/', '.')
|
||||
end
|
||||
|
||||
def table_name
|
||||
@table_name ||= begin
|
||||
base = pluralize_table_names? ? plural_name : singular_name
|
||||
(class_path + [base]).join('_')
|
||||
end
|
||||
end
|
||||
|
||||
# Tries to retrieve the application name or simple return application.
|
||||
def application_name
|
||||
if defined?(Rails) && Rails.application
|
||||
Rails.application.class.name.split('::').first.underscore
|
||||
else
|
||||
"application"
|
||||
end
|
||||
end
|
||||
|
||||
def assign_names!(name) #:nodoc:
|
||||
@class_path = name.include?('/') ? name.split('/') : name.split('::')
|
||||
@class_path.map! { |m| m.underscore }
|
||||
@file_name = @class_path.pop
|
||||
end
|
||||
|
||||
# Convert attributes array into GeneratedAttribute objects.
|
||||
def parse_attributes! #:nodoc:
|
||||
self.attributes = (attributes || []).map do |key_value|
|
||||
name, type = key_value.split(':')
|
||||
|
@ -53,29 +65,6 @@ module Rails
|
|||
end
|
||||
end
|
||||
|
||||
# Extract modules from filesystem-style or ruby-style path. Both
|
||||
# good/fun/stuff and Good::Fun::Stuff produce the same results.
|
||||
#
|
||||
def extract_modules(name) #:nodoc:
|
||||
modules = name.include?('/') ? name.split('/') : name.split('::')
|
||||
name = modules.pop
|
||||
path = modules.map { |m| m.underscore }
|
||||
|
||||
file_path = (path + [name.underscore]).join('/')
|
||||
nesting = modules.map { |m| m.camelize }.join('::')
|
||||
|
||||
[name, path, file_path, nesting, modules.size]
|
||||
end
|
||||
|
||||
# Receives name and return camelized, underscored and pluralized names.
|
||||
#
|
||||
def inflect_names(name) #:nodoc:
|
||||
camel = name.camelize
|
||||
under = camel.underscore
|
||||
plural = under.pluralize
|
||||
[camel, under, plural]
|
||||
end
|
||||
|
||||
def pluralize_table_names?
|
||||
!defined?(ActiveRecord::Base) || ActiveRecord::Base.pluralize_table_names
|
||||
end
|
||||
|
|
|
@ -9,14 +9,7 @@ module Rails
|
|||
mattr_accessor :skip_warn
|
||||
|
||||
def self.included(base) #:nodoc:
|
||||
base.class_eval do
|
||||
class_option :force_plural, :type => :boolean, :desc => "Forces the use of a plural ModelName"
|
||||
|
||||
no_tasks {
|
||||
attr_reader :controller_name, :controller_class_name, :controller_file_name,
|
||||
:controller_class_path, :controller_file_path
|
||||
}
|
||||
end
|
||||
base.class_option :force_plural, :type => :boolean, :desc => "Forces the use of a plural ModelName"
|
||||
end
|
||||
|
||||
# Set controller variables on initialization.
|
||||
|
@ -29,29 +22,40 @@ module Rails
|
|||
say "Plural version of the model detected, using singularized version. Override with --force-plural."
|
||||
ResourceHelpers.skip_warn = true
|
||||
end
|
||||
|
||||
name.replace name.singularize
|
||||
assign_names!(self.name)
|
||||
assign_names!(name)
|
||||
end
|
||||
|
||||
@controller_name = name.pluralize
|
||||
|
||||
base_name, @controller_class_path, @controller_file_path, class_nesting, class_nesting_depth = extract_modules(@controller_name)
|
||||
class_name_without_nesting, @controller_file_name, controller_plural_name = inflect_names(base_name)
|
||||
|
||||
@controller_class_name = if class_nesting.empty?
|
||||
class_name_without_nesting
|
||||
else
|
||||
"#{class_nesting}::#{class_name_without_nesting}"
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
attr_reader :controller_name
|
||||
|
||||
def controller_class_path
|
||||
@class_path
|
||||
end
|
||||
|
||||
def controller_file_name
|
||||
@controller_file_name ||= file_name.pluralize
|
||||
end
|
||||
|
||||
def controller_file_path
|
||||
@controller_file_path ||= (controller_class_path + [controller_file_name]).join('/')
|
||||
end
|
||||
|
||||
def controller_class_name
|
||||
@controller_class_name ||= (controller_class_path + [controller_file_name]).map!{ |m| m.camelize }.join('::')
|
||||
end
|
||||
|
||||
def controller_i18n_scope
|
||||
@controller_i18n_scope ||= controller_file_path.gsub('/', '.')
|
||||
end
|
||||
|
||||
# Loads the ORM::Generators::ActiveModel class. This class is responsable
|
||||
# to tell scaffold entities how to generate an specific method for the
|
||||
# ORM. Check Rails::Generators::ActiveModel for more information.
|
||||
#
|
||||
def orm_class
|
||||
@orm_class ||= begin
|
||||
# Raise an error if the class_option :orm was not defined.
|
||||
|
@ -68,7 +72,6 @@ module Rails
|
|||
end
|
||||
|
||||
# Initialize ORM::Generators::ActiveModel to access instance methods.
|
||||
#
|
||||
def orm_instance(name=file_name)
|
||||
@orm_instance ||= @orm_class.new(name)
|
||||
end
|
||||
|
|
|
@ -7,7 +7,18 @@ class MailerGeneratorTest < Rails::Generators::TestCase
|
|||
|
||||
def test_mailer_skeleton_is_created
|
||||
run_generator
|
||||
assert_file "app/mailers/notifier.rb", /class Notifier < ActionMailer::Base/
|
||||
assert_file "app/mailers/notifier.rb" do |mailer|
|
||||
assert_match /class Notifier < ActionMailer::Base/, mailer
|
||||
assert_match /delivers_from "from@example.com"/, mailer
|
||||
end
|
||||
end
|
||||
|
||||
def test_mailer_with_i18n_helper
|
||||
run_generator
|
||||
assert_file "app/mailers/notifier.rb" do |mailer|
|
||||
assert_match /en\.actionmailer\.notifier\.foo\.subject/, mailer
|
||||
assert_match /en\.actionmailer\.notifier\.bar\.subject/, mailer
|
||||
end
|
||||
end
|
||||
|
||||
def test_check_class_collision
|
||||
|
@ -24,8 +35,15 @@ class MailerGeneratorTest < Rails::Generators::TestCase
|
|||
|
||||
def test_invokes_default_template_engine
|
||||
run_generator
|
||||
assert_file "app/views/notifier/foo.erb", /app\/views\/notifier\/foo/
|
||||
assert_file "app/views/notifier/bar.erb", /app\/views\/notifier\/bar/
|
||||
assert_file "app/views/notifier/foo.text.erb" do |view|
|
||||
assert_match /app\/views\/notifier\/foo/, view
|
||||
assert_match /<%= @greeting %>/, view
|
||||
end
|
||||
|
||||
assert_file "app/views/notifier/bar.text.erb" do |view|
|
||||
assert_match /app\/views\/notifier\/bar/, view
|
||||
assert_match /<%= @greeting %>/, view
|
||||
end
|
||||
end
|
||||
|
||||
def test_invokes_default_template_engine_even_with_no_action
|
||||
|
@ -40,7 +58,18 @@ class MailerGeneratorTest < Rails::Generators::TestCase
|
|||
|
||||
def test_actions_are_turned_into_methods
|
||||
run_generator
|
||||
assert_file "app/mailers/notifier.rb", /def foo/
|
||||
assert_file "app/mailers/notifier.rb", /def bar/
|
||||
|
||||
assert_file "app/mailers/notifier.rb" do |mailer|
|
||||
assert_instance_method :foo, mailer do |foo|
|
||||
assert_match /mail\(:to => "to@example.com"\)/, foo
|
||||
assert_match /@greeting = "Hi"/, foo
|
||||
end
|
||||
|
||||
assert_instance_method :bar, mailer do |bar|
|
||||
assert_match /mail\(:to => "to@example.com"\)/, bar
|
||||
assert_match /@greeting = "Hi"/, bar
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -16,28 +16,68 @@ class NamedBaseTest < Rails::Generators::TestCase
|
|||
tests Rails::Generators::ScaffoldControllerGenerator
|
||||
|
||||
def test_named_generator_attributes
|
||||
g = generator ["admin/foo"]
|
||||
assert_equal 'admin/foo', g.name
|
||||
assert_equal %w(admin), g.class_path
|
||||
assert_equal 1, g.class_nesting_depth
|
||||
assert_equal 'Admin::Foo', g.class_name
|
||||
assert_equal 'foo', g.singular_name
|
||||
assert_equal 'foos', g.plural_name
|
||||
assert_equal g.singular_name, g.file_name
|
||||
assert_equal "admin_#{g.plural_name}", g.table_name
|
||||
g = generator ['admin/foo']
|
||||
assert_name g, 'admin/foo', :name
|
||||
assert_name g, %w(admin), :class_path
|
||||
assert_name g, 'Admin::Foo', :class_name
|
||||
assert_name g, 'admin/foo', :file_path
|
||||
assert_name g, 'foo', :file_name
|
||||
assert_name g, 'foo', :singular_name
|
||||
assert_name g, 'foos', :plural_name
|
||||
assert_name g, 'admin.foo', :i18n_scope
|
||||
assert_name g, 'admin_foos', :table_name
|
||||
end
|
||||
|
||||
def test_named_generator_attributes_as_ruby
|
||||
g = generator ['Admin::Foo']
|
||||
assert_name g, 'Admin::Foo', :name
|
||||
assert_name g, %w(admin), :class_path
|
||||
assert_name g, 'Admin::Foo', :class_name
|
||||
assert_name g, 'admin/foo', :file_path
|
||||
assert_name g, 'foo', :file_name
|
||||
assert_name g, 'foo', :singular_name
|
||||
assert_name g, 'foos', :plural_name
|
||||
assert_name g, 'admin.foo', :i18n_scope
|
||||
assert_name g, 'admin_foos', :table_name
|
||||
end
|
||||
|
||||
def test_named_generator_attributes_without_pluralized
|
||||
ActiveRecord::Base.pluralize_table_names = false
|
||||
g = generator ["admin/foo"]
|
||||
assert_equal "admin_#{g.singular_name}", g.table_name
|
||||
g = generator ['admin/foo']
|
||||
assert_name g, 'admin_foo', :table_name
|
||||
end
|
||||
|
||||
def test_scaffold_plural_names
|
||||
g = generator ["ProductLine"]
|
||||
assert_equal "ProductLines", g.controller_name
|
||||
assert_equal "ProductLines", g.controller_class_name
|
||||
assert_equal "product_lines", g.controller_file_name
|
||||
g = generator ['admin/foo']
|
||||
assert_name g, 'admin/foos', :controller_name
|
||||
assert_name g, %w(admin), :controller_class_path
|
||||
assert_name g, 'Admin::Foos', :controller_class_name
|
||||
assert_name g, 'admin/foos', :controller_file_path
|
||||
assert_name g, 'foos', :controller_file_name
|
||||
assert_name g, 'admin.foos', :controller_i18n_scope
|
||||
end
|
||||
|
||||
def test_scaffold_plural_names_as_ruby
|
||||
g = generator ['Admin::Foo']
|
||||
assert_name g, 'Admin::Foos', :controller_name
|
||||
assert_name g, %w(admin), :controller_class_path
|
||||
assert_name g, 'Admin::Foos', :controller_class_name
|
||||
assert_name g, 'admin/foos', :controller_file_path
|
||||
assert_name g, 'foos', :controller_file_name
|
||||
assert_name g, 'admin.foos', :controller_i18n_scope
|
||||
end
|
||||
|
||||
def test_application_name
|
||||
g = generator ['Admin::Foo']
|
||||
Rails.stubs(:application).returns(Object.new)
|
||||
assert_name g, "object", :application_name
|
||||
Rails.stubs(:application).returns(nil)
|
||||
assert_name g, "application", :application_name
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def assert_name(generator, value, method)
|
||||
assert_equal value, generator.send(method)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue