sparkpost_rails 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +48 -2
- data/lib/sparkpost_rails.rb +9 -0
- data/lib/sparkpost_rails/delivery_method.rb +101 -7
- data/lib/sparkpost_rails/version.rb +1 -1
- data/spec/attachments_spec.rb +5 -1
- data/spec/delivery_schedule_spec.rb +46 -0
- data/spec/description_spec.rb +39 -0
- data/spec/headers_spec.rb +33 -0
- data/spec/ip_pool_spec.rb +50 -0
- data/spec/skip_suppression_spec.rb +27 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/subaccount_api_spec.rb +75 -0
- data/spec/transactional_spec.rb +50 -0
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 81fd8507b990b04184b483dd003722b8ca08289f
|
4
|
+
data.tar.gz: 8b1007d2d0ddd41f8391215e873675d9bc58fc55
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5fcc12025be8147f289b17ff1dcb56ea568c2018ab3cb98499e77fea53241ca41b077c1bbcbcdb01b7e4bf8fa22169e8731ff9160fa08ad51a993c6a85035181
|
7
|
+
data.tar.gz: c2521eca5c10a02e8d313882653ebfdfb7c4423d5f117d054c29bc5d2f3af6f912be938b45714266267fe29d5bc575eeede28035216cbc678406c1e1934701c3
|
data/README.md
CHANGED
@@ -45,6 +45,8 @@ SparkPostRails.configure do |c|
|
|
45
45
|
c.track_clicks = true
|
46
46
|
c.return_path = 'BOUNCE-EMAIL@YOUR-DOMAIN.COM'
|
47
47
|
c.campaign_id = 'YOUR-CAMPAIGN'
|
48
|
+
c.transactional = true
|
49
|
+
c.ip_pool = "MY-POOL"
|
48
50
|
end
|
49
51
|
```
|
50
52
|
|
@@ -56,6 +58,8 @@ track_opens = false
|
|
56
58
|
track_clicks = false
|
57
59
|
return_path = nil
|
58
60
|
campaign_id = nil
|
61
|
+
transactional = false
|
62
|
+
ip_pool = nil
|
59
63
|
```
|
60
64
|
|
61
65
|
Usage
|
@@ -90,7 +94,11 @@ to the mail message in a field named "sparkpost_data":
|
|
90
94
|
```
|
91
95
|
data = { track_opens: true,
|
92
96
|
track_clicks: false,
|
93
|
-
campaign_id: "My Campaign"
|
97
|
+
campaign_id: "My Campaign",
|
98
|
+
transactional: true,
|
99
|
+
ip_pool = "SPECIAL_POOL",
|
100
|
+
subaccount_api_key = "SUBACCOUNT_API_KEY"
|
101
|
+
}
|
94
102
|
|
95
103
|
mail(to: to_email, subject: "Test", body: "test", sparkpost_data: data)
|
96
104
|
```
|
@@ -101,6 +109,33 @@ Additionally, return_path can be overriden on a specific email by setting that f
|
|
101
109
|
mail(to: to_email, subject: "Test", body: "test", return_path: "bounces@example.com")
|
102
110
|
```
|
103
111
|
|
112
|
+
### Transmission Specific Settings
|
113
|
+
|
114
|
+
For an individual transmisison you can specifiy that SparkPost should ignore customer supression rules - if your SparkPost account allows for this
|
115
|
+
feature. Simply include the flag in the "sparkpost_data" field on the message:
|
116
|
+
|
117
|
+
```
|
118
|
+
data = { skip_suppression: true }
|
119
|
+
|
120
|
+
mail(to: to_email, subject: "Test", body: "test", sparkpost_data: data)
|
121
|
+
```
|
122
|
+
|
123
|
+
To schedule the generation of messages for a future date and time, specify a start time in the date parameter of the mail. Date must be in the future and less than 1 year from today. If date is in the past or too far in the future, no date will be passed, and no delivery schedule will be set.
|
124
|
+
|
125
|
+
```
|
126
|
+
start_time = DateTime.now + 4.hours
|
127
|
+
|
128
|
+
mail(to: to_email, subject: "Test", body: "test", date: start_time)
|
129
|
+
```
|
130
|
+
|
131
|
+
You can set a description for a transmission via the "sparkpost_data" as well. The maximum length of the decription is 1024 characters - values
|
132
|
+
longer than the maxium will be truncated.
|
133
|
+
|
134
|
+
```
|
135
|
+
data = { description: "My Important Message" }
|
136
|
+
|
137
|
+
mail(to: to_email, subject: "Test", body: "test", sparkpost_data: data)
|
138
|
+
```
|
104
139
|
|
105
140
|
### Recipient Lists
|
106
141
|
SparkPostRails supports using SparkPost stored recipient lists. Simply add the list_id to the sparkpost_data hash on the mail message:
|
@@ -121,7 +156,7 @@ to your sparkpost_data hash, with the key :substitution_data.
|
|
121
156
|
|
122
157
|
```
|
123
158
|
sub_data = {first_name: "Sam",
|
124
|
-
last_name: "Test}
|
159
|
+
last_name: "Test"}
|
125
160
|
|
126
161
|
data = { substitution_data: sub_data }
|
127
162
|
|
@@ -141,6 +176,17 @@ mail(to: to_email, sparkpost_data: data)
|
|
141
176
|
**NOTE**: All inline-content that may exist in your mail message will be ignored, as the SparkPost API does not accept that data when a template id is
|
142
177
|
supplied. This includes Subject, From, ReplyTo, Attachments, and Inline Images.
|
143
178
|
|
179
|
+
###Other Mail Headers
|
180
|
+
If you need to identify custom mail headers for your messages, utilize the ActionMailer header[] method. The gem will pass all approprite headers through
|
181
|
+
to the api. Note, per the SparkPost API documentation, "Headers such as 'Content-Type' and 'Content-Transfer-Encoding' are not allowed here as they are auto
|
182
|
+
generated upon construction of the email."
|
183
|
+
|
184
|
+
```
|
185
|
+
headers["Priority"] = "urgent"
|
186
|
+
headers["Sensitivity"] = "private"
|
187
|
+
|
188
|
+
mail(to: to_email, subject: "Test", body: "test")
|
189
|
+
```
|
144
190
|
|
145
191
|
Update Note!
|
146
192
|
============
|
data/lib/sparkpost_rails.rb
CHANGED
@@ -22,6 +22,10 @@ module SparkPostRails
|
|
22
22
|
attr_accessor :campaign_id
|
23
23
|
attr_accessor :return_path
|
24
24
|
|
25
|
+
attr_accessor :transactional
|
26
|
+
attr_accessor :ip_pool
|
27
|
+
|
28
|
+
attr_accessor :subaccount
|
25
29
|
|
26
30
|
def initialize
|
27
31
|
set_defaults
|
@@ -41,6 +45,11 @@ module SparkPostRails
|
|
41
45
|
|
42
46
|
@campaign_id = nil
|
43
47
|
@return_path = nil
|
48
|
+
|
49
|
+
@transactional = false
|
50
|
+
@ip_pool = nil
|
51
|
+
|
52
|
+
@subaccount = nil
|
44
53
|
end
|
45
54
|
end
|
46
55
|
end
|
@@ -2,7 +2,7 @@ module SparkPostRails
|
|
2
2
|
class DeliveryMethod
|
3
3
|
require 'net/http'
|
4
4
|
|
5
|
-
attr_accessor :settings, :data, :response
|
5
|
+
attr_accessor :settings, :data, :response, :headers
|
6
6
|
|
7
7
|
def initialize(options = {})
|
8
8
|
@settings = options
|
@@ -28,8 +28,11 @@ module SparkPostRails
|
|
28
28
|
end
|
29
29
|
|
30
30
|
prepare_substitution_data_from sparkpost_data
|
31
|
+
prepare_description_from sparkpost_data
|
31
32
|
prepare_options_from mail, sparkpost_data
|
32
|
-
|
33
|
+
prepare_additional_mail_headers_from mail
|
34
|
+
|
35
|
+
prepare_api_headers_from sparkpost_data
|
33
36
|
|
34
37
|
result = post_to_api
|
35
38
|
|
@@ -162,9 +165,9 @@ module SparkPostRails
|
|
162
165
|
mail.attachments.each do |attachment|
|
163
166
|
#We decode and reencode here to ensure that attachments are
|
164
167
|
#Base64 encoded without line breaks as required by the API.
|
165
|
-
attachment_data = { name: attachment.filename,
|
168
|
+
attachment_data = { name: attachment.inline? ? attachment.url : attachment.filename,
|
166
169
|
type: attachment.content_type,
|
167
|
-
data: Base64.
|
170
|
+
data: Base64.strict_encode64(attachment.body.decoded) }
|
168
171
|
|
169
172
|
if attachment.inline?
|
170
173
|
inline_images << attachment_data
|
@@ -190,7 +193,10 @@ module SparkPostRails
|
|
190
193
|
prepare_click_tracking_from sparkpost_data
|
191
194
|
prepare_campaign_id_from sparkpost_data
|
192
195
|
prepare_return_path_from mail
|
193
|
-
|
196
|
+
prepare_transactional_from sparkpost_data
|
197
|
+
prepare_skip_suppression_from sparkpost_data
|
198
|
+
prepare_ip_pool_from sparkpost_data
|
199
|
+
prepare_delivery_schedule_from mail
|
194
200
|
end
|
195
201
|
|
196
202
|
def prepare_sandbox_mode_from sparkpost_data
|
@@ -247,11 +253,99 @@ module SparkPostRails
|
|
247
253
|
end
|
248
254
|
end
|
249
255
|
|
250
|
-
def
|
256
|
+
def prepare_transactional_from sparkpost_data
|
257
|
+
@data[:options][:transactional] = SparkPostRails.configuration.transactional
|
258
|
+
|
259
|
+
if sparkpost_data.has_key?(:transactional)
|
260
|
+
@data[:options][:transactional] = sparkpost_data[:transactional]
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
|
265
|
+
def prepare_skip_suppression_from sparkpost_data
|
266
|
+
if sparkpost_data[:skip_suppression]
|
267
|
+
@data[:options][:skip_suppression] = sparkpost_data[:skip_suppression]
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
def prepare_description_from sparkpost_data
|
272
|
+
if sparkpost_data[:description]
|
273
|
+
@data[:description] = sparkpost_data[:description].truncate(1024)
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
def prepare_ip_pool_from sparkpost_data
|
278
|
+
ip_pool = SparkPostRails.configuration.ip_pool
|
279
|
+
|
280
|
+
if sparkpost_data.has_key?(:ip_pool)
|
281
|
+
ip_pool = sparkpost_data[:ip_pool]
|
282
|
+
end
|
283
|
+
|
284
|
+
if ip_pool
|
285
|
+
@data[:options][:ip_pool] = ip_pool
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
def prepare_delivery_schedule_from mail
|
290
|
+
# Format YYYY-MM-DDTHH:MM:SS+-HH:MM or "now". Example: '2015-02-11T08:00:00-04:00'. -From SparkPost API Docs
|
291
|
+
if mail.date && (mail.date > DateTime.now) && (mail.date < (DateTime.now + 1.year))
|
292
|
+
@data[:options][:start_time] = mail.date.strftime("%Y-%m-%dT%H:%M:%S%:z")
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
def prepare_additional_mail_headers_from mail
|
297
|
+
valid_headers = Hash.new
|
298
|
+
|
299
|
+
invalid_names = ["sparkpost-data",
|
300
|
+
"from",
|
301
|
+
"to",
|
302
|
+
"cc",
|
303
|
+
"bcc",
|
304
|
+
"subject",
|
305
|
+
"reply-to",
|
306
|
+
"return-path",
|
307
|
+
"date",
|
308
|
+
"mime-version",
|
309
|
+
"content-type",
|
310
|
+
"content-transfer-encoding",
|
311
|
+
"text-part"]
|
312
|
+
|
313
|
+
mail.header.fields.each do |field|
|
314
|
+
unless invalid_names.include?(field.name.downcase)
|
315
|
+
valid_headers[field.name] = field.value
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
if valid_headers.count > 0
|
320
|
+
unless @data[:content].has_key?(:headers)
|
321
|
+
@data[:content][:headers] = Hash.new
|
322
|
+
end
|
323
|
+
|
324
|
+
@data[:content][:headers].merge!(valid_headers)
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
def prepare_api_headers_from sparkpost_data
|
329
|
+
if sparkpost_data.has_key?(:api_key)
|
330
|
+
api_key = sparkpost_data[:api_key]
|
331
|
+
else
|
332
|
+
api_key = SparkPostRails.configuration.api_key
|
333
|
+
end
|
334
|
+
|
251
335
|
@headers = {
|
252
|
-
"Authorization" =>
|
336
|
+
"Authorization" => api_key,
|
253
337
|
"Content-Type" => "application/json"
|
254
338
|
}
|
339
|
+
|
340
|
+
if sparkpost_data.has_key?(:subaccount)
|
341
|
+
subaccount = sparkpost_data[:subaccount]
|
342
|
+
else
|
343
|
+
subaccount = SparkPostRails.configuration.subaccount
|
344
|
+
end
|
345
|
+
|
346
|
+
if subaccount
|
347
|
+
@headers["X-MSYS-SUBACCOUNT"] = subaccount.to_s
|
348
|
+
end
|
255
349
|
end
|
256
350
|
|
257
351
|
def post_to_api
|
data/spec/attachments_spec.rb
CHANGED
@@ -44,7 +44,11 @@ describe SparkPostRails::DeliveryMethod do
|
|
44
44
|
test_email = Mailer.test_email inline_attachments: 1
|
45
45
|
@delivery_method.deliver!(test_email)
|
46
46
|
|
47
|
-
|
47
|
+
images = @delivery_method.data[:content][:inline_images]
|
48
|
+
expect(images.length).to eq(1)
|
49
|
+
image = images[0]
|
50
|
+
expect(image).to include(:name, :type=>"image/png; filename=image_0.png", :data=>"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")
|
51
|
+
expect(image[:name]).to match(/cid:.*@.*/)
|
48
52
|
end
|
49
53
|
|
50
54
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SparkPostRails::DeliveryMethod do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@delivery_method = SparkPostRails::DeliveryMethod.new
|
7
|
+
end
|
8
|
+
|
9
|
+
context "Delivery Schedule" do
|
10
|
+
it "handles supplied future DateTime value less than a year from now" do
|
11
|
+
start_time = (DateTime.now + 4.hours)
|
12
|
+
formatted_start_time = start_time.strftime("%Y-%m-%dT%H:%M:%S%:z")
|
13
|
+
|
14
|
+
test_email = Mailer.test_email date: start_time
|
15
|
+
@delivery_method.deliver!(test_email)
|
16
|
+
|
17
|
+
expect(@delivery_method.data[:options][:start_time]).to eq(formatted_start_time)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "does not include start_time if date is in the past" do
|
21
|
+
start_time = (DateTime.now - 4.hours)
|
22
|
+
|
23
|
+
test_email = Mailer.test_email date: start_time
|
24
|
+
@delivery_method.deliver!(test_email)
|
25
|
+
|
26
|
+
expect(@delivery_method.data[:options].has_key?(:start_time)).to eq(false)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "does not include start_time if date is more than 1 year from now" do
|
30
|
+
start_time = (DateTime.now + 4.years)
|
31
|
+
|
32
|
+
test_email = Mailer.test_email date: start_time
|
33
|
+
@delivery_method.deliver!(test_email)
|
34
|
+
|
35
|
+
expect(@delivery_method.data[:options].has_key?(:start_time)).to eq(false)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "does not include start_time if not set" do
|
39
|
+
test_email = Mailer.test_email
|
40
|
+
@delivery_method.deliver!(test_email)
|
41
|
+
|
42
|
+
expect(@delivery_method.data[:options].has_key?(:start_time)).to eq(false)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SparkPostRails::DeliveryMethod do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@delivery_method = SparkPostRails::DeliveryMethod.new
|
7
|
+
end
|
8
|
+
|
9
|
+
context "Description" do
|
10
|
+
it "handles value from message" do
|
11
|
+
test_email = Mailer.test_email sparkpost_data: {description: "Test Email"}
|
12
|
+
|
13
|
+
@delivery_method.deliver!(test_email)
|
14
|
+
|
15
|
+
expect(@delivery_method.data[:description]).to eq("Test Email")
|
16
|
+
end
|
17
|
+
|
18
|
+
it "truncates values longer than 1024 characters" do
|
19
|
+
raw_description = "X" * 1050
|
20
|
+
truncated_description = ("X" * 1021) + "..."
|
21
|
+
|
22
|
+
test_email = Mailer.test_email sparkpost_data: {description: raw_description}
|
23
|
+
|
24
|
+
@delivery_method.deliver!(test_email)
|
25
|
+
|
26
|
+
expect(@delivery_method.data[:description]).to eq(truncated_description)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "does not include description element if not supplied" do
|
30
|
+
test_email = Mailer.test_email
|
31
|
+
@delivery_method.deliver!(test_email)
|
32
|
+
|
33
|
+
expect(@delivery_method.data.has_key?(:description)).to eq(false)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SparkPostRails::DeliveryMethod do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@delivery_method = SparkPostRails::DeliveryMethod.new
|
7
|
+
end
|
8
|
+
|
9
|
+
context "Headers" do
|
10
|
+
it "passes appropriate headers through to the API" do
|
11
|
+
test_email = Mailer.test_email headers: {"Priority" => "urgent", "Sensitivity" => "private"}
|
12
|
+
@delivery_method.deliver!(test_email)
|
13
|
+
|
14
|
+
expect(@delivery_method.data[:content][:headers]).to eq({"Priority" => "urgent", "Sensitivity" => "private"})
|
15
|
+
end
|
16
|
+
|
17
|
+
it "is compatible with CC functionality" do
|
18
|
+
test_email = Mailer.test_email cc: "Carl Test <cc@example.com>", headers: {"Priority" => "urgent", "Sensitivity" => "private"}
|
19
|
+
@delivery_method.deliver!(test_email)
|
20
|
+
|
21
|
+
expect(@delivery_method.data[:content][:headers]).to eq({cc: ["cc@example.com"], "Priority" => "urgent", "Sensitivity" => "private"})
|
22
|
+
end
|
23
|
+
|
24
|
+
it "does not pass inappropriate headers through to the API" do
|
25
|
+
test_email = Mailer.test_email headers: {content_type: "POSTSCRIPT", "Priority" => "urgent", "Sensitivity" => "private"}
|
26
|
+
@delivery_method.deliver!(test_email)
|
27
|
+
|
28
|
+
expect(@delivery_method.data[:content][:headers]).to eq({"Priority" => "urgent", "Sensitivity" => "private"})
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SparkPostRails::DeliveryMethod do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
SparkPostRails.configuration.set_defaults
|
7
|
+
@delivery_method = SparkPostRails::DeliveryMethod.new
|
8
|
+
end
|
9
|
+
|
10
|
+
context "IP Pool" do
|
11
|
+
it "handles ip_pool set in the configuration" do
|
12
|
+
SparkPostRails.configure do |c|
|
13
|
+
c.ip_pool = "default_ip"
|
14
|
+
end
|
15
|
+
|
16
|
+
test_email = Mailer.test_email
|
17
|
+
@delivery_method.deliver!(test_email)
|
18
|
+
|
19
|
+
expect(@delivery_method.data[:options][:ip_pool]).to eq("default_ip")
|
20
|
+
end
|
21
|
+
|
22
|
+
it "handles ip_pool set on an individual message" do
|
23
|
+
test_email = Mailer.test_email sparkpost_data: {ip_pool: "message_ip"}
|
24
|
+
|
25
|
+
@delivery_method.deliver!(test_email)
|
26
|
+
|
27
|
+
expect(@delivery_method.data[:options][:ip_pool]).to eq("message_ip")
|
28
|
+
end
|
29
|
+
|
30
|
+
it "handles the value on an individual message overriding configuration" do
|
31
|
+
SparkPostRails.configure do |c|
|
32
|
+
c.ip_pool = "default_ip"
|
33
|
+
end
|
34
|
+
|
35
|
+
test_email = Mailer.test_email sparkpost_data: {ip_pool: "message_ip"}
|
36
|
+
|
37
|
+
@delivery_method.deliver!(test_email)
|
38
|
+
|
39
|
+
expect(@delivery_method.data[:options][:ip_pool]).to eq("message_ip")
|
40
|
+
end
|
41
|
+
|
42
|
+
it "handles a default setting of none" do
|
43
|
+
test_email = Mailer.test_email
|
44
|
+
@delivery_method.deliver!(test_email)
|
45
|
+
|
46
|
+
expect(@delivery_method.data[:options].has_key?(:ip_pool)).to eq(false)
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SparkPostRails::DeliveryMethod do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@delivery_method = SparkPostRails::DeliveryMethod.new
|
7
|
+
end
|
8
|
+
|
9
|
+
context "Skip Suppression" do
|
10
|
+
it "handles value from message" do
|
11
|
+
test_email = Mailer.test_email sparkpost_data: {skip_suppression: true}
|
12
|
+
|
13
|
+
@delivery_method.deliver!(test_email)
|
14
|
+
|
15
|
+
expect(@delivery_method.data[:options][:skip_suppression]).to eq(true)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "does not include skip_suppression element if not supplied" do
|
19
|
+
test_email = Mailer.test_email
|
20
|
+
@delivery_method.deliver!(test_email)
|
21
|
+
|
22
|
+
expect(@delivery_method.data[:options].has_key?(:skip_suppression)).to eq(false)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
data/spec/spec_helper.rb
CHANGED
@@ -52,6 +52,14 @@ class Mailer < ActionMailer::Base
|
|
52
52
|
options.delete(:inline_attachments)
|
53
53
|
end
|
54
54
|
|
55
|
+
if options.has_key?(:headers)
|
56
|
+
if options[:headers].class == Hash
|
57
|
+
headers options[:headers]
|
58
|
+
end
|
59
|
+
|
60
|
+
options.delete(:headers)
|
61
|
+
end
|
62
|
+
|
55
63
|
data.merge! options
|
56
64
|
|
57
65
|
if data.has_key?(:html_part)
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SparkPostRails::DeliveryMethod do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
SparkPostRails.configuration.set_defaults
|
7
|
+
@delivery_method = SparkPostRails::DeliveryMethod.new
|
8
|
+
end
|
9
|
+
|
10
|
+
context "Message-Specific API Key" do
|
11
|
+
it "uses supplied API key instead of default" do
|
12
|
+
SparkPostRails.configure do |c|
|
13
|
+
c.api_key = 'NEW_DEFAULT_API_KEY'
|
14
|
+
end
|
15
|
+
|
16
|
+
test_email = Mailer.test_email sparkpost_data: {api_key: 'SUBACCOUNT_API_KEY'}
|
17
|
+
@delivery_method.deliver!(test_email)
|
18
|
+
|
19
|
+
expect(@delivery_method.headers).to include("Authorization" => "SUBACCOUNT_API_KEY")
|
20
|
+
end
|
21
|
+
|
22
|
+
it "uses default API if no message-specific API key applied" do
|
23
|
+
SparkPostRails.configure do |c|
|
24
|
+
c.api_key = 'NEW_DEFAULT_API_KEY'
|
25
|
+
end
|
26
|
+
|
27
|
+
test_email = Mailer.test_email
|
28
|
+
@delivery_method.deliver!(test_email)
|
29
|
+
|
30
|
+
expect(@delivery_method.headers).to include("Authorization" => "NEW_DEFAULT_API_KEY")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "Subaccount ID" do
|
35
|
+
it "accepts a subaccount ID in the configuration" do
|
36
|
+
SparkPostRails.configure do |c|
|
37
|
+
c.subaccount = 123
|
38
|
+
end
|
39
|
+
|
40
|
+
test_email = Mailer.test_email
|
41
|
+
@delivery_method.deliver!(test_email)
|
42
|
+
|
43
|
+
expect(@delivery_method.headers).to include("X-MSYS-SUBACCOUNT" => "123")
|
44
|
+
end
|
45
|
+
|
46
|
+
it "defaults to no subaccount ID in the configuration" do
|
47
|
+
expect(SparkPostRails.configuration.subaccount).to eq(nil)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "accepts subaccount ID for an individual message" do
|
51
|
+
test_email = Mailer.test_email sparkpost_data: {subaccount: 456}
|
52
|
+
@delivery_method.deliver!(test_email)
|
53
|
+
|
54
|
+
expect(@delivery_method.headers).to include("X-MSYS-SUBACCOUNT" => "456")
|
55
|
+
end
|
56
|
+
|
57
|
+
it "uses subaccount ID on message instead of value in configuration" do
|
58
|
+
SparkPostRails.configure do |c|
|
59
|
+
c.subaccount = 123
|
60
|
+
end
|
61
|
+
|
62
|
+
test_email = Mailer.test_email sparkpost_data: {subaccount: 456}
|
63
|
+
@delivery_method.deliver!(test_email)
|
64
|
+
|
65
|
+
expect(@delivery_method.headers).to include("X-MSYS-SUBACCOUNT" => "456")
|
66
|
+
end
|
67
|
+
|
68
|
+
it "does not include the subaccount header when none is specified" do
|
69
|
+
test_email = Mailer.test_email
|
70
|
+
@delivery_method.deliver!(test_email)
|
71
|
+
|
72
|
+
expect(@delivery_method.headers.has_key?("X-MSYS-SUBACCOUNT")).to eq(false)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SparkPostRails::DeliveryMethod do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
SparkPostRails.configuration.set_defaults
|
7
|
+
@delivery_method = SparkPostRails::DeliveryMethod.new
|
8
|
+
end
|
9
|
+
|
10
|
+
context "Transactional" do
|
11
|
+
it "handles transactional flag set in the configuration" do
|
12
|
+
SparkPostRails.configure do |c|
|
13
|
+
c.transactional = true
|
14
|
+
end
|
15
|
+
|
16
|
+
test_email = Mailer.test_email
|
17
|
+
@delivery_method.deliver!(test_email)
|
18
|
+
|
19
|
+
expect(@delivery_method.data[:options][:transactional]).to eq(true)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "handles transactional set on an individual message" do
|
23
|
+
test_email = Mailer.test_email sparkpost_data: {transactional: true}
|
24
|
+
|
25
|
+
@delivery_method.deliver!(test_email)
|
26
|
+
|
27
|
+
expect(@delivery_method.data[:options][:transactional]).to eq(true)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "handles the value on an individual message overriding configuration" do
|
31
|
+
SparkPostRails.configure do |c|
|
32
|
+
c.transactional = true
|
33
|
+
end
|
34
|
+
|
35
|
+
test_email = Mailer.test_email sparkpost_data: {transactional: false}
|
36
|
+
|
37
|
+
@delivery_method.deliver!(test_email)
|
38
|
+
|
39
|
+
expect(@delivery_method.data[:options][:transactional]).to eq(false)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "handles unset value" do
|
43
|
+
test_email = Mailer.test_email
|
44
|
+
@delivery_method.deliver!(test_email)
|
45
|
+
|
46
|
+
expect(@delivery_method.data[:options][:transactional]).to eq(false)
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sparkpost_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Kimball
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-04-
|
12
|
+
date: 2016-04-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -74,8 +74,12 @@ files:
|
|
74
74
|
- spec/campaign_id_spec.rb
|
75
75
|
- spec/cc_recipients_spec.rb
|
76
76
|
- spec/click_tracking_spec.rb
|
77
|
+
- spec/delivery_schedule_spec.rb
|
78
|
+
- spec/description_spec.rb
|
77
79
|
- spec/from_spec.rb
|
80
|
+
- spec/headers_spec.rb
|
78
81
|
- spec/inline_content_spec.rb
|
82
|
+
- spec/ip_pool_spec.rb
|
79
83
|
- spec/open_tracking_spec.rb
|
80
84
|
- spec/recipients_list_spec.rb
|
81
85
|
- spec/recipients_spec.rb
|
@@ -83,9 +87,12 @@ files:
|
|
83
87
|
- spec/response_spec.rb
|
84
88
|
- spec/return_path_spec.rb
|
85
89
|
- spec/sandbox_mode_spec.rb
|
90
|
+
- spec/skip_suppression_spec.rb
|
86
91
|
- spec/spec_helper.rb
|
92
|
+
- spec/subaccount_api_spec.rb
|
87
93
|
- spec/substitution_data_spec.rb
|
88
94
|
- spec/template_spec.rb
|
95
|
+
- spec/transactional_spec.rb
|
89
96
|
homepage: https://github.com/the-refinery/sparkpost_rails
|
90
97
|
licenses:
|
91
98
|
- MIT
|
@@ -112,15 +119,21 @@ specification_version: 4
|
|
112
119
|
summary: SparkPost for Rails
|
113
120
|
test_files:
|
114
121
|
- spec/cc_recipients_spec.rb
|
122
|
+
- spec/subaccount_api_spec.rb
|
123
|
+
- spec/ip_pool_spec.rb
|
115
124
|
- spec/inline_content_spec.rb
|
116
125
|
- spec/return_path_spec.rb
|
126
|
+
- spec/transactional_spec.rb
|
117
127
|
- spec/recipients_list_spec.rb
|
118
128
|
- spec/campaign_id_spec.rb
|
129
|
+
- spec/description_spec.rb
|
119
130
|
- spec/response_spec.rb
|
120
131
|
- spec/bcc_recipients_spec.rb
|
121
132
|
- spec/sandbox_mode_spec.rb
|
122
133
|
- spec/from_spec.rb
|
123
134
|
- spec/recipients_spec.rb
|
135
|
+
- spec/delivery_schedule_spec.rb
|
136
|
+
- spec/headers_spec.rb
|
124
137
|
- spec/spec_helper.rb
|
125
138
|
- spec/template_spec.rb
|
126
139
|
- spec/open_tracking_spec.rb
|
@@ -128,3 +141,4 @@ test_files:
|
|
128
141
|
- spec/attachments_spec.rb
|
129
142
|
- spec/click_tracking_spec.rb
|
130
143
|
- spec/substitution_data_spec.rb
|
144
|
+
- spec/skip_suppression_spec.rb
|