postmark 0.9.19 → 1.0.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/.travis.yml +8 -0
- data/CHANGELOG.rdoc +20 -0
- data/Gemfile +6 -0
- data/README.md +351 -91
- data/VERSION +1 -1
- data/lib/postmark.rb +40 -132
- data/lib/postmark/api_client.rb +162 -0
- data/lib/postmark/bounce.rb +20 -17
- data/lib/postmark/handlers/mail.rb +10 -3
- data/lib/postmark/helpers/hash_helper.rb +35 -0
- data/lib/postmark/helpers/message_helper.rb +62 -0
- data/lib/postmark/http_client.rb +44 -28
- data/lib/postmark/inbound.rb +21 -0
- data/lib/postmark/inflector.rb +28 -0
- data/lib/postmark/message_extensions/mail.rb +50 -5
- data/lib/postmark/message_extensions/shared.rb +23 -28
- data/lib/postmark/version.rb +1 -1
- data/postmark.gemspec +4 -7
- data/spec/data/empty.gif +0 -0
- data/spec/integration/api_client_hashes_spec.rb +101 -0
- data/spec/integration/api_client_messages_spec.rb +127 -0
- data/spec/integration/mail_delivery_method_spec.rb +80 -0
- data/spec/spec_helper.rb +15 -5
- data/spec/support/helpers.rb +11 -0
- data/spec/{shared_examples.rb → support/shared_examples.rb} +0 -0
- data/spec/unit/postmark/api_client_spec.rb +246 -0
- data/spec/unit/postmark/bounce_spec.rb +142 -0
- data/spec/unit/postmark/handlers/mail_spec.rb +39 -0
- data/spec/unit/postmark/helpers/hash_helper_spec.rb +34 -0
- data/spec/unit/postmark/helpers/message_helper_spec.rb +115 -0
- data/spec/unit/postmark/http_client_spec.rb +204 -0
- data/spec/unit/postmark/inbound_spec.rb +88 -0
- data/spec/unit/postmark/inflector_spec.rb +35 -0
- data/spec/unit/postmark/json_spec.rb +37 -0
- data/spec/unit/postmark/message_extensions/mail_spec.rb +205 -0
- data/spec/unit/postmark_spec.rb +164 -0
- metadata +45 -93
- data/lib/postmark/attachments_fix_for_mail.rb +0 -48
- data/lib/postmark/message_extensions/tmail.rb +0 -115
- data/spec/bounce_spec.rb +0 -53
- data/spec/postmark_spec.rb +0 -253
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Postmark::Inbound do
|
4
|
+
# http://developer.postmarkapp.com/developer-inbound-parse.html#example-hook
|
5
|
+
let(:example_inbound) { '{"From":"myUser@theirDomain.com","FromFull":{"Email":"myUser@theirDomain.com","Name":"John Doe"},"To":"451d9b70cf9364d23ff6f9d51d870251569e+ahoy@inbound.postmarkapp.com","ToFull":[{"Email":"451d9b70cf9364d23ff6f9d51d870251569e+ahoy@inbound.postmarkapp.com","Name":""}],"Cc":"\"Full name\" <sample.cc@emailDomain.com>, \"Another Cc\" <another.cc@emailDomain.com>","CcFull":[{"Email":"sample.cc@emailDomain.com","Name":"Full name"},{"Email":"another.cc@emailDomain.com","Name":"Another Cc"}],"ReplyTo":"myUsersReplyAddress@theirDomain.com","Subject":"This is an inbound message","MessageID":"22c74902-a0c1-4511-804f2-341342852c90","Date":"Thu, 5 Apr 2012 16:59:01 +0200","MailboxHash":"ahoy","TextBody":"[ASCII]","HtmlBody":"[HTML(encoded)]","Tag":"","Headers":[{"Name":"X-Spam-Checker-Version","Value":"SpamAssassin 3.3.1 (2010-03-16) onrs-ord-pm-inbound1.wildbit.com"},{"Name":"X-Spam-Status","Value":"No"},{"Name":"X-Spam-Score","Value":"-0.1"},{"Name":"X-Spam-Tests","Value":"DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,SPF_PASS"},{"Name":"Received-SPF","Value":"Pass (sender SPF authorized) identity=mailfrom; client-ip=209.85.160.180; helo=mail-gy0-f180.google.com; envelope-from=myUser@theirDomain.com; receiver=451d9b70cf9364d23ff6f9d51d870251569e+ahoy@inbound.postmarkapp.com"},{"Name":"DKIM-Signature","Value":"v=1; a=rsa-sha256; c=relaxed\/relaxed; d=wildbit.com; s=google; h=mime-version:reply-to:date:message-id:subject:from:to:cc :content-type; bh=cYr\/+oQiklaYbBJOQU3CdAnyhCTuvemrU36WT7cPNt0=; b=QsegXXbTbC4CMirl7A3VjDHyXbEsbCUTPL5vEHa7hNkkUTxXOK+dQA0JwgBHq5C+1u iuAJMz+SNBoTqEDqte2ckDvG2SeFR+Edip10p80TFGLp5RucaYvkwJTyuwsA7xd78NKT Q9ou6L1hgy\/MbKChnp2kxHOtYNOrrszY3JfQM="},{"Name":"MIME-Version","Value":"1.0"},{"Name":"Message-ID","Value":"<CAGXpo2WKfxHWZ5UFYCR3H_J9SNMG+5AXUovfEFL6DjWBJSyZaA@mail.gmail.com>"}],"Attachments":[{"Name":"myimage.png","Content":"[BASE64-ENCODED CONTENT]","ContentType":"image/png","ContentLength":4096},{"Name":"mypaper.doc","Content":"[BASE64-ENCODED CONTENT]","ContentType":"application/msword","ContentLength":16384}]}' }
|
6
|
+
|
7
|
+
context "given a serialized inbound document" do
|
8
|
+
subject { Postmark::Inbound.to_ruby_hash(example_inbound) }
|
9
|
+
|
10
|
+
it { should have_key(:from) }
|
11
|
+
it { should have_key(:from_full) }
|
12
|
+
it { should have_key(:to) }
|
13
|
+
it { should have_key(:to_full) }
|
14
|
+
it { should have_key(:cc) }
|
15
|
+
it { should have_key(:cc_full) }
|
16
|
+
it { should have_key(:reply_to) }
|
17
|
+
it { should have_key(:subject) }
|
18
|
+
it { should have_key(:message_id) }
|
19
|
+
it { should have_key(:date) }
|
20
|
+
it { should have_key(:mailbox_hash) }
|
21
|
+
it { should have_key(:text_body) }
|
22
|
+
it { should have_key(:html_body) }
|
23
|
+
it { should have_key(:tag) }
|
24
|
+
it { should have_key(:headers) }
|
25
|
+
it { should have_key(:attachments) }
|
26
|
+
|
27
|
+
context "cc" do
|
28
|
+
it 'has 2 CCs' do
|
29
|
+
subject[:cc_full].count.should == 2
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'stores CCs as an array of Ruby hashes' do
|
33
|
+
cc = subject[:cc_full].last
|
34
|
+
cc.should have_key(:email)
|
35
|
+
cc.should have_key(:name)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context "to" do
|
40
|
+
it 'has 1 recipients' do
|
41
|
+
subject[:to_full].count.should == 1
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'stores TOs as an array of Ruby hashes' do
|
45
|
+
cc = subject[:to_full].last
|
46
|
+
cc.should have_key(:email)
|
47
|
+
cc.should have_key(:name)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "from" do
|
52
|
+
it 'is a hash' do
|
53
|
+
subject[:from_full].should be_a Hash
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should have all required fields' do
|
57
|
+
subject[:from_full].should have_key(:email)
|
58
|
+
subject[:from_full].should have_key(:name)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "headers" do
|
63
|
+
it 'has 8 headers' do
|
64
|
+
subject[:headers].count.should == 8
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'stores headers as an array of Ruby hashes' do
|
68
|
+
header = subject[:headers].last
|
69
|
+
header.should have_key(:name)
|
70
|
+
header.should have_key(:value)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context "attachments" do
|
75
|
+
it 'has 2 attachments' do
|
76
|
+
subject[:attachments].count.should == 2
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'stores attachemnts as an array of Ruby hashes' do
|
80
|
+
attachment = subject[:attachments].last
|
81
|
+
attachment.should have_key(:name)
|
82
|
+
attachment.should have_key(:content)
|
83
|
+
attachment.should have_key(:content_type)
|
84
|
+
attachment.should have_key(:content_length)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Postmark::Inflector do
|
4
|
+
|
5
|
+
describe ".to_postmark" do
|
6
|
+
it 'converts rubyish underscored format to camel cased symbols accepted by the Postmark API' do
|
7
|
+
subject.to_postmark(:foo_bar).should == 'FooBar'
|
8
|
+
subject.to_postmark(:_bar).should == 'Bar'
|
9
|
+
subject.to_postmark(:really_long_long_long_long_symbol).should == 'ReallyLongLongLongLongSymbol'
|
10
|
+
subject.to_postmark(:foo_bar_1).should == 'FooBar1'
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'accepts strings as well' do
|
14
|
+
subject.to_postmark('foo_bar').should == 'FooBar'
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'acts idempotentely' do
|
18
|
+
subject.to_postmark('FooBar').should == 'FooBar'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe ".to_ruby" do
|
23
|
+
it 'converts camel cased symbols returned by the Postmark API to underscored Ruby symbols' do
|
24
|
+
subject.to_ruby('FooBar').should == :foo_bar
|
25
|
+
subject.to_ruby('LongTimeAgoInAFarFarGalaxy').should == :long_time_ago_in_a_far_far_galaxy
|
26
|
+
subject.to_ruby('MessageID').should == :message_id
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'acts idempotentely' do
|
30
|
+
subject.to_ruby(:foo_bar).should == :foo_bar
|
31
|
+
subject.to_ruby(:foo_bar_1).should == :foo_bar_1
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Postmark::Json do
|
4
|
+
let(:data) { {"bar" => "foo", "foo" => "bar"} }
|
5
|
+
|
6
|
+
shared_examples "json parser" do
|
7
|
+
it 'encodes and decodes data correctly' do
|
8
|
+
hash = Postmark::Json.decode(Postmark::Json.encode(data))
|
9
|
+
hash.should have_key("bar")
|
10
|
+
hash.should have_key("foo")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context "given response parser is JSON" do
|
15
|
+
before do
|
16
|
+
Postmark.response_parser_class = :Json
|
17
|
+
end
|
18
|
+
|
19
|
+
it_behaves_like "json parser"
|
20
|
+
end
|
21
|
+
|
22
|
+
context "given response parser is ActiveSupport::JSON" do
|
23
|
+
before do
|
24
|
+
Postmark.response_parser_class = :ActiveSupport
|
25
|
+
end
|
26
|
+
|
27
|
+
it_behaves_like "json parser"
|
28
|
+
end
|
29
|
+
|
30
|
+
context "given response parser is Yajl", :skip_for_platform => 'java' do
|
31
|
+
before do
|
32
|
+
Postmark.response_parser_class = :Yajl
|
33
|
+
end
|
34
|
+
|
35
|
+
it_behaves_like "json parser"
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,205 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mail::Message do
|
4
|
+
before do
|
5
|
+
Kernel.stub(:warn)
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:mail_message) do
|
9
|
+
Mail.new do
|
10
|
+
from "sheldon@bigbangtheory.com"
|
11
|
+
to "lenard@bigbangtheory.com"
|
12
|
+
subject "Hello!"
|
13
|
+
body "Hello Sheldon!"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:tagged_mail_message) do
|
18
|
+
Mail.new do
|
19
|
+
from "sheldon@bigbangtheory.com"
|
20
|
+
to "lenard@bigbangtheory.com"
|
21
|
+
subject "Hello!"
|
22
|
+
body "Hello Sheldon!"
|
23
|
+
tag "sheldon"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
let(:mail_message_without_body) do
|
28
|
+
Mail.new do
|
29
|
+
from "sheldon@bigbangtheory.com"
|
30
|
+
to "lenard@bigbangtheory.com"
|
31
|
+
subject "Hello!"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
let(:mail_html_message) do
|
36
|
+
mail = Mail.new do
|
37
|
+
from "sheldon@bigbangtheory.com"
|
38
|
+
to "lenard@bigbangtheory.com"
|
39
|
+
subject "Hello!"
|
40
|
+
content_type 'text/html; charset=UTF-8'
|
41
|
+
body "<b>Hello Sheldon!</b>"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
let(:mail_multipart_message) do
|
46
|
+
mail = Mail.new do
|
47
|
+
from "sheldon@bigbangtheory.com"
|
48
|
+
to "lenard@bigbangtheory.com"
|
49
|
+
subject "Hello!"
|
50
|
+
text_part do
|
51
|
+
body "Hello Sheldon!"
|
52
|
+
end
|
53
|
+
html_part do
|
54
|
+
body "<b>Hello Sheldon!</b>"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
let(:mail_message_with_attachment) do
|
60
|
+
Mail.new do
|
61
|
+
from "sheldon@bigbangtheory.com"
|
62
|
+
to "lenard@bigbangtheory.com"
|
63
|
+
subject "Hello!"
|
64
|
+
body "Hello Sheldon!"
|
65
|
+
add_file empty_gif_path
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "#html?" do
|
70
|
+
it 'is true for html only email' do
|
71
|
+
mail_html_message.should be_html
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "#body_html" do
|
76
|
+
it 'returns html body if present' do
|
77
|
+
mail_html_message.body_html.should == "<b>Hello Sheldon!</b>"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "#body_text" do
|
82
|
+
it 'returns text body if present' do
|
83
|
+
mail_message.body_text.should == "Hello Sheldon!"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "#postmark_attachments=" do
|
88
|
+
let(:attached_hash) { {'Name' => 'picture.jpeg',
|
89
|
+
'ContentType' => 'image/jpeg'} }
|
90
|
+
|
91
|
+
it "stores attachments as an array" do
|
92
|
+
mail_message.postmark_attachments = attached_hash
|
93
|
+
mail_message.instance_variable_get(:@_attachments).should include(attached_hash)
|
94
|
+
end
|
95
|
+
|
96
|
+
it "is deprecated" do
|
97
|
+
Kernel.should_receive(:warn).with(/deprecated/)
|
98
|
+
mail_message.postmark_attachments = attached_hash
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe "#postmark_attachments" do
|
103
|
+
let(:attached_file) { mock("file") }
|
104
|
+
let(:attached_hash) { {'Name' => 'picture.jpeg',
|
105
|
+
'ContentType' => 'image/jpeg'} }
|
106
|
+
let(:exported_file) { {'Name' => 'file.jpeg',
|
107
|
+
'ContentType' => 'application/octet-stream',
|
108
|
+
'Content' => ''} }
|
109
|
+
|
110
|
+
before do
|
111
|
+
attached_file.stub(:is_a?) { |arg| arg == File ? true : false }
|
112
|
+
attached_file.stub(:path) { '/tmp/file.jpeg' }
|
113
|
+
end
|
114
|
+
|
115
|
+
it "supports multiple attachment formats" do
|
116
|
+
IO.should_receive(:read).with("/tmp/file.jpeg").and_return("")
|
117
|
+
|
118
|
+
mail_message.postmark_attachments = [attached_hash, attached_file]
|
119
|
+
attachments = mail_message.export_attachments
|
120
|
+
|
121
|
+
attachments.should include(attached_hash)
|
122
|
+
attachments.should include(exported_file)
|
123
|
+
end
|
124
|
+
|
125
|
+
it "is deprecated" do
|
126
|
+
mail_message.postmark_attachments = attached_hash
|
127
|
+
Kernel.should_receive(:warn).with(/deprecated/)
|
128
|
+
mail_message.postmark_attachments
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe "#export_attachments" do
|
133
|
+
let(:file_data) { 'binarydatahere' }
|
134
|
+
let(:exported_data) do
|
135
|
+
{'Name' => 'face.jpeg',
|
136
|
+
'Content' => "YmluYXJ5ZGF0YWhlcmU=\n",
|
137
|
+
'ContentType' => 'image/jpeg'}
|
138
|
+
end
|
139
|
+
|
140
|
+
it "exports native attachments" do
|
141
|
+
mail_message.attachments["face.jpeg"] = file_data
|
142
|
+
mail_message.export_attachments.should include(exported_data)
|
143
|
+
end
|
144
|
+
|
145
|
+
it "still supports the deprecated attachments API" do
|
146
|
+
mail_message.attachments["face.jpeg"] = file_data
|
147
|
+
mail_message.postmark_attachments = exported_data
|
148
|
+
mail_message.export_attachments.should == [exported_data, exported_data]
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
describe "#to_postmark_hash" do
|
153
|
+
it 'converts plain text messages correctly' do
|
154
|
+
mail_message.to_postmark_hash.should == {
|
155
|
+
"From" => "sheldon@bigbangtheory.com",
|
156
|
+
"Subject" => "Hello!",
|
157
|
+
"TextBody" => "Hello Sheldon!",
|
158
|
+
"To" => "lenard@bigbangtheory.com"}
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'converts tagged text messages correctly' do
|
162
|
+
tagged_mail_message.to_postmark_hash.should == {
|
163
|
+
"From" => "sheldon@bigbangtheory.com",
|
164
|
+
"Subject" => "Hello!",
|
165
|
+
"TextBody" => "Hello Sheldon!",
|
166
|
+
"Tag" => "sheldon",
|
167
|
+
"To"=>"lenard@bigbangtheory.com"}
|
168
|
+
end
|
169
|
+
|
170
|
+
it 'converts plain text messages without body correctly' do
|
171
|
+
mail_message_without_body.to_postmark_hash.should == {
|
172
|
+
"From" => "sheldon@bigbangtheory.com",
|
173
|
+
"Subject" => "Hello!",
|
174
|
+
"To" => "lenard@bigbangtheory.com"}
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'converts html messages correctly' do
|
178
|
+
mail_html_message.to_postmark_hash.should == {
|
179
|
+
"From" => "sheldon@bigbangtheory.com",
|
180
|
+
"Subject" => "Hello!",
|
181
|
+
"HtmlBody" => "<b>Hello Sheldon!</b>",
|
182
|
+
"To" => "lenard@bigbangtheory.com"}
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'converts multipart messages correctly' do
|
186
|
+
mail_multipart_message.to_postmark_hash.should == {
|
187
|
+
"From" => "sheldon@bigbangtheory.com",
|
188
|
+
"Subject" => "Hello!",
|
189
|
+
"HtmlBody" => "<b>Hello Sheldon!</b>",
|
190
|
+
"TextBody" => "Hello Sheldon!",
|
191
|
+
"To" => "lenard@bigbangtheory.com"}
|
192
|
+
end
|
193
|
+
|
194
|
+
it 'converts messages with attachments correctly' do
|
195
|
+
mail_message_with_attachment.to_postmark_hash.should == {
|
196
|
+
"From" => "sheldon@bigbangtheory.com",
|
197
|
+
"Subject" => "Hello!",
|
198
|
+
"Attachments" => [{"Name"=>"empty.gif",
|
199
|
+
"Content"=>encoded_empty_gif_data,
|
200
|
+
"ContentType"=>"image/gif"}],
|
201
|
+
"TextBody"=>"Hello Sheldon!",
|
202
|
+
"To"=>"lenard@bigbangtheory.com"}
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Postmark do
|
4
|
+
let(:api_key) { mock }
|
5
|
+
let(:secure) { mock }
|
6
|
+
let(:proxy_host) { mock }
|
7
|
+
let(:proxy_port) { mock }
|
8
|
+
let(:proxy_user) { mock }
|
9
|
+
let(:proxy_pass) { mock }
|
10
|
+
let(:host) { mock }
|
11
|
+
let(:port) { mock }
|
12
|
+
let(:path_prefix) { mock }
|
13
|
+
let(:max_retries) { mock }
|
14
|
+
|
15
|
+
before do
|
16
|
+
subject.api_key = api_key
|
17
|
+
subject.secure = secure
|
18
|
+
subject.proxy_host = proxy_host
|
19
|
+
subject.proxy_port = proxy_port
|
20
|
+
subject.proxy_user = proxy_user
|
21
|
+
subject.proxy_pass = proxy_pass
|
22
|
+
subject.host = host
|
23
|
+
subject.port = port
|
24
|
+
subject.path_prefix = path_prefix
|
25
|
+
subject.max_retries = max_retries
|
26
|
+
end
|
27
|
+
|
28
|
+
context "attr readers" do
|
29
|
+
it { should respond_to(:secure) }
|
30
|
+
it { should respond_to(:api_key) }
|
31
|
+
it { should respond_to(:proxy_host) }
|
32
|
+
it { should respond_to(:proxy_port) }
|
33
|
+
it { should respond_to(:proxy_user) }
|
34
|
+
it { should respond_to(:proxy_pass) }
|
35
|
+
it { should respond_to(:host) }
|
36
|
+
it { should respond_to(:port) }
|
37
|
+
it { should respond_to(:path_prefix) }
|
38
|
+
it { should respond_to(:http_open_timeout) }
|
39
|
+
it { should respond_to(:http_read_timeout) }
|
40
|
+
it { should respond_to(:max_retries) }
|
41
|
+
end
|
42
|
+
|
43
|
+
context "attr writers" do
|
44
|
+
it { should respond_to(:secure=) }
|
45
|
+
it { should respond_to(:api_key=) }
|
46
|
+
it { should respond_to(:proxy_host=) }
|
47
|
+
it { should respond_to(:proxy_port=) }
|
48
|
+
it { should respond_to(:proxy_user=) }
|
49
|
+
it { should respond_to(:proxy_pass=) }
|
50
|
+
it { should respond_to(:host=) }
|
51
|
+
it { should respond_to(:port=) }
|
52
|
+
it { should respond_to(:path_prefix=) }
|
53
|
+
it { should respond_to(:http_open_timeout=) }
|
54
|
+
it { should respond_to(:http_read_timeout=) }
|
55
|
+
it { should respond_to(:max_retries=) }
|
56
|
+
it { should respond_to(:response_parser_class=) }
|
57
|
+
it { should respond_to(:api_client=) }
|
58
|
+
end
|
59
|
+
|
60
|
+
describe ".response_parser_class" do
|
61
|
+
|
62
|
+
after do
|
63
|
+
subject.instance_variable_set(:@response_parser_class, nil)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "returns :ActiveSupport when ActiveSupport::JSON is available" do
|
67
|
+
subject.response_parser_class.should == :ActiveSupport
|
68
|
+
end
|
69
|
+
|
70
|
+
it "returns :Json when ActiveSupport::JSON is not available" do
|
71
|
+
hide_const("ActiveSupport::JSON")
|
72
|
+
subject.response_parser_class.should == :Json
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
describe ".configure" do
|
78
|
+
|
79
|
+
it 'yields itself to the block' do
|
80
|
+
expect { |b| subject.configure(&b) }.to yield_with_args(subject)
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
describe ".api_client" do
|
86
|
+
let(:api_client) { mock }
|
87
|
+
|
88
|
+
context "when shared client instance already exists" do
|
89
|
+
|
90
|
+
it 'returns the existing instance' do
|
91
|
+
subject.instance_variable_set(:@api_client, api_client)
|
92
|
+
subject.api_client.should == api_client
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
context "when shared client instance does not exist" do
|
98
|
+
|
99
|
+
it 'creates a new instance of Postmark::ApiClient' do
|
100
|
+
Postmark::ApiClient.should_receive(:new).
|
101
|
+
with(api_key,
|
102
|
+
:secure => secure,
|
103
|
+
:proxy_host => proxy_host,
|
104
|
+
:proxy_port => proxy_port,
|
105
|
+
:proxy_user => proxy_user,
|
106
|
+
:proxy_pass => proxy_pass,
|
107
|
+
:host => host,
|
108
|
+
:port => port,
|
109
|
+
:path_prefix => path_prefix,
|
110
|
+
:max_retries => max_retries).
|
111
|
+
and_return(api_client)
|
112
|
+
subject.api_client.should == api_client
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
describe ".deliver_message" do
|
120
|
+
let(:api_client) { mock }
|
121
|
+
let(:message) { mock }
|
122
|
+
|
123
|
+
before do
|
124
|
+
subject.api_client = api_client
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'delegates the method to the shared api client instance' do
|
128
|
+
api_client.should_receive(:deliver_message).with(message)
|
129
|
+
subject.deliver_message(message)
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'is also accessible as .send_through_postmark' do
|
133
|
+
api_client.should_receive(:deliver_message).with(message)
|
134
|
+
subject.send_through_postmark(message)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
describe ".deliver_messages" do
|
139
|
+
let(:api_client) { mock }
|
140
|
+
let(:message) { mock }
|
141
|
+
|
142
|
+
before do
|
143
|
+
subject.api_client = api_client
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'delegates the method to the shared api client instance' do
|
147
|
+
api_client.should_receive(:deliver_messages).with(message)
|
148
|
+
subject.deliver_messages(message)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
describe ".delivery_stats" do
|
153
|
+
let(:api_client) { mock }
|
154
|
+
|
155
|
+
before do
|
156
|
+
subject.api_client = api_client
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'delegates the method to the shared api client instance' do
|
160
|
+
api_client.should_receive(:delivery_stats)
|
161
|
+
subject.delivery_stats
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|