mailthis 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|