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.
Files changed (60) hide show
  1. data/.gitignore +2 -1
  2. data/.travis.yml +10 -0
  3. data/README.md +283 -59
  4. data/Rakefile +38 -19
  5. data/lib/multi_mail/cloudmailin/receiver.rb +3 -13
  6. data/lib/multi_mail/mailgun/message.rb +67 -0
  7. data/lib/multi_mail/mailgun/receiver.rb +20 -13
  8. data/lib/multi_mail/mailgun/sender.rb +79 -2
  9. data/lib/multi_mail/mandrill/message.rb +74 -0
  10. data/lib/multi_mail/mandrill/receiver.rb +36 -16
  11. data/lib/multi_mail/mandrill/sender.rb +77 -2
  12. data/lib/multi_mail/message/base.rb +40 -0
  13. data/lib/multi_mail/postmark/receiver.rb +1 -1
  14. data/lib/multi_mail/postmark/sender.rb +35 -5
  15. data/lib/multi_mail/receiver/base.rb +31 -2
  16. data/lib/multi_mail/receiver.rb +1 -4
  17. data/lib/multi_mail/sender/base.rb +23 -1
  18. data/lib/multi_mail/sendgrid/message.rb +74 -0
  19. data/lib/multi_mail/sendgrid/receiver.rb +72 -23
  20. data/lib/multi_mail/sendgrid/sender.rb +63 -2
  21. data/lib/multi_mail/service.rb +48 -56
  22. data/lib/multi_mail/simple/receiver.rb +4 -4
  23. data/lib/multi_mail/version.rb +1 -1
  24. data/lib/multi_mail.rb +16 -1
  25. data/multi_mail.gemspec +4 -1
  26. data/spec/fixtures/empty.gif +0 -0
  27. data/spec/fixtures/mailgun/raw/invalid.txt +13 -0
  28. data/spec/fixtures/mailgun/raw/missing.txt +13 -0
  29. data/spec/fixtures/mailgun/raw/spam.txt +13 -0
  30. data/spec/fixtures/mailgun/raw/valid.txt +13 -0
  31. data/spec/fixtures/mandrill/invalid.txt +15 -0
  32. data/spec/fixtures/mandrill/missing.txt +14 -0
  33. data/spec/fixtures/mandrill/multiple.txt +15 -0
  34. data/spec/fixtures/mandrill/valid.txt +10 -5
  35. data/spec/fixtures/postmark/valid.txt +13 -13
  36. data/spec/fixtures/sendgrid/encoding.txt +90 -0
  37. data/spec/fixtures/sendgrid/spam.txt +94 -0
  38. data/spec/fixtures/sendgrid/valid.txt +136 -0
  39. data/spec/mailgun/message_spec.rb +251 -0
  40. data/spec/mailgun/receiver_spec.rb +35 -20
  41. data/spec/mailgun/sender_spec.rb +175 -0
  42. data/spec/mandrill/message_spec.rb +305 -0
  43. data/spec/mandrill/receiver_spec.rb +90 -46
  44. data/spec/mandrill/sender_spec.rb +138 -0
  45. data/spec/message/base_spec.rb +81 -0
  46. data/spec/postmark/receiver_spec.rb +4 -4
  47. data/spec/postmark/sender_spec.rb +118 -0
  48. data/spec/receiver/base_spec.rb +16 -9
  49. data/spec/sender/base_spec.rb +24 -10
  50. data/spec/sendgrid/message_spec.rb +265 -0
  51. data/spec/sendgrid/receiver_spec.rb +77 -0
  52. data/spec/sendgrid/sender_spec.rb +140 -0
  53. data/spec/service_spec.rb +18 -1
  54. data/spec/simple/receiver_spec.rb +1 -1
  55. data/spec/spec_helper.rb +46 -4
  56. metadata +226 -143
  57. data/lib/multi_mail/sender.rb +0 -46
  58. data/lib/multi_mail/simple/sender.rb +0 -14
  59. data/spec/sender_spec.rb +0 -13
  60. 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(MultiMail::Service) do
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
- contents = File.read(File.expand_path("../fixtures/#{provider}/#{fixture}.txt", __FILE__))
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['content-type']['multipart/form-data']
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(MultiMail::Service) do
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