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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6daae188c29ed7eb15c6a8dbd0c5617755f0e5b3
4
- data.tar.gz: 23751028cb6b932d786b812a894656da1b4221e9
3
+ metadata.gz: 81fd8507b990b04184b483dd003722b8ca08289f
4
+ data.tar.gz: 8b1007d2d0ddd41f8391215e873675d9bc58fc55
5
5
  SHA512:
6
- metadata.gz: 970b8a2255cf43de5c63164715993edca7a55deb0a0eb75c47da3079c0938e1132e482a88c9244df73852a4894ba0d94e848d41f9287f0265ec065b8c799570a
7
- data.tar.gz: 63fcc3276a23701abdf75bdd14be5000425e5369a78d3dd9c9f1e2d166209e535f1f66df25278e3caf836265e622727d7bc9b5b6dddc6c7c4212b84ceb0419a7
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
  ============
@@ -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
- prepare_headers
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.encode64(attachment.body.decoded).gsub("\n","") }
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 prepare_headers
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" => SparkPostRails.configuration.api_key,
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
@@ -1,4 +1,4 @@
1
1
  module SparkPostRails
2
- VERSION = "1.1.0"
2
+ VERSION = "1.2.0"
3
3
  end
4
4
 
@@ -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
- expect(@delivery_method.data[:content][:inline_images]).to eq([{:name=>"image_0.png", :type=>"image/png; filename=image_0.png", :data=>"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"}])
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.1.0
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-07 00:00:00.000000000 Z
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