send_grid_mailer 0.5.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +102 -0
  3. data/.circleci/setup-rubygems.sh +3 -0
  4. data/.rubocop.yml +31 -591
  5. data/.ruby-version +1 -1
  6. data/CHANGELOG.md +39 -0
  7. data/README.md +69 -8
  8. data/lib/send_grid_mailer/api.rb +42 -0
  9. data/lib/send_grid_mailer/definition.rb +35 -23
  10. data/lib/send_grid_mailer/deliverer.rb +12 -35
  11. data/lib/send_grid_mailer/dev_deliverer.rb +70 -0
  12. data/lib/send_grid_mailer/engine.rb +7 -3
  13. data/lib/send_grid_mailer/errors.rb +20 -1
  14. data/lib/send_grid_mailer/interceptor/recipient_interceptor.rb +42 -0
  15. data/lib/send_grid_mailer/interceptors_handler.rb +14 -0
  16. data/lib/send_grid_mailer/logger.rb +36 -40
  17. data/lib/send_grid_mailer/mailer_base_ext.rb +18 -7
  18. data/lib/send_grid_mailer/version.rb +1 -1
  19. data/send_grid_mailer.gemspec +12 -6
  20. data/spec/dummy/Rakefile +1 -1
  21. data/spec/dummy/app/assets/config/manifest.js +3 -0
  22. data/spec/dummy/app/assets/stylesheets/application.css +3 -3
  23. data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
  24. data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
  25. data/spec/dummy/app/controllers/application_controller.rb +0 -3
  26. data/spec/dummy/app/{assets/javascripts → javascript/packs}/application.js +3 -1
  27. data/spec/dummy/app/jobs/application_job.rb +7 -0
  28. data/spec/dummy/app/mailers/application_mailer.rb +1 -1
  29. data/spec/dummy/app/mailers/test_mailer.rb +12 -5
  30. data/spec/dummy/app/models/application_record.rb +3 -0
  31. data/spec/dummy/app/views/layouts/application.html.erb +10 -9
  32. data/spec/dummy/bin/rails +3 -3
  33. data/spec/dummy/bin/rake +2 -2
  34. data/spec/dummy/bin/setup +18 -14
  35. data/spec/dummy/config.ru +3 -1
  36. data/spec/dummy/config/application.rb +12 -22
  37. data/spec/dummy/config/boot.rb +3 -3
  38. data/spec/dummy/config/cable.yml +10 -0
  39. data/spec/dummy/config/database.yml +2 -2
  40. data/spec/dummy/config/environment.rb +1 -1
  41. data/spec/dummy/config/environments/development.rb +48 -18
  42. data/spec/dummy/config/environments/production.rb +63 -22
  43. data/spec/dummy/config/environments/test.rb +29 -12
  44. data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
  45. data/spec/dummy/config/initializers/assets.rb +4 -3
  46. data/spec/dummy/config/initializers/backtrace_silencers.rb +4 -3
  47. data/spec/dummy/config/initializers/content_security_policy.rb +28 -0
  48. data/spec/dummy/config/initializers/cookies_serializer.rb +2 -0
  49. data/spec/dummy/config/initializers/filter_parameter_logging.rb +3 -1
  50. data/spec/dummy/config/initializers/permissions_policy.rb +11 -0
  51. data/spec/dummy/config/initializers/wrap_parameters.rb +2 -2
  52. data/spec/dummy/config/locales/en.yml +11 -1
  53. data/spec/dummy/config/puma.rb +43 -0
  54. data/spec/dummy/config/routes.rb +1 -54
  55. data/spec/dummy/config/storage.yml +34 -0
  56. data/spec/dummy/public/404.html +6 -6
  57. data/spec/dummy/public/422.html +6 -6
  58. data/spec/dummy/public/500.html +6 -6
  59. data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
  60. data/spec/dummy/public/apple-touch-icon.png +0 -0
  61. data/spec/dummy/spec/lib/send_grid_mailer/definition_spec.rb +52 -23
  62. data/spec/dummy/spec/mailers/test_mailer_spec.rb +558 -327
  63. data/spec/rails_helper.rb +5 -7
  64. metadata +127 -43
  65. data/.hound.yml +0 -4
  66. data/.travis.yml +0 -15
  67. data/lib/send_grid_mailer/mail_message_ext.rb +0 -7
  68. data/spec/dummy/bin/bundle +0 -3
  69. data/spec/dummy/config/initializers/session_store.rb +0 -3
  70. data/spec/dummy/config/secrets.yml +0 -22
  71. data/spec/dummy/db/schema.rb +0 -16
  72. data/spec/dummy/spec/support/test_helpers.rb +0 -5
