Skip to content
Browse files

Merge branch 'master' into tmm1

  • Loading branch information...
2 parents d4e408a + 1b55cfd commit a8b7096758ff027d2e57af0cae4fd64c88fefbec @mikel mikel committed Jan 28, 2010
View
17 CHANGELOG.rdoc
@@ -1,3 +1,20 @@
+== Mon Jan 25 11:36:13 UTC 2010 Mikel Lindsaar <raasdnil@gmail.com>
+
+* Added ability for address fields to init on an array instead of just a string.
+* Version bump to 2.1.1
+
+== Mon Jan 25 10:36:33 UTC 2010 Mikel Lindsaar <raasdnil@gmail.com>
+
+* Now passes a block to the delivery handler, which can just call yield if it want's Mail to just do it's normal delivery method
+* Moved Mail.deliveries into Mail::TestMailer.deliveries. Now only gets mail appended to it if you are sending with the :test delivery_method (only for testing)
+* Version bump to 2.1.0
+
+== Mon Jan 25 01:44:13 UTC 2010 Mikel Lindsaar <raasdnil@gmail.com>
+
+* Change :deliver! to deliver a mail object, bypassing the :perform_deliveries and :raise_delivery_errors flags, also does not append the mail object to Mail.deliveries, thus the ! (dangerous). The intended use for :deliver! is for people wanting to have their own delivery_handler (like ActionMailer uses) to track and handle delivery failures.
+* Added :delivery_handler to Message. Allows you to pass an object that will be sent :deliver_mail(self) by the Mail::Message instance when it is sent :deliver and bypasses the usual delivery method.
+* Changed :perform_deliveries flag to be more consistent with it's name, mail will not append itself to the Mail.deliveries collection if :perform_deliveries is false
+
== Sat Jan 23 23:49:50 UTC 2010 Mikel Lindsaar <raasdnil@gmail.com>
* Version bump to 2.0.5
View
32 README.rdoc
@@ -219,11 +219,9 @@ what you are doing.
=== Sending an email:
- require 'mail'
-
- Mail.defaults do
- smtp '127.0.0.1', 25
- end
+Mail defaults to sending via SMTP to local host port 25. If you have a
+sendmail or postfix daemon running on on this port, sending email is as
+easy as:
Mail.deliver do
from 'me@test.lindsaar.net'
@@ -235,10 +233,6 @@ what you are doing.
or
- Mail.defaults do
- smtp '127.0.0.1' # Port 25 defult
- end
-
mail = Mail.new do
from 'me@test.lindsaar.net'
to 'you@test.lindsaar.net'
@@ -249,6 +243,22 @@ or
mail.deliver!
+Sending via sendmail can be done like so:
+
+ mail = Mail.new do
+ from 'me@test.lindsaar.net'
+ to 'you@test.lindsaar.net'
+ subject 'Here is the image you wanted'
+ body File.read('body.txt')
+ add_file {:filename => 'somefile.png', :content => File.read('/somefile.png')}
+ end
+
+ mail.delivery_method :sendmail
+
+ mail.deliver
+
+mail.deliver!
+
=== Getting emails from a pop server:
@@ -344,10 +354,6 @@ simple as possible.... (asking a lot from a mail library)
require 'mail'
- Mail.defaults do
- smtp '127.0.0.1' # Port 25 defult
- end
-
mail = Mail.deliver do
to 'nicolas@test.lindsaar.net.au'
from 'Mikel Lindsaar <mikel@test.lindsaar.net.au>'
View
2 Rakefile
@@ -12,7 +12,7 @@ require 'bundler'
spec = Gem::Specification.new do |s|
s.name = "mail"
- s.version = "2.0.5"
+ s.version = "2.1.1"
s.author = "Mike Lindsaar"
s.email = "raasdnil@gmail.com"
s.homepage = "http://github.com/mikel/mail"
View
9 lib/mail/configuration.rb
@@ -13,9 +13,12 @@ module Mail
# which can be overwritten on a per mail object basis.
class Configuration
include Singleton
-
- @delivery_method = nil
- @retriever_method = nil
+
+ def initialize
+ @delivery_method = nil
+ @retriever_method = nil
+ super
+ end
def delivery_method(method = nil, settings = {})
return @delivery_method if @delivery_method && method.nil?
View
6 lib/mail/fields/common/common_field.rb
@@ -46,7 +46,11 @@ def responsible_for?( val )
private
def strip_field(field_name, string)
- string.to_s.gsub(/#{field_name}:\s+/i, '')
+ if string.is_a?(Array)
+ string.join(', ')
+ else
+ string.to_s.gsub(/#{field_name}:\s+/i, '')
+ end
end
end
View
19 lib/mail/mail.rb
@@ -169,25 +169,6 @@ def Mail.all(*args, &block)
def Mail.read(filename)
Mail.new(File.read(filename))
end
-
- # Provides a store of all the emails sent
- def Mail.deliveries
- @@deliveries ||= []
- end
-
- # Allows you to over write the default deliveries store from an array to some
- # other object. If you just want to clear the store, call Mail.deliveries.clear.
- #
- # If you place another object here, please make sure it responds to:
- #
- # * << (message)
- # * clear
- # * length
- # * size
- # * and other common Array methods
- def Mail.deliveries=(val)
- @@deliveries = val
- end
protected
View
113 lib/mail/message.rb
@@ -102,9 +102,12 @@ def initialize(*args, &block)
@perform_deliveries = true
@raise_delivery_errors = true
+
+ @delivery_handler = nil
+
@delivery_method = Mail.delivery_method.dup
@delivery_notification_observers = []
-
+
if args.flatten.first.respond_to?(:each_pair)
init_with_hash(args.flatten.first)
else
@@ -118,7 +121,76 @@ def initialize(*args, &block)
self
end
+ # If you assign a delivery handler, mail will call :deliver_mail on the
+ # object you assign to delivery_handler, it will pass itself as the
+ # single argument.
+ #
+ # If you define a delivery_handler, then you are responsible for the
+ # following actions in the delivery cycle:
+ #
+ # * Appending the mail object to Mail.deliveries as you see fit.
+ # * Checking the mail.perform_deliveries flag to decide if you should
+ # actually call :deliver! the mail object or not.
+ # * Checking the mail.raise_delivery_errors flag to decide if you
+ # should raise delivery errors if they occur.
+ # * Actually calling :deliver! (with the bang) on the mail object to
+ # get it to deliver itself.
+ #
+ # A simplest implementation of a delivery_handler would be
+ #
+ # class MyObject
+ #
+ # def initialize
+ # @mail = Mail.new('To: mikel@test.lindsaar.net')
+ # @mail.delivery_handler = self
+ # end
+ #
+ # attr_accessor :mail
+ #
+ # def deliver_mail(mail)
+ # yield
+ # end
+ # end
+ #
+ # Then doing:
+ #
+ # obj = MyObject.new
+ # obj.mail.deliver
+ #
+ # Would cause Mail to call obj.deliver_mail passing itself as a parameter,
+ # which then can just yield and let Mail do it's own private do_delivery
+ # method.
+ attr_accessor :delivery_handler
+
+ # If set to false, mail will go through the motions of doing a delivery,
+ # but not actually call the delivery method or append the mail object to
+ # the Mail.deliveries collection. Useful for testing.
+ #
+ # Mail.deliveries.size #=> 0
+ # mail.delivery_method :smtp
+ # mail.perform_deliveries = false
+ # mail.deliver # Mail::SMTP not called here
+ # Mail.deliveries.size #=> 0
+ #
+ # If you want to test and query the Mail.deliveries collection to see what
+ # mail you sent, you should set perform_deliveries to true and use
+ # the :test mail delivery_method:
+ #
+ # Mail.deliveries.size #=> 0
+ # mail.delivery_method :test
+ # mail.perform_deliveries = true
+ # mail.deliver
+ # Mail.deliveries.size #=> 1
+ #
+ # This setting is ignored by mail (though still available as a flag) if you
+ # define a delivery_handler
attr_accessor :perform_deliveries
+
+ # If set to false, mail will silently catch and ignore any exceptions
+ # raised through attempting to deliver an email.
+ #
+ # This setting is ignored by mail (though still available as a flag) if you
+ # define a delivery_handler
attr_accessor :raise_delivery_errors
def register_for_delivery_notification(observer)
@@ -138,22 +210,29 @@ def inform_observers
# Examples:
#
# mail = Mail.read('file.eml')
- # mail.deliver!
+ # mail.deliver
def deliver
- if perform_deliveries
- begin
- delivery_method.deliver!(self)
- Mail.deliveries << self
- rescue Exception => e # Net::SMTP errors or sendmail pipe errors
- raise e if raise_delivery_errors
- end
+ if delivery_handler
+ delivery_handler.deliver_mail(self) { do_delivery }
+ else
+ do_delivery
+ inform_observers
end
+ self
+ end
+
+ # This method bypasses checking perform_deliveries and raise_delivery_errors,
+ # so use with caution.
+ #
+ # It still however fires callbacks to the observers if they are defined.
+ #
+ # Returns self
+ def deliver!
+ delivery_method.deliver!(self)
inform_observers
self
end
- alias :deliver! :deliver
-
def delivery_method(method = nil, settings = {})
unless method
@delivery_method
@@ -1571,7 +1650,7 @@ def filename
find_attachment
end
- private
+ private
# 2.1. General Description
# A message consists of header fields (collectively called "the header
@@ -1679,5 +1758,15 @@ def find_attachment
filename
end
+ def do_delivery
+ begin
+ if perform_deliveries
+ delivery_method.deliver!(self)
+ end
+ rescue Exception => e # Net::SMTP errors or sendmail pipe errors
+ raise e if raise_delivery_errors
+ end
+ end
+
end
end
View
21 lib/mail/network/delivery_methods/test_mailer.rb
@@ -6,13 +6,34 @@ module Mail
# if you want to make a custom mailer for Mail
class TestMailer
+ # Provides a store of all the emails sent with the TestMailer so you can check them.
+ def TestMailer.deliveries
+ @@deliveries ||= []
+ end
+
+ # Allows you to over write the default deliveries store from an array to some
+ # other object. If you just want to clear the store,
+ # call TestMailer.deliveries.clear.
+ #
+ # If you place another object here, please make sure it responds to:
+ #
+ # * << (message)
+ # * clear
+ # * length
+ # * size
+ # * and other common Array methods
+ def TestMailer.deliveries=(val)
+ @@deliveries = val
+ end
+
def initialize(values)
@settings = {}
end
attr_accessor :settings
def deliver!(mail)
+ Mail::TestMailer.deliveries << mail
end
end
View
4 lib/mail/version.rb
@@ -2,8 +2,8 @@
module Mail
module VERSION
MAJOR = 2
- MINOR = 0
- TINY = 5
+ MINOR = 1
+ TINY = 1
STRING = [MAJOR, MINOR, TINY].join('.')
end
View
5 spec/mail/field_spec.rb
@@ -10,6 +10,11 @@
Mail::Field.new('To: Mikel').field.class.should == Mail::ToField
end
+ it "should allow you to init on an array" do
+ field = Mail::Field.new("To", ['test1@lindsaar.net', 'Mikel <test2@lindsaar.net>'])
+ field.addresses.should == ["test1@lindsaar.net", "test2@lindsaar.net"]
+ end
+
it "should allow us to pass an empty value" do
doing {Mail::Field.new('To')}.should_not raise_error
Mail::Field.new('To').field.class.should == Mail::ToField
View
2 spec/mail/fields/common/common_address_spec.rb
@@ -60,7 +60,7 @@
field.value = 'mikel@test.lindsaar.net'
field.addresses.should == ['mikel@test.lindsaar.net']
end
-
+
it "should encode to an empty string if it has no addresses or groups" do
field = Mail::ToField.new("To", "")
field.encoded.should == ''
View
501 spec/mail/message_spec.rb
@@ -703,492 +703,27 @@ def basic_email
message.encoded.should match(%r{<b>test</b> HTML<br/>})
end
- end
-
- end
-
- describe "MIME Emails" do
-
- describe "general helper methods" do
-
- it "should read a mime version from an email" do
- mail = Mail.new("Mime-Version: 1.0")
- mail.mime_version.should == '1.0'
- end
-
- it "should return nil if the email has no mime version" do
- mail = Mail.new("To: bob")
- mail.mime_version.should == nil
- end
-
- it "should read the content-transfer-encoding" do
- mail = Mail.new("Content-Transfer-Encoding: quoted-printable")
- mail.content_transfer_encoding.should == 'quoted-printable'
- end
-
- it "should read the content-description" do
- mail = Mail.new("Content-Description: This is a description")
- mail.content_description.should == 'This is a description'
- end
-
- it "should return the content-type" do
- mail = Mail.new("Content-Type: text/plain")
- mail.mime_type.should == 'text/plain'
- end
-
- it "should return the charset" do
- mail = Mail.new("Content-Type: text/plain; charset=utf-8")
- mail.charset.should == 'utf-8'
- end
-
- it "should allow you to set the charset" do
- mail = Mail.new
- mail.charset = 'utf-8'
- mail.charset.should == 'utf-8'
- end
-
- it "should return the main content-type" do
- mail = Mail.new("Content-Type: text/plain")
- mail.main_type.should == 'text'
- end
-
- it "should return the sub content-type" do
- mail = Mail.new("Content-Type: text/plain")
- mail.sub_type.should == 'plain'
- end
-
- it "should return the content-type parameters" do
- mail = Mail.new("Content-Type: text/plain; charset=US-ASCII; format=flowed")
- mail.content_type_parameters.should == {'charset' => 'US-ASCII', 'format' => 'flowed'}
- end
-
- it "should recognize a multipart email" do
- mail = Mail.read(fixture('emails', 'mime_emails', 'raw_email7.eml'))
- mail.should be_multipart
- end
-
- it "should recognize a non multipart email" do
- mail = Mail.read(fixture('emails', 'plain_emails', 'basic_email.eml'))
- mail.should_not be_multipart
- end
-
- it "should give how may (top level) parts there are" do
- mail = Mail.read(fixture('emails', 'mime_emails', 'raw_email7.eml'))
- mail.parts.length.should == 2
- end
-
- it "should give the content_type of each part" do
- mail = Mail.read(fixture('emails', 'mime_emails', 'raw_email11.eml'))
- mail.mime_type.should == 'multipart/alternative'
- mail.parts[0].mime_type.should == 'text/plain'
- mail.parts[1].mime_type.should == 'text/enriched'
- end
-
- it "should report the mail :has_attachments?" do
- mail = Mail.read(fixture(File.join('emails', 'attachment_emails', 'attachment_pdf.eml')))
- mail.should be_has_attachments
- end
-
+ it "should allow you to init on an array of addresses from a hash" do
+ mail = Mail.new(:to => ['test1@lindsaar.net', 'Mikel <test2@lindsaar.net>'])
+ mail.to.should == ['test1@lindsaar.net', 'test2@lindsaar.net']
end
- describe "multipart emails" do
- it "should add a boundary if there is none defined and a part is added" do
- mail = Mail.new do
- part('This is a part')
- part('This is another part')
- end
- mail.boundary.should_not be_nil
- end
-
- it "should not add a boundary for a message that is only an attachment" do
- mail = Mail.new
- mail.attachments['test.png'] = "2938492384923849"
- mail.boundary.should be_nil
- end
+ it "should allow you to init on an array of addresses directly" do
+ mail = Mail.new
+ mail.to = ['test1@lindsaar.net', 'Mikel <test2@lindsaar.net>']
+ mail.to.should == ['test1@lindsaar.net', 'test2@lindsaar.net']
end
- describe "multipart/alternative emails" do
-
- it "should know what it's boundary is if it is a multipart document" do
- mail = Mail.new('Content-Type: multitype/mixed; boundary="--==Boundary"')
- mail.boundary.should == "--==Boundary"
- end
-
- it "should return nil if there is no content-type defined" do
- mail = Mail.new
- mail.boundary.should == nil
- end
-
- it "should allow you to assign a text part" do
- mail = Mail.new
- text_mail = Mail.new("This is Text")
- doing { mail.text_part = text_mail }.should_not raise_error
- end
-
- it "should assign the text part and allow you to reference" do
- mail = Mail.new
- text_mail = Mail.new("This is Text")
- mail.text_part = text_mail
- mail.text_part.should == text_mail
- end
-
- it "should allow you to assign a html part" do
- mail = Mail.new
- html_mail = Mail.new("<b>This is HTML</b>")
- doing { mail.text_part = html_mail }.should_not raise_error
- end
-
- it "should assign the html part and allow you to reference" do
- mail = Mail.new
- html_mail = Mail.new("<b>This is HTML</b>")
- mail.html_part = html_mail
- mail.html_part.should == html_mail
- end
-
- it "should add the html part and text part" do
- mail = Mail.new
- mail.text_part = Mail::Part.new do
- body "This is Text"
- end
- mail.html_part = Mail::Part.new do
- content_type = "text/html; charset=US-ASCII"
- body = "<b>This is HTML</b>"
- end
- mail.parts.length.should == 2
- mail.parts.first.class.should == Mail::Part
- mail.parts.last.class.should == Mail::Part
- end
-
- it "should set the content type to multipart/alternative if you use the html_part and text_part helpers" do
- mail = Mail.new
- mail.text_part = Mail::Part.new do
- body "This is Text"
- end
- mail.html_part = Mail::Part.new do
- content_type = "text/html; charset=US-ASCII"
- body "<b>This is HTML</b>"
- end
- mail.to_s.should =~ %r|Content-Type: multipart/alternative;\s+boundary="#{mail.boundary}"|
- end
-
- it "should add the end boundary tag" do
- mail = Mail.new
- mail.text_part = Mail::Part.new do
- body "This is Text"
- end
- mail.html_part = Mail::Part.new do
- content_type = "text/html; charset=US-ASCII"
- body "<b>This is HTML</b>"
- end
- mail.to_s.should =~ %r|#{mail.boundary}--|
- end
-
- it "should not put message-ids into parts" do
- mail = Mail.new('Subject: FooBar')
- mail.text_part = Mail::Part.new do
- body "This is Text"
- end
- mail.html_part = Mail::Part.new do
- content_type = "text/html; charset=US-ASCII"
- body "<b>This is HTML</b>"
- end
- mail.to_s
- mail.parts.first.message_id.should be_nil
- mail.parts.last.message_id.should be_nil
- end
-
- it "should create a multipart/alternative email through a block" do
- mail = Mail.new do
- to 'nicolas.fouche@gmail.com'
- from 'Mikel Lindsaar <raasdnil@gmail.com>'
- subject 'First multipart email sent with Mail'
- text_part do
- body 'This is plain text'
- end
- html_part do
- content_type 'text/html; charset=UTF-8'
- body '<h1>This is HTML</h1>'
- end
- end
- mail.should be_multipart
- mail.parts.length.should == 2
- mail.text_part.class.should == Mail::Part
- mail.text_part.body.to_s.should == 'This is plain text'
- mail.html_part.class.should == Mail::Part
- mail.html_part.body.to_s.should == '<h1>This is HTML</h1>'
- end
-
- end
-
- describe "multipart/report emails" do
-
- it "should know if it is a multipart report type" do
- mail = Mail.read(fixture('emails', 'multipart_report_emails', 'report_422.eml'))
- mail.should be_multipart_report
- end
-
- describe "delivery-status reports" do
-
- it "should know if it is a deliver-status report" do
- mail = Mail.read(fixture('emails', 'multipart_report_emails', 'report_422.eml'))
- mail.should be_delivery_status_report
- end
-
- it "should find it's message/delivery-status part" do
- mail = Mail.read(fixture('emails', 'multipart_report_emails', 'report_422.eml'))
- mail.delivery_status_part.should_not be_nil
- end
-
- describe "temporary failure" do
-
- before(:each) do
- @mail = Mail.read(fixture('emails', 'multipart_report_emails', 'report_422.eml'))
- end
-
- it "should be bounced" do
- @mail.should_not be_bounced
- end
-
- it "should say action 'delayed'" do
- @mail.action.should == 'delayed'
- end
-
- it "should give a final recipient" do
- @mail.final_recipient.should == 'RFC822; fraser@oooooooo.com.au'
- end
-
- it "should give an error code" do
- @mail.error_status.should == '4.2.2'
- end
-
- it "should give a diagostic code" do
- @mail.diagnostic_code.should == 'SMTP; 452 4.2.2 <fraser@oooooooo.com.au>... Mailbox full'
- end
-
- it "should give a remote-mta" do
- @mail.remote_mta.should == 'DNS; mail.oooooooo.com.au'
- end
-
- it "should be retryable" do
- @mail.should be_retryable
- end
- end
-
- describe "permanent failure" do
-
- before(:each) do
- @mail = Mail.read(fixture('emails', 'multipart_report_emails', 'report_530.eml'))
- end
-
- it "should be bounced" do
- @mail.should be_bounced
- end
-
- it "should say action 'failed'" do
- @mail.action.should == 'failed'
- end
-
- it "should give a final recipient" do
- @mail.final_recipient.should == 'RFC822; edwin@zzzzzzz.com'
- end
-
- it "should give an error code" do
- @mail.error_status.should == '5.3.0'
- end
-
- it "should give a diagostic code" do
- @mail.diagnostic_code.should == 'SMTP; 553 5.3.0 <edwin@zzzzzzz.com>... Unknown E-Mail Address'
- end
-
- it "should give a remote-mta" do
- @mail.remote_mta.should == 'DNS; mail.zzzzzz.com'
- end
-
- it "should be retryable" do
- @mail.should_not be_retryable
- end
- end
-
- end
-
- end
-
- describe "finding attachments" do
-
- it "should return an array of attachments" do
- mail = Mail.read(fixture('emails', 'attachment_emails', 'attachment_content_disposition.eml'))
- mail.attachments.length.should == 1
- mail.attachments.first.filename.should == 'hello.rb'
- end
-
- it "should return an array of attachments" do
- mail = Mail.read(fixture('emails', 'mime_emails', 'raw_email_with_nested_attachment.eml'))
- mail.attachments.length.should == 2
- mail.attachments[0].filename.should == 'byo-ror-cover.png'
- mail.attachments[1].filename.should == 'smime.p7s'
- end
-
- end
-
- describe "adding a file attachment" do
-
- it "should set to multipart/mixed if a text part and you add an attachment" do
- mail = Mail::Message.new
- mail.text_part { body("log message goes here") }
- mail.add_file(fixture('attachments', 'test.png'))
- mail.mime_type.should == 'multipart/mixed'
- end
-
- it "should set to multipart/mixed if you add an attachment and then a text part" do
- mail = Mail::Message.new
- mail.add_file(fixture('attachments', 'test.png'))
- mail.text_part { body("log message goes here") }
- mail.mime_type.should == 'multipart/mixed'
- end
-
- it "should add a part given a filename" do
- mail = Mail::Message.new
- mail.add_file(fixture('attachments', 'test.png'))
- mail.parts.length.should == 1 # First part is an empty text body
- end
-
- it "should give the part the right content type" do
- mail = Mail::Message.new
- mail.add_file(fixture('attachments', 'test.png'))
- mail.parts.first[:content_type].content_type.should == 'image/png'
- end
-
- it "should return attachment objects" do
- mail = Mail::Message.new
- mail.add_file(fixture('attachments', 'test.png'))
- mail.attachments.first.class.should == Mail::Part
- end
-
- it "should be return an aray of attachments" do
- mail = Mail::Message.new do
- from 'mikel@from.lindsaar.net'
- subject 'Hello there Mikel'
- to 'mikel@to.lindsaar.net'
- add_file fixture('attachments', 'test.png')
- add_file fixture('attachments', 'test.jpg')
- add_file fixture('attachments', 'test.pdf')
- add_file fixture('attachments', 'test.zip')
- end
- mail.attachments.length.should == 4
- mail.attachments.each { |a| a.class.should == Mail::Part }
- end
-
- it "should return the filename of each attachment" do
- mail = Mail::Message.new do
- from 'mikel@from.lindsaar.net'
- subject 'Hello there Mikel'
- to 'mikel@to.lindsaar.net'
- add_file fixture('attachments', 'test.png')
- add_file fixture('attachments', 'test.jpg')
- add_file fixture('attachments', 'test.pdf')
- add_file fixture('attachments', 'test.zip')
- end
- mail.attachments[0].filename.should == 'test.png'
- mail.attachments[1].filename.should == 'test.jpg'
- mail.attachments[2].filename.should == 'test.pdf'
- mail.attachments[3].filename.should == 'test.zip'
- end
-
- it "should return the mime/type of each attachment" do
- mail = Mail::Message.new do
- from 'mikel@from.lindsaar.net'
- subject 'Hello there Mikel'
- to 'mikel@to.lindsaar.net'
- add_file fixture('attachments', 'test.png')
- add_file fixture('attachments', 'test.jpg')
- add_file fixture('attachments', 'test.pdf')
- add_file fixture('attachments', 'test.zip')
- end
- mail.attachments[0].mime_type.should == 'image/png'
- mail.attachments[1].mime_type.should == 'image/jpeg'
- mail.attachments[2].mime_type.should == 'application/pdf'
- mail.attachments[3].mime_type.should == 'application/zip'
- end
-
- it "should return the content of each attachment" do
- mail = Mail::Message.new do
- from 'mikel@from.lindsaar.net'
- subject 'Hello there Mikel'
- to 'mikel@to.lindsaar.net'
- add_file fixture('attachments', 'test.png')
- add_file fixture('attachments', 'test.jpg')
- add_file fixture('attachments', 'test.pdf')
- add_file fixture('attachments', 'test.zip')
- end
- if RUBY_VERSION >= '1.9'
- tripped = mail.attachments[0].decoded
- original = File.read(fixture('attachments', 'test.png')).force_encoding(Encoding::BINARY)
- tripped.should == original
- tripped = mail.attachments[1].decoded
- original = File.read(fixture('attachments', 'test.jpg')).force_encoding(Encoding::BINARY)
- tripped.should == original
- tripped = mail.attachments[2].decoded
- original = File.read(fixture('attachments', 'test.pdf')).force_encoding(Encoding::BINARY)
- tripped.should == original
- tripped = mail.attachments[3].decoded
- original = File.read(fixture('attachments', 'test.zip')).force_encoding(Encoding::BINARY)
- tripped.should == original
- else
- mail.attachments[0].decoded.should == File.read(fixture('attachments', 'test.png'))
- mail.attachments[1].decoded.should == File.read(fixture('attachments', 'test.jpg'))
- mail.attachments[2].decoded.should == File.read(fixture('attachments', 'test.pdf'))
- mail.attachments[3].decoded.should == File.read(fixture('attachments', 'test.zip'))
- end
- end
-
- it "should allow you to send in file data instead of having to read it" do
- file_data = File.read(fixture('attachments', 'test.png'))
- mail = Mail::Message.new do
- from 'mikel@from.lindsaar.net'
- subject 'Hello there Mikel'
- to 'mikel@to.lindsaar.net'
- add_file(:filename => 'test.png', :content => file_data)
- end
- if RUBY_VERSION >= '1.9'
- tripped = mail.attachments[0].decoded
- original = File.read(fixture('attachments', 'test.png')).force_encoding(Encoding::BINARY)
- tripped.should == original
- else
- mail.attachments[0].decoded.should == File.read(fixture('attachments', 'test.png'))
- end
- end
-
- it "should be able to add a body before adding a file" do
- m = Mail.new do
- from 'mikel@from.lindsaar.net'
- subject 'Hello there Mikel'
- to 'mikel@to.lindsaar.net'
- body "Attached"
- add_file fixture('attachments', 'test.png')
- end
- m.attachments.length.should == 1
- m.parts.length.should == 2
- m.parts[0].body.should == "Attached"
- m.parts[1].filename.should == "test.png"
- end
-
- it "should allow you to add a body as text part if you have added a file" do
- m = Mail.new do
- from 'mikel@from.lindsaar.net'
- subject 'Hello there Mikel'
- to 'mikel@to.lindsaar.net'
- add_file fixture('attachments', 'test.png')
- body "Attached"
- end
- m.parts.length.should == 2
- m.parts.first[:content_type].content_type.should == 'image/png'
- m.parts.last[:content_type].content_type.should == 'text/plain'
- end
-
+ it "should allow you to init on an array of addresses directly" do
+ mail = Mail.new
+ mail[:to] = ['test1@lindsaar.net', 'Mikel <test2@lindsaar.net>']
+ mail.to.should == ['test1@lindsaar.net', 'test2@lindsaar.net']
end
+ end
+
end
-
+
describe "handling missing required fields:" do
describe "every email" do
@@ -1727,4 +1262,12 @@ def basic_email
mail.parts.first.parts[1].body.decoded.should == "<b>test</b> HTML<br/>\nline #2"
end
end
+
+ describe "deliver" do
+ it "should return self after delivery" do
+ mail = Mail.new
+ mail.perform_deliveries = false
+ mail.deliver.should == mail
+ end
+ end
end
View
391 spec/mail/mime_messages_spec.rb
@@ -0,0 +1,391 @@
+# encoding: utf-8
+require File.join(File.dirname(File.expand_path(__FILE__)), '..', 'spec_helper')
+
+describe "MIME Emails" do
+
+ describe "general helper methods" do
+
+ it "should read a mime version from an email" do
+ mail = Mail.new("Mime-Version: 1.0")
+ mail.mime_version.should == '1.0'
+ end
+
+ it "should return nil if the email has no mime version" do
+ mail = Mail.new("To: bob")
+ mail.mime_version.should == nil
+ end
+
+ it "should read the content-transfer-encoding" do
+ mail = Mail.new("Content-Transfer-Encoding: quoted-printable")
+ mail.content_transfer_encoding.should == 'quoted-printable'
+ end
+
+ it "should read the content-description" do
+ mail = Mail.new("Content-Description: This is a description")
+ mail.content_description.should == 'This is a description'
+ end
+
+ it "should return the content-type" do
+ mail = Mail.new("Content-Type: text/plain")
+ mail.mime_type.should == 'text/plain'
+ end
+
+ it "should return the charset" do
+ mail = Mail.new("Content-Type: text/plain; charset=utf-8")
+ mail.charset.should == 'utf-8'
+ end
+
+ it "should allow you to set the charset" do
+ mail = Mail.new
+ mail.charset = 'utf-8'
+ mail.charset.should == 'utf-8'
+ end
+
+ it "should return the main content-type" do
+ mail = Mail.new("Content-Type: text/plain")
+ mail.main_type.should == 'text'
+ end
+
+ it "should return the sub content-type" do
+ mail = Mail.new("Content-Type: text/plain")
+ mail.sub_type.should == 'plain'
+ end
+
+ it "should return the content-type parameters" do
+ mail = Mail.new("Content-Type: text/plain; charset=US-ASCII; format=flowed")
+ mail.content_type_parameters.should == {'charset' => 'US-ASCII', 'format' => 'flowed'}
+ end
+
+ it "should recognize a multipart email" do
+ mail = Mail.read(fixture('emails', 'mime_emails', 'raw_email7.eml'))
+ mail.should be_multipart
+ end
+
+ it "should recognize a non multipart email" do
+ mail = Mail.read(fixture('emails', 'plain_emails', 'basic_email.eml'))
+ mail.should_not be_multipart
+ end
+
+ it "should give how may (top level) parts there are" do
+ mail = Mail.read(fixture('emails', 'mime_emails', 'raw_email7.eml'))
+ mail.parts.length.should == 2
+ end
+
+ it "should give the content_type of each part" do
+ mail = Mail.read(fixture('emails', 'mime_emails', 'raw_email11.eml'))
+ mail.mime_type.should == 'multipart/alternative'
+ mail.parts[0].mime_type.should == 'text/plain'
+ mail.parts[1].mime_type.should == 'text/enriched'
+ end
+
+ it "should report the mail :has_attachments?" do
+ mail = Mail.read(fixture(File.join('emails', 'attachment_emails', 'attachment_pdf.eml')))
+ mail.should be_has_attachments
+ end
+
+ end
+
+ describe "multipart emails" do
+ it "should add a boundary if there is none defined and a part is added" do
+ mail = Mail.new do
+ part('This is a part')
+ part('This is another part')
+ end
+ mail.boundary.should_not be_nil
+ end
+
+ it "should not add a boundary for a message that is only an attachment" do
+ mail = Mail.new
+ mail.attachments['test.png'] = "2938492384923849"
+ mail.boundary.should be_nil
+ end
+ end
+
+ describe "multipart/alternative emails" do
+
+ it "should know what it's boundary is if it is a multipart document" do
+ mail = Mail.new('Content-Type: multitype/mixed; boundary="--==Boundary"')
+ mail.boundary.should == "--==Boundary"
+ end
+
+ it "should return nil if there is no content-type defined" do
+ mail = Mail.new
+ mail.boundary.should == nil
+ end
+
+ it "should allow you to assign a text part" do
+ mail = Mail.new
+ text_mail = Mail.new("This is Text")
+ doing { mail.text_part = text_mail }.should_not raise_error
+ end
+
+ it "should assign the text part and allow you to reference" do
+ mail = Mail.new
+ text_mail = Mail.new("This is Text")
+ mail.text_part = text_mail
+ mail.text_part.should == text_mail
+ end
+
+ it "should allow you to assign a html part" do
+ mail = Mail.new
+ html_mail = Mail.new("<b>This is HTML</b>")
+ doing { mail.text_part = html_mail }.should_not raise_error
+ end
+
+ it "should assign the html part and allow you to reference" do
+ mail = Mail.new
+ html_mail = Mail.new("<b>This is HTML</b>")
+ mail.html_part = html_mail
+ mail.html_part.should == html_mail
+ end
+
+ it "should add the html part and text part" do
+ mail = Mail.new
+ mail.text_part = Mail::Part.new do
+ body "This is Text"
+ end
+ mail.html_part = Mail::Part.new do
+ content_type = "text/html; charset=US-ASCII"
+ body = "<b>This is HTML</b>"
+ end
+ mail.parts.length.should == 2
+ mail.parts.first.class.should == Mail::Part
+ mail.parts.last.class.should == Mail::Part
+ end
+
+ it "should set the content type to multipart/alternative if you use the html_part and text_part helpers" do
+ mail = Mail.new
+ mail.text_part = Mail::Part.new do
+ body "This is Text"
+ end
+ mail.html_part = Mail::Part.new do
+ content_type = "text/html; charset=US-ASCII"
+ body "<b>This is HTML</b>"
+ end
+ mail.to_s.should =~ %r|Content-Type: multipart/alternative;\s+boundary="#{mail.boundary}"|
+ end
+
+ it "should add the end boundary tag" do
+ mail = Mail.new
+ mail.text_part = Mail::Part.new do
+ body "This is Text"
+ end
+ mail.html_part = Mail::Part.new do
+ content_type = "text/html; charset=US-ASCII"
+ body "<b>This is HTML</b>"
+ end
+ mail.to_s.should =~ %r|#{mail.boundary}--|
+ end
+
+ it "should not put message-ids into parts" do
+ mail = Mail.new('Subject: FooBar')
+ mail.text_part = Mail::Part.new do
+ body "This is Text"
+ end
+ mail.html_part = Mail::Part.new do
+ content_type = "text/html; charset=US-ASCII"
+ body "<b>This is HTML</b>"
+ end
+ mail.to_s
+ mail.parts.first.message_id.should be_nil
+ mail.parts.last.message_id.should be_nil
+ end
+
+ it "should create a multipart/alternative email through a block" do
+ mail = Mail.new do
+ to 'nicolas.fouche@gmail.com'
+ from 'Mikel Lindsaar <raasdnil@gmail.com>'
+ subject 'First multipart email sent with Mail'
+ text_part do
+ body 'This is plain text'
+ end
+ html_part do
+ content_type 'text/html; charset=UTF-8'
+ body '<h1>This is HTML</h1>'
+ end
+ end
+ mail.should be_multipart
+ mail.parts.length.should == 2
+ mail.text_part.class.should == Mail::Part
+ mail.text_part.body.to_s.should == 'This is plain text'
+ mail.html_part.class.should == Mail::Part
+ mail.html_part.body.to_s.should == '<h1>This is HTML</h1>'
+ end
+
+ end
+
+ describe "finding attachments" do
+
+ it "should return an array of attachments" do
+ mail = Mail.read(fixture('emails', 'attachment_emails', 'attachment_content_disposition.eml'))
+ mail.attachments.length.should == 1
+ mail.attachments.first.filename.should == 'hello.rb'
+ end
+
+ it "should return an array of attachments" do
+ mail = Mail.read(fixture('emails', 'mime_emails', 'raw_email_with_nested_attachment.eml'))
+ mail.attachments.length.should == 2
+ mail.attachments[0].filename.should == 'byo-ror-cover.png'
+ mail.attachments[1].filename.should == 'smime.p7s'
+ end
+
+ end
+
+ describe "adding a file attachment" do
+
+ it "should set to multipart/mixed if a text part and you add an attachment" do
+ mail = Mail::Message.new
+ mail.text_part { body("log message goes here") }
+ mail.add_file(fixture('attachments', 'test.png'))
+ mail.mime_type.should == 'multipart/mixed'
+ end
+
+ it "should set to multipart/mixed if you add an attachment and then a text part" do
+ mail = Mail::Message.new
+ mail.add_file(fixture('attachments', 'test.png'))
+ mail.text_part { body("log message goes here") }
+ mail.mime_type.should == 'multipart/mixed'
+ end
+
+ it "should add a part given a filename" do
+ mail = Mail::Message.new
+ mail.add_file(fixture('attachments', 'test.png'))
+ mail.parts.length.should == 1 # First part is an empty text body
+ end
+
+ it "should give the part the right content type" do
+ mail = Mail::Message.new
+ mail.add_file(fixture('attachments', 'test.png'))
+ mail.parts.first[:content_type].content_type.should == 'image/png'
+ end
+
+ it "should return attachment objects" do
+ mail = Mail::Message.new
+ mail.add_file(fixture('attachments', 'test.png'))
+ mail.attachments.first.class.should == Mail::Part
+ end
+
+ it "should be return an aray of attachments" do
+ mail = Mail::Message.new do
+ from 'mikel@from.lindsaar.net'
+ subject 'Hello there Mikel'
+ to 'mikel@to.lindsaar.net'
+ add_file fixture('attachments', 'test.png')
+ add_file fixture('attachments', 'test.jpg')
+ add_file fixture('attachments', 'test.pdf')
+ add_file fixture('attachments', 'test.zip')
+ end
+ mail.attachments.length.should == 4
+ mail.attachments.each { |a| a.class.should == Mail::Part }
+ end
+
+ it "should return the filename of each attachment" do
+ mail = Mail::Message.new do
+ from 'mikel@from.lindsaar.net'
+ subject 'Hello there Mikel'
+ to 'mikel@to.lindsaar.net'
+ add_file fixture('attachments', 'test.png')
+ add_file fixture('attachments', 'test.jpg')
+ add_file fixture('attachments', 'test.pdf')
+ add_file fixture('attachments', 'test.zip')
+ end
+ mail.attachments[0].filename.should == 'test.png'
+ mail.attachments[1].filename.should == 'test.jpg'
+ mail.attachments[2].filename.should == 'test.pdf'
+ mail.attachments[3].filename.should == 'test.zip'
+ end
+
+ it "should return the mime/type of each attachment" do
+ mail = Mail::Message.new do
+ from 'mikel@from.lindsaar.net'
+ subject 'Hello there Mikel'
+ to 'mikel@to.lindsaar.net'
+ add_file fixture('attachments', 'test.png')
+ add_file fixture('attachments', 'test.jpg')
+ add_file fixture('attachments', 'test.pdf')
+ add_file fixture('attachments', 'test.zip')
+ end
+ mail.attachments[0].mime_type.should == 'image/png'
+ mail.attachments[1].mime_type.should == 'image/jpeg'
+ mail.attachments[2].mime_type.should == 'application/pdf'
+ mail.attachments[3].mime_type.should == 'application/zip'
+ end
+
+ it "should return the content of each attachment" do
+ mail = Mail::Message.new do
+ from 'mikel@from.lindsaar.net'
+ subject 'Hello there Mikel'
+ to 'mikel@to.lindsaar.net'
+ add_file fixture('attachments', 'test.png')
+ add_file fixture('attachments', 'test.jpg')
+ add_file fixture('attachments', 'test.pdf')
+ add_file fixture('attachments', 'test.zip')
+ end
+ if RUBY_VERSION >= '1.9'
+ tripped = mail.attachments[0].decoded
+ original = File.read(fixture('attachments', 'test.png')).force_encoding(Encoding::BINARY)
+ tripped.should == original
+ tripped = mail.attachments[1].decoded
+ original = File.read(fixture('attachments', 'test.jpg')).force_encoding(Encoding::BINARY)
+ tripped.should == original
+ tripped = mail.attachments[2].decoded
+ original = File.read(fixture('attachments', 'test.pdf')).force_encoding(Encoding::BINARY)
+ tripped.should == original
+ tripped = mail.attachments[3].decoded
+ original = File.read(fixture('attachments', 'test.zip')).force_encoding(Encoding::BINARY)
+ tripped.should == original
+ else
+ mail.attachments[0].decoded.should == File.read(fixture('attachments', 'test.png'))
+ mail.attachments[1].decoded.should == File.read(fixture('attachments', 'test.jpg'))
+ mail.attachments[2].decoded.should == File.read(fixture('attachments', 'test.pdf'))
+ mail.attachments[3].decoded.should == File.read(fixture('attachments', 'test.zip'))
+ end
+ end
+
+ it "should allow you to send in file data instead of having to read it" do
+ file_data = File.read(fixture('attachments', 'test.png'))
+ mail = Mail::Message.new do
+ from 'mikel@from.lindsaar.net'
+ subject 'Hello there Mikel'
+ to 'mikel@to.lindsaar.net'
+ add_file(:filename => 'test.png', :content => file_data)
+ end
+ if RUBY_VERSION >= '1.9'
+ tripped = mail.attachments[0].decoded
+ original = File.read(fixture('attachments', 'test.png')).force_encoding(Encoding::BINARY)
+ tripped.should == original
+ else
+ mail.attachments[0].decoded.should == File.read(fixture('attachments', 'test.png'))
+ end
+ end
+
+ it "should be able to add a body before adding a file" do
+ m = Mail.new do
+ from 'mikel@from.lindsaar.net'
+ subject 'Hello there Mikel'
+ to 'mikel@to.lindsaar.net'
+ body "Attached"
+ add_file fixture('attachments', 'test.png')
+ end
+ m.attachments.length.should == 1
+ m.parts.length.should == 2
+ m.parts[0].body.should == "Attached"
+ m.parts[1].filename.should == "test.png"
+ end
+
+ it "should allow you to add a body as text part if you have added a file" do
+ m = Mail.new do
+ from 'mikel@from.lindsaar.net'
+ subject 'Hello there Mikel'
+ to 'mikel@to.lindsaar.net'
+ add_file fixture('attachments', 'test.png')
+ body "Attached"
+ end
+ m.parts.length.should == 2
+ m.parts.first[:content_type].content_type.should == 'image/png'
+ m.parts.last[:content_type].content_type.should == 'text/plain'
+ end
+
+ end
+
+end
View
96 spec/mail/multipart_report_spec.rb
@@ -0,0 +1,96 @@
+# encoding: utf-8
+require File.join(File.dirname(File.expand_path(__FILE__)), '..', 'spec_helper')
+
+describe "multipart/report emails" do
+
+ it "should know if it is a multipart report type" do
+ mail = Mail.read(fixture('emails', 'multipart_report_emails', 'report_422.eml'))
+ mail.should be_multipart_report
+ end
+
+ describe "delivery-status reports" do
+
+ it "should know if it is a deliver-status report" do
+ mail = Mail.read(fixture('emails', 'multipart_report_emails', 'report_422.eml'))
+ mail.should be_delivery_status_report
+ end
+
+ it "should find it's message/delivery-status part" do
+ mail = Mail.read(fixture('emails', 'multipart_report_emails', 'report_422.eml'))
+ mail.delivery_status_part.should_not be_nil
+ end
+
+ describe "temporary failure" do
+
+ before(:each) do
+ @mail = Mail.read(fixture('emails', 'multipart_report_emails', 'report_422.eml'))
+ end
+
+ it "should be bounced" do
+ @mail.should_not be_bounced
+ end
+
+ it "should say action 'delayed'" do
+ @mail.action.should == 'delayed'
+ end
+
+ it "should give a final recipient" do
+ @mail.final_recipient.should == 'RFC822; fraser@oooooooo.com.au'
+ end
+
+ it "should give an error code" do
+ @mail.error_status.should == '4.2.2'
+ end
+
+ it "should give a diagostic code" do
+ @mail.diagnostic_code.should == 'SMTP; 452 4.2.2 <fraser@oooooooo.com.au>... Mailbox full'
+ end
+
+ it "should give a remote-mta" do
+ @mail.remote_mta.should == 'DNS; mail.oooooooo.com.au'
+ end
+
+ it "should be retryable" do
+ @mail.should be_retryable
+ end
+ end
+
+ describe "permanent failure" do
+
+ before(:each) do
+ @mail = Mail.read(fixture('emails', 'multipart_report_emails', 'report_530.eml'))
+ end
+
+ it "should be bounced" do
+ @mail.should be_bounced
+ end
+
+ it "should say action 'failed'" do
+ @mail.action.should == 'failed'
+ end
+
+ it "should give a final recipient" do
+ @mail.final_recipient.should == 'RFC822; edwin@zzzzzzz.com'
+ end
+
+ it "should give an error code" do
+ @mail.error_status.should == '5.3.0'
+ end
+
+ it "should give a diagostic code" do
+ @mail.diagnostic_code.should == 'SMTP; 553 5.3.0 <edwin@zzzzzzz.com>... Unknown E-Mail Address'
+ end
+
+ it "should give a remote-mta" do
+ @mail.remote_mta.should == 'DNS; mail.zzzzzz.com'
+ end
+
+ it "should be retryable" do
+ @mail.should_not be_retryable
+ end
+ end
+
+ end
+
+end
+
View
22 spec/mail/network/delivery_methods/test_mailer_spec.rb
@@ -1,7 +1,7 @@
# encoding: utf-8
require File.join(File.dirname(File.expand_path(__FILE__)), '..', '..', '..', 'spec_helper')
-describe "TestMailer" do
+describe "Mail::TestMailer" do
before(:each) do
# Reset all defaults back to original state
Mail.defaults do
@@ -12,18 +12,18 @@
:password => nil,
:authentication => nil,
:enable_starttls_auto => true }
+ Mail::TestMailer.deliveries.clear
end
- Mail.deliveries.clear
end
it "should have no deliveries when first initiated" do
Mail.defaults do
delivery_method :test
end
- Mail.deliveries.should be_empty
+ Mail::TestMailer.deliveries.should be_empty
end
- it "should deliver an email to the Mail.deliveries array" do
+ it "should deliver an email to the Mail::TestMailer.deliveries array" do
Mail.defaults do
delivery_method :test
end
@@ -33,9 +33,9 @@
subject 'testing'
body 'hello'
end
- mail.deliver!
- Mail.deliveries.length.should == 1
- Mail.deliveries.first.should == mail
+ mail.deliver
+ Mail::TestMailer.deliveries.length.should == 1
+ Mail::TestMailer.deliveries.first.should == mail
end
it "should clear the deliveries when told to" do
@@ -48,10 +48,10 @@
subject 'testing'
body 'hello'
end
- mail.deliver!
- Mail.deliveries.length.should == 1
- Mail.deliveries.clear
- Mail.deliveries.should be_empty
+ mail.deliver
+ Mail::TestMailer.deliveries.length.should == 1
+ Mail::TestMailer.deliveries.clear
+ Mail::TestMailer.deliveries.should be_empty
end
end
View
156 spec/mail/network_spec.rb
@@ -167,7 +167,7 @@ class MyRetriever; def initialize(settings); end; end
end
describe "sending emails via SMTP" do
-
+
before(:each) do
# Set the delivery method to test as the default
MockSMTP.clear_deliveries
@@ -205,7 +205,7 @@ class MyRetriever; def initialize(settings); end; end
end
- describe "deliveries, perform delivery and observers" do
+ describe "deliveries" do
class MyDeliveryMethod
attr_accessor :settings
@@ -217,56 +217,142 @@ class MyObserver
def self.delivered_email(message); end
end
- def message
- @message ||= Mail.new do
+ class MyDeliveryHandler
+ def deliver_mail(mail)
+ mail.deliver!
+ end
+ end
+
+ class MyYieldingDeliveryHandler
+ def deliver_mail(mail)
+ yield
+ end
+ end
+
+ before(:each) do
+ @message = Mail.new do
from 'mikel@test.lindsaar.net'
to 'ada@test.lindsaar.net'
subject 'Re: No way!'
body 'Yeah sure'
end
+ @message.delivery_method :test
end
- it "should add itself to the deliveries collection on mail on delivery" do
- Mail.deliveries.clear
- message.deliver
- Mail.deliveries.length.should == 1
+ describe "adding to Mail.deliveries" do
+ it "should add itself to the deliveries collection on mail on delivery" do
+ doing { @message.deliver }.should change(Mail::TestMailer.deliveries, :size).by(1)
+ end
end
+
+ describe "perform_deliveries" do
+ it "should call deliver! on the delivery method by default" do
+ delivery_agent = MyDeliveryMethod.new
+ @message.should_receive(:delivery_method).and_return(delivery_agent)
+ delivery_agent.should_receive(:deliver!).with(@message)
+ @message.deliver
+ end
- it "should call deliver on the delivery method by default" do
- delivery_agent = MyDeliveryMethod.new
- message.should_receive(:delivery_method).and_return(delivery_agent)
- delivery_agent.should_receive(:deliver!).with(message)
- message.deliver
- end
+ it "should not call deliver if perform deliveries is set to false" do
+ @message.perform_deliveries = false
+ delivery_agent = MyDeliveryMethod.new
+ @message.should_not_receive(:delivery_method).and_return(delivery_agent)
+ delivery_agent.should_not_receive(:deliver!)
+ @message.deliver
+ end
+
+ it "should add to the deliveries array if perform_deliveries is true" do
+ @message.perform_deliveries = true
+ doing { @message.deliver }.should change(Mail::TestMailer.deliveries, :size).by(1)
+ end
- it "should not call deliver if perform deliveries is set to false" do
- message.perform_deliveries = false
- delivery_agent = MyDeliveryMethod.new
- message.should_not_receive(:delivery_method).and_return(delivery_agent)
- delivery_agent.should_not_receive(:deliver!)
- message.deliver
+ it "should not add to the deliveries array if perform_deliveries is false" do
+ @message.perform_deliveries = false
+ doing { @message.deliver }.should_not change(Mail::TestMailer.deliveries, :size)
+ end
end
- it "should tell it's observers that it was told to deliver an email" do
- message.register_for_delivery_notification(MyObserver)
- MyObserver.should_receive(:delivered_email).with(message).once
- message.deliver
+ describe "observers" do
+ it "should tell it's observers that it was told to deliver an email" do
+ @message.register_for_delivery_notification(MyObserver)
+ MyObserver.should_receive(:delivered_email).with(@message).once
+ @message.deliver
+ end
+
+ it "should tell it's observers that it was told to deliver an email even if perform_deliveries is false" do
+ @message.register_for_delivery_notification(MyObserver)
+ @message.perform_deliveries = false
+ MyObserver.should_receive(:delivered_email).with(@message).once
+ @message.deliver
+ end
+
+ it "should tell it's observers that it was told to deliver an email even if it is using a delivery_handler" do
+ @message.delivery_handler = MyDeliveryHandler.new
+ @message.register_for_delivery_notification(MyObserver)
+ @message.perform_deliveries = false
+ MyObserver.should_receive(:delivered_email).with(@message).once
+ @message.deliver
+ end
+
end
- it "should pass on delivery errors if raised" do
- delivery_agent = MyDeliveryMethod.new
- message.stub!(:delivery_method).and_return(delivery_agent)
- delivery_agent.stub!(:deliver!).and_raise(Exception)
- doing { message.deliver }.should raise_error(Exception)
+ describe "raise_delivery_errors" do
+ it "should pass on delivery errors if raised" do
+ delivery_agent = MyDeliveryMethod.new
+ @message.stub!(:delivery_method).and_return(delivery_agent)
+ delivery_agent.stub!(:deliver!).and_raise(Exception)
+ doing { @message.deliver }.should raise_error(Exception)
+ end
+
+ it "should not pass on delivery errors if raised raise_delivery_errors is set to false" do
+ delivery_agent = MyDeliveryMethod.new
+ @message.stub!(:delivery_method).and_return(delivery_agent)
+ @message.raise_delivery_errors = false
+ delivery_agent.stub!(:deliver!).and_raise(Exception)
+ doing { @message.deliver }.should_not raise_error(Exception)
+ end
end
- it "should not pass on delivery errors if raised raise_delivery_errors is set to false" do
- delivery_agent = MyDeliveryMethod.new
- message.stub!(:delivery_method).and_return(delivery_agent)
- message.raise_delivery_errors = false
- delivery_agent.stub!(:deliver!).and_raise(Exception)
- doing { message.deliver }.should_not raise_error(Exception)
+ describe "delivery_handler" do
+
+ it "should allow you to hand off performing the actual delivery to another object" do
+ delivery_handler = MyDeliveryHandler.new
+ delivery_handler.should_receive(:deliver_mail).with(@message).exactly(:once)
+ @message.delivery_handler = delivery_handler
+ @message.deliver
+ end
+
+ it "mail should be told to :deliver once and then :deliver! once by the delivery handler" do
+ @message.delivery_handler = MyDeliveryHandler.new
+ @message.should_receive(:deliver!).exactly(:once)
+ @message.deliver
+ end
+
+ it "mail only call it's delivery_method once" do
+ @message.delivery_handler = MyDeliveryHandler.new
+ @message.should_receive(:delivery_method).exactly(:once).and_return(Mail::TestMailer.new({}))
+ @message.deliver
+ end
+
+ it "mail should not catch any exceptions when using a delivery_handler" do
+ @message.delivery_handler = MyDeliveryHandler.new
+ @message.should_receive(:delivery_method).and_raise(Exception)
+ doing { @message.deliver }.should raise_error(Exception)
+ end
+
+ it "mail should not modify the Mail.deliveries object if using a delivery_handler" do
+ @message.delivery_handler = MyDeliveryHandler.new
+ doing { @message.deliver }.should_not change(Mail::TestMailer, :deliveries)
+ end
+
+ it "should be able to just yield and let mail do it's thing" do
+ @message.delivery_handler = MyYieldingDeliveryHandler.new
+ @message.should_receive(:do_delivery).exactly(:once)
+ @message.deliver
+ end
+
end
+
end
end

0 comments on commit a8b7096

Please sign in to comment.
Something went wrong with that request. Please try again.