multi_mail 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -1
- data/.travis.yml +10 -0
- data/README.md +283 -59
- data/Rakefile +38 -19
- data/lib/multi_mail/cloudmailin/receiver.rb +3 -13
- data/lib/multi_mail/mailgun/message.rb +67 -0
- data/lib/multi_mail/mailgun/receiver.rb +20 -13
- data/lib/multi_mail/mailgun/sender.rb +79 -2
- data/lib/multi_mail/mandrill/message.rb +74 -0
- data/lib/multi_mail/mandrill/receiver.rb +36 -16
- data/lib/multi_mail/mandrill/sender.rb +77 -2
- data/lib/multi_mail/message/base.rb +40 -0
- data/lib/multi_mail/postmark/receiver.rb +1 -1
- data/lib/multi_mail/postmark/sender.rb +35 -5
- data/lib/multi_mail/receiver/base.rb +31 -2
- data/lib/multi_mail/receiver.rb +1 -4
- data/lib/multi_mail/sender/base.rb +23 -1
- data/lib/multi_mail/sendgrid/message.rb +74 -0
- data/lib/multi_mail/sendgrid/receiver.rb +72 -23
- data/lib/multi_mail/sendgrid/sender.rb +63 -2
- data/lib/multi_mail/service.rb +48 -56
- data/lib/multi_mail/simple/receiver.rb +4 -4
- data/lib/multi_mail/version.rb +1 -1
- data/lib/multi_mail.rb +16 -1
- data/multi_mail.gemspec +4 -1
- data/spec/fixtures/empty.gif +0 -0
- data/spec/fixtures/mailgun/raw/invalid.txt +13 -0
- data/spec/fixtures/mailgun/raw/missing.txt +13 -0
- data/spec/fixtures/mailgun/raw/spam.txt +13 -0
- data/spec/fixtures/mailgun/raw/valid.txt +13 -0
- data/spec/fixtures/mandrill/invalid.txt +15 -0
- data/spec/fixtures/mandrill/missing.txt +14 -0
- data/spec/fixtures/mandrill/multiple.txt +15 -0
- data/spec/fixtures/mandrill/valid.txt +10 -5
- data/spec/fixtures/postmark/valid.txt +13 -13
- data/spec/fixtures/sendgrid/encoding.txt +90 -0
- data/spec/fixtures/sendgrid/spam.txt +94 -0
- data/spec/fixtures/sendgrid/valid.txt +136 -0
- data/spec/mailgun/message_spec.rb +251 -0
- data/spec/mailgun/receiver_spec.rb +35 -20
- data/spec/mailgun/sender_spec.rb +175 -0
- data/spec/mandrill/message_spec.rb +305 -0
- data/spec/mandrill/receiver_spec.rb +90 -46
- data/spec/mandrill/sender_spec.rb +138 -0
- data/spec/message/base_spec.rb +81 -0
- data/spec/postmark/receiver_spec.rb +4 -4
- data/spec/postmark/sender_spec.rb +118 -0
- data/spec/receiver/base_spec.rb +16 -9
- data/spec/sender/base_spec.rb +24 -10
- data/spec/sendgrid/message_spec.rb +265 -0
- data/spec/sendgrid/receiver_spec.rb +77 -0
- data/spec/sendgrid/sender_spec.rb +140 -0
- data/spec/service_spec.rb +18 -1
- data/spec/simple/receiver_spec.rb +1 -1
- data/spec/spec_helper.rb +46 -4
- metadata +226 -143
- data/lib/multi_mail/sender.rb +0 -46
- data/lib/multi_mail/simple/sender.rb +0 -14
- data/spec/sender_spec.rb +0 -13
- data/spec/simple/sender_spec.rb +0 -0
@@ -0,0 +1,140 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
require 'multi_mail/sendgrid/sender'
|
3
|
+
|
4
|
+
describe MultiMail::Sender::SendGrid do
|
5
|
+
let :message do
|
6
|
+
Mail.new do
|
7
|
+
date Time.at(946702800)
|
8
|
+
from 'foo@example.com'
|
9
|
+
to 'bar@example.com'
|
10
|
+
subject 'test'
|
11
|
+
body 'hello'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
let :message_without_from do
|
16
|
+
Mail.new do
|
17
|
+
date Time.at(946702800)
|
18
|
+
to 'bar@example.com'
|
19
|
+
subject 'test'
|
20
|
+
body 'hello'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
let :message_without_to do
|
25
|
+
Mail.new do
|
26
|
+
date Time.at(946702800)
|
27
|
+
from 'foo@example.com'
|
28
|
+
subject 'test'
|
29
|
+
body 'hello'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
let :message_without_subject do
|
34
|
+
Mail.new do
|
35
|
+
date Time.at(946702800)
|
36
|
+
from 'foo@example.com'
|
37
|
+
to 'bar@example.com'
|
38
|
+
body 'hello'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
let :message_without_body do
|
43
|
+
Mail.new do
|
44
|
+
date Time.at(946702800)
|
45
|
+
from 'foo@example.com'
|
46
|
+
to 'bar@example.com'
|
47
|
+
subject 'test'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe '#initialize' do
|
52
|
+
it 'should raise an error if :api_user is missing' do
|
53
|
+
expect{
|
54
|
+
message.delivery_method MultiMail::Sender::SendGrid, :api_key => 'xxx'
|
55
|
+
message.deliver # request not sent
|
56
|
+
}.to raise_error(ArgumentError, "Missing required arguments: api_user")
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should raise an error if :api_key is missing' do
|
60
|
+
expect{
|
61
|
+
message.delivery_method MultiMail::Sender::SendGrid, :api_user => 'xxx'
|
62
|
+
message.deliver # request not sent
|
63
|
+
}.to raise_error(ArgumentError, "Missing required arguments: api_key")
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should raise an error if :api_user is nil' do
|
67
|
+
expect{
|
68
|
+
message.delivery_method MultiMail::Sender::SendGrid, :api_user => nil, :api_key => 'xxx'
|
69
|
+
message.deliver # request not sent
|
70
|
+
}.to raise_error(ArgumentError, "Missing required arguments: api_user")
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should raise an error if :api_key is nil' do
|
74
|
+
expect{
|
75
|
+
message.delivery_method MultiMail::Sender::SendGrid, :api_user => 'xxx', :api_key => nil
|
76
|
+
message.deliver # request not sent
|
77
|
+
}.to raise_error(ArgumentError, "Missing required arguments: api_key")
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'should raise an error if :api_user or :api_key are invalid' do
|
81
|
+
expect{
|
82
|
+
message.delivery_method MultiMail::Sender::SendGrid, :api_user => 'xxx', :api_key => 'xxx'
|
83
|
+
message.deliver
|
84
|
+
}.to raise_error(MultiMail::InvalidAPIKey, 'Bad username / password')
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'should transform x-smtpapi to JSON if it is not JSON' do
|
88
|
+
sender = MultiMail::Sender::SendGrid.new(:api_user => '', :api_key => '', 'x-smtpapi' => {:foo => 'bar'})
|
89
|
+
sender.settings[:'x-smtpapi'].should == '{"foo":"bar"}'
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'should not transform x-smtpapi to JSON if it is JSON' do
|
93
|
+
sender = MultiMail::Sender::SendGrid.new(:api_user => '', :api_key => '', 'x-smtpapi' => '{"foo":"bar"}')
|
94
|
+
sender.settings[:'x-smtpapi'].should == '{"foo":"bar"}'
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe '#deliver' do
|
99
|
+
before :all do
|
100
|
+
Mail.defaults do
|
101
|
+
delivery_method MultiMail::Sender::SendGrid, :api_user => ENV['SENDGRID_API_USER'], :api_key => ENV['SENDGRID_API_KEY']
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'should send a message' do
|
106
|
+
message.deliver.should == message
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe '#deliver!' do
|
111
|
+
before :all do
|
112
|
+
Mail.defaults do
|
113
|
+
delivery_method MultiMail::Sender::SendGrid, :api_user => ENV['SENDGRID_API_USER'], :api_key => ENV['SENDGRID_API_KEY'], :return_response => true
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'should send a message' do
|
118
|
+
result = message.deliver!
|
119
|
+
result.size.should == 1
|
120
|
+
|
121
|
+
result['message'].should == 'success'
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'should not send a message without a From header' do
|
125
|
+
expect{message_without_from.deliver!}.to raise_error(MultiMail::MissingSender, 'Empty from email address (required)')
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'should not send a message without a To header' do
|
129
|
+
expect{message_without_to.deliver!}.to raise_error(MultiMail::MissingRecipients, 'Missing destination email')
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'should not send a message without a subject' do
|
133
|
+
expect{message_without_subject.deliver!}.to raise_error(MultiMail::MissingSubject, 'Missing subject')
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'should not send a message without a body' do
|
137
|
+
expect{message_without_body.deliver!}.to raise_error(MultiMail::MissingBody, 'Missing email body')
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
data/spec/service_spec.rb
CHANGED
@@ -2,9 +2,15 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
2
|
|
3
3
|
describe MultiMail::Service do
|
4
4
|
let :klass do
|
5
|
-
Class.new
|
5
|
+
Class.new do
|
6
|
+
extend MultiMail::Service
|
7
|
+
|
6
8
|
requires :required_argument1, :required_argument2
|
7
9
|
recognizes :optional_argument1, :optional_argument2
|
10
|
+
|
11
|
+
def initialize(options = {})
|
12
|
+
self.class.validate_options(options)
|
13
|
+
end
|
8
14
|
end
|
9
15
|
end
|
10
16
|
|
@@ -56,5 +62,16 @@ describe MultiMail::Service do
|
|
56
62
|
})
|
57
63
|
}.to raise_error(ArgumentError, "Unrecognized arguments: bar, foo")
|
58
64
|
end
|
65
|
+
|
66
|
+
it 'should raise not an error if unrecognized arguments are allowed' do
|
67
|
+
expect{
|
68
|
+
klass.validate_options({
|
69
|
+
:required_argument1 => 1,
|
70
|
+
:required_argument2 => 1,
|
71
|
+
:bar => 1,
|
72
|
+
:foo => 1,
|
73
|
+
}, false)
|
74
|
+
}.to_not raise_error(ArgumentError, "Unrecognized arguments: bar, foo")
|
75
|
+
end
|
59
76
|
end
|
60
77
|
end
|
@@ -15,7 +15,7 @@ describe MultiMail::Receiver::Simple do
|
|
15
15
|
|
16
16
|
describe '#transform' do
|
17
17
|
it 'should return a mail message' do
|
18
|
-
message = service.transform(params('valid'))[0]
|
18
|
+
message = service.transform(params('valid')['message'])[0]
|
19
19
|
|
20
20
|
# Headers
|
21
21
|
message.date.should == DateTime.parse('Thu, 27 Dec 2012 15:25:37 -0500')
|
data/spec/spec_helper.rb
CHANGED
@@ -3,13 +3,26 @@ require 'rubygems'
|
|
3
3
|
require 'coveralls'
|
4
4
|
Coveralls.wear!
|
5
5
|
|
6
|
+
require 'digest/sha1'
|
6
7
|
require 'net/http'
|
7
8
|
require 'yaml'
|
8
9
|
|
9
10
|
require 'rspec'
|
10
11
|
require 'rack'
|
12
|
+
require 'vcr'
|
11
13
|
require File.dirname(__FILE__) + '/../lib/multi_mail'
|
12
14
|
|
15
|
+
if RUBY_VERSION >= '1.9'
|
16
|
+
VCR.configure do |c|
|
17
|
+
c.cassette_library_dir = 'spec/cassettes'
|
18
|
+
c.hook_into :faraday
|
19
|
+
|
20
|
+
c.around_http_request do |request| # Ruby 1.9+
|
21
|
+
VCR.use_cassette(Digest::SHA1.hexdigest(request.uri + request.body), &request)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
13
26
|
# Requires supporting ruby files with custom matchers and macros, etc,
|
14
27
|
# in spec/support/ and its subdirectories.
|
15
28
|
Dir[File.expand_path("../support/**/*.rb", __FILE__)].each {|f| require f}
|
@@ -25,9 +38,13 @@ Dir[File.expand_path("../support/**/*.rb", __FILE__)].each {|f| require f}
|
|
25
38
|
# :mailgun_api_key: ...
|
26
39
|
# :mandrill_api_key: ...
|
27
40
|
# :postmark_api_key: ...
|
41
|
+
# :sendgrid_username: ...
|
42
|
+
# :sendgrid_password: ...
|
28
43
|
#
|
29
44
|
# For Postmark, you must create a server to get an API key.
|
30
45
|
#
|
46
|
+
# If you see `bad content body` exceptions, run `unix2dos` on the fixtures.
|
47
|
+
#
|
31
48
|
# # Cloudmailin
|
32
49
|
#
|
33
50
|
# Change the HTTP POST format on Cloudmailin and wait a few minutes. Run
|
@@ -61,6 +78,14 @@ Dir[File.expand_path("../support/**/*.rb", __FILE__)].each {|f| require f}
|
|
61
78
|
# spam.txt Send a subject-less message with message body XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X
|
62
79
|
# valid.txt Send a complex multipart message
|
63
80
|
#
|
81
|
+
# # SendGrid
|
82
|
+
#
|
83
|
+
# Run `bundle exec rake sendgrid` to set up SendGrid once SendGrid has
|
84
|
+
# provisioned your account.
|
85
|
+
#
|
86
|
+
# spam.txt Send a subject-less message with message body XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X
|
87
|
+
# valid.txt Send a complex multipart message
|
88
|
+
#
|
64
89
|
# @param [String] provider a provider
|
65
90
|
# @param [String] fixture one of "valid", "invalid" or "spam"
|
66
91
|
# @param [Boolean] action_dispatch whether uploaded files should be
|
@@ -68,8 +93,9 @@ Dir[File.expand_path("../support/**/*.rb", __FILE__)].each {|f| require f}
|
|
68
93
|
# @return [String] the provider's baked response
|
69
94
|
# @see FakeWeb::Responder#baked_response
|
70
95
|
# @see https://github.com/rack/rack/blob/master/test/spec_multipart.rb
|
71
|
-
def response(provider, fixture, action_dispatch = false)
|
72
|
-
|
96
|
+
def response(provider, fixture, action_dispatch = false, encoding = 'UTF-8')
|
97
|
+
path = File.expand_path("../fixtures/#{provider}/#{fixture}.txt", __FILE__)
|
98
|
+
contents = File.open(path, "r:#{encoding}"){|f| f.read}
|
73
99
|
io = StringIO.new(contents)
|
74
100
|
socket = Net::BufferedIO.new(io)
|
75
101
|
response = Net::HTTPResponse.read_new(socket)
|
@@ -79,7 +105,13 @@ def response(provider, fixture, action_dispatch = false)
|
|
79
105
|
body = contents[/(?:\r?\n){2,}(.+)\z/m, 1]
|
80
106
|
|
81
107
|
# It's kind of crazy that no library has an easier way of doing this.
|
82
|
-
if response.header['
|
108
|
+
if response.header['x-mandrill-signature']
|
109
|
+
body = Rack::Request.new(Rack::MockRequest.env_for('/', {
|
110
|
+
'HTTP_X_MANDRILL_SIGNATURE' => response.header['x-mandrill-signature'],
|
111
|
+
:method => 'POST',
|
112
|
+
:input => body,
|
113
|
+
}))
|
114
|
+
elsif response.header['content-type']['multipart/form-data']
|
83
115
|
body = Rack::Multipart.parse_multipart(Rack::MockRequest.env_for('/', {
|
84
116
|
'CONTENT_TYPE' => response.header['content-type'],
|
85
117
|
:input => body,
|
@@ -88,7 +120,7 @@ def response(provider, fixture, action_dispatch = false)
|
|
88
120
|
|
89
121
|
if action_dispatch
|
90
122
|
# ActionDispatch would parse the request into a parameters hash.
|
91
|
-
klass = Class.new
|
123
|
+
klass = Class.new do
|
92
124
|
include MultiMail::Receiver::Base
|
93
125
|
end
|
94
126
|
normalize_encode_params(klass.parse(body))
|
@@ -138,3 +170,13 @@ def normalize_encode_params(params)
|
|
138
170
|
params
|
139
171
|
end
|
140
172
|
end
|
173
|
+
|
174
|
+
# @return [String] the path to the GIF file
|
175
|
+
def empty_gif_path
|
176
|
+
File.expand_path('../fixtures/empty.gif', __FILE__)
|
177
|
+
end
|
178
|
+
|
179
|
+
# @return [String] the content of the GIF file
|
180
|
+
def empty_gif_content
|
181
|
+
File.read(empty_gif_path)
|
182
|
+
end
|