mailthis 0.1.0
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/.gitignore +21 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +78 -0
- data/Rakefile +1 -0
- data/lib/mailthis.rb +11 -0
- data/lib/mailthis/exceptions.rb +7 -0
- data/lib/mailthis/mailer.rb +50 -0
- data/lib/mailthis/net_smtp_tls.rb +75 -0
- data/lib/mailthis/outgoing_email.rb +98 -0
- data/lib/mailthis/version.rb +3 -0
- data/log/.gitkeep +0 -0
- data/mailthis.gemspec +26 -0
- data/test/helper.rb +11 -0
- data/test/support/factory.rb +35 -0
- data/test/unit/mailer_tests.rb +182 -0
- data/test/unit/mailthis_tests.rb +42 -0
- data/test/unit/outgoing_email_tests.rb +115 -0
- metadata +140 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2009-Present Kelly Redding
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
# Mailthis
|
2
|
+
|
3
|
+
## Description
|
4
|
+
|
5
|
+
Configure and send email using Mail (https://github.com/mikel/mail) over Net:SMTP.
|
6
|
+
|
7
|
+
## Usage
|
8
|
+
|
9
|
+
### A basic example
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
require 'mailthis'
|
13
|
+
|
14
|
+
GMAIL = Mailthis.mailer do
|
15
|
+
smtp_helo "example.com"
|
16
|
+
smtp_server "smtp.gmail.com"
|
17
|
+
smtp_port 587
|
18
|
+
smtp_user "test@example.com"
|
19
|
+
smtp_pw 'secret'
|
20
|
+
end
|
21
|
+
|
22
|
+
GMAIL.deliver do
|
23
|
+
subject 'a message for you'
|
24
|
+
to 'you@example.com'
|
25
|
+
body 'here is a message for you'
|
26
|
+
end
|
27
|
+
```
|
28
|
+
|
29
|
+
### A more complex example
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
require 'mailthis'
|
33
|
+
|
34
|
+
GMAIL = Mailthis.mailer do
|
35
|
+
smtp_helo "example.com"
|
36
|
+
smtp_server "smtp.gmail.com"
|
37
|
+
smtp_port 587
|
38
|
+
smtp_user "test@example.com"
|
39
|
+
smtp_pw 'secret'
|
40
|
+
|
41
|
+
smtp_auth "plain" # (optional) default: "login"
|
42
|
+
from "me@example.com" # (optional) default: config.smtp_username (if valid)
|
43
|
+
logger Logger.new("log/email.log") # (optional) default: no logger, no logging
|
44
|
+
end
|
45
|
+
|
46
|
+
msg = Mail.new
|
47
|
+
msg.from = 'bob@example.com', # (optional) default: mailer #from
|
48
|
+
msg.reply_to = 'bob@me.com', # (optional) default: self #from
|
49
|
+
msg.to = "you@example.com",
|
50
|
+
msg.cc = "Another <another@example.com>",
|
51
|
+
msg.bcc = ["one@example.com", "Two <two@example.com>"],
|
52
|
+
msg.subject = "a message",
|
53
|
+
msg.body = "a message body"
|
54
|
+
|
55
|
+
GMAIL.deliver(msg)
|
56
|
+
```
|
57
|
+
|
58
|
+
## Installation
|
59
|
+
|
60
|
+
Add this line to your application's Gemfile:
|
61
|
+
|
62
|
+
gem 'mailthis'
|
63
|
+
|
64
|
+
And then execute:
|
65
|
+
|
66
|
+
$ bundle
|
67
|
+
|
68
|
+
Or install it yourself as:
|
69
|
+
|
70
|
+
$ gem install mailthis
|
71
|
+
|
72
|
+
## Contributing
|
73
|
+
|
74
|
+
1. Fork it
|
75
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
76
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
77
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
78
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/lib/mailthis.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'ns-options/proxy'
|
2
|
+
require 'mail'
|
3
|
+
require 'mailthis/exceptions'
|
4
|
+
require 'mailthis/outgoing_email'
|
5
|
+
|
6
|
+
module Mailthis
|
7
|
+
|
8
|
+
class Mailer
|
9
|
+
include NsOptions::Proxy
|
10
|
+
|
11
|
+
option :smtp_helo, String, :required => true
|
12
|
+
option :smtp_server, String, :required => true
|
13
|
+
option :smtp_port, Integer, :required => true
|
14
|
+
option :smtp_user, String, :required => true
|
15
|
+
option :smtp_pw, String, :required => true
|
16
|
+
option :smtp_auth, String, :required => true, :default => proc{ "login" }
|
17
|
+
|
18
|
+
option :from, String, :required => true
|
19
|
+
option :logger, :required => true, :default => proc{ NullLogger.new }
|
20
|
+
|
21
|
+
def initialize(values=nil, &block)
|
22
|
+
# this is defaulted here because we want to use the Configuration instance
|
23
|
+
# `smtp_user`. If we define a proc above, we will be using the Configuration
|
24
|
+
# class `smtp_user`, which will not update the option as expected.
|
25
|
+
super((values || {}).merge(:from => proc{ self.smtp_user }))
|
26
|
+
self.define(&block)
|
27
|
+
end
|
28
|
+
|
29
|
+
def validate!
|
30
|
+
raise(MailerError, "missing required settings") if !valid?
|
31
|
+
self # for chaining
|
32
|
+
end
|
33
|
+
|
34
|
+
def deliver(message = nil, &block)
|
35
|
+
(message || ::Mail.new).tap do |msg|
|
36
|
+
msg.instance_eval(&block) if block
|
37
|
+
OutgoingEmail.new(self, msg).deliver
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class NullLogger
|
42
|
+
require 'logger'
|
43
|
+
::Logger::Severity.constants.each do |name|
|
44
|
+
define_method(name.downcase){ |*args| } # no-op
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
|
3
|
+
# Note: This is a complete rip of http://github.com/ambethia/smtp-tls/tree/master
|
4
|
+
# => I chose to copy the source in here instead of add yet another gem depencency
|
5
|
+
# => I take no credit for this work, check out the link for more info.
|
6
|
+
|
7
|
+
require 'net/smtp'
|
8
|
+
|
9
|
+
Net::SMTP.class_eval do
|
10
|
+
private
|
11
|
+
def do_start(helodomain, user, secret, authtype)
|
12
|
+
raise IOError, 'SMTP session already started' if @started
|
13
|
+
|
14
|
+
if RUBY_VERSION > "1.8.6"
|
15
|
+
check_auth_args user, secret if user or secret
|
16
|
+
else
|
17
|
+
check_auth_args user, secret, authtype if user or secret
|
18
|
+
end
|
19
|
+
|
20
|
+
sock = timeout(@open_timeout) { TCPSocket.open(@address, @port) }
|
21
|
+
@socket = Net::InternetMessageIO.new(sock)
|
22
|
+
@socket.read_timeout = 60 #@read_timeout
|
23
|
+
|
24
|
+
check_response(critical { recv_response() })
|
25
|
+
do_helo(helodomain)
|
26
|
+
|
27
|
+
if starttls
|
28
|
+
raise 'openssl library not installed' unless defined?(OpenSSL)
|
29
|
+
ssl = OpenSSL::SSL::SSLSocket.new(sock)
|
30
|
+
ssl.sync_close = true
|
31
|
+
ssl.connect
|
32
|
+
@socket = Net::InternetMessageIO.new(ssl)
|
33
|
+
@socket.read_timeout = 60 #@read_timeout
|
34
|
+
do_helo(helodomain)
|
35
|
+
end
|
36
|
+
|
37
|
+
authenticate user, secret, authtype if user
|
38
|
+
@started = true
|
39
|
+
ensure
|
40
|
+
unless @started
|
41
|
+
# authentication failed, cancel connection.
|
42
|
+
@socket.close if not @started and @socket and not @socket.closed?
|
43
|
+
@socket = nil
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def do_helo(helodomain)
|
48
|
+
begin
|
49
|
+
if @esmtp
|
50
|
+
ehlo helodomain
|
51
|
+
else
|
52
|
+
helo helodomain
|
53
|
+
end
|
54
|
+
rescue Net::ProtocolError
|
55
|
+
if @esmtp
|
56
|
+
@esmtp = false
|
57
|
+
@error_occured = false
|
58
|
+
retry
|
59
|
+
end
|
60
|
+
raise
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def starttls
|
65
|
+
getok('STARTTLS') rescue return false
|
66
|
+
return true
|
67
|
+
end
|
68
|
+
|
69
|
+
def quit
|
70
|
+
begin
|
71
|
+
getok('QUIT')
|
72
|
+
rescue EOFError
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'mail'
|
2
|
+
require 'mailthis/exceptions'
|
3
|
+
require 'mailthis/net_smtp_tls'
|
4
|
+
|
5
|
+
module Mailthis
|
6
|
+
|
7
|
+
class OutgoingEmail
|
8
|
+
|
9
|
+
# deliver a message using using Net::SMTP with TLS encryption
|
10
|
+
# it is recommended to use Mail (https://github.com/mikel/mail) messages
|
11
|
+
# to disable delivery, set `ENV['MAILTHIS_DISABLE_SEND'] = 'yes'`
|
12
|
+
|
13
|
+
REQUIRED_FIELDS = [:from, :subject]
|
14
|
+
ADDRESS_FIELDS = [:to, :cc, :bcc]
|
15
|
+
|
16
|
+
attr_reader :mailer, :message
|
17
|
+
|
18
|
+
def initialize(mailer, message)
|
19
|
+
@mailer, @message = mailer, message
|
20
|
+
@message.from ||= @mailer.from if @message.respond_to?(:from=)
|
21
|
+
@message.reply_to ||= @message.from if @message.respond_to?(:reply_to=)
|
22
|
+
end
|
23
|
+
|
24
|
+
def validate!
|
25
|
+
if !valid_message?
|
26
|
+
raise Mailthis::MessageError, "invalid message"
|
27
|
+
end
|
28
|
+
|
29
|
+
REQUIRED_FIELDS.each do |field|
|
30
|
+
if @message.send(field).nil?
|
31
|
+
raise Mailthis::MessageError, "missing `#{field}` field"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
if !address_exists?
|
36
|
+
raise Mailthis::MessageError, "no #{ADDRESS_FIELDS.join('/')} specified"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def deliver
|
41
|
+
self.validate!
|
42
|
+
@mailer.validate!
|
43
|
+
deliver_smtp if ENV['MAILTHIS_DISABLE_SEND'].nil?
|
44
|
+
|
45
|
+
log_message # and return it
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def valid_message?
|
51
|
+
(REQUIRED_FIELDS + ADDRESS_FIELDS + [:to_s]).inject(true) do |invalid, meth|
|
52
|
+
invalid && @message.respond_to?(meth)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def address_exists?
|
57
|
+
ADDRESS_FIELDS.inject(false) do |exists, field|
|
58
|
+
exists || (!@message.send(field).nil? && !@message.send(field).empty?)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def deliver_smtp
|
63
|
+
smtp_start_args = [
|
64
|
+
@mailer.smtp_server,
|
65
|
+
@mailer.smtp_port,
|
66
|
+
@mailer.smtp_helo,
|
67
|
+
@mailer.smtp_user,
|
68
|
+
@mailer.smtp_pw,
|
69
|
+
@mailer.smtp_auth
|
70
|
+
]
|
71
|
+
|
72
|
+
Net::SMTP.start(*smtp_start_args) do |smtp|
|
73
|
+
ADDRESS_FIELDS.each do |field|
|
74
|
+
if (recipients = @message.send(field))
|
75
|
+
recipients.each{ |r| smtp.send_message(@message.to_s, @message.from, r) }
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def log_message
|
82
|
+
@message.tap do |msg|
|
83
|
+
log "Sent '#{msg.subject}' to #{msg.to ? msg.to.join(', ') : "''"}"
|
84
|
+
|
85
|
+
log "\n"\
|
86
|
+
"==============================================================\n"\
|
87
|
+
"#{msg}\n"\
|
88
|
+
"==============================================================\n", :debug
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def log(msg, level = nil)
|
93
|
+
@mailer.logger.send(level || :info, msg)
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
data/log/.gitkeep
ADDED
File without changes
|
data/mailthis.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "mailthis/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "mailthis"
|
8
|
+
gem.version = Mailthis::VERSION
|
9
|
+
gem.authors = ["Kelly Redding"]
|
10
|
+
gem.email = ["kelly@kellyredding.com"]
|
11
|
+
gem.description = %q{a simple mailer for ruby}
|
12
|
+
gem.summary = %q{a simple mailer for ruby}
|
13
|
+
gem.homepage = "http://github.com/kellyredding/mailthis"
|
14
|
+
gem.license = 'MIT'
|
15
|
+
|
16
|
+
gem.files = `git ls-files`.split($/)
|
17
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
18
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
|
+
gem.require_paths = ["lib"]
|
20
|
+
|
21
|
+
gem.add_development_dependency("assert", ["~> 2.0"])
|
22
|
+
|
23
|
+
gem.add_dependency("ns-options", ["~> 1.1", ">= 1.1.4"])
|
24
|
+
gem.add_dependency("mail", ["~> 2.5"])
|
25
|
+
|
26
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# this file is automatically required when you run `assert`
|
2
|
+
# put any test helpers here
|
3
|
+
|
4
|
+
# add the root dir to the load path
|
5
|
+
$LOAD_PATH.unshift(File.expand_path("../..", __FILE__))
|
6
|
+
|
7
|
+
# require pry for debugging (`binding.pry`)
|
8
|
+
require 'pry'
|
9
|
+
|
10
|
+
# disable actually delivering emails for testing purposes
|
11
|
+
ENV['MAILTHIS_DISABLE_SEND'] = 'yes'
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Factory
|
2
|
+
|
3
|
+
def self.mailer
|
4
|
+
require 'mailthis/mailer'
|
5
|
+
Mailthis::Mailer.new do
|
6
|
+
smtp_helo "example.com"
|
7
|
+
smtp_server "smtp.example.com"
|
8
|
+
smtp_port 25
|
9
|
+
smtp_user "test@example.com"
|
10
|
+
smtp_pw "secret"
|
11
|
+
smtp_auth :plain
|
12
|
+
from "me@example.com"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.message(settings = nil)
|
17
|
+
require 'mail'
|
18
|
+
message = Mail.new do
|
19
|
+
to 'you@example.com'
|
20
|
+
subject 'a message'
|
21
|
+
end
|
22
|
+
(settings || {}).inject(message) do |msg, (setting, value)|
|
23
|
+
msg[setting] = value
|
24
|
+
msg
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.logger(string_val)
|
29
|
+
require 'logger'
|
30
|
+
require 'stringio'
|
31
|
+
Logger.new(StringIO.new(string_val))
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
@@ -0,0 +1,182 @@
|
|
1
|
+
require 'assert'
|
2
|
+
require 'mailthis/mailer'
|
3
|
+
|
4
|
+
require 'test/support/factory'
|
5
|
+
require 'mailthis/exceptions'
|
6
|
+
|
7
|
+
class Mailthis::Mailer
|
8
|
+
|
9
|
+
class UnitTests < Assert::Context
|
10
|
+
desc "Mailthis::Mailer"
|
11
|
+
setup do
|
12
|
+
@mailer = Mailthis::Mailer.new
|
13
|
+
end
|
14
|
+
subject{ @mailer }
|
15
|
+
|
16
|
+
should have_imeths :smtp_helo, :smtp_server, :smtp_port
|
17
|
+
should have_imeths :smtp_user, :smtp_pw, :smtp_auth
|
18
|
+
should have_imeths :from, :logger
|
19
|
+
should have_imeths :validate!, :deliver
|
20
|
+
|
21
|
+
should "know its smtp settings" do
|
22
|
+
{ :smtp_helo => 'example.com',
|
23
|
+
:smtp_server => 'smtp.example.com',
|
24
|
+
:smtp_port => 25,
|
25
|
+
:smtp_user => 'test@example.com',
|
26
|
+
:smtp_pw => 'secret'
|
27
|
+
}.each do |setting, val|
|
28
|
+
assert_nil subject.send(setting)
|
29
|
+
|
30
|
+
subject.send(setting, val)
|
31
|
+
assert_equal val, subject.send(setting)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
should "use `\"login\"` as the auth by default" do
|
36
|
+
assert_equal "login", subject.smtp_auth
|
37
|
+
|
38
|
+
subject.smtp_auth 'plain'
|
39
|
+
assert_equal 'plain', subject.smtp_auth
|
40
|
+
end
|
41
|
+
|
42
|
+
should "use smtp_user as the from by default" do
|
43
|
+
assert_nil subject.from
|
44
|
+
|
45
|
+
subject.smtp_user 'user'
|
46
|
+
assert_equal 'user', subject.from
|
47
|
+
end
|
48
|
+
|
49
|
+
should "allow overriding the from" do
|
50
|
+
subject.from 'a-user'
|
51
|
+
assert_equal 'a-user', subject.from
|
52
|
+
end
|
53
|
+
|
54
|
+
should "know its logger" do
|
55
|
+
assert_kind_of Mailthis::Mailer::NullLogger, subject.logger
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
class ValidationTests < UnitTests
|
61
|
+
desc "when validating"
|
62
|
+
setup do
|
63
|
+
@invalid = Mailthis::Mailer.new do
|
64
|
+
smtp_helo "example.com"
|
65
|
+
smtp_server "smtp.example.com"
|
66
|
+
smtp_port 25
|
67
|
+
smtp_user "test@example.com"
|
68
|
+
smtp_pw "secret"
|
69
|
+
smtp_auth :plain
|
70
|
+
end
|
71
|
+
end
|
72
|
+
subject{ @invalid }
|
73
|
+
|
74
|
+
should "not complain if all settings are in place" do
|
75
|
+
assert_valid
|
76
|
+
end
|
77
|
+
|
78
|
+
should "return itself when validating" do
|
79
|
+
assert_same subject, subject.validate!
|
80
|
+
end
|
81
|
+
|
82
|
+
should "be invalid if missing the helo domain" do
|
83
|
+
subject.smtp_helo = nil
|
84
|
+
assert_invalid
|
85
|
+
end
|
86
|
+
|
87
|
+
should "be invalid if missing the server" do
|
88
|
+
subject.smtp_server = nil
|
89
|
+
assert_invalid
|
90
|
+
end
|
91
|
+
|
92
|
+
should "be invalid if missing the port" do
|
93
|
+
subject.smtp_port = nil
|
94
|
+
assert_invalid
|
95
|
+
end
|
96
|
+
|
97
|
+
should "be invalid if missing the user" do
|
98
|
+
subject.smtp_user = nil
|
99
|
+
assert_invalid
|
100
|
+
end
|
101
|
+
|
102
|
+
should "be invalid if missing the pw" do
|
103
|
+
subject.smtp_pw = nil
|
104
|
+
assert_invalid
|
105
|
+
end
|
106
|
+
|
107
|
+
should "be invalid if missing the auth" do
|
108
|
+
subject.smtp_auth = nil
|
109
|
+
assert_invalid
|
110
|
+
end
|
111
|
+
|
112
|
+
should "be invalid if missing the from" do
|
113
|
+
subject.from = nil
|
114
|
+
assert_invalid
|
115
|
+
end
|
116
|
+
|
117
|
+
should "be invalid if missing the logger" do
|
118
|
+
subject.logger = nil
|
119
|
+
assert_invalid
|
120
|
+
end
|
121
|
+
|
122
|
+
private
|
123
|
+
|
124
|
+
def assert_valid
|
125
|
+
assert_nothing_raised do
|
126
|
+
subject.validate!
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def assert_invalid
|
131
|
+
assert_raises(Mailthis::MailerError) do
|
132
|
+
subject.validate!
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
class SendMailTests < UnitTests
|
139
|
+
desc "when sending mail"
|
140
|
+
setup do
|
141
|
+
@message = Factory.message(:from => "me@example.com")
|
142
|
+
@mailer = Factory.mailer
|
143
|
+
@mailer.logger = Factory.logger(@out = "")
|
144
|
+
|
145
|
+
@sent_msg = @mailer.deliver(@message)
|
146
|
+
end
|
147
|
+
|
148
|
+
should "return the message that was sent" do
|
149
|
+
assert_same @message, @sent_msg
|
150
|
+
end
|
151
|
+
|
152
|
+
should "log that the message was sent" do
|
153
|
+
assert_not_empty @out
|
154
|
+
end
|
155
|
+
|
156
|
+
should "build the message from the given block" do
|
157
|
+
built_msg = @mailer.deliver do
|
158
|
+
from 'me@example.com'
|
159
|
+
to 'you@example.com'
|
160
|
+
subject 'a message'
|
161
|
+
end
|
162
|
+
|
163
|
+
assert_kind_of ::Mail::Message, built_msg
|
164
|
+
assert_equal ['me@example.com'], built_msg.from
|
165
|
+
assert_equal ['you@example.com'], built_msg.to
|
166
|
+
assert_equal 'a message', built_msg.subject
|
167
|
+
end
|
168
|
+
|
169
|
+
should "task a message and apply the given block" do
|
170
|
+
built_msg = @mailer.deliver(Factory.message) do
|
171
|
+
from 'me@example.com'
|
172
|
+
end
|
173
|
+
|
174
|
+
assert_kind_of ::Mail::Message, built_msg
|
175
|
+
assert_equal ['me@example.com'], built_msg.from
|
176
|
+
assert_equal ['you@example.com'], built_msg.to
|
177
|
+
assert_equal 'a message', built_msg.subject
|
178
|
+
end
|
179
|
+
|
180
|
+
end
|
181
|
+
|
182
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'assert'
|
2
|
+
require 'mailthis'
|
3
|
+
|
4
|
+
require 'mailthis/mailer'
|
5
|
+
require 'mailthis/exceptions'
|
6
|
+
|
7
|
+
module Mailthis
|
8
|
+
|
9
|
+
class UnitTests < Assert::Context
|
10
|
+
desc "Mailthis"
|
11
|
+
subject{ Mailthis }
|
12
|
+
|
13
|
+
should have_imeth :mailer
|
14
|
+
|
15
|
+
should "build a mailer with given args" do
|
16
|
+
mailer = Mailthis.mailer do
|
17
|
+
smtp_helo "example.com"
|
18
|
+
smtp_server "smtp.example.com"
|
19
|
+
smtp_port 25
|
20
|
+
smtp_user "test@example.com"
|
21
|
+
smtp_pw "secret"
|
22
|
+
smtp_auth :plain
|
23
|
+
end
|
24
|
+
|
25
|
+
assert_kind_of Mailer, mailer
|
26
|
+
assert_equal "example.com", mailer.smtp_helo
|
27
|
+
assert_equal "smtp.example.com", mailer.smtp_server
|
28
|
+
assert_equal 25, mailer.smtp_port
|
29
|
+
assert_equal "test@example.com", mailer.smtp_user
|
30
|
+
assert_equal "secret", mailer.smtp_pw
|
31
|
+
assert_equal 'plain', mailer.smtp_auth
|
32
|
+
end
|
33
|
+
|
34
|
+
should "complain if building a mailer with missing settings" do
|
35
|
+
assert_raises(MailerError) do
|
36
|
+
mailer = Mailthis.mailer
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'assert'
|
2
|
+
require 'mailthis/outgoing_email'
|
3
|
+
|
4
|
+
require 'test/support/factory'
|
5
|
+
require 'mailthis/exceptions'
|
6
|
+
|
7
|
+
class Mailthis::OutgoingEmail
|
8
|
+
|
9
|
+
class UnitTests < Assert::Context
|
10
|
+
desc "Mailthis::OutgoingEmail"
|
11
|
+
setup do
|
12
|
+
@mailer = Factory.mailer
|
13
|
+
@message = Factory.message
|
14
|
+
@email = Mailthis::OutgoingEmail.new(@mailer, @message)
|
15
|
+
end
|
16
|
+
subject{ @email }
|
17
|
+
|
18
|
+
should have_readers :mailer, :message
|
19
|
+
should have_imeths :validate!, :deliver
|
20
|
+
|
21
|
+
should "know its mailer and message" do
|
22
|
+
assert_same @mailer, subject.mailer
|
23
|
+
assert_same @message, subject.message
|
24
|
+
end
|
25
|
+
|
26
|
+
should "set the message's from to the mailer's from if message has no from" do
|
27
|
+
assert_nil Factory.message.from
|
28
|
+
assert_not_nil subject.message.from
|
29
|
+
assert_equal [@mailer.from], subject.message.from
|
30
|
+
end
|
31
|
+
|
32
|
+
should "set the message's reply_to to the message's from if message has no reply_to" do
|
33
|
+
assert_nil Factory.message.reply_to
|
34
|
+
assert_not_nil subject.message.reply_to
|
35
|
+
assert_equal subject.message.from, subject.message.reply_to
|
36
|
+
end
|
37
|
+
|
38
|
+
should "complain if delivering with an invalid mailer" do
|
39
|
+
@mailer.smtp_server = nil
|
40
|
+
assert_not @mailer.valid?
|
41
|
+
|
42
|
+
assert_raises(Mailthis::MailerError) do
|
43
|
+
subject.deliver
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
should "complain if delivering an invalid message" do
|
48
|
+
msg = Factory.message
|
49
|
+
msg.to = nil
|
50
|
+
|
51
|
+
assert_raises(Mailthis::MessageError) do
|
52
|
+
Mailthis::OutgoingEmail.new(@mailer, msg).deliver
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
should "log when delivering a message" do
|
57
|
+
@mailer.logger = Factory.logger(out = "")
|
58
|
+
assert_empty out
|
59
|
+
|
60
|
+
subject.deliver
|
61
|
+
|
62
|
+
assert_not_empty out
|
63
|
+
assert_includes "Sent '#{@message.subject}'", out
|
64
|
+
assert_includes @message.to_s, out
|
65
|
+
end
|
66
|
+
|
67
|
+
should "return the delivered message" do
|
68
|
+
assert_same @message, subject.deliver
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
class ValidationTests < UnitTests
|
74
|
+
desc "when validating"
|
75
|
+
|
76
|
+
should "not complain if all settings are in place" do
|
77
|
+
assert_valid_with @message
|
78
|
+
end
|
79
|
+
|
80
|
+
should "complain if using an invalid message" do
|
81
|
+
assert_invalid_with "not-a-valid-msg-obj"
|
82
|
+
end
|
83
|
+
|
84
|
+
should "complain if the message is missing required fields" do
|
85
|
+
msg = Factory.message
|
86
|
+
msg.subject = nil
|
87
|
+
assert_invalid_with msg
|
88
|
+
end
|
89
|
+
|
90
|
+
should "complain if the message is not addressed to anyone" do
|
91
|
+
msg = Factory.message
|
92
|
+
|
93
|
+
msg.to = msg.cc = msg.bcc = nil
|
94
|
+
assert_invalid_with msg
|
95
|
+
end
|
96
|
+
|
97
|
+
private
|
98
|
+
|
99
|
+
def assert_valid_with(msg)
|
100
|
+
assert_nothing_raised do
|
101
|
+
Mailthis::OutgoingEmail.new(@mailer, msg).validate!
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def assert_invalid_with(msg)
|
106
|
+
with_backtrace(caller) do
|
107
|
+
assert_raises(Mailthis::MessageError) do
|
108
|
+
Mailthis::OutgoingEmail.new(@mailer, msg).validate!
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
metadata
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mailthis
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Kelly Redding
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2013-07-22 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: assert
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ~>
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 2
|
31
|
+
- 0
|
32
|
+
version: "2.0"
|
33
|
+
type: :development
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: ns-options
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 13
|
44
|
+
segments:
|
45
|
+
- 1
|
46
|
+
- 1
|
47
|
+
version: "1.1"
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
hash: 27
|
51
|
+
segments:
|
52
|
+
- 1
|
53
|
+
- 1
|
54
|
+
- 4
|
55
|
+
version: 1.1.4
|
56
|
+
type: :runtime
|
57
|
+
version_requirements: *id002
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: mail
|
60
|
+
prerelease: false
|
61
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ~>
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
hash: 9
|
67
|
+
segments:
|
68
|
+
- 2
|
69
|
+
- 5
|
70
|
+
version: "2.5"
|
71
|
+
type: :runtime
|
72
|
+
version_requirements: *id003
|
73
|
+
description: a simple mailer for ruby
|
74
|
+
email:
|
75
|
+
- kelly@kellyredding.com
|
76
|
+
executables: []
|
77
|
+
|
78
|
+
extensions: []
|
79
|
+
|
80
|
+
extra_rdoc_files: []
|
81
|
+
|
82
|
+
files:
|
83
|
+
- .gitignore
|
84
|
+
- Gemfile
|
85
|
+
- LICENSE.txt
|
86
|
+
- README.md
|
87
|
+
- Rakefile
|
88
|
+
- lib/mailthis.rb
|
89
|
+
- lib/mailthis/exceptions.rb
|
90
|
+
- lib/mailthis/mailer.rb
|
91
|
+
- lib/mailthis/net_smtp_tls.rb
|
92
|
+
- lib/mailthis/outgoing_email.rb
|
93
|
+
- lib/mailthis/version.rb
|
94
|
+
- log/.gitkeep
|
95
|
+
- mailthis.gemspec
|
96
|
+
- test/helper.rb
|
97
|
+
- test/support/factory.rb
|
98
|
+
- test/unit/mailer_tests.rb
|
99
|
+
- test/unit/mailthis_tests.rb
|
100
|
+
- test/unit/outgoing_email_tests.rb
|
101
|
+
- tmp/.gitkeep
|
102
|
+
homepage: http://github.com/kellyredding/mailthis
|
103
|
+
licenses:
|
104
|
+
- MIT
|
105
|
+
post_install_message:
|
106
|
+
rdoc_options: []
|
107
|
+
|
108
|
+
require_paths:
|
109
|
+
- lib
|
110
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
111
|
+
none: false
|
112
|
+
requirements:
|
113
|
+
- - ">="
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
hash: 3
|
116
|
+
segments:
|
117
|
+
- 0
|
118
|
+
version: "0"
|
119
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
|
+
none: false
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
hash: 3
|
125
|
+
segments:
|
126
|
+
- 0
|
127
|
+
version: "0"
|
128
|
+
requirements: []
|
129
|
+
|
130
|
+
rubyforge_project:
|
131
|
+
rubygems_version: 1.8.24
|
132
|
+
signing_key:
|
133
|
+
specification_version: 3
|
134
|
+
summary: a simple mailer for ruby
|
135
|
+
test_files:
|
136
|
+
- test/helper.rb
|
137
|
+
- test/support/factory.rb
|
138
|
+
- test/unit/mailer_tests.rb
|
139
|
+
- test/unit/mailthis_tests.rb
|
140
|
+
- test/unit/outgoing_email_tests.rb
|