erikhansson-emailer 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.gitignore +5 -0
- data/LICENSE +20 -0
- data/README.rdoc +54 -0
- data/Rakefile +48 -0
- data/VERSION +1 -0
- data/emailer.gemspec +62 -0
- data/lib/emailer/authsmtp_facade.rb +18 -0
- data/lib/emailer/mail_queue.rb +60 -0
- data/lib/emailer/mock_smtp_facade.rb +37 -0
- data/lib/emailer/smtp_facade.rb +87 -0
- data/lib/emailer.rb +4 -0
- data/spec/emailer/authsmtp_facade_spec.rb +16 -0
- data/spec/emailer/mail_queue_spec.rb +104 -0
- data/spec/emailer/smtp_facade_spec.rb +158 -0
- data/spec/spec_helper.rb +11 -0
- metadata +82 -0
data/.document
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Erik Hansson
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
= emailer
|
2
|
+
|
3
|
+
Emailer is a collection of utility classes for sending emails
|
4
|
+
using an existing SMTP service. I personally only use it with
|
5
|
+
AuthSMTP, and it's not been extensively tested. Use at your
|
6
|
+
own risk.
|
7
|
+
|
8
|
+
Notice that you'll need to install TMail to use emailer. I've
|
9
|
+
not included it as a dependency as the gem does not currently
|
10
|
+
install with Ruby 1.9, there are, however, patched versions out
|
11
|
+
there.
|
12
|
+
|
13
|
+
I apologize in advance for the lack of documentation. There is
|
14
|
+
little going on in the code, and the interface should be easy
|
15
|
+
enough for anyone to figure out with a minute to glance at the
|
16
|
+
code. Here's a taste:
|
17
|
+
|
18
|
+
== Basic use
|
19
|
+
|
20
|
+
smtp = Emailer::AuthsmtpFacade.new :username => '[username]', :pasword => '[password]', :domain => 'localhost'
|
21
|
+
smtp.open do
|
22
|
+
smtp.send_text(
|
23
|
+
:from => 'your@email.com',
|
24
|
+
:to => 'to@email.com',
|
25
|
+
:subject => 'Thanks',
|
26
|
+
:body => 'Mail body.'
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
== Bulk messages
|
31
|
+
|
32
|
+
queue = Emailer::MailQueue.new smtp
|
33
|
+
queue.add(
|
34
|
+
:from => 'your@email.com',
|
35
|
+
:to => 'to@email.com',
|
36
|
+
:subject => 'Thanks',
|
37
|
+
:body => 'Mail body.'
|
38
|
+
) { |success, mail| puts "Sent mail to #{mail[:to]}..." }
|
39
|
+
queue.process
|
40
|
+
|
41
|
+
== Note on Patches/Pull Requests
|
42
|
+
|
43
|
+
* Fork the project.
|
44
|
+
* Make your feature addition or bug fix.
|
45
|
+
* Add tests for it. This is important so I don't break it in a
|
46
|
+
future version unintentionally.
|
47
|
+
* Commit, do not mess with rakefile, version, or history.
|
48
|
+
(if you want to have your own version, that is fine but
|
49
|
+
bump version in a commit by itself I can ignore when I pull)
|
50
|
+
* Send me a pull request. Bonus points for topic branches.
|
51
|
+
|
52
|
+
== Copyright
|
53
|
+
|
54
|
+
Copyright (c) 2009 Erik Hansson. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "emailer"
|
8
|
+
gem.summary = %Q{A really simple way to send emails...}
|
9
|
+
gem.description = %Q{}
|
10
|
+
gem.email = "erik@bits2life.com"
|
11
|
+
gem.homepage = "http://github.com/erikhansson/emailer"
|
12
|
+
gem.authors = ["Erik Hansson"]
|
13
|
+
gem.add_development_dependency "rspec", ">= 1.2.4"
|
14
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
15
|
+
end
|
16
|
+
rescue LoadError
|
17
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
18
|
+
end
|
19
|
+
|
20
|
+
require 'spec/rake/spectask'
|
21
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
22
|
+
spec.libs << 'lib' << 'spec'
|
23
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
24
|
+
end
|
25
|
+
|
26
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
27
|
+
spec.libs << 'lib' << 'spec'
|
28
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
29
|
+
spec.rcov = true
|
30
|
+
end
|
31
|
+
|
32
|
+
task :spec => :check_dependencies
|
33
|
+
|
34
|
+
task :default => :spec
|
35
|
+
|
36
|
+
require 'rake/rdoctask'
|
37
|
+
Rake::RDocTask.new do |rdoc|
|
38
|
+
if File.exist?('VERSION')
|
39
|
+
version = File.read('VERSION')
|
40
|
+
else
|
41
|
+
version = ""
|
42
|
+
end
|
43
|
+
|
44
|
+
rdoc.rdoc_dir = 'rdoc'
|
45
|
+
rdoc.title = "emailer #{version}"
|
46
|
+
rdoc.rdoc_files.include('README*')
|
47
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
48
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.1
|
data/emailer.gemspec
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{emailer}
|
8
|
+
s.version = "0.1.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Erik Hansson"]
|
12
|
+
s.date = %q{2009-08-21}
|
13
|
+
s.description = %q{}
|
14
|
+
s.email = %q{erik@bits2life.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".gitignore",
|
22
|
+
"LICENSE",
|
23
|
+
"README.rdoc",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"emailer.gemspec",
|
27
|
+
"lib/emailer.rb",
|
28
|
+
"lib/emailer/authsmtp_facade.rb",
|
29
|
+
"lib/emailer/mail_queue.rb",
|
30
|
+
"lib/emailer/mock_smtp_facade.rb",
|
31
|
+
"lib/emailer/smtp_facade.rb",
|
32
|
+
"spec/emailer/authsmtp_facade_spec.rb",
|
33
|
+
"spec/emailer/mail_queue_spec.rb",
|
34
|
+
"spec/emailer/smtp_facade_spec.rb",
|
35
|
+
"spec/spec_helper.rb"
|
36
|
+
]
|
37
|
+
s.has_rdoc = true
|
38
|
+
s.homepage = %q{http://github.com/erikhansson/emailer}
|
39
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
40
|
+
s.require_paths = ["lib"]
|
41
|
+
s.rubygems_version = %q{1.3.1}
|
42
|
+
s.summary = %q{A really simple way to send emails...}
|
43
|
+
s.test_files = [
|
44
|
+
"spec/emailer/authsmtp_facade_spec.rb",
|
45
|
+
"spec/emailer/mail_queue_spec.rb",
|
46
|
+
"spec/emailer/smtp_facade_spec.rb",
|
47
|
+
"spec/spec_helper.rb"
|
48
|
+
]
|
49
|
+
|
50
|
+
if s.respond_to? :specification_version then
|
51
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
52
|
+
s.specification_version = 2
|
53
|
+
|
54
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
55
|
+
s.add_development_dependency(%q<rspec>, [">= 1.2.4"])
|
56
|
+
else
|
57
|
+
s.add_dependency(%q<rspec>, [">= 1.2.4"])
|
58
|
+
end
|
59
|
+
else
|
60
|
+
s.add_dependency(%q<rspec>, [">= 1.2.4"])
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
|
2
|
+
module Emailer
|
3
|
+
class AuthSmtpFacade < SmtpFacade
|
4
|
+
|
5
|
+
def self.default_configuration
|
6
|
+
{
|
7
|
+
:host => 'mail.authsmtp.com',
|
8
|
+
:port => 2525,
|
9
|
+
:authentication => :cram_md5
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(settings)
|
14
|
+
super AuthSmtpFacade.default_configuration.merge(settings)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
|
2
|
+
module Emailer
|
3
|
+
class MailQueue
|
4
|
+
def initialize(smtp)
|
5
|
+
@smtp = smtp
|
6
|
+
@queue = []
|
7
|
+
end
|
8
|
+
|
9
|
+
def empty?
|
10
|
+
@queue.empty?
|
11
|
+
end
|
12
|
+
|
13
|
+
def length
|
14
|
+
@queue.length
|
15
|
+
end
|
16
|
+
|
17
|
+
def add(mail, &callback)
|
18
|
+
mail[:content_type] ||= 'text/plain'
|
19
|
+
mail[:encoding] ||= 'utf-8'
|
20
|
+
|
21
|
+
@queue << mail.merge(:callback => callback)
|
22
|
+
end
|
23
|
+
|
24
|
+
def add_html(mail, &callback)
|
25
|
+
add({ :content_type => 'text/html' }.merge(mail))
|
26
|
+
end
|
27
|
+
|
28
|
+
def last
|
29
|
+
@queue.last
|
30
|
+
end
|
31
|
+
|
32
|
+
def process(tcount = 4)
|
33
|
+
tcount = length if length < tcount
|
34
|
+
|
35
|
+
threads = []
|
36
|
+
mutex = Mutex.new
|
37
|
+
|
38
|
+
tcount.times do |n|
|
39
|
+
threads << Thread.new(n) do |tid|
|
40
|
+
while !empty?
|
41
|
+
send_mail mutex
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
threads.each { |thr| thr.join }
|
47
|
+
end
|
48
|
+
|
49
|
+
def send_mail(mutex)
|
50
|
+
smtp = @smtp.clone
|
51
|
+
smtp.open do
|
52
|
+
while mail = mutex.synchronize { @queue.shift }
|
53
|
+
result = smtp.send_mail mail
|
54
|
+
mail[:callback].call(result, mail) if mail[:callback]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Emailer
|
2
|
+
|
3
|
+
class MockNetSmtp
|
4
|
+
def start(*args); end
|
5
|
+
def sendmail(*args); end
|
6
|
+
def finish; end
|
7
|
+
end
|
8
|
+
|
9
|
+
class MockSmtpFacade < SmtpFacade
|
10
|
+
|
11
|
+
attr_reader :sent
|
12
|
+
|
13
|
+
def initialize(settings = {})
|
14
|
+
@sent = []
|
15
|
+
super
|
16
|
+
end
|
17
|
+
|
18
|
+
# Don't open connections...
|
19
|
+
def get_net_smtp_instance
|
20
|
+
MockNetSmtp.new
|
21
|
+
end
|
22
|
+
|
23
|
+
# And save, don't send, mail...
|
24
|
+
def send_mail(options)
|
25
|
+
raise ConnectionNotOpenError unless @open
|
26
|
+
@sent << options
|
27
|
+
true
|
28
|
+
rescue ConnectionNotOpenError => e
|
29
|
+
raise e
|
30
|
+
rescue StandardError => e
|
31
|
+
@error = e
|
32
|
+
@offending_mail = mail
|
33
|
+
false
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'tmail'
|
2
|
+
require 'net/smtp'
|
3
|
+
|
4
|
+
module Emailer
|
5
|
+
|
6
|
+
class MailerError < RuntimeError; end
|
7
|
+
class ConnectionNotOpenError < MailerError; end
|
8
|
+
|
9
|
+
class SmtpFacade
|
10
|
+
attr_reader :settings, :error, :offending_mail
|
11
|
+
|
12
|
+
def initialize(settings)
|
13
|
+
@settings = settings
|
14
|
+
@settings.keys.each do |key|
|
15
|
+
raise ArgumentError unless [
|
16
|
+
:host, :port, :username, :password, :authentication, :domain
|
17
|
+
].include?(key)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def open
|
22
|
+
@open = true
|
23
|
+
open_connection
|
24
|
+
yield
|
25
|
+
ensure
|
26
|
+
@open = false
|
27
|
+
close_connection
|
28
|
+
end
|
29
|
+
|
30
|
+
def get_net_smtp_instance
|
31
|
+
Net::SMTP.new settings[:host], settings[:port]
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Sends a mail to the represented SMTP server. Options is expected to include
|
36
|
+
# :to, :from, :subject, :body, :content_type and :encoding. Use send_html or
|
37
|
+
# send_text to provide defaults for :content_type and :encoding.
|
38
|
+
#
|
39
|
+
def send_mail(options)
|
40
|
+
raise ConnectionNotOpenError unless @open
|
41
|
+
|
42
|
+
content_type_args = options[:content_type].split('/') << { 'charset' => options[:encoding] }
|
43
|
+
|
44
|
+
mail = TMail::Mail.new
|
45
|
+
mail.set_content_type *content_type_args
|
46
|
+
mail.to = options[:to]
|
47
|
+
mail.from = options[:from]
|
48
|
+
mail.subject = options[:subject]
|
49
|
+
mail.body = options[:body]
|
50
|
+
|
51
|
+
@connection.sendmail(mail.encoded, mail.from[0], mail.destinations)
|
52
|
+
true
|
53
|
+
rescue ConnectionNotOpenError => e
|
54
|
+
raise e
|
55
|
+
rescue StandardError => e
|
56
|
+
@error = e
|
57
|
+
@offending_mail = mail
|
58
|
+
close_connection
|
59
|
+
false
|
60
|
+
end
|
61
|
+
|
62
|
+
def send_html(options)
|
63
|
+
send_mail(options.merge(:content_type => 'text/html', :encoding => 'utf-8'))
|
64
|
+
end
|
65
|
+
|
66
|
+
def send_text(options)
|
67
|
+
send_mail(options.merge(:content_type => 'text/plain', :encoding => 'utf-8'))
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
def open_connection
|
72
|
+
@connection = get_net_smtp_instance
|
73
|
+
@connection.start(
|
74
|
+
settings[:domain],
|
75
|
+
settings[:username],
|
76
|
+
settings[:password],
|
77
|
+
settings[:authentication]
|
78
|
+
)
|
79
|
+
end
|
80
|
+
|
81
|
+
def close_connection
|
82
|
+
@connection.finish if @connection
|
83
|
+
@connection = @open = nil
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
data/lib/emailer.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "../spec_helper")
|
2
|
+
|
3
|
+
module Emailer
|
4
|
+
describe AuthSmtpFacade do
|
5
|
+
|
6
|
+
describe :initialize do
|
7
|
+
it "should default to standard AuthSMTP settings" do
|
8
|
+
smtp = AuthSmtpFacade.new :username => 'username', :password => 'password', :domain => 'www.domain.com'
|
9
|
+
smtp.settings[:host].should == 'mail.authsmtp.com'
|
10
|
+
smtp.settings[:port].should == 2525
|
11
|
+
smtp.settings[:authentication].should == :cram_md5
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "../spec_helper")
|
2
|
+
|
3
|
+
module Emailer
|
4
|
+
describe MailQueue do
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
@smtp = MockSmtpFacade.new
|
8
|
+
@queue = MailQueue.new @smtp
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "a new MailQueue" do
|
12
|
+
it "should be empty" do
|
13
|
+
@queue.should be_empty
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe :add do
|
18
|
+
before(:each) do
|
19
|
+
@queue.add(
|
20
|
+
:from => 'from@email.com',
|
21
|
+
:to => 'to@email.com',
|
22
|
+
:subject => 'subject',
|
23
|
+
:body => 'body'
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should default :content_type to 'text/plain'" do
|
28
|
+
@queue.last[:content_type].should == 'text/plain'
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should default :encoding to 'utf-8'" do
|
32
|
+
@queue.last[:encoding].should == 'utf-8'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe :add_html do
|
37
|
+
it "should default :content_type to 'text/html'" do
|
38
|
+
@queue.add_html(
|
39
|
+
:from => 'from@email.com',
|
40
|
+
:to => 'to@email.com',
|
41
|
+
:subject => 'subject',
|
42
|
+
:body => 'body'
|
43
|
+
)
|
44
|
+
@queue.last[:content_type].should == 'text/html'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "a mail queue with two mails" do
|
49
|
+
def add_mail
|
50
|
+
@queue.add(
|
51
|
+
:from => 'from@email.com',
|
52
|
+
:to => 'to@email.com',
|
53
|
+
:subject => 'subject',
|
54
|
+
:body => 'body'
|
55
|
+
) do |success, mail|
|
56
|
+
@verified << mail
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
before(:each) do
|
61
|
+
@verified = []
|
62
|
+
2.times { add_mail }
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should not be empty" do
|
66
|
+
@queue.should_not be_empty
|
67
|
+
end
|
68
|
+
|
69
|
+
context "when we call :process" do
|
70
|
+
before(:each) do
|
71
|
+
@queue.process
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should send both mails" do
|
75
|
+
@smtp.sent.length.should == 2
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should call the mail's respective callbacks" do
|
79
|
+
@verified.length.should == 2
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should be empty" do
|
83
|
+
@queue.should be_empty
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context "with an additional mail added" do
|
88
|
+
before(:each) do
|
89
|
+
add_mail
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should have three mails" do
|
93
|
+
@queue.length.should == 3
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should send three mails when processed" do
|
97
|
+
@queue.process
|
98
|
+
@verified.length.should == 3
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "../spec_helper")
|
2
|
+
|
3
|
+
module Emailer
|
4
|
+
describe SmtpFacade do
|
5
|
+
|
6
|
+
MAIL_OPTIONS = {
|
7
|
+
:from => 'from@email.com',
|
8
|
+
:to => 'to@email.com',
|
9
|
+
:subject => 'subject',
|
10
|
+
:body => 'body',
|
11
|
+
:content_type => 'text/plain',
|
12
|
+
:encoding => 'utf-8'
|
13
|
+
}
|
14
|
+
SMTP_OPTIONS = {
|
15
|
+
:host => 'smtp.host.com',
|
16
|
+
:port => 25,
|
17
|
+
:username => 'username',
|
18
|
+
:password => 'password',
|
19
|
+
:authentication => :cram_md5,
|
20
|
+
:domain => 'www.domain.com'
|
21
|
+
}
|
22
|
+
|
23
|
+
|
24
|
+
describe :initialize do
|
25
|
+
it "should accept only known options" do
|
26
|
+
lambda do
|
27
|
+
SmtpFacade.new :foobar => 'fail'
|
28
|
+
end.should raise_error
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should accept all known options" do
|
32
|
+
SmtpFacade.new SMTP_OPTIONS
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe :clone do
|
37
|
+
it "should return an instance with the same settings" do
|
38
|
+
one = SmtpFacade.new SMTP_OPTIONS
|
39
|
+
two = one.clone
|
40
|
+
|
41
|
+
two.settings.should == one.settings
|
42
|
+
end
|
43
|
+
it "should not return the same instance" do
|
44
|
+
one = SmtpFacade.new SMTP_OPTIONS
|
45
|
+
two = one.clone
|
46
|
+
|
47
|
+
two.should_not == one
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "given an SMTP server's settings" do
|
52
|
+
before(:each) do
|
53
|
+
@smtp = SmtpFacade.new SMTP_OPTIONS
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should remember these settings" do
|
57
|
+
smtp = SmtpFacade.new SMTP_OPTIONS
|
58
|
+
smtp.settings[:port].should == 25
|
59
|
+
smtp.settings[:username].should == 'username'
|
60
|
+
end
|
61
|
+
|
62
|
+
describe :get_net_smtp_instance do
|
63
|
+
it "should use :host and :port to initialize connection" do
|
64
|
+
Net::SMTP.should_receive(:new).with('smtp.host.com', 25).and_return nil
|
65
|
+
@smtp.get_net_smtp_instance
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe :open do
|
70
|
+
before(:each) do
|
71
|
+
@netsmtp = mock('net_smtp').as_null_object
|
72
|
+
@smtp.stub!(:get_net_smtp_instance).and_return @netsmtp
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should get a connection using :get_net_smtp_instance" do
|
76
|
+
@smtp.should_receive(:get_net_smtp_instance).and_return @netsmtp
|
77
|
+
@smtp.open do
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should initialize the connection and authenticate" do
|
82
|
+
@netsmtp.should_receive(:start).with('www.domain.com', 'username', 'password', :cram_md5)
|
83
|
+
@smtp.open do
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should close this connection after the block is finished" do
|
88
|
+
@netsmtp.should_receive(:finish)
|
89
|
+
@smtp.open do
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe :send_mail do
|
95
|
+
it "should raise an ConnectionNotOpenError unless we're inside :open" do
|
96
|
+
lambda do
|
97
|
+
@smtp.send_mail({})
|
98
|
+
end.should raise_error(ConnectionNotOpenError)
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should send the mail to the opened connection" do
|
102
|
+
@netsmtp = mock('net_smtp').as_null_object
|
103
|
+
@smtp.should_receive(:get_net_smtp_instance).and_return @netsmtp
|
104
|
+
@netsmtp.should_receive(:sendmail).once
|
105
|
+
|
106
|
+
@smtp.open do
|
107
|
+
@smtp.send_mail(MAIL_OPTIONS)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should close the connection if it encounters an error" do
|
112
|
+
@netsmtp = mock('net_smtp').as_null_object
|
113
|
+
@smtp.should_receive(:get_net_smtp_instance).and_return @netsmtp
|
114
|
+
@netsmtp.should_receive(:sendmail).once.and_raise(StandardError)
|
115
|
+
|
116
|
+
lambda do
|
117
|
+
@smtp.open do
|
118
|
+
2.times do
|
119
|
+
@smtp.send_mail(MAIL_OPTIONS).should be_false
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end.should raise_error(ConnectionNotOpenError)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe :send_text do
|
127
|
+
it "should delegate to :send_mail with :content_type => 'text/plain' and :encoding => 'utf-8'" do
|
128
|
+
@netsmtp = mock('net_smtp').as_null_object
|
129
|
+
@smtp.should_receive(:get_net_smtp_instance).and_return @netsmtp
|
130
|
+
|
131
|
+
@smtp.should_receive(:send_mail).once.with(MAIL_OPTIONS.merge(
|
132
|
+
:content_type => 'text/plain',
|
133
|
+
:encoding => 'utf-8'
|
134
|
+
))
|
135
|
+
@smtp.open do
|
136
|
+
@smtp.send_text MAIL_OPTIONS.reject { |k, _| [:content_type, :encoding].include?(k) }
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
describe :send_html do
|
142
|
+
it "should delegate to :send_mail with :content_type => 'text/html' and :encoding => 'utf-8'" do
|
143
|
+
@netsmtp = mock('net_smtp').as_null_object
|
144
|
+
@smtp.should_receive(:get_net_smtp_instance).and_return @netsmtp
|
145
|
+
|
146
|
+
@smtp.should_receive(:send_mail).once.with(MAIL_OPTIONS.merge(
|
147
|
+
:content_type => 'text/html',
|
148
|
+
:encoding => 'utf-8'
|
149
|
+
))
|
150
|
+
@smtp.open do
|
151
|
+
@smtp.send_html MAIL_OPTIONS.reject { |k, _| [:content_type, :encoding].include?(k) }
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
|
4
|
+
require 'emailer'
|
5
|
+
require 'emailer/mock_smtp_facade'
|
6
|
+
require 'spec'
|
7
|
+
require 'spec/autorun'
|
8
|
+
|
9
|
+
Spec::Runner.configure do |config|
|
10
|
+
|
11
|
+
end
|
metadata
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: erikhansson-emailer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Erik Hansson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-08-21 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rspec
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.2.4
|
24
|
+
version:
|
25
|
+
description: ""
|
26
|
+
email: erik@bits2life.com
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- LICENSE
|
33
|
+
- README.rdoc
|
34
|
+
files:
|
35
|
+
- .document
|
36
|
+
- .gitignore
|
37
|
+
- LICENSE
|
38
|
+
- README.rdoc
|
39
|
+
- Rakefile
|
40
|
+
- VERSION
|
41
|
+
- emailer.gemspec
|
42
|
+
- lib/emailer.rb
|
43
|
+
- lib/emailer/authsmtp_facade.rb
|
44
|
+
- lib/emailer/mail_queue.rb
|
45
|
+
- lib/emailer/mock_smtp_facade.rb
|
46
|
+
- lib/emailer/smtp_facade.rb
|
47
|
+
- spec/emailer/authsmtp_facade_spec.rb
|
48
|
+
- spec/emailer/mail_queue_spec.rb
|
49
|
+
- spec/emailer/smtp_facade_spec.rb
|
50
|
+
- spec/spec_helper.rb
|
51
|
+
has_rdoc: true
|
52
|
+
homepage: http://github.com/erikhansson/emailer
|
53
|
+
licenses:
|
54
|
+
post_install_message:
|
55
|
+
rdoc_options:
|
56
|
+
- --charset=UTF-8
|
57
|
+
require_paths:
|
58
|
+
- lib
|
59
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: "0"
|
64
|
+
version:
|
65
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: "0"
|
70
|
+
version:
|
71
|
+
requirements: []
|
72
|
+
|
73
|
+
rubyforge_project:
|
74
|
+
rubygems_version: 1.3.5
|
75
|
+
signing_key:
|
76
|
+
specification_version: 2
|
77
|
+
summary: A really simple way to send emails...
|
78
|
+
test_files:
|
79
|
+
- spec/emailer/authsmtp_facade_spec.rb
|
80
|
+
- spec/emailer/mail_queue_spec.rb
|
81
|
+
- spec/emailer/smtp_facade_spec.rb
|
82
|
+
- spec/spec_helper.rb
|