postmark 1.8.1 → 1.21.3
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.
- checksums.yaml +5 -5
- data/.gitignore +2 -0
- data/.travis.yml +8 -5
- data/CHANGELOG.rdoc +86 -0
- data/CONTRIBUTING.md +18 -0
- data/Gemfile +6 -5
- data/LICENSE +1 -1
- data/README.md +34 -607
- data/RELEASE.md +12 -0
- data/VERSION +1 -1
- data/gemfiles/Gemfile.legacy +5 -4
- data/lib/postmark.rb +1 -18
- data/lib/postmark/account_api_client.rb +55 -1
- data/lib/postmark/api_client.rb +145 -17
- data/lib/postmark/bounce.rb +0 -4
- data/lib/postmark/client.rb +12 -4
- data/lib/postmark/error.rb +127 -0
- data/lib/postmark/handlers/mail.rb +10 -4
- data/lib/postmark/helpers/message_helper.rb +4 -0
- data/lib/postmark/http_client.rb +20 -32
- data/lib/postmark/mail_message_converter.rb +18 -5
- data/lib/postmark/message_extensions/mail.rb +83 -8
- data/lib/postmark/version.rb +1 -1
- data/postmark.gemspec +1 -1
- data/postmark.png +0 -0
- data/spec/integration/account_api_client_spec.rb +42 -10
- data/spec/integration/api_client_hashes_spec.rb +32 -49
- data/spec/integration/api_client_messages_spec.rb +33 -52
- data/spec/integration/api_client_resources_spec.rb +12 -44
- data/spec/integration/mail_delivery_method_spec.rb +21 -23
- data/spec/spec_helper.rb +4 -7
- data/spec/support/custom_matchers.rb +44 -0
- data/spec/support/shared_examples.rb +16 -16
- data/spec/unit/postmark/account_api_client_spec.rb +239 -45
- data/spec/unit/postmark/api_client_spec.rb +792 -406
- data/spec/unit/postmark/bounce_spec.rb +40 -62
- data/spec/unit/postmark/client_spec.rb +0 -6
- data/spec/unit/postmark/error_spec.rb +231 -0
- data/spec/unit/postmark/handlers/mail_spec.rb +59 -27
- data/spec/unit/postmark/helpers/hash_helper_spec.rb +5 -6
- data/spec/unit/postmark/helpers/message_helper_spec.rb +60 -11
- data/spec/unit/postmark/http_client_spec.rb +76 -61
- data/spec/unit/postmark/inbound_spec.rb +34 -34
- data/spec/unit/postmark/inflector_spec.rb +11 -13
- data/spec/unit/postmark/json_spec.rb +2 -2
- data/spec/unit/postmark/mail_message_converter_spec.rb +250 -81
- data/spec/unit/postmark/message_extensions/mail_spec.rb +249 -38
- data/spec/unit/postmark_spec.rb +37 -37
- metadata +41 -11
@@ -6,11 +6,11 @@ describe Postmark::HashHelper do
|
|
6
6
|
let(:target) { {"From" => "support@postmarkapp.com", "ReplyTo" => "contact@wildbit.com"} }
|
7
7
|
|
8
8
|
it 'converts Hash keys to Postmark format' do
|
9
|
-
subject.to_postmark(source).
|
9
|
+
expect(subject.to_postmark(source)).to eq target
|
10
10
|
end
|
11
11
|
|
12
12
|
it 'acts idempotentely' do
|
13
|
-
subject.to_postmark(target).
|
13
|
+
expect(subject.to_postmark(target)).to eq target
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
@@ -19,16 +19,15 @@ describe Postmark::HashHelper do
|
|
19
19
|
let(:target) { {:from => "support@postmarkapp.com", :reply_to => "contact@wildbit.com"} }
|
20
20
|
|
21
21
|
it 'converts Hash keys to Ruby format' do
|
22
|
-
subject.to_ruby(source).
|
22
|
+
expect(subject.to_ruby(source)).to eq target
|
23
23
|
end
|
24
24
|
|
25
25
|
it 'has compatible mode' do
|
26
|
-
subject.to_ruby(source, true).
|
26
|
+
expect(subject.to_ruby(source, true)).to eq target.merge(source)
|
27
27
|
end
|
28
28
|
|
29
29
|
it 'acts idempotentely' do
|
30
|
-
subject.to_ruby(target).
|
30
|
+
expect(subject.to_ruby(target)).to eq target
|
31
31
|
end
|
32
32
|
end
|
33
|
-
|
34
33
|
end
|
@@ -80,48 +80,97 @@ describe Postmark::MessageHelper do
|
|
80
80
|
message.merge(:track_opens => true)
|
81
81
|
}
|
82
82
|
|
83
|
+
let(:message_with_open_tracking_false) {
|
84
|
+
message.merge(:track_opens => false)
|
85
|
+
}
|
86
|
+
|
83
87
|
let(:postmark_message_with_open_tracking) {
|
84
88
|
postmark_message.merge("TrackOpens" => true)
|
85
89
|
}
|
86
90
|
|
91
|
+
let(:postmark_message_with_open_tracking_false) {
|
92
|
+
postmark_message.merge("TrackOpens" => false)
|
93
|
+
}
|
94
|
+
|
87
95
|
it 'converts messages without custom headers and attachments correctly' do
|
88
|
-
subject.to_postmark(message).
|
96
|
+
expect(subject.to_postmark(message)).to eq postmark_message
|
89
97
|
end
|
90
98
|
|
91
99
|
it 'converts messages with custom headers and without attachments correctly' do
|
92
|
-
subject.to_postmark(message_with_headers).
|
100
|
+
expect(subject.to_postmark(message_with_headers)).to eq postmark_message_with_headers
|
93
101
|
end
|
94
102
|
|
95
103
|
it 'converts messages with custom headers and attachments correctly' do
|
96
|
-
subject.to_postmark(message_with_headers_and_attachments).
|
104
|
+
expect(subject.to_postmark(message_with_headers_and_attachments)).to eq postmark_message_with_headers_and_attachments
|
105
|
+
end
|
106
|
+
|
107
|
+
context 'open tracking' do
|
108
|
+
|
109
|
+
it 'converts messages with open tracking flag set to true correctly' do
|
110
|
+
expect(subject.to_postmark(message_with_open_tracking)).to eq(postmark_message_with_open_tracking)
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'converts messages with open tracking flag set to false correctly' do
|
114
|
+
expect(subject.to_postmark(message_with_open_tracking_false)).to eq(postmark_message_with_open_tracking_false)
|
115
|
+
end
|
116
|
+
|
97
117
|
end
|
98
118
|
|
99
|
-
|
100
|
-
|
119
|
+
context 'metadata' do
|
120
|
+
it 'converts messages with metadata correctly' do
|
121
|
+
metadata = {"test" => "value"}
|
122
|
+
data= message.merge(:metadata => metadata)
|
123
|
+
expect(subject.to_postmark(data)).to include(postmark_message.merge("Metadata" => metadata))
|
124
|
+
end
|
101
125
|
end
|
102
126
|
|
127
|
+
context 'link tracking' do
|
128
|
+
let(:message_with_link_tracking_html) { message.merge(:track_links => :html_only) }
|
129
|
+
let(:message_with_link_tracking_text) { message.merge(:track_links => :text_only) }
|
130
|
+
let(:message_with_link_tracking_all) { message.merge(:track_links => :html_and_text) }
|
131
|
+
let(:message_with_link_tracking_none) { message.merge(:track_links => :none) }
|
132
|
+
|
133
|
+
let(:postmark_message_with_link_tracking_html) { postmark_message.merge("TrackLinks" => 'HtmlOnly') }
|
134
|
+
let(:postmark_message_with_link_tracking_text) { postmark_message.merge("TrackLinks" => 'TextOnly') }
|
135
|
+
let(:postmark_message_with_link_tracking_all) { postmark_message.merge("TrackLinks" => 'HtmlAndText') }
|
136
|
+
let(:postmark_message_with_link_tracking_none) { postmark_message.merge("TrackLinks" => 'None') }
|
137
|
+
|
138
|
+
it 'converts html body link tracking to Postmark format' do
|
139
|
+
expect(subject.to_postmark(message_with_link_tracking_html)).to eq(postmark_message_with_link_tracking_html)
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'converts text body link tracking to Postmark format' do
|
143
|
+
expect(subject.to_postmark(message_with_link_tracking_text)).to eq(postmark_message_with_link_tracking_text)
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'converts html and text body link tracking to Postmark format' do
|
147
|
+
expect(subject.to_postmark(message_with_link_tracking_all)).to eq(postmark_message_with_link_tracking_all)
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'converts no link tracking to Postmark format' do
|
151
|
+
expect(subject.to_postmark(message_with_link_tracking_none)).to eq(postmark_message_with_link_tracking_none)
|
152
|
+
end
|
153
|
+
end
|
103
154
|
end
|
104
155
|
|
105
156
|
describe ".headers_to_postmark" do
|
106
157
|
it 'converts headers to Postmark format' do
|
107
|
-
subject.headers_to_postmark(headers).
|
158
|
+
expect(subject.headers_to_postmark(headers)).to eq postmark_headers
|
108
159
|
end
|
109
160
|
|
110
161
|
it 'accepts single header as a non-array' do
|
111
|
-
subject.headers_to_postmark(headers.first).
|
162
|
+
expect(subject.headers_to_postmark(headers.first)).to eq [postmark_headers.first]
|
112
163
|
end
|
113
164
|
end
|
114
165
|
|
115
166
|
describe ".attachments_to_postmark" do
|
116
|
-
|
117
167
|
it 'converts attachments to Postmark format' do
|
118
|
-
subject.attachments_to_postmark(attachments).
|
168
|
+
expect(subject.attachments_to_postmark(attachments)).to eq postmark_attachments
|
119
169
|
end
|
120
170
|
|
121
171
|
it 'accepts single attachment as a non-array' do
|
122
|
-
subject.attachments_to_postmark(attachments.first).
|
172
|
+
expect(subject.attachments_to_postmark(attachments.first)).to eq [postmark_attachments.first]
|
123
173
|
end
|
124
|
-
|
125
174
|
end
|
126
175
|
|
127
176
|
end
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe Postmark::HttpClient do
|
4
4
|
|
5
5
|
def response_body(status, message = "")
|
6
|
-
|
6
|
+
{"ErrorCode" => status, "Message" => message}.to_json
|
7
7
|
end
|
8
8
|
|
9
9
|
let(:api_token) { "provided-postmark-api-token" }
|
@@ -11,39 +11,40 @@ describe Postmark::HttpClient do
|
|
11
11
|
subject { http_client }
|
12
12
|
|
13
13
|
context "attr writers" do
|
14
|
-
it {
|
15
|
-
it {
|
14
|
+
it { expect(subject).to respond_to(:api_token=) }
|
15
|
+
it { expect(subject).to respond_to(:api_key=) }
|
16
16
|
end
|
17
17
|
|
18
18
|
context "attr readers" do
|
19
|
-
it {
|
20
|
-
it {
|
21
|
-
it {
|
22
|
-
it {
|
23
|
-
it {
|
24
|
-
it {
|
25
|
-
it {
|
26
|
-
it {
|
27
|
-
it {
|
28
|
-
it {
|
29
|
-
it {
|
30
|
-
it {
|
31
|
-
it {
|
19
|
+
it { expect(subject).to respond_to(:http) }
|
20
|
+
it { expect(subject).to respond_to(:secure) }
|
21
|
+
it { expect(subject).to respond_to(:api_token) }
|
22
|
+
it { expect(subject).to respond_to(:api_key) }
|
23
|
+
it { expect(subject).to respond_to(:proxy_host) }
|
24
|
+
it { expect(subject).to respond_to(:proxy_port) }
|
25
|
+
it { expect(subject).to respond_to(:proxy_user) }
|
26
|
+
it { expect(subject).to respond_to(:proxy_pass) }
|
27
|
+
it { expect(subject).to respond_to(:host) }
|
28
|
+
it { expect(subject).to respond_to(:port) }
|
29
|
+
it { expect(subject).to respond_to(:path_prefix) }
|
30
|
+
it { expect(subject).to respond_to(:http_open_timeout) }
|
31
|
+
it { expect(subject).to respond_to(:http_read_timeout) }
|
32
|
+
it { expect(subject).to respond_to(:http_ssl_version) }
|
32
33
|
end
|
33
34
|
|
34
35
|
context "when it is created without options" do
|
35
|
-
its(:api_token) {
|
36
|
-
its(:api_key) {
|
37
|
-
its(:host) {
|
38
|
-
its(:port) {
|
39
|
-
its(:secure) {
|
40
|
-
its(:path_prefix) {
|
41
|
-
its(:http_read_timeout) {
|
42
|
-
its(:http_open_timeout) {
|
43
|
-
|
44
|
-
it '
|
36
|
+
its(:api_token) { is_expected.to eq api_token }
|
37
|
+
its(:api_key) { is_expected.to eq api_token }
|
38
|
+
its(:host) { is_expected.to eq 'api.postmarkapp.com' }
|
39
|
+
its(:port) { is_expected.to eq 443 }
|
40
|
+
its(:secure) { is_expected.to be true }
|
41
|
+
its(:path_prefix) { is_expected.to eq '/' }
|
42
|
+
its(:http_read_timeout) { is_expected.to eq 15 }
|
43
|
+
its(:http_open_timeout) { is_expected.to eq 5 }
|
44
|
+
|
45
|
+
it 'does not provide a default which utilizes the Net::HTTP default', :skip_ruby_version => ['1.8.7'] do
|
45
46
|
http_client = subject.http
|
46
|
-
http_client.ssl_version.
|
47
|
+
expect(http_client.ssl_version).to eq nil
|
47
48
|
end
|
48
49
|
end
|
49
50
|
|
@@ -54,10 +55,11 @@ describe Postmark::HttpClient do
|
|
54
55
|
let(:proxy_user) { "provided proxy user" }
|
55
56
|
let(:proxy_pass) { "provided proxy pass" }
|
56
57
|
let(:host) { "providedhostname.org" }
|
57
|
-
let(:port) {
|
58
|
+
let(:port) { 4443 }
|
58
59
|
let(:path_prefix) { "/provided/path/prefix" }
|
59
60
|
let(:http_open_timeout) { 42 }
|
60
61
|
let(:http_read_timeout) { 42 }
|
62
|
+
let(:http_ssl_version) { :TLSv1_2}
|
61
63
|
|
62
64
|
subject { Postmark::HttpClient.new(api_token,
|
63
65
|
:secure => secure,
|
@@ -69,20 +71,36 @@ describe Postmark::HttpClient do
|
|
69
71
|
:port => port,
|
70
72
|
:path_prefix => path_prefix,
|
71
73
|
:http_open_timeout => http_open_timeout,
|
72
|
-
:http_read_timeout => http_read_timeout
|
73
|
-
|
74
|
-
|
75
|
-
its(:
|
76
|
-
its(:
|
77
|
-
its(:
|
78
|
-
its(:
|
79
|
-
its(:
|
80
|
-
its(:
|
81
|
-
its(:
|
82
|
-
its(:
|
83
|
-
its(:
|
84
|
-
its(:
|
85
|
-
its(:
|
74
|
+
:http_read_timeout => http_read_timeout,
|
75
|
+
:http_ssl_version => http_ssl_version) }
|
76
|
+
|
77
|
+
its(:api_token) { is_expected.to eq api_token }
|
78
|
+
its(:api_key) { is_expected.to eq api_token }
|
79
|
+
its(:secure) { is_expected.to eq secure }
|
80
|
+
its(:proxy_host) { is_expected.to eq proxy_host }
|
81
|
+
its(:proxy_port) { is_expected.to eq proxy_port }
|
82
|
+
its(:proxy_user) { is_expected.to eq proxy_user }
|
83
|
+
its(:proxy_pass) { is_expected.to eq proxy_pass }
|
84
|
+
its(:host) { is_expected.to eq host }
|
85
|
+
its(:port) { is_expected.to eq port }
|
86
|
+
its(:path_prefix) { is_expected.to eq path_prefix }
|
87
|
+
its(:http_open_timeout) { is_expected.to eq http_open_timeout }
|
88
|
+
its(:http_read_timeout) { is_expected.to eq http_read_timeout }
|
89
|
+
its(:http_ssl_version) { is_expected.to eq http_ssl_version }
|
90
|
+
|
91
|
+
it 'uses port 80 for plain HTTP connections' do
|
92
|
+
expect(Postmark::HttpClient.new(api_token, :secure => false).port).to eq(80)
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'uses port 443 for secure HTTP connections' do
|
96
|
+
expect(Postmark::HttpClient.new(api_token, :secure => true).port).to eq(443)
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'respects port over secure option' do
|
100
|
+
client = Postmark::HttpClient.new(api_token, :port => 80, :secure => true)
|
101
|
+
expect(client.port).to eq(80)
|
102
|
+
expect(client.protocol).to eq('https')
|
103
|
+
end
|
86
104
|
end
|
87
105
|
|
88
106
|
describe "#post" do
|
@@ -92,18 +110,17 @@ describe Postmark::HttpClient do
|
|
92
110
|
it "sends a POST request to provided URI" do
|
93
111
|
FakeWeb.register_uri(:post, target_url, :body => response_body(200))
|
94
112
|
subject.post(target_path)
|
95
|
-
FakeWeb.
|
113
|
+
expect(FakeWeb.last_request.method).to eq('POST')
|
114
|
+
expect(FakeWeb.last_request.path).to eq('/' + target_path)
|
96
115
|
end
|
97
116
|
|
98
117
|
it "raises a custom error when API token authorization fails" do
|
99
|
-
FakeWeb.register_uri(:post, target_url, :body => response_body(401),
|
100
|
-
:status => [ "401", "Unauthorized" ])
|
118
|
+
FakeWeb.register_uri(:post, target_url, :body => response_body(401), :status => [ "401", "Unauthorized" ])
|
101
119
|
expect { subject.post(target_path) }.to raise_error Postmark::InvalidApiKeyError
|
102
120
|
end
|
103
121
|
|
104
122
|
it "raises a custom error when sent JSON was not valid" do
|
105
|
-
FakeWeb.register_uri(:post, target_url, :body => response_body(422),
|
106
|
-
:status => [ "422", "Invalid" ])
|
123
|
+
FakeWeb.register_uri(:post, target_url, :body => response_body(422), :status => [ "422", "Invalid" ])
|
107
124
|
expect { subject.post(target_path) }.to raise_error Postmark::InvalidMessageError
|
108
125
|
end
|
109
126
|
|
@@ -114,8 +131,7 @@ describe Postmark::HttpClient do
|
|
114
131
|
end
|
115
132
|
|
116
133
|
it "raises a custom error when the request times out" do
|
117
|
-
subject.http.
|
118
|
-
and_raise(Timeout::Error)
|
134
|
+
expect(subject.http).to receive(:post).at_least(:once).and_raise(Timeout::Error)
|
119
135
|
expect { subject.post(target_path) }.to raise_error Postmark::TimeoutError
|
120
136
|
end
|
121
137
|
|
@@ -124,7 +140,7 @@ describe Postmark::HttpClient do
|
|
124
140
|
:status => [ "485", "Custom HTTP response status" ])
|
125
141
|
expect { subject.post(target_path) }.to raise_error Postmark::UnknownError
|
126
142
|
end
|
127
|
-
|
143
|
+
|
128
144
|
end
|
129
145
|
|
130
146
|
describe "#get" do
|
@@ -134,18 +150,17 @@ describe Postmark::HttpClient do
|
|
134
150
|
it "sends a GET request to provided URI" do
|
135
151
|
FakeWeb.register_uri(:get, target_url, :body => response_body(200))
|
136
152
|
subject.get(target_path)
|
137
|
-
FakeWeb.
|
153
|
+
expect(FakeWeb.last_request.method).to eq('GET')
|
154
|
+
expect(FakeWeb.last_request.path).to eq('/' + target_path)
|
138
155
|
end
|
139
156
|
|
140
157
|
it "raises a custom error when API token authorization fails" do
|
141
|
-
FakeWeb.register_uri(:get, target_url, :body => response_body(401),
|
142
|
-
:status => [ "401", "Unauthorized" ])
|
158
|
+
FakeWeb.register_uri(:get, target_url, :body => response_body(401), :status => [ "401", "Unauthorized" ])
|
143
159
|
expect { subject.get(target_path) }.to raise_error Postmark::InvalidApiKeyError
|
144
160
|
end
|
145
161
|
|
146
162
|
it "raises a custom error when sent JSON was not valid" do
|
147
|
-
FakeWeb.register_uri(:get, target_url, :body => response_body(422),
|
148
|
-
:status => [ "422", "Invalid" ])
|
163
|
+
FakeWeb.register_uri(:get, target_url, :body => response_body(422), :status => [ "422", "Invalid" ])
|
149
164
|
expect { subject.get(target_path) }.to raise_error Postmark::InvalidMessageError
|
150
165
|
end
|
151
166
|
|
@@ -156,7 +171,7 @@ describe Postmark::HttpClient do
|
|
156
171
|
end
|
157
172
|
|
158
173
|
it "raises a custom error when the request times out" do
|
159
|
-
subject.http.
|
174
|
+
expect(subject.http).to receive(:get).at_least(:once).and_raise(Timeout::Error)
|
160
175
|
expect { subject.get(target_path) }.to raise_error Postmark::TimeoutError
|
161
176
|
end
|
162
177
|
|
@@ -165,7 +180,7 @@ describe Postmark::HttpClient do
|
|
165
180
|
:status => [ "485", "Custom HTTP response status" ])
|
166
181
|
expect { subject.get(target_path) }.to raise_error Postmark::UnknownError
|
167
182
|
end
|
168
|
-
|
183
|
+
|
169
184
|
end
|
170
185
|
|
171
186
|
describe "#put" do
|
@@ -175,7 +190,8 @@ describe Postmark::HttpClient do
|
|
175
190
|
it "sends a PUT request to provided URI" do
|
176
191
|
FakeWeb.register_uri(:put, target_url, :body => response_body(200))
|
177
192
|
subject.put(target_path)
|
178
|
-
FakeWeb.
|
193
|
+
expect(FakeWeb.last_request.method).to eq('PUT')
|
194
|
+
expect(FakeWeb.last_request.path).to eq('/' + target_path)
|
179
195
|
end
|
180
196
|
|
181
197
|
it "raises a custom error when API token authorization fails" do
|
@@ -197,7 +213,7 @@ describe Postmark::HttpClient do
|
|
197
213
|
end
|
198
214
|
|
199
215
|
it "raises a custom error when the request times out" do
|
200
|
-
subject.http.
|
216
|
+
expect(subject.http).to receive(:put).at_least(:once).and_raise(Timeout::Error)
|
201
217
|
expect { subject.put(target_path) }.to raise_error Postmark::TimeoutError
|
202
218
|
end
|
203
219
|
|
@@ -206,6 +222,5 @@ describe Postmark::HttpClient do
|
|
206
222
|
:status => [ "485", "Custom HTTP response status" ])
|
207
223
|
expect { subject.put(target_path) }.to raise_error Postmark::UnknownError
|
208
224
|
end
|
209
|
-
|
210
225
|
end
|
211
|
-
end
|
226
|
+
end
|
@@ -7,81 +7,81 @@ describe Postmark::Inbound do
|
|
7
7
|
context "given a serialized inbound document" do
|
8
8
|
subject { Postmark::Inbound.to_ruby_hash(example_inbound) }
|
9
9
|
|
10
|
-
it {
|
11
|
-
it {
|
12
|
-
it {
|
13
|
-
it {
|
14
|
-
it {
|
15
|
-
it {
|
16
|
-
it {
|
17
|
-
it {
|
18
|
-
it {
|
19
|
-
it {
|
20
|
-
it {
|
21
|
-
it {
|
22
|
-
it {
|
23
|
-
it {
|
24
|
-
it {
|
25
|
-
it {
|
10
|
+
it { expect(subject).to have_key(:from) }
|
11
|
+
it { expect(subject).to have_key(:from_full) }
|
12
|
+
it { expect(subject).to have_key(:to) }
|
13
|
+
it { expect(subject).to have_key(:to_full) }
|
14
|
+
it { expect(subject).to have_key(:cc) }
|
15
|
+
it { expect(subject).to have_key(:cc_full) }
|
16
|
+
it { expect(subject).to have_key(:reply_to) }
|
17
|
+
it { expect(subject).to have_key(:subject) }
|
18
|
+
it { expect(subject).to have_key(:message_id) }
|
19
|
+
it { expect(subject).to have_key(:date) }
|
20
|
+
it { expect(subject).to have_key(:mailbox_hash) }
|
21
|
+
it { expect(subject).to have_key(:text_body) }
|
22
|
+
it { expect(subject).to have_key(:html_body) }
|
23
|
+
it { expect(subject).to have_key(:tag) }
|
24
|
+
it { expect(subject).to have_key(:headers) }
|
25
|
+
it { expect(subject).to have_key(:attachments) }
|
26
26
|
|
27
27
|
context "cc" do
|
28
28
|
it 'has 2 CCs' do
|
29
|
-
subject[:cc_full].count.
|
29
|
+
expect(subject[:cc_full].count).to eq 2
|
30
30
|
end
|
31
31
|
|
32
32
|
it 'stores CCs as an array of Ruby hashes' do
|
33
33
|
cc = subject[:cc_full].last
|
34
|
-
cc.
|
35
|
-
cc.
|
34
|
+
expect(cc).to have_key(:email)
|
35
|
+
expect(cc).to have_key(:name)
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
39
|
context "to" do
|
40
40
|
it 'has 1 recipients' do
|
41
|
-
subject[:to_full].count.
|
41
|
+
expect(subject[:to_full].count).to eq 1
|
42
42
|
end
|
43
43
|
|
44
44
|
it 'stores TOs as an array of Ruby hashes' do
|
45
45
|
cc = subject[:to_full].last
|
46
|
-
cc.
|
47
|
-
cc.
|
46
|
+
expect(cc).to have_key(:email)
|
47
|
+
expect(cc).to have_key(:name)
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
51
|
context "from" do
|
52
52
|
it 'is a hash' do
|
53
|
-
subject[:from_full].
|
53
|
+
expect(subject[:from_full]).to be_a Hash
|
54
54
|
end
|
55
55
|
|
56
|
-
it '
|
57
|
-
subject[:from_full].
|
58
|
-
subject[:from_full].
|
56
|
+
it 'has all required fields' do
|
57
|
+
expect(subject[:from_full]).to have_key(:email)
|
58
|
+
expect(subject[:from_full]).to have_key(:name)
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
62
|
context "headers" do
|
63
63
|
it 'has 8 headers' do
|
64
|
-
subject[:headers].count.
|
64
|
+
expect(subject[:headers].count).to eq 8
|
65
65
|
end
|
66
66
|
|
67
67
|
it 'stores headers as an array of Ruby hashes' do
|
68
68
|
header = subject[:headers].last
|
69
|
-
header.
|
70
|
-
header.
|
69
|
+
expect(header).to have_key(:name)
|
70
|
+
expect(header).to have_key(:value)
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
74
|
context "attachments" do
|
75
75
|
it 'has 2 attachments' do
|
76
|
-
subject[:attachments].count.
|
76
|
+
expect(subject[:attachments].count).to eq 2
|
77
77
|
end
|
78
78
|
|
79
79
|
it 'stores attachemnts as an array of Ruby hashes' do
|
80
80
|
attachment = subject[:attachments].last
|
81
|
-
attachment.
|
82
|
-
attachment.
|
83
|
-
attachment.
|
84
|
-
attachment.
|
81
|
+
expect(attachment).to have_key(:name)
|
82
|
+
expect(attachment).to have_key(:content)
|
83
|
+
expect(attachment).to have_key(:content_type)
|
84
|
+
expect(attachment).to have_key(:content_length)
|
85
85
|
end
|
86
86
|
end
|
87
87
|
end
|