@@ -1,423 +1,654 @@
1
1
  require "rails_helper"
2
2
 
3
3
  describe TestMailer do
4
- before do
5
- allow(TestMailer).to receive(:delivery_method).and_return(:sendgrid)
6
- allow_any_instance_of(SendGridMailer::Deliverer).to receive(:api_key).and_return("XXX")
4
+ let(:error_code) { "404" }
5
+ let(:success_code) { "200" }
6
+
7
+ def expect_sg_api_errors(errors)
8
+ error_messages = errors.map { |err| err['message'] }.join('. ')
9
+ message = "Sendgrid API error. Code: #{error_code}. Errors: #{error_messages}"
10
+ expect { deliver }.to raise_error(SendGridMailer::ApiError, message) do |e|
11
+ expect(e.error_code).to eq(error_code.to_i)
12
+ expect(e.errors).to eq(errors)
13
+ end
14
+ end
15
+
16
+ def expect_valid_sg_api_send_mail_request(request_body)
17
+ expect_sg_api_send_mail_request(success_code, request_body)
18
+ deliver
19
+ end
20
+
21
+ def expect_invalid_sg_api_send_mail_request(request_body, errors)
22
+ result = { errors: errors }.to_json
23
+ expect_sg_api_send_mail_request(error_code, request_body, result)
24
+ expect_sg_api_errors(errors)
7
25
  end
8
26
 
9
- def expect_valid_mail_sent(request_body)
10
- result = double(status_code: "202")
27
+ def expect_sg_api_send_mail_request(status_code, request_body, result = nil)
28
+ result = double(status_code: status_code, body: result)
11
29
  client2 = double(post: result)
12
30
  client1 = double(_: client2)
13
31
  expect_any_instance_of(SendGrid::Client).to receive(:_).with(:mail).and_return(client1)
14
32
  expect(client2).to receive(:post).with(request_body: request_body).and_return(result)
15
- deliver
16
33
  end
17
34
 
18
- context "setting body" do
19
- let(:deliver) { described_class.body_email.deliver_now! }
35
+ def expect_valid_sg_api_get_template_request(response)
36
+ expect_sg_api_get_template_request(success_code, response)
37
+ deliver
38
+ end
20
39
 
21
- it "sends mail with valid body" do
22
- request_body = {
23
- "from" =>
24
- {
25
- "email" => "default-sender@platan.us"
26
- },
27
- "personalizations" => [
28
- {
29
- "subject" => "Body email"
30
- }
31
- ],
32
- "content" => [
33
- {
34
- "type" => "text/plain",
35
- "value" => "Body"
36
- }
37
- ]
38
- }
40
+ def expect_invalid_sg_api_get_template_request(errors)
41
+ result = { errors: errors }.to_json
42
+ expect_sg_api_get_template_request(error_code, result)
43
+ expect_sg_api_errors(errors)
44
+ end
39
45
 
40
- expect_valid_mail_sent(request_body)
41
- end
46
+ def expect_sg_api_get_template_request(status_code, result = nil)
47
+ result = double(status_code: status_code, body: result)
48
+ client2 = double(post: result)
49
+ client1 = double(_: client2)
50
+ expect_any_instance_of(SendGrid::Client).to receive(:_).with(:templates).and_return(client1)
51
+ expect(client2).to receive(:get).and_return(result)
42
52
  end
43
53
 
44
- context "setting body from params" do
45
- let(:deliver) { described_class.body_params_email.deliver_now! }
54
+ context "when setting delivery_method to :sendgrid" do
55
+ before { allow(TestMailer).to receive(:delivery_method).and_return(:sendgrid) }
46
56
 
