sparkpost_rails 1.3.0 → 1.5.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 925047803a24a8f98ba5f888f81c4a1ad472f9fc
4
- data.tar.gz: 171842fb600f86f2e65143102ccdba962ac80d17
2
+ SHA256:
3
+ metadata.gz: bd9cf39367215bffb11029280b7526e52553b8484767d2823fc59448b9352c80
4
+ data.tar.gz: 662a03effd5a0332400c843e9a047f65dc34e823baabfa63ce3366867a3f4b69
5
5
  SHA512:
6
- metadata.gz: a783aaf00991597cc6f3b5558db1b43f285e9196cc9cebf22e21f87ba54c5b5cc7cfcc20158cfa1ef9309c70f9ff2da7e6f0fb30f1a6f6f1ae0606bcfa8187ea
7
- data.tar.gz: 6ef6d2888ebf9d6b1864ab77df43aaae54d59abd28ab173621b173b9e3d52877931f6415b27efbda4b9454b730026b1b6804e0f665d9543a084f65caa6ee0d54
6
+ metadata.gz: 5c62bb17ff1685deb530b442e4c022bf4eb88208d8ea988ad6b7baa4c9ee79d0e24180ae099db14d3635e9973367de9ce402dbd3f93418ba1c085a2732e828f4
7
+ data.tar.gz: 202997cc9e44bc84bfc4412b1d5f2f0e6b09246089cf3372506fe3606ce3ea383aec09ae99fbc7db31af27e96cd314f6555894cef2d19317d7cf0ad668519b4d
data/README.md CHANGED
@@ -4,159 +4,154 @@
4
4
  SparkPost Rails
5
5
  ===============
6
6
 
7
- This gem provides seamless integration of SparkPost with ActionMailer. It provides a delivery_method based upon the SparkPost API, and
8
- makes getting setup and sending email via SparkPost in a Rails app pretty painless.
7
+ This gem provides seamless integration of SparkPost with ActionMailer. It provides a `delivery_method` based upon the SparkPost API, and makes getting setup and sending email via SparkPost in a Rails app pretty painless.
9
8
 
10
9
  Getting Started
11
10
  ---------------
12
11
 
13
12
  Add the gem to your Gemfile
14
13
 
15
- ```
14
+ ```ruby
16
15
  gem 'sparkpost_rails'
17
16
  ```
18
17
 
19
18
  Then run the bundle command to install it.
20
19
 
21
- By default, the gem will look for your SparkPost API key in your environment, with the key 'SPARKPOST_API_KEY'. You can override this
22
- setting by identifying a different key in the initializer (`config/initializers/sparkpost_rails.rb`):
20
+ By default, the gem will look for your SparkPost API key in your environment, with the key `SPARKPOST_API_KEY`. You can override this setting by identifying a different key in the initializer (`config/initializers/sparkpost_rails.rb`):
23
21
 
24
- ```
22
+ ```ruby
25
23
  SparkPostRails.configure do |c|
26
24
  c.api_key = 'YOUR API KEY'
27
25
  end
28
26
  ```
