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
@@ -20,7 +20,7 @@ describe MultiMail::Receiver::Postmark do
|
|
20
20
|
# Headers
|
21
21
|
message.date.should == DateTime.parse('Mon, 15 Apr 2013 20:20:12 -0400')
|
22
22
|
message.from.should == ['james@opennorth.ca']
|
23
|
-
message.to.should == ['4354473e2e6ab001fa836f627a54004e@inbound.postmarkapp.com']
|
23
|
+
message.to.should == ['4354473e2e6ab001fa836f627a54004e+bar@inbound.postmarkapp.com']
|
24
24
|
message.subject.should == 'Test'
|
25
25
|
|
26
26
|
# Body
|
@@ -39,8 +39,8 @@ describe MultiMail::Receiver::Postmark do
|
|
39
39
|
attachment1.read.should == "Nam accumsan euismod eros et rhoncus.\n"
|
40
40
|
|
41
41
|
# Extra Postmark parameters
|
42
|
-
message['MailboxHash'].should
|
43
|
-
message['MessageID'].value.should == '
|
42
|
+
message['MailboxHash'].value.should == 'bar'
|
43
|
+
message['MessageID'].value.should == 'e27500eb-142e-4ca0-8529-e32ffd9931d6'
|
44
44
|
message['Tag'].should be_nil
|
45
45
|
end
|
46
46
|
end
|
@@ -56,5 +56,5 @@ describe MultiMail::Receiver::Postmark do
|
|
56
56
|
service.spam?(message).should == false
|
57
57
|
end
|
58
58
|
end
|
59
|
-
end
|
59
|
+
end
|
60
60
|
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
require 'multi_mail/postmark/sender'
|
3
|
+
|
4
|
+
# @see https://github.com/wildbit/postmark-gem/blob/master/spec/unit/postmark/handlers/mail_spec.rb
|
5
|
+
# @see https://github.com/wildbit/postmark-gem/blob/master/spec/integration/mail_delivery_method_spec.rb
|
6
|
+
describe MultiMail::Sender::Postmark do
|
7
|
+
let :message do
|
8
|
+
Mail.new do
|
9
|
+
from 'foo@example.com'
|
10
|
+
to 'bar@example.com'
|
11
|
+
subject 'test'
|
12
|
+
body 'hello'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
let :message_without_from do
|
17
|
+
Mail.new do
|
18
|
+
date Time.at(946702800)
|
19
|
+
to 'bar@example.com'
|
20
|
+
subject 'test'
|
21
|
+
body 'hello'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
let :message_without_to do
|
26
|
+
Mail.new do
|
27
|
+
date Time.at(946702800)
|
28
|
+
from 'foo@example.com'
|
29
|
+
subject 'test'
|
30
|
+
body 'hello'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
let :message_without_subject do
|
35
|
+
Mail.new do
|
36
|
+
date Time.at(946702800)
|
37
|
+
from 'foo@example.com'
|
38
|
+
to 'bar@example.com'
|
39
|
+
body 'hello'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
let :message_without_body do
|
44
|
+
Mail.new do
|
45
|
+
date Time.at(946702800)
|
46
|
+
from 'foo@example.com'
|
47
|
+
to 'bar@example.com'
|
48
|
+
subject 'test'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#initialize' do
|
53
|
+
it 'should raise an error if :api_key is missing' do
|
54
|
+
expect{
|
55
|
+
message.delivery_method MultiMail::Sender::Postmark
|
56
|
+
message.deliver
|
57
|
+
}.to raise_error(ArgumentError, "Missing required arguments: api_key")
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should raise an error if :api_key is nil' do
|
61
|
+
expect{
|
62
|
+
message.delivery_method MultiMail::Sender::Postmark, :api_key => nil
|
63
|
+
message.deliver
|
64
|
+
}.to raise_error(ArgumentError, "Missing required arguments: api_key")
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'should raise an error if :api_key is invalid' do
|
68
|
+
expect{
|
69
|
+
message.delivery_method MultiMail::Sender::Postmark, :api_key => 'xxx'
|
70
|
+
message.deliver
|
71
|
+
}.to raise_error(MultiMail::InvalidAPIKey, 'Bad or missing server or user API token.')
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe '#deliver' do
|
76
|
+
before :all do
|
77
|
+
Mail.defaults do
|
78
|
+
delivery_method MultiMail::Sender::Postmark, :api_key => 'POSTMARK_API_TEST'
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should send a message' do
|
83
|
+
message.deliver.should == message
|
84
|
+
message['Message-ID'].should_not be_nil # postmark gem
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe '#deliver!' do
|
89
|
+
before :all do
|
90
|
+
Mail.defaults do
|
91
|
+
delivery_method MultiMail::Sender::Postmark, :api_key => 'POSTMARK_API_TEST', :return_response => true
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'should send a message' do
|
96
|
+
result = message.deliver!
|
97
|
+
result.size.should == 10 # string keys are deprecated
|
98
|
+
|
99
|
+
Time.parse(result[:submitted_at]).should be_within(1).of(Time.now)
|
100
|
+
result[:to].should == "bar@example.com"
|
101
|
+
result[:message_id].should match(/\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/)
|
102
|
+
result[:error_code].should == 0
|
103
|
+
result[:message].should == 'Test job accepted'
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should not send a message without a From header' do
|
107
|
+
expect{message_without_from.deliver!}.to raise_error(MultiMail::MissingSender, "Invalid 'From' value.")
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'should not send a message without a To header' do
|
111
|
+
expect{message_without_to.deliver!}.to raise_error(MultiMail::MissingRecipients, 'Zero recipients specified')
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'should not send a message without a body' do
|
115
|
+
expect{message_without_body.deliver!}.to raise_error(MultiMail::MissingBody, 'Provide either email TextBody or HtmlBody or both.')
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
data/spec/receiver/base_spec.rb
CHANGED
@@ -2,7 +2,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
2
2
|
|
3
3
|
describe MultiMail::Receiver::Base do
|
4
4
|
let :klass do
|
5
|
-
Class.new
|
5
|
+
Class.new do
|
6
6
|
include MultiMail::Receiver::Base
|
7
7
|
|
8
8
|
def valid?(params)
|
@@ -36,29 +36,36 @@ describe MultiMail::Receiver::Base do
|
|
36
36
|
end
|
37
37
|
|
38
38
|
describe '#parse' do
|
39
|
+
let :expected do
|
40
|
+
{'foo' => '1', 'bar' => ['1', '1']}
|
41
|
+
end
|
42
|
+
|
39
43
|
it 'should parse JSON' do
|
40
|
-
klass.parse('{"foo":1,"bar":1,"
|
44
|
+
klass.parse('{"foo":"1","bar":["1","1"]}').should == expected
|
41
45
|
end
|
42
46
|
|
43
47
|
it 'should parse raw POST data' do
|
44
|
-
klass.parse('foo=1&bar=1&bar=1').should ==
|
48
|
+
klass.parse('foo=1&bar=1&bar=1').should == expected
|
45
49
|
end
|
46
50
|
|
47
51
|
it 'should accept an array' do
|
48
|
-
klass.parse([['foo', 1], ['bar', [1, 1]]]).should ==
|
49
|
-
end
|
50
|
-
|
51
|
-
it 'should accept a Rack::Request object' do
|
52
|
-
klass.parse(Rack::Request.new(Rack::MockRequest.env_for('/?foo=1&bar[]=1&bar[]=1'))).should == {'foo' => '1', 'bar' => ['1', '1']}
|
52
|
+
klass.parse([['foo', '1'], ['bar', ['1', '1']]]).should == expected
|
53
53
|
end
|
54
54
|
|
55
55
|
it 'should pass-through a hash' do
|
56
|
-
klass.parse('foo' => 1
|
56
|
+
klass.parse({'foo' => '1', 'bar' => ['1', '1']}).should == expected
|
57
57
|
end
|
58
58
|
|
59
59
|
it 'should raise an error if the argument is invalid' do
|
60
60
|
expect{ klass.parse(1) }.to raise_error(ArgumentError, "Can't handle Fixnum input")
|
61
61
|
end
|
62
|
+
|
63
|
+
it 'should accept a Rack::Request object' do
|
64
|
+
params = klass.parse(Rack::Request.new(Rack::MockRequest.env_for('/?foo=1&bar[]=1&bar[]=1')))
|
65
|
+
params['env'].should be_a(Hash)
|
66
|
+
params.delete('env')
|
67
|
+
params.should == expected
|
68
|
+
end
|
62
69
|
end
|
63
70
|
|
64
71
|
describe '#add_file_arguments' do
|
data/spec/sender/base_spec.rb
CHANGED
@@ -2,20 +2,34 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
2
2
|
|
3
3
|
describe MultiMail::Sender::Base do
|
4
4
|
let :klass do
|
5
|
-
Class.new
|
5
|
+
Class.new do
|
6
6
|
include MultiMail::Sender::Base
|
7
7
|
|
8
|
-
|
9
|
-
params['foo'] == 1
|
10
|
-
end
|
11
|
-
|
12
|
-
def transform(params)
|
13
|
-
[Mail.new]
|
14
|
-
end
|
8
|
+
requires :foo
|
15
9
|
end
|
16
10
|
end
|
17
11
|
|
18
|
-
|
19
|
-
|
12
|
+
describe '#initialize' do
|
13
|
+
it 'should symbolize keys' do
|
14
|
+
instance = klass.new('foo' => 1, :bar => 2, nil => 3, true => 4, false => 5, 6 => 6)
|
15
|
+
instance.settings.should == {
|
16
|
+
:foo => 1,
|
17
|
+
:bar => 2,
|
18
|
+
nil => 3,
|
19
|
+
true => 4,
|
20
|
+
false => 5,
|
21
|
+
6 => 6,
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should have default settings' do
|
26
|
+
sender = klass.new(:foo => '')
|
27
|
+
sender.tracking.should == {}
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should assign custom settings' do
|
31
|
+
sender = klass.new(:foo => '', :track => {:opens => true})
|
32
|
+
sender.tracking.should == {:opens => true}
|
33
|
+
end
|
20
34
|
end
|
21
35
|
end
|
@@ -0,0 +1,265 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
require 'multi_mail/sendgrid/message'
|
3
|
+
|
4
|
+
describe MultiMail::Message::SendGrid do
|
5
|
+
let :message do
|
6
|
+
headers = {
|
7
|
+
'X-Autoreply' => true,
|
8
|
+
'X-Precedence' => 'auto_reply',
|
9
|
+
'X-Numeric' => 42,
|
10
|
+
'Delivered-To' => 'Autoresponder',
|
11
|
+
}
|
12
|
+
|
13
|
+
MultiMail::Message::SendGrid.new do
|
14
|
+
date Time.at(946702800)
|
15
|
+
headers headers
|
16
|
+
from %("John Doe" <foo@example.com>)
|
17
|
+
to [%("Jane Doe" <bar@example.com>), '<baz@example.com>']
|
18
|
+
cc 'cc@example.com'
|
19
|
+
bcc 'bcc@example.com'
|
20
|
+
reply_to 'noreply@example.com'
|
21
|
+
subject 'test'
|
22
|
+
|
23
|
+
text_part do
|
24
|
+
body 'hello'
|
25
|
+
end
|
26
|
+
|
27
|
+
html_part do
|
28
|
+
content_type 'text/html; charset=UTF-8'
|
29
|
+
body '<p>hello</p>'
|
30
|
+
end
|
31
|
+
|
32
|
+
add_file empty_gif_path
|
33
|
+
add_file :filename => 'foo.txt', :content => 'hello world'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
let :message_without_names do
|
38
|
+
MultiMail::Message::SendGrid.new do
|
39
|
+
from 'foo@example.com'
|
40
|
+
to ['bar@example.com', 'baz@example.com']
|
41
|
+
subject 'test'
|
42
|
+
body 'hello'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
let :message_with_known_extension do
|
47
|
+
MultiMail::Message::SendGrid.new do
|
48
|
+
from 'foo@example.com'
|
49
|
+
to 'bar@example.com'
|
50
|
+
subject 'test'
|
51
|
+
body 'hello'
|
52
|
+
add_file :filename => 'xxx.mov', :content => ''
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
let :message_with_unknown_extension do
|
57
|
+
MultiMail::Message::SendGrid.new do
|
58
|
+
from 'foo@example.com'
|
59
|
+
to 'bar@example.com'
|
60
|
+
subject 'test'
|
61
|
+
body 'hello'
|
62
|
+
add_file :filename => 'xxx.xxx', :content => ''
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
let :message_without_extension do
|
67
|
+
MultiMail::Message::SendGrid.new do
|
68
|
+
from 'foo@example.com'
|
69
|
+
to 'bar@example.com'
|
70
|
+
subject 'test'
|
71
|
+
body 'hello'
|
72
|
+
add_file :filename => 'xxx', :content => ''
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
let :message_with_empty_file do
|
77
|
+
MultiMail::Message::SendGrid.new do
|
78
|
+
from 'foo@example.com'
|
79
|
+
to 'bar@example.com'
|
80
|
+
subject 'test'
|
81
|
+
body 'hello'
|
82
|
+
add_file :filename => '', :content => ''
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
let :message_with_empty_headers do
|
87
|
+
headers = {
|
88
|
+
'X-Autoreply' => nil,
|
89
|
+
}
|
90
|
+
|
91
|
+
MultiMail::Message::SendGrid.new do
|
92
|
+
headers headers
|
93
|
+
from 'foo@example.com'
|
94
|
+
to 'bar@example.com'
|
95
|
+
reply_to nil
|
96
|
+
subject 'test'
|
97
|
+
body 'hello'
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
let :message_without_html_body do
|
102
|
+
MultiMail::Message::SendGrid.new do
|
103
|
+
from 'foo@example.com'
|
104
|
+
to 'bar@example.com'
|
105
|
+
subject 'test'
|
106
|
+
body 'hello'
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
let :message_without_text_body do
|
111
|
+
MultiMail::Message::SendGrid.new do
|
112
|
+
from 'foo@example.com'
|
113
|
+
to 'bar@example.com'
|
114
|
+
subject 'test'
|
115
|
+
body '<p>hello</p>'
|
116
|
+
content_type 'text/html; charset=UTF-8'
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
let :empty_message do
|
121
|
+
MultiMail::Message::SendGrid.new
|
122
|
+
end
|
123
|
+
|
124
|
+
describe '#sendgrid_files' do
|
125
|
+
it 'should return the attachments' do
|
126
|
+
files = message.sendgrid_files
|
127
|
+
files['empty.gif'].content_type.should == 'image/gif; filename=empty.gif'
|
128
|
+
files['empty.gif'].original_filename.should == 'empty.gif'
|
129
|
+
files['empty.gif'].read.should == File.open(empty_gif_path, 'r:binary'){|f| f.read}
|
130
|
+
files['foo.txt'].content_type.should == 'text/plain; filename=foo.txt'
|
131
|
+
files['foo.txt'].original_filename.should == 'foo.txt'
|
132
|
+
files['foo.txt'].read.should == 'hello world'
|
133
|
+
files.size.should == 2
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'should return an attachment with an known extension' do
|
137
|
+
files = message_with_known_extension.sendgrid_files
|
138
|
+
files['xxx.mov'].content_type.should == 'video/quicktime; filename=xxx.mov'
|
139
|
+
files['xxx.mov'].original_filename.should == 'xxx.mov'
|
140
|
+
files['xxx.mov'].read.should == ''
|
141
|
+
files.size.should == 1
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'should return an attachment with an unknown extension' do
|
145
|
+
files = message_with_unknown_extension.sendgrid_files
|
146
|
+
files['xxx.xxx'].content_type.should == 'text/plain'
|
147
|
+
files['xxx.xxx'].original_filename.should == 'xxx.xxx'
|
148
|
+
files['xxx.xxx'].read.should == ''
|
149
|
+
files.size.should == 1
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'should return an attachment without an extension' do
|
153
|
+
files = message_without_extension.sendgrid_files
|
154
|
+
files['xxx'].content_type.should == 'text/plain'
|
155
|
+
files['xxx'].original_filename.should == 'xxx'
|
156
|
+
files['xxx'].read.should == ''
|
157
|
+
files.size.should == 1
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'should return an empty array if the attachment is blank' do
|
161
|
+
message_with_empty_file.sendgrid_files.should == {}
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'should return an empty array' do
|
165
|
+
empty_message.sendgrid_files.should == {}
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
describe '#sendgrid_content' do
|
170
|
+
it 'should return the content IDs' do
|
171
|
+
content = message.sendgrid_content
|
172
|
+
content.should == {'empty.gif' => 'empty.gif'}
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'should return an empty array if the attachment is blank' do
|
176
|
+
message_with_empty_file.sendgrid_content.should == {}
|
177
|
+
end
|
178
|
+
|
179
|
+
it 'should return an empty array' do
|
180
|
+
empty_message.sendgrid_content.should == {}
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
describe '#sendgrid_headers' do
|
185
|
+
it 'should return the headers' do
|
186
|
+
headers = message.sendgrid_headers
|
187
|
+
headers['Cc'].should == 'cc@example.com'
|
188
|
+
headers['X-Autoreply'].should == 'true'
|
189
|
+
headers['X-Precedence'].should == 'auto_reply'
|
190
|
+
headers['X-Numeric'].should == '42'
|
191
|
+
headers['Delivered-To'].should == 'Autoresponder'
|
192
|
+
|
193
|
+
headers['Content-Type'].should match(%r{\Amultipart/alternative; boundary=--==_mimepart_[0-9a-f_]+\z})
|
194
|
+
|
195
|
+
headers.size.should == 6
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'should return empty X-* headers' do
|
199
|
+
headers = message_with_empty_headers.sendgrid_headers
|
200
|
+
headers.should == {'X-Autoreply' => ''}
|
201
|
+
end
|
202
|
+
|
203
|
+
it 'should return an empty hash' do
|
204
|
+
empty_message.sendgrid_headers.should == {}
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
describe '#to_sendgrid_hash' do
|
209
|
+
it 'should return the message as SendGrid parameters' do
|
210
|
+
hash = message.to_sendgrid_hash
|
211
|
+
|
212
|
+
hash[:to].should == ['bar@example.com', 'baz@example.com']
|
213
|
+
hash[:toname].should == ['Jane Doe', nil]
|
214
|
+
hash[:subject].should == 'test'
|
215
|
+
hash[:text].should == 'hello'
|
216
|
+
hash[:html].should == '<p>hello</p>'
|
217
|
+
hash[:from].should == 'foo@example.com'
|
218
|
+
hash[:bcc].should == ['bcc@example.com']
|
219
|
+
hash[:fromname].should == 'John Doe'
|
220
|
+
hash[:replyto].should == 'noreply@example.com'
|
221
|
+
hash[:content].should == {'empty.gif' => 'empty.gif'}
|
222
|
+
|
223
|
+
hash[:headers].should match(/"Cc":"cc@example.com"/)
|
224
|
+
hash[:headers].should match(%r{"Content-Type":"multipart/alternative; boundary=--==_mimepart_[0-9a-f_]+"})
|
225
|
+
hash[:headers].should match(/"X-Autoreply":"true"/)
|
226
|
+
hash[:headers].should match(/"X-Precedence":"auto_reply"/)
|
227
|
+
hash[:headers].should match(/"X-Numeric":"42"/)
|
228
|
+
hash[:headers].should match(/"Delivered-To":"Autoresponder"/)
|
229
|
+
Time.parse(hash[:'date']).should be_within(1).of(Time.at(946702800))
|
230
|
+
|
231
|
+
hash[:files]['empty.gif'].content_type.should == 'image/gif; filename=empty.gif'
|
232
|
+
hash[:files]['empty.gif'].original_filename.should == 'empty.gif'
|
233
|
+
hash[:files]['empty.gif'].read.should == File.open(empty_gif_path, 'r:binary'){|f| f.read}
|
234
|
+
hash[:files]['foo.txt'].content_type.should == 'text/plain; filename=foo.txt'
|
235
|
+
hash[:files]['foo.txt'].original_filename.should == 'foo.txt'
|
236
|
+
hash[:files]['foo.txt'].read.should == 'hello world'
|
237
|
+
hash[:files].size.should == 2
|
238
|
+
|
239
|
+
hash.size.should == 13
|
240
|
+
end
|
241
|
+
|
242
|
+
it 'should convert the message without a text body' do
|
243
|
+
message_without_text_body.to_sendgrid_hash.should == {
|
244
|
+
:to => ['bar@example.com'],
|
245
|
+
:subject => 'test',
|
246
|
+
:html => '<p>hello</p>',
|
247
|
+
:from => 'foo@example.com',
|
248
|
+
:headers => %({"Content-Type":"text/html; charset=UTF-8"}),
|
249
|
+
}
|
250
|
+
end
|
251
|
+
|
252
|
+
it 'should convert the message without an HTML body' do
|
253
|
+
message_without_html_body.to_sendgrid_hash.should == {
|
254
|
+
:to => ['bar@example.com'],
|
255
|
+
:subject => 'test',
|
256
|
+
:text => 'hello',
|
257
|
+
:from => 'foo@example.com',
|
258
|
+
}
|
259
|
+
end
|
260
|
+
|
261
|
+
it 'should convert an empty message' do
|
262
|
+
empty_message.to_sendgrid_hash.should == {}
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
3
|
+
require 'multi_mail/sendgrid/receiver'
|
4
|
+
|
5
|
+
describe MultiMail::Receiver::SendGrid do
|
6
|
+
context 'after initialization' do
|
7
|
+
let :service do
|
8
|
+
MultiMail::Receiver.new(:provider => :sendgrid)
|
9
|
+
end
|
10
|
+
|
11
|
+
def params(fixture, encoding = 'UTF-8')
|
12
|
+
MultiMail::Receiver::SendGrid.parse(response('sendgrid', fixture, false, encoding))
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#transform' do
|
16
|
+
it 'should return a mail message' do
|
17
|
+
messages = service.transform(params('valid'))
|
18
|
+
messages.size.should == 1
|
19
|
+
message = messages[0]
|
20
|
+
|
21
|
+
# Headers
|
22
|
+
message.date.should == DateTime.parse('Mon, 15 Apr 2013 20:20:12 -0400')
|
23
|
+
message.from.should == ['james@opennorth.ca']
|
24
|
+
message.to.should == ['foo+bar@parolecitoyenne.com']
|
25
|
+
message.subject.should == 'Test'
|
26
|
+
|
27
|
+
# Body
|
28
|
+
message.multipart?.should == true
|
29
|
+
# @note SendGrid adds additional HTML parts as attachments, which is
|
30
|
+
# sensible, but it does not match the behavior of other email APIs.
|
31
|
+
message.parts.size.should == 6
|
32
|
+
message.parts[0].content_type.should == 'text/plain'
|
33
|
+
message.parts[1].content_type.should == 'text/html; charset=UTF-8'
|
34
|
+
message.parts[0].body.decoded.should == "bold text\n\n\n\nsome more bold text\n\n\n\nsome italic text\n\n> multiline\n> quoted\n> text\n\n\n--\nSignature block"
|
35
|
+
# @note Due to a SendGrid bug, the HTML part is missing content.
|
36
|
+
message.parts[1].body.decoded.should == %(<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><b>bold text</b><div><br></div><div></div></body></html>)
|
37
|
+
|
38
|
+
# HTML attachments
|
39
|
+
message.parts[3].content_type.should == 'text/html; filename=msg-12415-313.html'
|
40
|
+
message.parts[5].content_type.should == 'text/html; filename=msg-12415-314.html'
|
41
|
+
message.parts[3].body.decoded.should == %(<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><head></head><br><div></div><div><br></div><div><b>some more bold text</b></div><div><b><br></b></div><div><b></b></div></body></html>)
|
42
|
+
message.parts[5].body.decoded.should == %(<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><b></b></div><div><b><span class="Apple-style-span" style="font-weight: normal; "><br></span></b></div><div><b><span class="Apple-style-span" style="font-weight: normal; "><i>some italic text</i></span></b></div><div><b><span class="Apple-style-span" style="font-weight: normal; "><br></span></b></div><div><blockquote type="cite">multiline</blockquote><blockquote type="cite">quoted</blockquote><blockquote type="cite">text</blockquote></div><div><br></div><div>--</div><div>Signature block</div></body></html>)
|
43
|
+
|
44
|
+
# Attachments
|
45
|
+
attachment0 = message.attachments.find{|attachment| attachment.filename == 'foo.txt'}
|
46
|
+
attachment1 = message.attachments.find{|attachment| attachment.filename == 'bar.txt'}
|
47
|
+
attachment0.read.should == "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n"
|
48
|
+
attachment1.read.should == "Nam accumsan euismod eros et rhoncus.\n"
|
49
|
+
|
50
|
+
# Extra SendGrid parameters
|
51
|
+
message['dkim'].value.should == 'none'
|
52
|
+
message['SPF'].value.should == 'pass'
|
53
|
+
message['spam_report'].value.should == "Spam detection software, running on the system \"mx3.sendgrid.net\", has\r\nidentified this incoming email as possible spam. The original message\r\nhas been attached to this so you can view it (if it isn't spam) or label\r\nsimilar future email. If you have any questions, see\r\nthe administrator of that system for details.\r\n\r\nContent preview: bold text some more bold text some italic text [...] \r\n\r\nContent analysis details: (-2.6 points, 5.0 required)\r\n\r\n pts rule name description\r\n---- ---------------------- --------------------------------------------------\r\n-0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low\r\n trust\r\n [209.85.223.172 listed in list.dnswl.org]\r\n-1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1%\r\n [score: 0.0000]\r\n 0.0 HTML_MESSAGE BODY: HTML included in message\r\n\r\n"
|
54
|
+
message['spam_score'].value.should == '-2.599'
|
55
|
+
end
|
56
|
+
|
57
|
+
# No postbin is capable of handling mixed encodings, and most fail to even
|
58
|
+
# display the request. http://postbin.hackyon.com/ works best, but we
|
59
|
+
# still need to hand-edit the response.
|
60
|
+
it 'should respect encodings' do
|
61
|
+
service.transform(params('encoding', 'WINDOWS-1252'))[0].text_part.decoded.should == 'World €'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe '#spam?' do
|
66
|
+
it 'should return true if the response is spam' do
|
67
|
+
message = service.transform(params('spam'))[0]
|
68
|
+
service.spam?(message).should == true
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'should return false if the response is ham' do
|
72
|
+
message = service.transform(params('valid'))[0]
|
73
|
+
service.spam?(message).should == false
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|