Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

488 lines (421 sloc) 19.104 kb
# encoding: utf-8
require '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 eq '1.0'
end
it "should return nil if the email has no mime version" do
mail = Mail.new("To: bob")
mail.mime_version.should eq nil
end
it "should read the content-transfer-encoding" do
mail = Mail.new("Content-Transfer-Encoding: quoted-printable")
mail.content_transfer_encoding.should eq 'quoted-printable'
end
it "should read the content-description" do
mail = Mail.new("Content-Description: This is a description")
mail.content_description.should eq 'This is a description'
end
it "should return the content-type" do
mail = Mail.new("Content-Type: text/plain")
mail.mime_type.should eq 'text/plain'
end
it "should return the charset" do
mail = Mail.new("Content-Type: text/plain; charset=utf-8")
mail.charset.should eq 'utf-8'
end
it "should allow you to set the charset" do
mail = Mail.new
mail.charset = 'utf-8'
mail.charset.should eq 'utf-8'
end
it "should return the main content-type" do
mail = Mail.new("Content-Type: text/plain")
mail.main_type.should eq 'text'
end
it "should return the sub content-type" do
mail = Mail.new("Content-Type: text/plain")
mail.sub_type.should eq '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 eql({"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 not report the email as :attachment?" do
mail = Mail.read(fixture(File.join('emails', 'attachment_emails', 'attachment_pdf.eml')))
mail.attachment?.should eq false
end
it "should report the email as :attachment?" do
mail = Mail.read(fixture(File.join('emails', 'attachment_emails', 'attachment_only_email.eml')))
mail.attachment?.should eq true
end
it "should recognize an attachment part" do
mail = Mail.read(fixture(File.join('emails', 'attachment_emails', 'attachment_pdf.eml')))
mail.should_not be_attachment
mail.parts[0].attachment?.should eq false
mail.parts[1].attachment?.should eq true
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 eq 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 eq 'multipart/alternative'
mail.parts[0].mime_type.should eq 'text/plain'
mail.parts[1].mime_type.should eq '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: multipart/mixed; boundary="--==Boundary"')
mail.boundary.should eq "--==Boundary"
end
it "should return nil if there is no content-type defined" do
mail = Mail.new
mail.boundary.should eq 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 eq 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 eq 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 eq 2
mail.parts.first.class.should eq Mail::Part
mail.parts.last.class.should eq 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 eq 2
mail.text_part.class.should eq Mail::Part
mail.text_part.body.to_s.should eq 'This is plain text'
mail.html_part.class.should eq Mail::Part
mail.html_part.body.to_s.should eq '<h1>This is HTML</h1>'
end
it "should detect an html_part in an existing email" do
m = Mail.new(:content_type => 'multipart/alternative')
m.add_part(Mail::Part.new(:content_type => 'text/html', :body => 'HTML TEXT'))
m.add_part(Mail::Part.new(:content_type => 'text/plain', :body => 'PLAIN TEXT'))
m.text_part.body.decoded.should eq 'PLAIN TEXT'
m.html_part.body.decoded.should eq 'HTML TEXT'
end
it "should detect a text_part in an existing email with plain text attachment" do
m = Mail.new(:content_type => 'multipart/alternative')
m.add_file(fixture('attachments', 'てすと.txt'))
m.add_part(Mail::Part.new(:content_type => 'text/html', :body => 'HTML TEXT'))
m.add_part(Mail::Part.new(:content_type => 'text/plain', :body => 'PLAIN TEXT'))
m.text_part.body.decoded.should eq 'PLAIN TEXT'
m.html_part.body.decoded.should eq 'HTML TEXT'
end
it "should detect an html_part in a multi level mime email" do
m = Mail.new(:content_type => 'multipart/mixed')
a = Mail::Part.new(:content_type => 'text/script', :body => '12345')
p = Mail::Part.new(:content_type => 'multipart/alternative')
p.add_part(Mail::Part.new(:content_type => 'text/html', :body => 'HTML TEXT'))
p.add_part(Mail::Part.new(:content_type => 'text/plain', :body => 'PLAIN TEXT'))
m.add_part(p)
m.add_part(a)
m.text_part.body.decoded.should eq 'PLAIN TEXT'
m.html_part.body.decoded.should eq 'HTML TEXT'
end
it "should only the first part on a stupidly overly complex email" do
m = Mail.new(:content_type => 'multipart/mixed')
a = Mail::Part.new(:content_type => 'text/script', :body => '12345')
m.add_part(a)
b = Mail::Part.new(:content_type => 'multipart/alternative')
b.add_part(Mail::Part.new(:content_type => 'text/html', :body => 'HTML TEXT'))
b.add_part(Mail::Part.new(:content_type => 'text/plain', :body => 'PLAIN TEXT'))
m.add_part(b)
c = Mail::Part.new(:content_type => 'multipart/alternative')
c.add_part(Mail::Part.new(:content_type => 'text/html', :body => 'HTML 2 TEXT'))
c.add_part(Mail::Part.new(:content_type => 'text/plain', :body => 'PLAIN 2 TEXT'))
b.add_part(c)
d = Mail::Part.new(:content_type => 'multipart/alternative')
d.add_part(Mail::Part.new(:content_type => 'text/html', :body => 'HTML 3 TEXT'))
d.add_part(Mail::Part.new(:content_type => 'text/plain', :body => 'PLAIN 3 TEXT'))
b.add_part(d)
m.text_part.body.decoded.should eq 'PLAIN TEXT'
m.html_part.body.decoded.should eq 'HTML TEXT'
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 eq 1
mail.attachments.first.filename.should eq '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 eq 2
mail.attachments[0].filename.should eq 'byo-ror-cover.png'
mail.attachments[1].filename.should eq '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 eq '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 eq '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 eq 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 eq '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 eq 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 eq 4
mail.attachments.each { |a| a.class.should eq 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 eq 'test.png'
mail.attachments[1].filename.should eq 'test.jpg'
mail.attachments[2].filename.should eq 'test.pdf'
mail.attachments[3].filename.should eq 'test.zip'
end
it "should return the type/subtype 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 eq 'image/png'
mail.attachments[1].mime_type.should eq 'image/jpeg'
mail.attachments[2].mime_type.should eq 'application/pdf'
mail.attachments[3].mime_type.should eq '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 eq original
tripped = mail.attachments[1].decoded
original = File.read(fixture('attachments', 'test.jpg')).force_encoding(Encoding::BINARY)
tripped.should eq original
tripped = mail.attachments[2].decoded
original = File.read(fixture('attachments', 'test.pdf')).force_encoding(Encoding::BINARY)
tripped.should eq original
tripped = mail.attachments[3].decoded
original = File.read(fixture('attachments', 'test.zip')).force_encoding(Encoding::BINARY)
tripped.should eq original
else
mail.attachments[0].decoded.should eq File.read(fixture('attachments', 'test.png'))
mail.attachments[1].decoded.should eq File.read(fixture('attachments', 'test.jpg'))
mail.attachments[2].decoded.should eq File.read(fixture('attachments', 'test.pdf'))
mail.attachments[3].decoded.should eq 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 eq original
else
mail.attachments[0].decoded.should eq 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 eq 1
m.parts.length.should eq 2
m.parts[0].body.should eq "Attached"
m.parts[1].filename.should eq "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 eq 2
m.parts.first[:content_type].content_type.should eq 'image/png'
m.parts.last[:content_type].content_type.should eq 'text/plain'
end
it "should allow you to add a body as text part if you have added a file and not truncate after newlines - issue 208" 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 "First Line\n\nSecond Line\n\nThird Line\n\n"
#Note: trailing \n\n is stripped off by Mail::Part initialization
end
m.parts.length.should eq 2
m.parts.first[:content_type].content_type.should eq 'image/png'
m.parts.last[:content_type].content_type.should eq 'text/plain'
m.parts.last.to_s.should match(/^First Line\r\n\r\nSecond Line\r\n\r\nThird Line/)
end
it "should not raise a warning if there is a charset defined and there are non ascii chars in the body" do
body = "This is NOT plain text ASCII − かきくけこ"
mail = Mail.new
mail.body = body
mail.charset = 'UTF-8'
mail.add_file fixture('attachments', 'test.png')
STDERR.should_not_receive(:puts)
mail.to_s
end
end
end
Jump to Line
Something went wrong with that request. Please try again.