27
+ Note that an initializer file is not required to use this gem. If an initializer is not provided, default values will be used. See ["Additional Configuration"](#additional-configuration) below for a list of all the default settings.
29
28
 
30
29
  In each environment configuration file from which you want to send emails via Sparkpost, (i.e. `config/environments/production.rb`) add
31
30
 
32
- ```
31
+ ```ruby
33
32
  config.action_mailer.delivery_method = :sparkpost
34
33
  ```
35
34
 
36
35
  Additional Configuration
37
36
  ------------------------
38
- You can establish values for a number of SparkPost settings in the initializer. These values will be used for every message sent
39
- from your application. You can override these settings on individual messages.
37
+ You can establish values for a number of SparkPost settings in the initializer. These values will be used for every message sent from your application. You can override these settings on individual messages.
40
38
 
41
- ```
39
+ ```ruby
42
40
  SparkPostRails.configure do |c|
43
- c.sandbox = true
44
- c.track_opens = true
45
- c.track_clicks = true
46
- c.return_path = 'BOUNCE-EMAIL@YOUR-DOMAIN.COM'
47
- c.campaign_id = 'YOUR-CAMPAIGN'
48
- c.transactional = true
49
- c.ip_pool = "MY-POOL"
50
- c.inline_css = true
51
- c.html_content_only = true
52
- c.subaccount = "123"
41
+ c.api_endpoint = "https://api.eu.sparkpost.com/api/" # default: "https://api.sparkpost.com/api/"
42
+ c.sandbox = true # default: false
43
+ c.track_opens = true # default: false
44
+ c.track_clicks = true # default: false
45
+ c.return_path = 'BOUNCE-EMAIL@YOUR-DOMAIN.COM' # default: nil
46
+ c.campaign_id = 'YOUR-CAMPAIGN' # default: nil
47
+ c.transactional = true # default: false
48
+ c.ip_pool = "MY-POOL" # default: nil
49
+ c.inline_css = true # default: false
50
+ c.html_content_only = true # default: false
51
+ c.subaccount = "123" # default: nil
53
52
  end
54
53
  ```
55
54
 
56
- The default values for these optional configuration settings are:
57
-
58
- ```
59
- sandbox = false
60
- track_opens = false
61
- track_clicks = false
62
- return_path = nil
63
- campaign_id = nil
64
- transactional = false
65
- ip_pool = nil
66
- inline_css = false
67
- html_content_only = false
68
- subaccount = nil
69
- ```
70
-
71
55
  Usage
72
56
  -----
73
- When calling the deliver! method on the mail object returned from your mailer, SparkPostRails provides the response data directly back
74
- from SparkPost as a hash.
57
+ When calling the `deliver!` method on the mail object returned from your mailer, `SparkPostRails` provides the response data directly back from SparkPost as a hash.
75
58
 
76
- ```
59
+ ```ruby
77
60
  result = MyMailer.welcome_message(user).deliver!
78
61
  ```
79
62
 
80
63
  Example:
81
64
 
65
+ ```ruby
66
+ {
67
+ "total_rejected_recipients" => 0,
68
+ "total_accepted_recipients" => 1,
69
+ "id" => "00000000000000"
70
+ }
82
71
  ```
83
- {"total_rejected_recipients"=>0, "total_accepted_recipients"=>1, "id"=>"00000000000000"}
84
- ```
85
72
 
86
- If the SparkPost API reponds with an error condition, SparkPostRails will raise a SparkPostRails::DeliveryException, which will include all the message
87
- data returned by the API.
73
+ If the SparkPost API responds with an error condition, SparkPostRails will raise a `SparkPostRails::DeliveryException`, which will include all the message data returned by the API.
74
+
75
+ SparkPostRails will support multiple recipients, multiple CC, multiple BCC, ReplyTo address, file attachments, inline images, multi-part (HTML and plaintext) messages - all utilizing the standard `ActionMailer` methodologies.
88
76
 
89
- SparkPostRails will support multiple recipients, multilple CC, multiple BCC, ReplyTo address, file attachments, inline images, multi-part (HTML and plaintext) messages -
90
- all utilizing the standard ActionMailer methodologies.
77
+ Handling Errors
78
+ ---------------
79
+ If you are using `ActiveJob` and wish to do something special when the SparkPost API responds with an error condition you can do so by rescuing these exceptions via `ActionMailer::DeliveryJob`. Simply add an initializer:
91
80
 
81
+ `config/initializers/action_mailer.rb`
92
82
 
93
- SparkPost Specific Features
83
+ ```ruby
84
+ ActionMailer::DeliveryJob.rescue_from(SparkPostRails::DeliveryException) do |exception|
85
+ # do something special with the error
86
+ # do something special with the error
87
+ end
88
+ ```
89
+
90
+ SparkPost-Specific Features
94
91
  ---------------------------
95
92
 
96
93
  ### Configuration Settings
97
- You can specifiy values for any or all of the configuration settings listed above on an individual message. Simply add a hash of these values
98
- to the mail message in a field named "sparkpost_data":
99
-
100
- ```
101
- data = { track_opens: true,
102
- track_clicks: false,
103
- campaign_id: "My Campaign",
104
- transactional: true,
105
- ip_pool = "SPECIAL_POOL",
106
- api_key = "MESSAGE_SPECIFIC_API_KEY"
107
- subaccount = "123"
108
- }
94
+ You can specify values for any or all of the configuration settings listed above on an individual message. Simply add a hash of these values to the mail message in a field named `sparkpost_data`:
95
+
96
+ ```ruby
97
+ data = {
98
+ track_opens: true,
99
+ track_clicks: false,
100
+ campaign_id: 'My Campaign',
101
+ transactional: true,
102
+ ip_pool: 'SPECIAL_POOL',
103
+ api_key: 'MESSAGE_SPECIFIC_API_KEY',
104
+ subaccount: '123'
105
+ }
109
106
 
110
107
  mail(to: to_email, subject: "Test", body: "test", sparkpost_data: data)
111
108
  ```
112
109
 
113
- Additionally, return_path can be overriden on a specific email by setting that field on the mail message itself:
110
+ Additionally, `return_path` can be overridden on a specific email by setting that field on the mail message itself:
114
111
 
115
- ```
112
+ ```ruby
116
113
  mail(to: to_email, subject: "Test", body: "test", return_path: "bounces@example.com")
117
114
  ```
118
115
 
119
116
  ### Transmission Specific Settings
120
117
 
121
- For an individual transmisison you can specifiy that SparkPost should ignore customer supression rules - if your SparkPost account allows for this
122
- feature. Simply include the flag in the "sparkpost_data" field on the message:
118
+ For an individual transmisison you can specifiy that SparkPost should ignore customer supression rules - if your SparkPost account allows for this feature. Simply include the flag in the `sparkpost_data` field on the message:
123
119
 
124
- ```
120
+ ```ruby
125
121
  data = { skip_suppression: true }
126
122
 
127
123
  mail(to: to_email, subject: "Test", body: "test", sparkpost_data: data)
128
124
  ```
129
125
 
130
- 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.
126
+ To schedule the generation of messages for a future date and time, specify a start time in the `date` parameter of the mail. The `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.
131
127
 
132
- ```
133
- start_time = DateTime.now + 4.hours
128
+ ```ruby
129
+ start_time = DateTime.now + 4.hours
134
130
 
135
131
  mail(to: to_email, subject: "Test", body: "test", date: start_time)
136
132
  ```
137
133
 
138
- You can set a description for a transmission via the "sparkpost_data" as well. The maximum length of the decription is 1024 characters - values
139
- longer than the maxium will be truncated.
134
+ You can set a `description` for a transmission via the `sparkpost_data` as well. The maximum length of the `decription` is 1024 characters - values longer than the maxium will be truncated.
140
135
 
141
- ```
136
+ ```ruby
142
137
  data = { description: "My Important Message" }
143
138
 
144
139
  mail(to: to_email, subject: "Test", body: "test", sparkpost_data: data)
145
140
  ```
146
141
 
147
- By default, content from single-part messages is sent at plain-text. If you are only intending to send HTML email, with no plain-text part, you can specify this
148
- as shown below. You can also set this in the configuration to ensure that all single-part emails are sent as html.
142
+ By default, content from single-part messages is sent at plain-text. If you are only intending to send HTML email, with no plain-text part, you can specify this as shown below. You can also set this in the configuration to ensure that all single-part emails are sent as HTML.
149
143
 
150
- ```
144
+ ```ruby
151
145
  data = { html_content_only: true }
152
146
 
153
147
  mail(to: to_email, subject: "Test", body: "<h1>test</h1>", sparkpost_data: data)
154
148
  ```
155
149
 
156
150
  ### Subaccounts
151
+
157
152
  SparkPostRails supports sending messages via subaccounts in two ways. The default API key set in the configuration can be overriden on a message-by-message basis with a subaccount API key.
158
153
 
159
- ```
154
+ ```ruby
160
155
  data = { api_key: "SUBACCOUNT_API_KEY" }
161
156
 
162
157
  mail(subject: "Test", body: "test", sparkpost_data: data)
@@ -164,57 +159,72 @@ mail(subject: "Test", body: "test", sparkpost_data: data)
164
159
 
165
160
  Subaccounts can also be leveraged using the subaccount ID with the master API key.
166
161
 
167
- ```
162
+ ```ruby
168
163
  data = { subaccount: "123" }
169
164
 
170
165
  mail(subject: "Test", body: "test", sparkpost_data: data)
171
166
  ```
172
167
 
173
168
  ### Recipient Lists
174
- SparkPostRails supports using SparkPost stored recipient lists. Simply add the list_id to the sparkpost_data hash on the mail message:
169
+ SparkPostRails supports using SparkPost stored recipient lists. Simply add the `list_id` to the `sparkpost_data` hash on the mail message:
175
170
 
176
- ```
177
- data = { list_id: "MY-LIST"}
171
+ ```ruby
172
+ data = { recipient_list_id: "MY-LIST"}
178
173
 
179
174
  mail(subject: "Test", body: "test", sparkpost_data: data)
180
175
  ```
181
176
 
182
- **NOTE**: If you supply a recipient list id, all To:, CC:, and BCC: data specified on the mail message will be ignored. The SparkPost API does
183
- not support utilizing both a recipient list and inline recipients.
177
+ **NOTE**: If you supply a recipient `list_id`, all `To:`, `CC:`, and `BCC:` data specified on the mail message will be ignored. The SparkPost API does not support utilizing both a recipient list and inline recipients.
184
178
 
185
179
 
186
180
  ### Substitution Data
187
- You can leverage SparkPost's substitution engine through the gem as well. To supply substitution data, simply add your hash of substitution data
188
- to your sparkpost_data hash, with the key :substitution_data.
181
+ You can leverage SparkPost's substitution engine through the gem as well. To supply substitution data, simply add your hash of substitution data to your `sparkpost_data` hash, with the key `substitution_data`.
189
182
 
190
- ```
191
- sub_data = {first_name: "Sam",
192
- last_name: "Test}
183
+ ```ruby
184
+ sub_data = {
185
+ first_name: "Sam",
186
+ last_name: "Test
187
+ }
193
188
 
194
189
  data = { substitution_data: sub_data }
195
190
 
196
191
  mail(to: to_email, subject: "Test", body: "test", sparkpost_data: data)
197
192
  ```
198
193
 
199
- ### Using SparkPost Templates
200
- If you would rather leverage SparkPost's powerful templates rather than building ActionMailer views, SparkPostRails can support that as well. Simply
201
- add your template id to the sparkpost_data hash:
194
+ ### Recipient-Specific Data
195
+ When sending to multiple recipients, you can pass an array of data to complement each recipient. Simply pass an array called `recipients` containing an array of the additional data (e.g. `substitution_data`).
202
196
 
197
+ ```ruby
198
+ recipients = ['recipient1@email.com', 'recipient2@email.com']
199
+ sparkpost_data = {
200
+ recipients: [
201
+ { substitution_data: { name: 'Recipient1' } },
202
+ { substitution_data: { name: 'Recipient2' } }
203
+ ]
204
+ }
205
+ mail(to: recipients, sparkpost_data: sparkpost_data)
203
206
  ```
207
+
208
+
209
+ ### Using SparkPost Templates
210
+ You can leverage SparkPost's powerful templates rather than building ActionMailer views using SparkPostRails. Add your `template_id` to the `sparkpost_data` hash. By default, `ActionMailer` finds a template to use within views. A workaround to prevent this default action is to explicitly pass a block with an empty `text` part:
211
+
212
+ ```ruby
204
213
  data = { template_id: "MY-TEMPLATE" }
205
214
 
206
- mail(to: to_email, sparkpost_data: data)
215
+ mail(to: to_email, sparkpost_data: data) do |format|
216
+ format.text { render text: "" }
217
+ end
207
218
  ```
208
219
 
209
- **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
210
- supplied. This includes Subject, From, ReplyTo, Attachments, and Inline Images.
220
+ **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 supplied. This includes `Subject`, `From`, `ReplyTo`, Attachments, and Inline Images.
211
221
 
212
222
  ###Other Mail Headers
213
- If you need to identify custom mail headers for your messages, utilize the ActionMailer header[] method. The gem will pass all approprite headers through
214
- 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
215
- generated upon construction of the email."
223
+ If you need to identify custom mail headers for your messages, use the `ActionMailer` `header[]` method. The gem will pass all appropriate headers through to the API. Note, per the SparkPost API documentation
216
224
 
217
- ```
225
+ > Headers such as 'Content-Type' and 'Content-Transfer-Encoding' are not allowed here as they are auto-generated upon construction of the email.
226
+
227
+ ```ruby
218
228
  headers["Priority"] = "urgent"
219
229
  headers["Sensitivity"] = "private"
220
230
 
@@ -1,3 +1,4 @@
1
+ require "sparkpost_rails/data_options"
1
2
  require "sparkpost_rails/delivery_method"
2
3
  require "sparkpost_rails/exceptions"
3
4
  require "sparkpost_rails/railtie"
@@ -7,6 +8,10 @@ module SparkPostRails
7
8
  attr_accessor :configuration
8
9
  end
9
10
 
11
+ def self.configuration
12
+ @configuration ||= Configuration.new
13
+ end
14
+
10
15
  def self.configure
11
16
  self.configuration ||= Configuration.new
12
17
  yield(configuration)
@@ -14,6 +19,7 @@ module SparkPostRails
14
19
 
15
20
  class Configuration
16
21
  attr_accessor :api_key
22
+ attr_accessor :api_endpoint
17
23
  attr_accessor :sandbox
18
24
 
19
25
  attr_accessor :track_opens
@@ -40,6 +46,8 @@ module SparkPostRails
40
46
  @api_key = ""
41
47
  end
42
48
 
49
+ @api_endpoint = "https://api.sparkpost.com/api/"
50
+
43
51
  @sandbox = false
44
52
 
45
53
  @track_opens = false
@@ -0,0 +1,25 @@
1
+ module SparkPostRails
2
+ module DataOptions
3
+
4
+ def self.included(base)
5
+ base.class_eval do
6
+ prepend InstanceMethods
7
+ end
8
+ end
9
+
10
+ module InstanceMethods
11
+
12
+ def mail(headers={}, &block)
13
+ headers = headers.clone
14
+ sparkpost_data = headers.delete(:sparkpost_data)
15
+ sparkpost_data ||= {}
16
+ super(headers, &block).tap do |message|
17
+ message.singleton_class.class_eval { attr_accessor "sparkpost_data" }
18
+ message.sparkpost_data = sparkpost_data
19
+ end
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+ end
@@ -14,6 +14,7 @@ module SparkPostRails
14
14
  sparkpost_data = find_sparkpost_data_from mail
15
15
 
16
16
  prepare_recipients_from mail, sparkpost_data
17
+ prepare_recipients_data_from sparkpost_data
17
18
 
18
19
  if sparkpost_data.has_key?(:template_id)
19
20
  prepare_template_content_from sparkpost_data
@@ -28,6 +29,7 @@ module SparkPostRails
28
29
  end
29
30
 
30
31
  prepare_substitution_data_from sparkpost_data
32
+ prepare_metadata_from sparkpost_data
31
33
  prepare_description_from sparkpost_data
32
34
  prepare_options_from mail, sparkpost_data
33
35
  prepare_additional_mail_headers_from mail
@@ -41,11 +43,7 @@ module SparkPostRails
41
43
 
42
44
  private
43
45
  def find_sparkpost_data_from mail
44
- if mail[:sparkpost_data]
45
- eval(mail[:sparkpost_data].value)
46
- else
47
- Hash.new
48
- end
46
+ mail.sparkpost_data
49
47
  end
50
48
 
51
49
  def prepare_recipients_from mail, sparkpost_data
@@ -67,14 +65,15 @@ module SparkPostRails
67
65
 
68
66
  def prepare_addresses emails, names
69
67
  emails = [emails] unless emails.is_a?(Array)
70
- emails.each_with_index.map {|email, index| prepare_address(email, index, names) }
68
+ header_to = emails.join(",")
69
+ emails.each_with_index.map {|email, index| prepare_address(email, index, names, header_to) }
71
70
  end
72
71
 
73
- def prepare_address email, index, names
72
+ def prepare_address email, index, names, header_to
74
73
  if !names[index].nil?
75
- { address: { email: email, name: names[index] } }
74
+ { address: { email: email, name: names[index], header_to: header_to } }
76
75
  else
77
- { address: { email: email } }
76
+ { address: { email: email, header_to: header_to } }
78
77
  end
79
78
  end
80
79
 
@@ -95,6 +94,17 @@ module SparkPostRails
95
94
  end
96
95
  end
97
96
 
97
+ # See https://developers.sparkpost.com/api/#/introduction/substitutions-reference/links-and-substitution-expressions-within-substitution-values
98
+ def prepare_recipients_data_from sparkpost_data
99
+ if (recipients_data = sparkpost_data[:recipients])
100
+ @data[:recipients].each_with_index do |recipient, index|
101
+ if (recipient_data = recipients_data[index])
102
+ recipient.merge!(recipient_data)
103
+ end
104
+ end
105
+ end
106
+ end
107
+
98
108
  def prepare_template_content_from sparkpost_data
99
109
  @data[:content][:template_id] = sparkpost_data[:template_id]
100
110
 
@@ -106,6 +116,12 @@ module SparkPostRails
106
116
  end
107
117
  end
108
118
 
119
+ def prepare_metadata_from sparkpost_data
120
+ if sparkpost_data[:metadata]
121
+ @data[:metadata] = sparkpost_data[:metadata]
122
+ end
123
+ end
124
+
109
125
  def prepare_from_address_from mail
110
126
  if !mail[:from].display_names.first.nil?
111
127
  from = { email: mail.from.first, name: mail[:from].display_names.first }
@@ -135,7 +151,7 @@ module SparkPostRails
135
151
  emails << copy[:address][:email]
136
152
  end
137
153
 
138
- @data[:content][:headers] = { cc: emails }
154
+ @data[:content][:headers] = { cc: emails.join(",") }
139
155
  end
140
156
  end
141
157
 
@@ -166,9 +182,9 @@ module SparkPostRails
166
182
  inline_images = Array.new
167
183
 
168
184
  mail.attachments.each do |attachment|
169
- #We decode and reencode here to ensure that attachments are
185
+ #We decode and reencode here to ensure that attachments are
170
186
  #Base64 encoded without line breaks as required by the API.
171
- attachment_data = { name: attachment.inline? ? attachment.url : attachment.filename,
187
+ attachment_data = { name: attachment.inline? ? attachment.cid : attachment.filename,
172
188
  type: attachment.content_type,
173
189
  data: Base64.strict_encode64(attachment.body.decoded) }
174
190
 
@@ -361,15 +377,13 @@ module SparkPostRails
361
377
  end
362
378
 
363
379
  def post_to_api
364
- url = "https://api.sparkpost.com/api/v1/transmissions"
380
+ uri = URI.join(SparkPostRails.configuration.api_endpoint, 'v1/transmissions')
365
381
 
366
- uri = URI.parse(url)
367
382
  http = Net::HTTP.new(uri.host, uri.port)
368
383
  http.use_ssl = true
369
384
 
370
385
  request = Net::HTTP::Post.new(uri.path, @headers)
371
386
  request.body = JSON.generate(@data)
372
-
373
387
  http.request(request)
374
388
  end
375
389
 
@@ -1,4 +1,17 @@
1
1
  module SparkPostRails
2
2
  class DeliveryException < StandardError
3
+ attr_reader :service_message, :service_description, :service_code
4
+
5
+ def initialize(message)
6
+ errors = [*message].first
7
+
8
+ if errors.is_a?(Hash)
9
+ @service_message = errors['message']
10
+ @service_description = errors['description']
11
+ @service_code = errors['code']
12
+ end
13
+
14
+ super(message)
15
+ end
3
16
  end
4
17
  end
@@ -5,5 +5,11 @@ module SparkPostRails
5
5
  ActionMailer::Base.add_delivery_method :sparkpost, SparkPostRails::DeliveryMethod, return_response: true
6
6
  end
7
7
  end
8
+
9
+ initializer "sparkpost_rails.extend_with_data_options" do
10
+ ActiveSupport.on_load :action_mailer do
11
+ ActionMailer::Base.send :include, SparkPostRails::DataOptions
12
+ end
13
+ end
8
14
  end
9
15
  end
@@ -1,4 +1,4 @@
1
1
  module SparkPostRails
2
- VERSION = "1.3.0"
2
+ VERSION = "1.5.3"
3
3
  end
4
4
 
@@ -48,7 +48,7 @@ describe SparkPostRails::DeliveryMethod do
48
48
  expect(images.length).to eq(1)
49
49
  image = images[0]
50
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:.*@.*/)
51
+ expect(image[:name]).to match(/.*@.*/)
52
52
  end
53
53
 
54
54
  end
@@ -13,7 +13,8 @@ describe SparkPostRails::DeliveryMethod do
13
13
  test_email = Mailer.test_email bcc: "bcc@example.com"
14
14
  @delivery_method.deliver!(test_email)
15
15
 
16
- expect(@delivery_method.data[:recipients]).to eq([{address: {email: "to@example.com"}}, {address: {email: "bcc@example.com", header_to: "to@example.com"}}])
16
+ expect(@delivery_method.data[:recipients]).to match([a_hash_including({address: {email: "to@example.com", header_to: anything}}),
17
+ {address: {email: "bcc@example.com", header_to: "to@example.com"}}])
17
18
  expect(@delivery_method.data[:content]).not_to include(:headers)
18
19
  end
19
20
 
@@ -21,7 +22,9 @@ describe SparkPostRails::DeliveryMethod do
21
22
  test_email = Mailer.test_email to: "Joe Test <to1@example.com>, Sam Test <to2@example.com>", bcc: "Brock Test <bcc@example.com>"
22
23
  @delivery_method.deliver!(test_email)
23
24
 
24
- expect(@delivery_method.data[:recipients]).to eq([{address: {email: "to1@example.com", name: "Joe Test"}}, {address: {email: "to2@example.com", name: "Sam Test"}}, {address: {email: "bcc@example.com", name: "Brock Test", header_to: "to1@example.com"}}])
25
+ expect(@delivery_method.data[:recipients]).to match([a_hash_including({address: {email: "to1@example.com", name: "Joe Test", header_to: anything}}),
26
+ a_hash_including({address: {email: "to2@example.com", name: "Sam Test", header_to: anything}}),
27
+ {address: {email: "bcc@example.com", name: "Brock Test", header_to: "to1@example.com"}}])
25
28
  expect(@delivery_method.data[:content]).not_to include(:headers)
26
29
  end
27
30
  end
@@ -31,7 +34,10 @@ describe SparkPostRails::DeliveryMethod do
31
34
  test_email = Mailer.test_email bcc: "bcc1@example.com, bcc2@example.com"
32
35
  @delivery_method.deliver!(test_email)
33
36
 
34
- expect(@delivery_method.data[:recipients]).to eq([{address: {email: "to@example.com"}}, {address: {email: "bcc1@example.com", header_to: "to@example.com"}}, {address: {email: "bcc2@example.com", header_to: "to@example.com"}}])
37
+ expect(@delivery_method.data[:recipients]).to match([a_hash_including({address: {email: "to@example.com", header_to: anything}}),
38
+ {address: {email: "bcc1@example.com", header_to: "to@example.com"}},
39
+ {address: {email: "bcc2@example.com", header_to: "to@example.com"}}])
40
+
35
41
  expect(@delivery_method.data[:content]).not_to include(:headers)
36
42
  end
37
43
 
@@ -39,7 +45,9 @@ describe SparkPostRails::DeliveryMethod do
39
45
  test_email = Mailer.test_email to: "Joe Test <to@example.com>", bcc: "Brock Test <bcc1@example.com>, Brack Test <bcc2@example.com>"
40
46
  @delivery_method.deliver!(test_email)
41
47
 
42
- expect(@delivery_method.data[:recipients]).to eq([{address: {email: "to@example.com", name: "Joe Test"}}, {address: {email: "bcc1@example.com", name: "Brock Test", header_to: "to@example.com"}}, {address: {email: "bcc2@example.com", name: "Brack Test", header_to: "to@example.com"}}])
48
+ expect(@delivery_method.data[:recipients]).to match([a_hash_including({address: {email: "to@example.com", name: "Joe Test", header_to: anything}}),
49
+ {address: {email: "bcc1@example.com", name: "Brock Test", header_to: "to@example.com"}},
50
+ {address: {email: "bcc2@example.com", name: "Brack Test", header_to: "to@example.com"}}])
43
51
  expect(@delivery_method.data[:content]).not_to include(:headers)
44
52
  end
45
53
 
@@ -47,7 +55,9 @@ describe SparkPostRails::DeliveryMethod do
47
55
  test_email = Mailer.test_email to: "Joe Test <to@example.com>", bcc: "Brock Test <bcc1@example.com>, bcc2@example.com"
48
56
  @delivery_method.deliver!(test_email)
49
57
 
50
- expect(@delivery_method.data[:recipients]).to eq([{address: {email: "to@example.com", name: "Joe Test"}}, {address: {email: "bcc1@example.com", name: "Brock Test", header_to: "to@example.com"}}, {address: {email: "bcc2@example.com", header_to: "to@example.com"}}])
58
+ expect(@delivery_method.data[:recipients]).to match([a_hash_including({address: {email: "to@example.com", name: "Joe Test", header_to: anything}}),
59
+ {address: {email: "bcc1@example.com", name: "Brock Test", header_to: "to@example.com"}},
60
+ {address: {email: "bcc2@example.com", header_to: "to@example.com"}}])
51
61
  expect(@delivery_method.data[:content]).not_to include(:headers)
52
62
  end
53
63
  end
@@ -57,24 +67,35 @@ describe SparkPostRails::DeliveryMethod do
57
67
  test_email = Mailer.test_email to: "to1@example.com, to2@example.com", cc: "cc@example.com", bcc: "bcc@example.com"
58
68
  @delivery_method.deliver!(test_email)
59
69
 
60
- expect(@delivery_method.data[:recipients]).to eq([{address: {email: "to1@example.com"}}, {address: {email: "to2@example.com"}}, {address: {email: "cc@example.com", header_to: "to1@example.com"}}, {address: {email: "bcc@example.com", header_to: "to1@example.com"}}])
61
- expect(@delivery_method.data[:content][:headers]).to eq({cc: ["cc@example.com"]})
70
+ expect(@delivery_method.data[:recipients]).to match([a_hash_including({address: {email: "to1@example.com", header_to: anything}}),
71
+ a_hash_including({address: {email: "to2@example.com", header_to: anything}}),
72
+ {address: {email: "cc@example.com", header_to: "to1@example.com"}},
73
+ {address: {email: "bcc@example.com", header_to: "to1@example.com"}}])
74
+ expect(@delivery_method.data[:content][:headers]).to eq({cc: "cc@example.com"})
62
75
  end
63
76
 
64
77
  it "handles name and email" do
65
78
  test_email = Mailer.test_email to: "Joe Test <to1@example.com>, Sam Test <to2@example.com>", cc: "Carl Test <cc@example.com>", bcc: "Brock Test <bcc@example.com>"
66
79
  @delivery_method.deliver!(test_email)
67
80
 
68
- expect(@delivery_method.data[:recipients]).to eq([{address: {email: "to1@example.com", name: "Joe Test"}}, {address: {email: "to2@example.com", name: "Sam Test"}}, {address: {email: "cc@example.com", name: "Carl Test", header_to: "to1@example.com"}}, {address: {email: "bcc@example.com", name: "Brock Test", header_to: "to1@example.com"}}])
69
- expect(@delivery_method.data[:content][:headers]).to eq({cc: ["cc@example.com"]})
81
+ expect(@delivery_method.data[:recipients]).to match([a_hash_including({address: {email: "to1@example.com", name: "Joe Test", header_to: anything}}),
82
+ a_hash_including({address: {email: "to2@example.com", name: "Sam Test", header_to: anything}}),
83
+ {address: {email: "cc@example.com", name: "Carl Test", header_to: "to1@example.com"}},
84
+ {address: {email: "bcc@example.com", name: "Brock Test", header_to: "to1@example.com"}}])
85
+ expect(@delivery_method.data[:content][:headers]).to eq({cc: "cc@example.com"})
70
86
  end
71
87
 
72
88
  it "handles mix of email only and name/email" do
73
89
  test_email = Mailer.test_email to: "Joe Test <to1@example.com>, to2@example.com", cc: "cc1@example.com, Chris Test <cc2@example.com>", bcc: "Brock Test <bcc1@example.com>, bcc2@example.com"
74
90
  @delivery_method.deliver!(test_email)
75
91
 
76
- expect(@delivery_method.data[:recipients]).to eq([{address: {email: "to1@example.com", name: "Joe Test"}}, {address: {email: "to2@example.com"}}, {address: {email: "cc1@example.com", header_to: "to1@example.com"}}, {address: {email: "cc2@example.com", name: "Chris Test", header_to: "to1@example.com"}}, {address: {email: "bcc1@example.com", name: "Brock Test", header_to: "to1@example.com"}}, {address: {email: "bcc2@example.com", header_to: "to1@example.com"}}])
77
- expect(@delivery_method.data[:content][:headers]).to eq({cc: ["cc1@example.com", "cc2@example.com"]})
92
+ expect(@delivery_method.data[:recipients]).to match([a_hash_including({address: {email: "to1@example.com", name: "Joe Test", header_to: anything}}),
93
+ a_hash_including({address: {email: "to2@example.com", header_to: anything}}),
94
+ {address: {email: "cc1@example.com", header_to: "to1@example.com"}},
95
+ {address: {email: "cc2@example.com", name: "Chris Test", header_to: "to1@example.com"}},
96
+ {address: {email: "bcc1@example.com", name: "Brock Test", header_to: "to1@example.com"}},
97
+ {address: {email: "bcc2@example.com", header_to: "to1@example.com"}}])
98
+ expect(@delivery_method.data[:content][:headers]).to eq({cc: "cc1@example.com,cc2@example.com"})
78
99
  end
79
100
  end
80
101
  end
@@ -12,16 +12,18 @@ describe SparkPostRails::DeliveryMethod do
12
12
  test_email = Mailer.test_email cc: "cc@example.com"
13
13
  @delivery_method.deliver!(test_email)
14
14
 
15
- expect(@delivery_method.data[:recipients]).to eq([{address: {email: "to@example.com"}}, {address: {email: "cc@example.com", header_to: "to@example.com"}}])
16
- expect(@delivery_method.data[:content][:headers]).to eq({cc: ["cc@example.com"]})
15
+ expect(@delivery_method.data[:recipients]).to match([a_hash_including({address: {email: "to@example.com", header_to: anything}}),
16
+ {address: {email: "cc@example.com", header_to: "to@example.com"}}])
17
+ expect(@delivery_method.data[:content][:headers]).to eq({cc: "cc@example.com"})
17
18
  end
18
19
 
19
20
  it "handles name and email" do
20
21
  test_email = Mailer.test_email to: "Joe Test <to@example.com>", cc: "Carl Test <cc@example.com>"
21
22
  @delivery_method.deliver!(test_email)
22
23
 
23
- expect(@delivery_method.data[:recipients]).to eq([{address: {email: "to@example.com", name: "Joe Test"}}, {address: {email: "cc@example.com", name: "Carl Test", header_to: "to@example.com"}}])
24
- expect(@delivery_method.data[:content][:headers]).to eq({cc: ["cc@example.com"]})
24
+ expect(@delivery_method.data[:recipients]).to match([a_hash_including({address: {email: "to@example.com", name: "Joe Test", header_to: anything}}),
25
+ {address: {email: "cc@example.com", name: "Carl Test", header_to: "to@example.com"}}])
26
+ expect(@delivery_method.data[:content][:headers]).to eq({cc: "cc@example.com"})
25
27
  end
26
28
  end
27
29
 
@@ -30,24 +32,30 @@ describe SparkPostRails::DeliveryMethod do
30
32
  test_email = Mailer.test_email cc: "cc1@example.com, cc2@example.com"
31
33
  @delivery_method.deliver!(test_email)
32
34
 
33
- expect(@delivery_method.data[:recipients]).to eq([{address: {email: "to@example.com"}}, {address: {email: "cc1@example.com", header_to: "to@example.com"}}, {address: {email: "cc2@example.com", header_to: "to@example.com"}}])
34
- expect(@delivery_method.data[:content][:headers]).to eq({cc: ["cc1@example.com", "cc2@example.com"]})
35
+ expect(@delivery_method.data[:recipients]).to match([a_hash_including({address: {email: "to@example.com", header_to: anything}}),
36
+ {address: {email: "cc1@example.com", header_to: "to@example.com"}},
37
+ {address: {email: "cc2@example.com", header_to: "to@example.com"}}])
38
+ expect(@delivery_method.data[:content][:headers]).to eq({cc: "cc1@example.com,cc2@example.com"})
35
39
  end
36
40
 
37
41
  it "handles name and email" do
38
42
  test_email = Mailer.test_email to: "Joe Test <to@example.com>", cc: "Carl Test <cc1@example.com>, Chris Test <cc2@example.com>"
39
43
  @delivery_method.deliver!(test_email)
40
44
 
41
- expect(@delivery_method.data[:recipients]).to eq([{address: {email: "to@example.com", name: "Joe Test"}}, {address: {email: "cc1@example.com", name: "Carl Test", header_to: "to@example.com"}}, {address: {email: "cc2@example.com", name: "Chris Test", header_to: "to@example.com"}}])
42
- expect(@delivery_method.data[:content][:headers]).to eq({cc: ["cc1@example.com", "cc2@example.com"]})
45
+ expect(@delivery_method.data[:recipients]).to match([a_hash_including({address: {email: "to@example.com", name: "Joe Test", header_to: anything}}),
46
+ {address: {email: "cc1@example.com", name: "Carl Test", header_to: "to@example.com"}},
47
+ {address: {email: "cc2@example.com", name: "Chris Test", header_to: "to@example.com"}}])
48
+ expect(@delivery_method.data[:content][:headers]).to eq({cc: "cc1@example.com,cc2@example.com"})
43
49
  end
44
50
 
45
51
  it "handles mix of email only and name/email" do
46
52
  test_email = Mailer.test_email to: "Joe Test <to@example.com>", cc: "Carl Test <cc1@example.com>, cc2@example.com"
47
53
  @delivery_method.deliver!(test_email)
48
54
 
49
- expect(@delivery_method.data[:recipients]).to eq([{address: {email: "to@example.com", name: "Joe Test"}}, {address: {email: "cc1@example.com", name: "Carl Test", header_to: "to@example.com"}}, {address: {email: "cc2@example.com", header_to: "to@example.com"}}])
50
- expect(@delivery_method.data[:content][:headers]).to eq({cc: ["cc1@example.com", "cc2@example.com"]})
55
+ expect(@delivery_method.data[:recipients]).to match([a_hash_including({address: {email: "to@example.com", name: "Joe Test", header_to: anything}}),
56
+ {address: {email: "cc1@example.com", name: "Carl Test", header_to: "to@example.com"}},
57
+ {address: {email: "cc2@example.com", header_to: "to@example.com"}}])
58
+ expect(@delivery_method.data[:content][:headers]).to eq({cc: "cc1@example.com,cc2@example.com"})
51
59
  end
52
60
  end
53
61
 
@@ -56,16 +64,20 @@ describe SparkPostRails::DeliveryMethod do
56
64
  test_email = Mailer.test_email to: "to1@example.com, to2@example.com", cc: "cc@example.com"
57
65
  @delivery_method.deliver!(test_email)
58
66
 
59
- expect(@delivery_method.data[:recipients]).to eq([{address: {email: "to1@example.com"}}, {address: {email: "to2@example.com"}}, {address: {email: "cc@example.com", header_to: "to1@example.com"}}])
60
- expect(@delivery_method.data[:content][:headers]).to eq({cc: ["cc@example.com"]})
67
+ expect(@delivery_method.data[:recipients]).to match([a_hash_including({address: {email: "to1@example.com", header_to: anything}}),
68
+ a_hash_including({address: {email: "to2@example.com", header_to: anything}}),
69
+ {address: {email: "cc@example.com", header_to: "to1@example.com"}}])
70
+ expect(@delivery_method.data[:content][:headers]).to eq({cc: "cc@example.com"})
61
71
  end
62
72
 
63
73
  it "handles name and email" do
64
74
  test_email = Mailer.test_email to: "Joe Test <to1@example.com>, Sam Test <to2@example.com>", cc: "Carl Test <cc@example.com>"
65
75
  @delivery_method.deliver!(test_email)
66
76
 
67
- expect(@delivery_method.data[:recipients]).to eq([{address: {email: "to1@example.com", name: "Joe Test"}}, {address: {email: "to2@example.com", name: "Sam Test"}}, {address: {email: "cc@example.com", name: "Carl Test", header_to: "to1@example.com"}}])
68
- expect(@delivery_method.data[:content][:headers]).to eq({cc: ["cc@example.com"]})
77
+ expect(@delivery_method.data[:recipients]).to match([a_hash_including({address: {email: "to1@example.com", name: "Joe Test", header_to: anything}}),
78
+ a_hash_including({address: {email: "to2@example.com", name: "Sam Test", header_to: anything}}),
79
+ {address: {email: "cc@example.com", name: "Carl Test", header_to: "to1@example.com"}}])
80
+ expect(@delivery_method.data[:content][:headers]).to eq({cc: "cc@example.com"})
69
81
  end
70
82
  end
71
83
 
@@ -74,24 +86,33 @@ describe SparkPostRails::DeliveryMethod do
74
86
  test_email = Mailer.test_email to: "to1@example.com, to2@example.com", cc: "cc1@example.com, cc2@example.com"
75
87
  @delivery_method.deliver!(test_email)
76
88
 
77
- expect(@delivery_method.data[:recipients]).to eq([{address: {email: "to1@example.com"}}, {address: {email: "to2@example.com"}}, {address: {email: "cc1@example.com", header_to: "to1@example.com"}}, {address: {email: "cc2@example.com", header_to: "to1@example.com"}}])
78
- expect(@delivery_method.data[:content][:headers]).to eq({cc: ["cc1@example.com", "cc2@example.com"]})
89
+ expect(@delivery_method.data[:recipients]).to match([a_hash_including({address: {email: "to1@example.com", header_to: anything}}),
90
+ a_hash_including({address: {email: "to2@example.com", header_to: anything}}),
91
+ {address: {email: "cc1@example.com", header_to: "to1@example.com"}},
92
+ {address: {email: "cc2@example.com", header_to: "to1@example.com"}}])
93
+ expect(@delivery_method.data[:content][:headers]).to eq({cc: "cc1@example.com,cc2@example.com"})
79
94
  end
80
95
 
81
96
  it "handles name and email" do
82
97
  test_email = Mailer.test_email to: "Joe Test <to1@example.com>, Sam Test <to2@example.com>", cc: "Carl Test <cc1@example.com>, Chris Test <cc2@example.com>"
83
98
  @delivery_method.deliver!(test_email)
84
99
 
85
- expect(@delivery_method.data[:recipients]).to eq([{address: {email: "to1@example.com", name: "Joe Test"}}, {address: {email: "to2@example.com", name: "Sam Test"}}, {address: {email: "cc1@example.com", name: "Carl Test", header_to: "to1@example.com"}}, {address: {email: "cc2@example.com", name: "Chris Test", header_to: "to1@example.com"}}])
86
- expect(@delivery_method.data[:content][:headers]).to eq({cc: ["cc1@example.com", "cc2@example.com"]})
100
+ expect(@delivery_method.data[:recipients]).to match([a_hash_including({address: {email: "to1@example.com", name: "Joe Test", header_to: anything}}),
101
+ a_hash_including({address: {email: "to2@example.com", name: "Sam Test", header_to: anything}}),
102
+ {address: {email: "cc1@example.com", name: "Carl Test", header_to: "to1@example.com"}},
103
+ {address: {email: "cc2@example.com", name: "Chris Test", header_to: "to1@example.com"}}])
104
+ expect(@delivery_method.data[:content][:headers]).to eq({cc: "cc1@example.com,cc2@example.com"})
87
105
  end
88
106
 
89
107
  it "handles mix of email only and name/email for to recipients" do
90
108
  test_email = Mailer.test_email to: "Joe Test <to1@example.com>, to2@example.com", cc: "cc1@example.com, Chris Test <cc2@example.com>"
91
109
  @delivery_method.deliver!(test_email)
92
110
 
93
- expect(@delivery_method.data[:recipients]).to eq([{address: {email: "to1@example.com", name: "Joe Test"}}, {address: {email: "to2@example.com"}}, {address: {email: "cc1@example.com", header_to: "to1@example.com"}}, {address: {email: "cc2@example.com", name: "Chris Test", header_to: "to1@example.com"}}])
94
- expect(@delivery_method.data[:content][:headers]).to eq({cc: ["cc1@example.com", "cc2@example.com"]})
111
+ expect(@delivery_method.data[:recipients]).to match([a_hash_including({address: {email: "to1@example.com", name: "Joe Test", header_to: anything}}),
112
+ a_hash_including({address: {email: "to2@example.com", header_to: anything}}),
113
+ {address: {email: "cc1@example.com", header_to: "to1@example.com"}},
114
+ {address: {email: "cc2@example.com", name: "Chris Test", header_to: "to1@example.com"}}])
115
+ expect(@delivery_method.data[:content][:headers]).to eq({cc: "cc1@example.com,cc2@example.com"})
95
116
  end
96
117
  end
97
118
  end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe "SparkPostRails configuration" do
4
+ let(:delivery_method) { SparkPostRails::DeliveryMethod.new }
5
+
6
+ describe "#configuration" do
7
+ it "creates a new configuration + defaults if #configure is never called", skip_configure: true do
8
+ config = SparkPostRails.configuration
9
+ expect(config).to_not be_nil
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,65 @@
1
+ require 'spec_helper'
2
+
3
+ describe SparkPostRails::DeliveryException do
4
+ subject { SparkPostRails::DeliveryException.new(error) }
5
+
6
+ describe 'string' do
7
+ let(:error) { 'Some delivery error' }
8
+
9
+ it 'preserves original message' do
10
+ begin
11
+ raise subject
12
+ rescue SparkPostRails::DeliveryException => err
13
+ expect(error).to eq(err.message)
14
+ end
15
+ end
16
+ end
17
+
18
+ describe 'array with error details' do
19
+ let(:error) { [{ 'message' => 'Message generation rejected', 'description' => 'recipient address suppressed due to customer policy', 'code' => '1902' }] }
20
+
21
+ it 'assigns message' do
22
+ expect(subject.service_message).to eq('Message generation rejected')
23
+ end
24
+
25
+ it 'assigns description' do
26
+ expect(subject.service_description).to eq('recipient address suppressed due to customer policy')
27
+ end
28
+
29
+ it 'assigns code' do
30
+ expect(subject.service_code).to eq('1902')
31
+ end
32
+
33
+ it 'preserves original message' do
34
+ begin
35
+ raise subject
36
+ rescue SparkPostRails::DeliveryException => err
37
+ expect(error.to_s).to eq(err.message)
38
+ end
39
+ end
40
+ end
41
+
42
+ describe 'array with partial details' do
43
+ let(:error) { [{ 'message' => 'end of world' }] }
44
+
45
+ it 'assigns message' do
46
+ expect(subject.service_message).to eq('end of world')
47
+ end
48
+
49
+ it 'assigns description' do
50
+ expect(subject.service_description).to be nil
51
+ end
52
+
53
+ it 'assigns code' do
54
+ expect(subject.service_code).to be nil
55
+ end
56
+
57
+ it 'preserves original message' do
58
+ begin
59
+ raise subject
60
+ rescue SparkPostRails::DeliveryException => err
61
+ expect(error.to_s).to eq(err.message)
62
+ end
63
+ end
64
+ end
65
+ end
@@ -18,7 +18,7 @@ describe SparkPostRails::DeliveryMethod do
18
18
  test_email = Mailer.test_email cc: "Carl Test <cc@example.com>", headers: {"Priority" => "urgent", "Sensitivity" => "private"}
19
19
  @delivery_method.deliver!(test_email)
20
20
 
21
- expect(@delivery_method.data[:content][:headers]).to eq({cc: ["cc@example.com"], "Priority" => "urgent", "Sensitivity" => "private"})
21
+ expect(@delivery_method.data[:content][:headers]).to eq({cc: "cc@example.com", "Priority" => "urgent", "Sensitivity" => "private"})
22
22
  end
23
23
 
24
24
  it "does not pass inappropriate headers through to the API" do
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ describe SparkPostRails::DeliveryMethod do
4
+ subject { described_class.new }
5
+ let(:metadata) { {item_1: 'test data 1', item_2: 'test data 2'} }
6
+
7
+ describe 'Metadata' do
8
+ context 'template-based message' do
9
+ context 'when metadata is passed' do
10
+ it 'includes metadata' do
11
+ test_email = Mailer.test_email sparkpost_data: { template_id: 'test_template', metadata: metadata }
12
+ subject.deliver!(test_email)
13
+ expect(subject.data[:metadata]).to eq(metadata)
14
+ end
15
+ end
16
+
17
+ context "when metadata isn't passed" do
18
+ it "doesn't include metadata" do
19
+ test_email = Mailer.test_email sparkpost_data: { template_id: 'test_template' }
20
+ subject.deliver!(test_email)
21
+ expect(subject.data).to_not have_key(:metadata)
22
+ end
23
+ end
24
+ end
25
+
26
+ context 'inline-content message' do
27
+ context 'when metadata is passed' do
28
+ it 'includes metadata' do
29
+ test_email = Mailer.test_email sparkpost_data: { metadata: metadata }
30
+ subject.deliver!(test_email)
31
+ expect(subject.data[:metadata]).to eq(metadata)
32
+ end
33
+ end
34
+
35
+ context "when metadata isn't passed" do
36
+ it "doesn't include metadata" do
37
+ test_email = Mailer.test_email sparkpost_data: { metadata: nil }
38
+ subject.deliver!(test_email)
39
+ expect(subject.data).to_not have_key(:metadata)
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,30 @@
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 "Recipient Data" do
10
+
11
+ it "accepts data matching all recipients" do
12
+ recipients = ['recipient1@email.com', 'recipient2@email.com']
13
+ recipients_data = [
14
+ {substitution_data: {name: "Recipient1"}},
15
+ {substitution_data: {name: "Recipient2"}}
16
+ ]
17
+
18
+ test_email = Mailer.test_email to: recipients, sparkpost_data: {recipients: recipients_data}
19
+
20
+ @delivery_method.deliver!(test_email)
21
+
22
+ actual_recipients = @delivery_method.data[:recipients]
23
+ expect(actual_recipients.length).to eq(recipients.length)
24
+ expect(actual_recipients).to match(recipients.each_with_index.map { |recipient, index| recipients_data[index].merge(address: {email: recipient, header_to: anything}) })
25
+ end
26
+
27
+ end
28
+ end
29
+
30
+
@@ -13,14 +13,14 @@ describe SparkPostRails::DeliveryMethod do
13
13
  test_email = Mailer.test_email
14
14
  @delivery_method.deliver!(test_email)
15
15
 
16
- expect(@delivery_method.data[:recipients]).to eq([{address: {email: "to@example.com"}}])
16
+ expect(@delivery_method.data[:recipients]).to match([a_hash_including({address: {email: "to@example.com", header_to: anything}})])
17
17
  end
18
18
 
19
19
  it "handles name and email" do
20
20
  test_email = Mailer.test_email to: "Joe Test <to@example.com>"
21
21
  @delivery_method.deliver!(test_email)
22
22
 
23
- expect(@delivery_method.data[:recipients]).to eq([{address: {email: "to@example.com", name: "Joe Test"}}])
23
+ expect(@delivery_method.data[:recipients]).to match([a_hash_including({address: {email: "to@example.com", name: "Joe Test", header_to: anything}})])
24
24
  end
25
25
  end
26
26
 
@@ -29,21 +29,33 @@ describe SparkPostRails::DeliveryMethod do
29
29
  test_email = Mailer.test_email to: "to1@example.com, to2@example.com"
30
30
  @delivery_method.deliver!(test_email)
31
31
 
32
- expect(@delivery_method.data[:recipients]).to eq([{address: {email: "to1@example.com"}}, {address: {email: "to2@example.com"}}])
32
+ expect(@delivery_method.data[:recipients]).to match([a_hash_including({address: {email: "to1@example.com", header_to: anything}}),
33
+ a_hash_including({address: {email: "to2@example.com", header_to: anything}})])
33
34
  end
34
35
 
35
36
  it "handles name and email" do
36
37
  test_email = Mailer.test_email to: "Sam Test <to1@example.com>, Joe Test <to2@example.com>"
37
38
  @delivery_method.deliver!(test_email)
38
39
 
39
- expect(@delivery_method.data[:recipients]).to eq([{:address=>{:email=>"to1@example.com", :name=>"Sam Test"}}, {:address=>{:email=>"to2@example.com", :name=>"Joe Test"}}])
40
+ expect(@delivery_method.data[:recipients]).to match([a_hash_including({:address=>{:email=>"to1@example.com", :name=>"Sam Test", header_to: anything}}),
41
+ a_hash_including({:address=>{:email=>"to2@example.com", :name=>"Joe Test", header_to: anything}})])
40
42
  end
41
43
 
42
44
  it "handles mix of email only and name/email" do
43
45
  test_email = Mailer.test_email to: "Sam Test <to1@example.com>, to2@example.com"
44
46
  @delivery_method.deliver!(test_email)
45
47
 
46
- expect(@delivery_method.data[:recipients]).to eq([{:address=>{:email=>"to1@example.com", :name=>"Sam Test"}}, {:address=>{:email=>"to2@example.com"}}])
48
+ expect(@delivery_method.data[:recipients]).to match_array([a_hash_including({:address=>{:email=>"to1@example.com", :name=>"Sam Test", header_to: anything}}),
49
+ a_hash_including({:address=>{:email=>"to2@example.com", header_to: anything}})])
50
+ end
51
+
52
+ it "compiles list of email addresses to populate :header_to for each recipient" do
53
+ expected_header_to = "a@a.com,b@b.com"
54
+ test_email = Mailer.test_email to: "a <a@a.com>, b@b.com"
55
+ @delivery_method.deliver!(test_email)
56
+
57
+ expect(@delivery_method.data[:recipients].first[:address][:header_to]).to eql(expected_header_to)
58
+ expect(@delivery_method.data[:recipients].second[:address][:header_to]).to eql(expected_header_to)
47
59
  end
48
60
  end
49
61
  end
@@ -15,7 +15,8 @@ describe SparkPostRails::DeliveryMethod do
15
15
  end
16
16
 
17
17
  it "raises exception on error" do
18
- stub_request(:any, "https://api.sparkpost.com/api/v1/transmissions").
18
+ uri = URI.join(SparkPostRails.configuration.api_endpoint, 'v1/transmissions')
19
+ stub_request(:any, uri.to_s).
19
20
  to_return(body: "{\"errors\":[{\"message\":\"required field is missing\",\"description\":\"recipients or list_id required\",\"code\":\"1400\"}]}", status: 403)
20
21
 
21
22
  test_email = Mailer.test_email
@@ -6,13 +6,19 @@ require "sparkpost_rails"
6
6
  RSpec.configure do |config|
7
7
 
8
8
  config.before(:all) do
9
- SparkPostRails.configure do |c|
10
- c.api_key = "TESTKEY1234"
11
- end
9
+ ActionMailer::Base.send :include, SparkPostRails::DataOptions
12
10
  end
13
11
 
14
- config.before(:each) do
15
- stub_request(:any, "https://api.sparkpost.com/api/v1/transmissions").
12
+ config.before(:each) do |example|
13
+ if example.metadata[:skip_configure]
14
+ SparkPostRails.configuration = nil # Reset configuration
15
+ else
16
+ SparkPostRails.configure do |c|
17
+ c.api_key = "TESTKEY1234"
18
+ end
19
+ end
20
+ uri = URI.join(SparkPostRails.configuration.api_endpoint, 'v1/transmissions')
21
+ stub_request(:any, uri.to_s).
16
22
  to_return(body: "{\"results\":{\"total_rejected_recipients\":0,\"total_accepted_recipients\":1,\"id\":\"00000000000000000\"}}", status: 200)
17
23
  end
18
24
 
@@ -23,7 +29,7 @@ class Mailer < ActionMailer::Base
23
29
  def test_email options = {}
24
30
  data = {
25
31
  from: "from@example.com",
26
- to: "to@example.com",
32
+ to: options[:to] || "to@example.com",
27
33
  subject: "Test Email",
28
34
  text_part: "Hello, Testing!"
29
35
  }
@@ -65,14 +71,14 @@ class Mailer < ActionMailer::Base
65
71
  if data.has_key?(:html_part)
66
72
 
67
73
  mail(data) do |format|
68
- format.text {render text: data[:text_part]}
69
- format.html {render text: data[:html_part]}
74
+ format.text {render plain: data[:text_part]}
75
+ format.html {render plain: data[:html_part]}
70
76
  end
71
77
 
72
78
  else
73
79
 
74
80
  mail(data) do |format|
75
- format.text {render text: data[:text_part]}
81
+ format.text {render plain: data[:text_part]}
76
82
  end
77
83
 
78
84
  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.3.0
4
+ version: 1.5.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Kimball
@@ -9,22 +9,28 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-04-25 00:00:00.000000000 Z
12
+ date: 2020-10-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - "~>"
18
+ - - ">="
19
19
  - !ruby/object:Gem::Version
20
20
  version: '4.0'
21
+ - - "<"
22
+ - !ruby/object:Gem::Version
23
+ version: '6.1'
21
24
  type: :runtime
22
25
  prerelease: false
23
26
  version_requirements: !ruby/object:Gem::Requirement
24
27
  requirements:
25
- - - "~>"
28
+ - - ">="
26
29
  - !ruby/object:Gem::Version
27
30
  version: '4.0'
31
+ - - "<"
32
+ - !ruby/object:Gem::Version
33
+ version: '6.1'
28
34
  - !ruby/object:Gem::Dependency
29
35
  name: rspec
30
36
  requirement: !ruby/object:Gem::Requirement
@@ -65,6 +71,7 @@ files:
65
71
  - LICENSE
66
72
  - README.md
67
73
  - lib/sparkpost_rails.rb
74
+ - lib/sparkpost_rails/data_options.rb
68
75
  - lib/sparkpost_rails/delivery_method.rb
69
76
  - lib/sparkpost_rails/exceptions.rb
70
77
  - lib/sparkpost_rails/railtie.rb
@@ -74,14 +81,18 @@ files:
74
81
  - spec/campaign_id_spec.rb
75
82
  - spec/cc_recipients_spec.rb
76
83
  - spec/click_tracking_spec.rb
84
+ - spec/configuration_spec.rb
77
85
  - spec/delivery_schedule_spec.rb
78
86
  - spec/description_spec.rb
87
+ - spec/exceptions_spec.rb
79
88
  - spec/from_spec.rb
80
89
  - spec/headers_spec.rb
81
90
  - spec/inline_content_spec.rb
82
91
  - spec/inline_css_spec.rb
83
92
  - spec/ip_pool_spec.rb
93
+ - spec/metadata_spec.rb
84
94
  - spec/open_tracking_spec.rb
95
+ - spec/recipient_specific_data_spec.rb
85
96
  - spec/recipients_list_spec.rb
86
97
  - spec/recipients_spec.rb
87
98
  - spec/reply_to_spec.rb
@@ -113,34 +124,37 @@ required_rubygems_version: !ruby/object:Gem::Requirement
113
124
  - !ruby/object:Gem::Version
114
125
  version: '0'
115
126
  requirements: []
116
- rubyforge_project:
117
- rubygems_version: 2.2.2
127
+ rubygems_version: 3.1.4
118
128
  signing_key:
119
129
  specification_version: 4
120
130
  summary: SparkPost for Rails
121
131
  test_files:
122
- - spec/inline_content_spec.rb
132
+ - spec/reply_to_spec.rb
133
+ - spec/open_tracking_spec.rb
134
+ - spec/recipient_specific_data_spec.rb
135
+ - spec/response_spec.rb
136
+ - spec/click_tracking_spec.rb
137
+ - spec/substitution_data_spec.rb
138
+ - spec/spec_helper.rb
123
139
  - spec/from_spec.rb
140
+ - spec/ip_pool_spec.rb
141
+ - spec/metadata_spec.rb
124
142
  - spec/subaccount_api_spec.rb
143
+ - spec/return_path_spec.rb
144
+ - spec/campaign_id_spec.rb
145
+ - spec/inline_content_spec.rb
146
+ - spec/skip_suppression_spec.rb
125
147
  - spec/recipients_spec.rb
148
+ - spec/description_spec.rb
149
+ - spec/inline_css_spec.rb
150
+ - spec/exceptions_spec.rb
151
+ - spec/delivery_schedule_spec.rb
152
+ - spec/attachments_spec.rb
126
153
  - spec/headers_spec.rb
127
- - spec/transactional_spec.rb
128
154
  - spec/bcc_recipients_spec.rb
129
- - spec/ip_pool_spec.rb
130
- - spec/attachments_spec.rb
131
- - spec/cc_recipients_spec.rb
132
155
  - spec/recipients_list_spec.rb
133
- - spec/template_spec.rb
134
- - spec/campaign_id_spec.rb
135
- - spec/reply_to_spec.rb
136
- - spec/spec_helper.rb
137
- - spec/description_spec.rb
138
- - spec/click_tracking_spec.rb
139
- - spec/skip_suppression_spec.rb
140
- - spec/substitution_data_spec.rb
141
- - spec/inline_css_spec.rb
142
- - spec/response_spec.rb
143
- - spec/open_tracking_spec.rb
156
+ - spec/transactional_spec.rb
157
+ - spec/cc_recipients_spec.rb
144
158
  - spec/sandbox_mode_spec.rb
145
- - spec/return_path_spec.rb
146
- - spec/delivery_schedule_spec.rb
159
+ - spec/template_spec.rb
160
+ - spec/configuration_spec.rb