47
- it "sends mail with valid body" do
48
- request_body = {
49
- "from" =>
50
- {
51
- "email" => "default-sender@platan.us"
52
- },
53
- "personalizations" => [
54
- {
55
- "subject" => "Body params email"
56
- }
57
- ],
58
- "content" => [
59
- {
60
- "type" => "text/html",
61
- "value" => "<h1>Body Params</h1>"
57
+ context "with valid API key" do
58
+ before { allow_any_instance_of(SendGridMailer::Deliverer).to receive(:api_key).and_return("X") }
59
+
60
+ context "with unsuccessful response" do
61
+ let(:deliver) { described_class.body_email.deliver_now! }
62
+
63
+ it "doesn't send mail" do
64
+ request_body = {
65
+ "from" =>
66
+ {
67
+ "email" => "default-sender@platan.us"
68
+ },
69
+ "personalizations" => [
70
+ {
71
+ "subject" => "Body email"
72
+ }
73
+ ],
74
+ "content" => [
75
+ {
76
+ "type" => "text/plain",
77
+ "value" => "Body"
78
+ }
79
+ ]
62
80
  }
63
- ]
64
- }
65
81
 
66
- expect_valid_mail_sent(request_body)
67
- end
68
- end
82
+ errors = [
83
+ {
84
+ 'field' => 'from.email',
85
+ 'message' => 'The from email does not...'
86
+ },
87
+ {
88
+ 'field' => 'personalizations.0.to',
89
+ 'message' => 'The to array is required...'
90
+ }
91
+ ]
92
+
93
+ expect_invalid_sg_api_send_mail_request(request_body, errors)
94
+ end
95
+ end
69
96
 
70
- context "setting body from rails template" do
71
- let(:deliver) { described_class.rails_tpl_email.deliver_now! }
97
+ context "when setting body" do
98
+ let(:deliver) { described_class.body_email.deliver_now! }
72
99
 
73
- it "sends mail with valid body" do
74
- request_body = {
75
- "from" =>
76
- {
77
- "email" => "default-sender@platan.us"
78
- },
79
- "personalizations" => [
80
- {
81
- "subject" => "Rails tpl email"
82
- }
83
- ],
84
- "content" => [
85
- {
86
- "type" => "text/html",
87
- "value" => "<html>\n <body>\n Rails Template!\n\n </body>\n</html>\n"
100
+ it "sends mail with valid body" do
101
+ request_body = {
102
+ "from" =>
103
+ {
104
+ "email" => "default-sender@platan.us"
105
+ },
106
+ "personalizations" => [
107
+ {
108
+ "subject" => "Body email"
109
+ }
110
+ ],
111
+ "content" => [
112
+ {
113
+ "type" => "text/plain",
114
+ "value" => "Body"
115
+ }
116
+ ]
88
117
  }
89
- ]
90
- }
91
118
 
92
- expect_valid_mail_sent(request_body)
93
- end
94
- end
119
+ expect_valid_sg_api_send_mail_request(request_body)
120
+ end
121
+ end
95
122
 
96
- context "overriding default from" do
97
- let(:request_body) do
98
- {
99
- "from" =>
100
- {
101
- "email" => "override@platan.us"
102
- },
103
- "personalizations" => [
104
- {
105
- "subject" => subject
106
- }
107
- ],
108
- "content" => [
109
- {
110
- "type" => "text/plain",
111
- "value" => "X"
112
- }
113
- ]
114
- }
115
- end
123
+ context "when setting body from params" do
124
+ let(:deliver) { described_class.body_params_email.deliver_now! }
116
125
 
117
- context "using params" do
118
- let(:deliver) { described_class.from_params_email.deliver_now! }
119
- let(:subject) { "From params email" }
126
+ it "sends mail with valid body" do
127
+ request_body = {
128
+ "from" =>
129
+ {
130
+ "email" => "default-sender@platan.us"
131
+ },
132
+ "personalizations" => [
133
+ {
134
+ "subject" => "Body params email"
135
+ }
136
+ ],
137
+ "content" => [
138
+ {
139
+ "type" => "text/html",
140
+ "value" => "<h1>Body Params</h1>"
141
+ }
142
+ ]
143
+ }
120
144
 
121
- it "sends mail with valid sender" do
122
- expect_valid_mail_sent(request_body)
145
+ expect_valid_sg_api_send_mail_request(request_body)
146
+ end
123
147
  end
124
- end
125
148
 
126
- context "using methods" do
127
- let(:deliver) { described_class.from_email.deliver_now! }
128
- let(:subject) { "From email" }
149
+ context "when setting body from rails template" do
150
+ let(:deliver) { described_class.rails_tpl_email.deliver_now! }
129
151
 
130
- it "sends mail with valid sender" do
131
- expect_valid_mail_sent(request_body)
152
+ it "sends mail with valid body" do
153
+ request_body = {
154
+ "from" =>
155
+ {
156
+ "email" => "default-sender@platan.us"
157
+ },
158
+ "personalizations" => [
159
+ {
160
+ "subject" => "Rails tpl email"
161
+ }
162
+ ],
163
+ "content" => [
164
+ {
165
+ "type" => "text/html",
166
+ "value" => "<html>\n <body>\n Rails Template!\n\n </body>\n</html>\n"
167
+ }
168
+ ]
169
+ }
170
+
171
+ expect_valid_sg_api_send_mail_request(request_body)
172
+ end
132
173
  end
133
- end
134
- end
135
174
 
136
- context "setting recipients" do
137
- let(:request_body) do
138
- {
139
- "from" =>
175
+ context "when overriding default from" do
176
+ let(:request_body) do
140
177
  {
141
- "email" => "default-sender@platan.us"
142
- },
143
- "personalizations" => [
144
- {
145
- "to" => [
178
+ "from" =>
146
179
  {
147
- "email" => "r1@platan.us"
180
+ "email" => "override@platan.us"
148
181
  },
182
+ "personalizations" => [
149
183
  {
150
- "email" => "r2@platan.us"
184
+ "subject" => subject
151
185
  }
152
186
  ],
153
- "cc" => [
187
+ "content" => [
154
188
  {
155
- "email" => "r4@platan.us"
189
+ "type" => "text/plain",
190
+ "value" => "X"
156
191
  }
157
- ],
158
- "bcc" => [
192
+ ]
193
+ }
194
+ end
195
+
196
+ context "when using params" do
197
+ let(:deliver) { described_class.from_params_email.deliver_now! }
198
+ let(:subject) { "From params email" }
199
+
200
+ it "sends mail with valid sender" do
201
+ expect_valid_sg_api_send_mail_request(request_body)
202
+ end
203
+ end
204
+
205
+ context "when using methods" do
206
+ let(:deliver) { described_class.from_email.deliver_now! }
207
+ let(:subject) { "From email" }
208
+
209
+ it "sends mail with valid sender" do
210
+ expect_valid_sg_api_send_mail_request(request_body)
211
+ end
212
+ end
213
+ end
214
+
215
+ context "with setting recipients" do
216
+ let(:request_body) do
217
+ {
218
+ "from" =>
219
+ {
220
+ "email" => "default-sender@platan.us"
221
+ },
222
+ "personalizations" => [
159
223
  {
160
- "email" => "r5@platan.us"
224
+ "to" => [
225
+ {
226
+ "email" => "r1@platan.us"
227
+ },
228
+ {
229
+ "email" => "r2@platan.us"
230
+ }
231
+ ],
232
+ "cc" => [
233
+ {
234
+ "email" => "r4@platan.us"
235
+ }
236
+ ],
237
+ "bcc" => [
238
+ {
239
+ "email" => "r5@platan.us"
240
+ }
241
+ ],
242
+ "subject" => subject
161
243
  }
162
244
  ],
163
- "subject" => subject
164
- }
165
- ],
166
- "content" => [
167
- {
168
- "type" => "text/plain",
169
- "value" => "X"
245
+ "content" => [
246
+ {
247
+ "type" => "text/plain",
248
+ "value" => "X"
249
+ }
250
+ ]
170
251
  }
171
- ]
172
- }
173
- end
252
+ end
174
253
 
175
- context "using params" do
176
- let(:deliver) { described_class.recipients_params_email.deliver_now! }
177
- let(:subject) { "Recipients params email" }
254
+ context "when using params" do
255
+ let(:deliver) { described_class.recipients_params_email.deliver_now! }
256
+ let(:subject) { "Recipients params email" }
178
257
 
179
- it "sends mail with valid recipients" do
180
- expect_valid_mail_sent(request_body)
181
- end
182
- end
258
+ it "sends mail with valid recipients" do
259
+ expect_valid_sg_api_send_mail_request(request_body)
260
+ end
261
+ end
183
262
 
184
- context "using methods" do
185
- let(:deliver) { described_class.recipients_email.deliver_now! }
186
- let(:subject) { "Recipients email" }
263
+ context "when using methods" do
264
+ let(:deliver) { described_class.recipients_email.deliver_now! }
265
+ let(:subject) { "Recipients email" }
187
266
 
188
- it "sends mail with valid recipients" do
189
- expect_valid_mail_sent(request_body)
267
+ it "sends mail with valid recipients" do
268
+ expect_valid_sg_api_send_mail_request(request_body)
269
+ end
270
+ end
190
271
  end
191
- end
192
- end
193
272
 
194
- context "setting template id" do
195
- let(:request_body) do
196
- {
197
- "from" =>
198
- {
199
- "email" => "default-sender@platan.us"
200
- },
201
- "personalizations" => [
273
+ context "when setting template id" do
274
+ let(:request_body) do
202
275
  {
203
- "subject" => subject
276
+ "from" =>
277
+ {
278
+ "email" => "default-sender@platan.us"
279
+ },
280
+ "personalizations" => [
281
+ {
282
+ "subject" => subject
283
+ }
284
+ ],
285
+ "template_id" => "XXX"
204
286
  }
205
- ],
206
- "template_id" => "XXX"
207
- }
208
- end
287
+ end
209
288
 
210
- context "using params" do
211
- let(:deliver) { described_class.template_id_params_email.deliver_now! }
212
- let(:subject) { "Template id params email" }
289
+ context "when using params" do
290
+ let(:deliver) { described_class.template_id_params_email.deliver_now! }
291
+ let(:subject) { "Template id params email" }
213
292
 
214
- it "sends mail with valid template" do
215
- expect_valid_mail_sent(request_body)
216
- end
217
- end
293
+ it "sends mail with valid template" do
294
+ expect_valid_sg_api_send_mail_request(request_body)
295
+ end
296
+ end
218
297
 
219
- context "using methods" do
220
- let(:deliver) { described_class.template_id_email.deliver_now! }
221
- let(:subject) { "Template id email" }
298
+ context "when using methods" do
299
+ let(:deliver) { described_class.template_id_email.deliver_now! }
300
+ let(:subject) { "Template id email" }
222
301
 
223
- it "sends mail with valid template id" do
224
- expect_valid_mail_sent(request_body)
302
+ it "sends mail with valid template id" do
303
+ expect_valid_sg_api_send_mail_request(request_body)
304
+ end
305
+ end
225
306
  end
226
- end
227
- end
228
307
 
229
- context "setting subject" do
230
- let(:request_body) do
231
- {
232
- "from" =>
308
+ context "when setting subject" do
309
+ let(:request_body) do
233
310
  {
234
- "email" => "default-sender@platan.us"
235
- },
236
- "personalizations" => [
237
- {
238
- "subject" => "My Subject"
239
- }
240
- ],
241
- "content" => [
242
- {
243
- "type" => "text/plain",
244
- "value" => "X"
311
+ "from" =>
312
+ {
313
+ "email" => "default-sender@platan.us"
314
+ },
315
+ "personalizations" => [
316
+ {
317
+ "subject" => "My Subject"
318
+ }
319
+ ],
320
+ "content" => [
321
+ {
322
+ "type" => "text/plain",
323
+ "value" => "X"
324
+ }
325
+ ]
245
326
  }
246
- ]
247
- }
248
- end
327
+ end
249
328
 
250
- context "using params" do
251
- let(:deliver) { described_class.subject_params_email.deliver_now! }
329
+ context "when using params" do
330
+ let(:deliver) { described_class.subject_params_email.deliver_now! }
252
331
 
253
- it "sends mail with valid subject" do
254
- expect_valid_mail_sent(request_body)
255
- end
256
- end
332
+ it "sends mail with valid subject" do
333
+ expect_valid_sg_api_send_mail_request(request_body)
334
+ end
335
+ end
257
336
 
258
- context "using methods" do
259
- let(:deliver) { described_class.subject_email.deliver_now! }
337
+ context "when using methods" do
338
+ let(:deliver) { described_class.subject_email.deliver_now! }
260
339
 
261
- it "sends mail with valid subject" do
262
- expect_valid_mail_sent(request_body)
340
+ it "sends mail with valid subject" do
341
+ expect_valid_sg_api_send_mail_request(request_body)
342
+ end
343
+ end
263
344
  end
264
- end
265
- end
266
345
 
267
- context "setting headers" do
268
- let(:request_body) do
269
- {
270
- "from" =>
346
+ context "when setting headers" do
347
+ let(:request_body) do
271
348
  {
272
- "email" => "default-sender@platan.us"
273
- },
274
- "personalizations" => [
275
- {
276
- "subject" => subject,
277
- "headers" =>
349
+ "from" =>
350
+ {
351
+ "email" => "default-sender@platan.us"
352
+ },
353
+ "personalizations" => [
278
354
  {
279
- "HEADER-1" => "VALUE-1",
280
- "HEADER-2" => "VALUE-2"
355
+ "subject" => subject,
356
+ "headers" =>
357
+ {
358
+ "HEADER-1" => "VALUE-1",
359
+ "HEADER-2" => "VALUE-2"
360
+ }
281
361
  }
362
+ ],
363
+ "content" => [
364
+ {
365
+ "type" => "text/plain",
366
+ "value" => "X"
367
+ }
368
+ ]
282
369
  }
283
- ],
284
- "content" => [
285
- {
286
- "type" => "text/plain",
287
- "value" => "X"
288
- }
289
- ]
290
- }
291
- end
370
+ end
292
371
 
293
- context "using params" do
294
- let(:deliver) { described_class.headers_params_email.deliver_now! }
295
- let(:subject) { "Headers params email" }
372
+ context "when using params" do
373
+ let(:deliver) { described_class.headers_params_email.deliver_now! }
374
+ let(:subject) { "Headers params email" }
296
375
 
297
- it "sends mail with valid headers" do
298
- expect_valid_mail_sent(request_body)
299
- end
300
- end
376
+ it "sends mail with valid headers" do
377
+ expect_valid_sg_api_send_mail_request(request_body)
378
+ end
379
+ end
301
380
 
302
- context "using methods" do
303
- let(:deliver) { described_class.headers_email.deliver_now! }
304
- let(:subject) { "Headers email" }
381
+ context "when using methods" do
382
+ let(:deliver) { described_class.headers_email.deliver_now! }
383
+ let(:subject) { "Headers email" }
305
384
 
306
- it "sends mail with valid headers" do
307
- expect_valid_mail_sent(request_body)
385
+ it "sends mail with valid headers" do
386
+ expect_valid_sg_api_send_mail_request(request_body)
387
+ end
388
+ end
308
389
  end
309
- end
310
- end
311
390
 
312
- context "adding attachments" do
313
- let(:deliver) { described_class.add_attachments_email.deliver_now! }
391
+ context "when adding attachments" do
392
+ let(:deliver) { described_class.add_attachments_email.deliver_now! }
314
393
 
315
- it "sends mail with valid body" do
316
- expect_any_instance_of(SendGrid::Attachment).to receive(:content).and_return("X")
317
- expect_any_instance_of(SendGrid::Attachment).to receive(:content_id).and_return("A")
394
+ it "sends mail with valid body" do
395
+ expect_any_instance_of(SendGrid::Attachment).to receive(:content).and_return("X")
396
+ expect_any_instance_of(SendGrid::Attachment).to receive(:content_id).and_return("A")
318
397
 
319
- request_body = {
320
- "from" =>
321
- {
322
- "email" => "default-sender@platan.us"
323
- },
324
- "personalizations" => [
325
- {
326
- "subject" => "Add attachments email"
327
- }
328
- ],
329
- "content" => [
330
- {
331
- "type" => "text/plain",
332
- "value" => "X"
333
- }
334
- ],
335
- "attachments" => [
336
- {
337
- "content" => "X",
338
- "type" => "image/png",
339
- "filename" => "nana.png",
340
- "disposition" => "attachment",
341
- "content_id" => "A"
398
+ request_body = {
399
+ "from" =>
400
+ {
401
+ "email" => "default-sender@platan.us"
402
+ },
403
+ "personalizations" => [
404
+ {
405
+ "subject" => "Add attachments email"
406
+ }
407
+ ],
408
+ "content" => [
409
+ {
410
+ "type" => "text/plain",
411
+ "value" => "X"
412
+ }
413
+ ],
414
+ "attachments" => [
415
+ {
416
+ "content" => "X",
417
+ "type" => "image/png",
418
+ "filename" => "nana.png",
419
+ "disposition" => "attachment",
420
+ "content_id" => "A"
421
+ }
422
+ ]
342
423
  }
343
- ]
344
- }
345
424
 
346
- expect_valid_mail_sent(request_body)
347
- end
348
- end
425
+ expect_valid_sg_api_send_mail_request(request_body)
426
+ end
427
+ end
349
428
 
350
- context "adding substitutions" do
351
- let(:deliver) { described_class.substitutions_email.deliver_now! }
429
+ context "when adding substitutions" do
430
+ let(:deliver) { described_class.substitutions_email.deliver_now! }
352
431
 
353
- it "sends mail with valid body" do
354
- request_body = {
355
- "from" =>
356
- {
357
- "email" => "default-sender@platan.us"
358
- },
359
- "personalizations" => [
360
- {
361
- "subject" => "Substitutions email",
362
- "substitutions" =>
432
+ it "sends mail with valid body" do
433
+ request_body = {
434
+ "from" =>
435
+ {
436
+ "email" => "default-sender@platan.us"
437
+ },
438
+ "personalizations" => [
363
439
  {
364
- "%key1%" => "value1",
365
- "%key2%" => "value2"
440
+ "subject" => "Substitutions email",
441
+ "substitutions" =>
442
+ {
443
+ "%key1%" => "value1",
444
+ "%key2%" => "value2"
445
+ }
366
446
  }
447
+ ],
448
+ "content" => [
449
+ {
450
+ "type" => "text/plain",
451
+ "value" => "X"
452
+ }
453
+ ]
367
454
  }
368
- ],
369
- "content" => [
455
+
456
+ expect_valid_sg_api_send_mail_request(request_body)
457
+ end
458
+ end
459
+
460
+ context "when working with recipient interceptor" do
461
+ let(:interceptor) { double(:interceptor, class: "RecipientInterceptor") }
462
+ let(:deliver) { described_class.recipients_email.deliver_now! }
463
+ let(:request_body) do
370
464
  {
371
- "type" => "text/plain",
372
- "value" => "X"
465
+ "from" =>
466
+ {
467
+ "email" => "default-sender@platan.us"
468
+ },
469
+ "personalizations" => [
470
+ {
471
+ "to" => [
472
+ { "email" => "interceptor1@platan.us" },
473
+ { "email" => "interceptor2@platan.us" }
474
+ ],
475
+ "subject" => "[STAGING] Recipients email",
476
+ "headers" =>
477
+ {
478
+ "X-Intercepted-To" => "r1@platan.us, r2@platan.us",
479
+ "X-Intercepted-Cc" => "r4@platan.us",
480
+ "X-Intercepted-Bcc" => "r5@platan.us"
481
+ }
482
+ }
483
+ ],
484
+ "content" => [
485
+ {
486
+ "type" => "text/plain",
487
+ "value" => "X"
488
+ }
489
+ ]
373
490
  }
374
- ]
375
- }
376
-
377
- expect_valid_mail_sent(request_body)
491
+ end
492
+
493
+ before do
494
+ allow(interceptor).to receive(:instance_variable_get)
495
+ .with(:@recipients).and_return(["interceptor1@platan.us", "interceptor2@platan.us"])
496
+ allow(interceptor).to receive(:instance_variable_get)
497
+ .with(:@subject_prefix).and_return("[STAGING]")
498
+ allow(Mail).to receive(:class_variable_get)
499
+ .with(:@@delivery_interceptors).and_return([interceptor])
500
+ end
501
+
502
+ it "sends mail with valid recipients" do
503
+ expect_valid_sg_api_send_mail_request(request_body)
504
+ end
505
+ end
378
506
  end
379
- end
380
507
 
381
- def get_templates(status_code, response = nil)
382
- result = double(status_code: status_code, body: response)
383
- client = double(get: result)
384
- expect_any_instance_of(SendGrid::Client).to receive(:_).with(:templates).and_return(client)
385
- end
508
+ context "with invalid API key" do
509
+ let(:deliver) { described_class.body_email.deliver_now! }
386
510
 
387
- context "setting template name" do
388
- let(:deliver) { described_class.template_name_email.deliver_now! }
511
+ before do
512
+ allow_any_instance_of(SendGridMailer::Deliverer).to receive(:api_key).and_return(nil)
513
+ end
389
514
 
390
- it "sends mail with valid template id" do
391
- response = { templates: [{ id: "123", name: "my template name" }] }.to_json
392
- get_templates("200", response)
515
+ it { expect { deliver }.to raise_error(SendGridMailer::InvalidApiKey) }
516
+ end
517
+ end
393
518
 
394
- request_body = {
395
- "from" =>
396
- {
397
- "email" => "default-sender@platan.us"
398
- },
399
- "personalizations" => [
400
- {
401
- "subject" => "Template name email"
402
- }
403
- ],
404
- "template_id" => "123"
405
- }
519
+ context "when setting delivery_method to :sendgrid_dev" do
520
+ before { allow(TestMailer).to receive(:delivery_method).and_return(:sendgrid_dev) }
406
521
 
407
- expect_valid_mail_sent(request_body)
408
- end
522
+ context "with valid API key" do
523
+ before do
524
+ allow_any_instance_of(SendGridMailer::DevDeliverer).to receive(:api_key).and_return("X")
525
+ end
409
526
 
410
- it "raises error when templates endpoint is down" do
411
- get_templates("500")
412
- expect { deliver }.to raise_error(SendGridMailer::Exception,
413
- "Error trying to get templates. Status Code: 500")
414
- end
527
+ context "with unsuccessful response" do
528
+ let(:sub) { 'value' }
529
+ let(:deliver) { described_class.template_with_substitutions_email(sub).deliver_now! }
530
+
531
+ it "raises sendgrid mailer error" do
532
+ errors = [
533
+ {
534
+ 'field' => 'from.email',
535
+ 'message' => 'The from email does not...'
536
+ },
537
+ {
538
+ 'field' => 'personalizations.0.to',
539
+ 'message' => 'The to array is required...'
540
+ }
541
+ ]
542
+ expect_invalid_sg_api_get_template_request(errors)
543
+ end
544
+ end
415
545
 
416
- it "raises error when template name does not match with server response" do
417
- response = { templates: [{ id: "123", name: "other template" }] }.to_json
418
- get_templates("200", response)
419
- expect { deliver }.to raise_error(SendGridMailer::Exception,
420
- "No template with name my template name")
546
+ context "with succesful response" do
547
+ let(:lo) { double(deliver!: nil) }
548
+
549
+ before { allow(LetterOpener::DeliveryMethod).to receive(:new).and_return(lo) }
550
+
551
+ context 'when there are no versions but there is a rails template' do
552
+ let(:response) { {}.to_json }
553
+ let(:deliver) { described_class.rails_tpl_email.deliver_now! }
554
+ let(:content) do
555
+ "<html>\r\n <body>\r\n Rails Template!\r\n\r\n </body>\r\n</html>\r\n"
556
+ end
557
+ let(:request_body) do
558
+ {
559
+ "from" =>
560
+ {
561
+ "email" => "default-sender@platan.us"
562
+ },
563
+ "personalizations" => [
564
+ {
565
+ "subject" => "Rails tpl email"
566
+ }
567
+ ],
568
+ "content" => [
569
+ {
570
+ "type" => "text/html",
571
+ "value" => content
572
+ }
573
+ ]
574
+ }
575
+ end
576
+
577
+ it "calls letter_opener with template content as html_part" do
578
+ expect_valid_sg_api_get_template_request(response)
579
+ expect(lo).to have_received(:deliver!) do |arg|
580
+ expect(arg.html_part.to_s).to include(content)
581
+ end
582
+ end
583
+ end
584
+
585
+ context 'when there are template versions' do
586
+ context "when using substitutions" do
587
+ let(:sub) { 'value' }
588
+ let(:deliver) { described_class.template_with_substitutions_email(sub).deliver_now! }
589
+ let(:response) do
590
+ {
591
+ versions: [
592
+ {
593
+ active: 1,
594
+ html_content: active_template
595
+ },
596
+ {
597
+ active: 0,
598
+ html_content: ''
599
+ }
600
+ ]
601
+ }.to_json
602
+ end
603
+
604
+ def active_template(sub = "%key%")
605
+ "<h1>Active version</h1>"\
606
+ "<span>This should be replaced: #{sub}</span>"\
607
+ "<span>This should not be replaced: %key2%</span>"
608
+ end
609
+
610
+ it "gets templates from sendgrid api, applies substitutions to active one and "\
611
+ "uses LetterOpener to deliver it" do
612
+ expect_valid_sg_api_get_template_request(response)
613
+ expect(lo).to have_received(:deliver!) do |arg|
614
+ expect(arg.html_part.to_s).to include(active_template(sub))
615
+ end
616
+ end
617
+ end
618
+
619
+ context "when using dynamic templates" do
620
+ let(:data) { 'value' }
621
+ let(:deliver) { described_class.dynamic_template_email(data).deliver_now! }
622
+ let(:response) do
623
+ {
624
+ versions: [
625
+ {
626
+ active: 1,
627
+ html_content: active_dynamic_template
628
+ },
629
+ {
630
+ active: 0,
631
+ html_content: ''
632
+ }
633
+ ]
634
+ }.to_json
635
+ end
636
+
637
+ def active_dynamic_template(data = "{{key}}")
638
+ "<h1>Active dynamic version</h1>"\
639
+ "<span>This should be replaced: #{data}</span>"
640
+ end
641
+
642
+ it "gets templates from sendgrid api, applies dynamic data to active one and "\
643
+ "uses LetterOpener to deliver it" do
644
+ expect_valid_sg_api_get_template_request(response)
645
+ expect(lo).to have_received(:deliver!) do |arg|
646
+ expect(arg.html_part.to_s).to include(active_dynamic_template(data))
647
+ end
648
+ end
649
+ end
650
+ end
651
+ end
421
652
  end
422
653
  end
423
654
  end