sparkpost_rails 1.1.0 → 1.2.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.
- 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
|