bjornblomqvist-emailer 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
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,49 @@
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","Bjorn Blomqvist"]
13
+ gem.add_development_dependency "rspec", ">= 1.2.4"
14
+ gem.add_dependency('bjornblomqvist-tmail', '>= 0.0.2')
15
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
+ end
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
19
+ end
20
+
21
+ require 'spec/rake/spectask'
22
+ Spec::Rake::SpecTask.new(:spec) do |spec|
23
+ spec.libs << 'lib' << 'spec'
24
+ spec.spec_files = FileList['spec/**/*_spec.rb']
25
+ end
26
+
27
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
28
+ spec.libs << 'lib' << 'spec'
29
+ spec.pattern = 'spec/**/*_spec.rb'
30
+ spec.rcov = true
31
+ end
32
+
33
+ task :spec => :check_dependencies
34
+
35
+ task :default => :spec
36
+
37
+ require 'rake/rdoctask'
38
+ Rake::RDocTask.new do |rdoc|
39
+ if File.exist?('VERSION')
40
+ version = File.read('VERSION')
41
+ else
42
+ version = ""
43
+ end
44
+
45
+ rdoc.rdoc_dir = 'rdoc'
46
+ rdoc.title = "emailer #{version}"
47
+ rdoc.rdoc_files.include('README*')
48
+ rdoc.rdoc_files.include('lib/**/*.rb')
49
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.4
data/emailer.gemspec ADDED
@@ -0,0 +1,68 @@
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.4"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Erik Hansson", "Bjorn Blomqvist"]
12
+ s.date = %q{2009-09-17}
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
+ "lib/emailer/string_utilities.rb",
33
+ "spec/emailer/authsmtp_facade_spec.rb",
34
+ "spec/emailer/mail_queue_spec.rb",
35
+ "spec/emailer/mock_smtp_facade_spec.rb",
36
+ "spec/emailer/smtp_facade_spec.rb",
37
+ "spec/spec_helper.rb"
38
+ ]
39
+ s.has_rdoc = true
40
+ s.homepage = %q{http://github.com/erikhansson/emailer}
41
+ s.rdoc_options = ["--charset=UTF-8"]
42
+ s.require_paths = ["lib"]
43
+ s.rubygems_version = %q{1.3.1}
44
+ s.summary = %q{A really simple way to send emails...}
45
+ s.test_files = [
46
+ "spec/emailer/authsmtp_facade_spec.rb",
47
+ "spec/emailer/mail_queue_spec.rb",
48
+ "spec/emailer/mock_smtp_facade_spec.rb",
49
+ "spec/emailer/smtp_facade_spec.rb",
50
+ "spec/spec_helper.rb"
51
+ ]
52
+
53
+ if s.respond_to? :specification_version then
54
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
55
+ s.specification_version = 2
56
+
57
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
58
+ s.add_development_dependency(%q<rspec>, [">= 1.2.4"])
59
+ s.add_runtime_dependency(%q<bjornblomqvist-tmail>, [">= 0.0.2"])
60
+ else
61
+ s.add_dependency(%q<rspec>, [">= 1.2.4"])
62
+ s.add_dependency(%q<bjornblomqvist-tmail>, [">= 0.0.2"])
63
+ end
64
+ else
65
+ s.add_dependency(%q<rspec>, [">= 1.2.4"])
66
+ s.add_dependency(%q<bjornblomqvist-tmail>, [">= 0.0.2"])
67
+ end
68
+ end
data/lib/emailer.rb ADDED
@@ -0,0 +1,6 @@
1
+
2
+ require 'emailer/smtp_facade'
3
+ require 'emailer/authsmtp_facade'
4
+ require 'emailer/mail_queue'
5
+ require 'emailer/string_utilities'
6
+ require 'emailer/mock_smtp_facade.rb'
@@ -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), &callback)
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,38 @@
1
+ module Emailer
2
+
3
+ class MockNetSmtp
4
+ def start(*args); end
5
+ def sendmail(*args); end
6
+ def finish; end
7
+ def started?; end
8
+ end
9
+
10
+ class MockSmtpFacade < SmtpFacade
11
+
12
+ attr_reader :sent
13
+
14
+ def initialize(settings = {})
15
+ @sent = []
16
+ super
17
+ end
18
+
19
+ # Don't open connections...
20
+ def get_net_smtp_instance
21
+ MockNetSmtp.new
22
+ end
23
+
24
+ # And save, don't send, mail...
25
+ def send_mail(options)
26
+ raise ConnectionNotOpenError unless @open
27
+ @sent << options
28
+ true
29
+ rescue ConnectionNotOpenError => e
30
+ raise e
31
+ rescue StandardError => e
32
+ @error = e
33
+ @offending_mail = mail
34
+ false
35
+ end
36
+
37
+ end
38
+ end
@@ -0,0 +1,90 @@
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
+
11
+ class << self; attr_accessor :default end
12
+
13
+ attr_reader :settings, :error, :offending_mail
14
+
15
+ def initialize(settings)
16
+ @settings = settings
17
+ @settings.keys.each do |key|
18
+ raise ArgumentError unless [
19
+ :host, :port, :username, :password, :authentication, :domain
20
+ ].include?(key)
21
+ end
22
+ end
23
+
24
+ def open
25
+ @open = true
26
+ open_connection
27
+ yield
28
+ ensure
29
+ @open = false
30
+ close_connection
31
+ end
32
+
33
+ def get_net_smtp_instance
34
+ Net::SMTP.new settings[:host], settings[:port]
35
+ end
36
+
37
+ ##
38
+ # Sends a mail to the represented SMTP server. Options is expected to include
39
+ # :to, :from, :subject, :body, :content_type and :encoding. Use send_html or
40
+ # send_text to provide defaults for :content_type and :encoding.
41
+ #
42
+ def send_mail(options)
43
+ raise ConnectionNotOpenError unless @open
44
+
45
+ content_type_args = options[:content_type].split('/') << { 'charset' => options[:encoding] }
46
+
47
+ mail = TMail::Mail.new
48
+ mail.set_content_type *content_type_args
49
+ mail.to = options[:to]
50
+ mail.from = options[:from]
51
+ mail.subject = options[:subject]
52
+ mail.body = options[:body]
53
+
54
+ @connection.sendmail(mail.encoded, mail.from[0], mail.destinations)
55
+ true
56
+ rescue ConnectionNotOpenError => e
57
+ raise e
58
+ rescue StandardError => e
59
+ @error = e
60
+ @offending_mail = mail
61
+ close_connection
62
+ false
63
+ end
64
+
65
+ def send_html(options)
66
+ send_mail(options.merge(:content_type => 'text/html', :encoding => 'utf-8'))
67
+ end
68
+
69
+ def send_text(options)
70
+ send_mail(options.merge(:content_type => 'text/plain', :encoding => 'utf-8'))
71
+ end
72
+
73
+ private
74
+ def open_connection
75
+ @connection = get_net_smtp_instance
76
+ @connection.start(
77
+ settings[:domain],
78
+ settings[:username],
79
+ settings[:password],
80
+ settings[:authentication]
81
+ )
82
+ end
83
+
84
+ def close_connection
85
+ @connection.finish if @connection && @connection.started?
86
+ @connection = @open = nil
87
+ end
88
+
89
+ end
90
+ end
@@ -0,0 +1,50 @@
1
+ module Emailer
2
+ module StringUtilities
3
+
4
+ def q_encode_char(n)
5
+ hex = n.to_s 16
6
+ hex = "0#{hex}" if hex.length == 1
7
+ "=#{hex}"
8
+ end
9
+
10
+ def q_char(n)
11
+ # We can escape SPACE (0x20) with '_'
12
+ return '_' if n == 32
13
+
14
+ # We can use ASCII 33 to 126, except '=', '?' and '_' (see above).
15
+ # All other byte values will be encoded with =XX
16
+ (n < 33 || n == 61 || n == 63 || n == 95 || n > 126) ? q_encode_char(n) : n.chr
17
+ end
18
+
19
+ def q_encode_bytes(str)
20
+ str.bytes.map { |b| q_char(b) }
21
+ end
22
+
23
+ def q_word(encoding, encoded_str)
24
+ "=?#{encoding}?Q?#{encoded_str}?="
25
+ end
26
+
27
+ def string_to_q(str)
28
+ max_word_length = 76 - "=?#{str.encoding.to_s}?Q??=".length
29
+ lines = split_string q_encode_bytes(str), max_word_length
30
+ lines.map { |l| q_word(str.encoding.to_s, l) }.join("\r\n ")
31
+ end
32
+
33
+ def split_string(parts, maxlen)
34
+ result = ['']
35
+ while parts.length > 0
36
+ if (result[-1].length + parts[0].length <= maxlen)
37
+ result[-1] += parts.shift
38
+ else
39
+ result << parts.shift
40
+ end
41
+ end
42
+
43
+ result
44
+ end
45
+
46
+ end
47
+ end
48
+
49
+ # require 'lib/emailer/string_utilities'
50
+ # extend Emailer::StringUtilities
@@ -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,27 @@
1
+ require File.join(File.dirname(__FILE__), "../spec_helper")
2
+
3
+ module Emailer
4
+ describe MockSmtpFacade do
5
+
6
+ describe :initialize do
7
+ it "Should be able to send without actulay sending anything" do
8
+
9
+ message = {:to => "test@bits2life.com",
10
+ :from => "test@bits2life.com",
11
+ :subject => "A test",
12
+ :body => "A test body"}
13
+
14
+ smtp = MockSmtpFacade.new
15
+
16
+ smtp.open do
17
+ smtp.send_mail(
18
+ message
19
+ )
20
+ end
21
+
22
+ smtp.sent.first.should == message
23
+ end
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,166 @@
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
+ describe :default do
157
+ it "should contain a global default emailer" do
158
+ v = MockSmtpFacade.new
159
+ Emailer::SmtpFacade.default = v
160
+ Emailer::SmtpFacade.default.should == v
161
+ end
162
+ end
163
+
164
+ end
165
+ end
166
+ end
@@ -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,96 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bjornblomqvist-emailer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.4
5
+ platform: ruby
6
+ authors:
7
+ - Erik Hansson
8
+ - Bjorn Blomqvist
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2009-09-17 00:00:00 -07:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: rspec
18
+ type: :development
19
+ version_requirement:
20
+ version_requirements: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: 1.2.4
25
+ version:
26
+ - !ruby/object:Gem::Dependency
27
+ name: bjornblomqvist-tmail
28
+ type: :runtime
29
+ version_requirement:
30
+ version_requirements: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: 0.0.2
35
+ version:
36
+ description: ""
37
+ email: erik@bits2life.com
38
+ executables: []
39
+
40
+ extensions: []
41
+
42
+ extra_rdoc_files:
43
+ - LICENSE
44
+ - README.rdoc
45
+ files:
46
+ - .document
47
+ - .gitignore
48
+ - LICENSE
49
+ - README.rdoc
50
+ - Rakefile
51
+ - VERSION
52
+ - emailer.gemspec
53
+ - lib/emailer.rb
54
+ - lib/emailer/authsmtp_facade.rb
55
+ - lib/emailer/mail_queue.rb
56
+ - lib/emailer/mock_smtp_facade.rb
57
+ - lib/emailer/smtp_facade.rb
58
+ - lib/emailer/string_utilities.rb
59
+ - spec/emailer/authsmtp_facade_spec.rb
60
+ - spec/emailer/mail_queue_spec.rb
61
+ - spec/emailer/mock_smtp_facade_spec.rb
62
+ - spec/emailer/smtp_facade_spec.rb
63
+ - spec/spec_helper.rb
64
+ has_rdoc: true
65
+ homepage: http://github.com/erikhansson/emailer
66
+ licenses:
67
+ post_install_message:
68
+ rdoc_options:
69
+ - --charset=UTF-8
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: "0"
77
+ version:
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: "0"
83
+ version:
84
+ requirements: []
85
+
86
+ rubyforge_project:
87
+ rubygems_version: 1.3.5
88
+ signing_key:
89
+ specification_version: 2
90
+ summary: A really simple way to send emails...
91
+ test_files:
92
+ - spec/emailer/authsmtp_facade_spec.rb
93
+ - spec/emailer/mail_queue_spec.rb
94
+ - spec/emailer/mock_smtp_facade_spec.rb
95
+ - spec/emailer/smtp_facade_spec.rb
96
+ - spec/spec_helper.rb