send_grid_mailer 0.5.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,3 @@
1
1
  module SendGridMailer
2
- VERSION = "0.5.0"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -44,11 +44,6 @@ class TestMailer < ApplicationMailer
44
44
  mail
45
45
  end
46
46
 
47
- def template_name_email
48
- set_template_name("my template name")
49
- mail(body: "X")
50
- end
51
-
52
47
  def template_id_params_email
53
48
  mail(template_id: "XXX")
54
49
  end
@@ -1,423 +1,489 @@
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
+ def expect_valid_sg_api_request(request_body)
5
+ expect_sg_api_request(SendGridMailer::Api::SUCCESS_CODE, request_body)
6
+ deliver
7
7
  end
8
8
 
9
- def expect_valid_mail_sent(request_body)
10
- result = double(status_code: "202")
9
+ def expect_invalid_sg_api_request(request_body, errors)
10
+ error_code = "404"
11
+ result = { errors: errors }.to_json
12
+ expect_sg_api_request(error_code, request_body, result)
13
+ expect { deliver }.to raise_error(SendGridMailer::ApiError, "sendgrid api error") do |e|
14
+ expect(e.error_code).to eq(error_code)
15
+ expect(e.errors).to eq(errors)
16
+ end
17
+ end
18
+
19
+ def expect_sg_api_request(status_code, request_body, result = nil)
20
+ result = double(status_code: status_code, body: result)
11
21
  client2 = double(post: result)
12
22
  client1 = double(_: client2)
13
23
  expect_any_instance_of(SendGrid::Client).to receive(:_).with(:mail).and_return(client1)
14
24
  expect(client2).to receive(:post).with(request_body: request_body).and_return(result)
15
- deliver
16
25
  end
17
26
 
18
- context "setting body" do
19
- let(:deliver) { described_class.body_email.deliver_now! }
20
-
21
- it "sends mail with valid body" do
22
- request_body = {
23
- "from" =>
24
- {
25
- "email" => "default-sender@platan.us"
27
+ before { allow(TestMailer).to receive(:delivery_method).and_return(:sendgrid) }
28
+
29
+ context "with valid API key" do
30
+ before { allow_any_instance_of(SendGridMailer::Deliverer).to receive(:api_key).and_return("X") }
31
+
32
+ context "with unsuccessful response" do
33
+ let(:deliver) { described_class.body_email.deliver_now! }
34
+
35
+ it "sends mail with valid body" do
36
+ request_body = {
37
+ "from" =>
38
+ {
39
+ "email" => "default-sender@platan.us"
40
+ },
41
+ "personalizations" => [
42
+ {
43
+ "subject" => "Body email"
44
+ }
45
+ ],
46
+ "content" => [
47
+ {
48
+ "type" => "text/plain",
49
+ "value" => "Body"
50
+ }
51
+ ]
52
+ }
53
+
54
+ errors = [
55
+ {
56
+ 'field' => 'from.email',
57
+ 'message' => 'The from email does not...'
26
58
  },
27
- "personalizations" => [
28
59
  {
29
- "subject" => "Body email"
30
- }
31
- ],
32
- "content" => [
33
- {
34
- "type" => "text/plain",
35
- "value" => "Body"
60
+ 'field' => 'personalizations.0.to',
61
+ 'message' => 'The to array is required...'
36
62
  }
37
63
  ]
38
- }
39
64
 
40
- expect_valid_mail_sent(request_body)
65
+ expect_invalid_sg_api_request(request_body, errors)
66
+ end
41
67
  end
42
- end
43
-
44
- context "setting body from params" do
45
- let(:deliver) { described_class.body_params_email.deliver_now! }
46
68
 
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>"
62
- }
63
- ]
64
- }
65
-
66
- expect_valid_mail_sent(request_body)
69
+ context "setting body" do
70
+ let(:deliver) { described_class.body_email.deliver_now! }
71
+
72
+ it "sends mail with valid body" do
73
+ request_body = {
74
+ "from" =>
75
+ {
76
+ "email" => "default-sender@platan.us"
77
+ },
78
+ "personalizations" => [
79
+ {
80
+ "subject" => "Body email"
81
+ }
82
+ ],
83
+ "content" => [
84
+ {
85
+ "type" => "text/plain",
86
+ "value" => "Body"
87
+ }
88
+ ]
89
+ }
90
+
91
+ expect_valid_sg_api_request(request_body)
92
+ end
67
93
  end
68
- end
69
-
70
- context "setting body from rails template" do
71
- let(:deliver) { described_class.rails_tpl_email.deliver_now! }
72
-
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"
88
- }
89
- ]
90
- }
91
94
 
92
- expect_valid_mail_sent(request_body)
95
+ context "setting body from params" do
96
+ let(:deliver) { described_class.body_params_email.deliver_now! }
97
+
98
+ it "sends mail with valid body" do
99
+ request_body = {
100
+ "from" =>
101
+ {
102
+ "email" => "default-sender@platan.us"
103
+ },
104
+ "personalizations" => [
105
+ {
106
+ "subject" => "Body params email"
107
+ }
108
+ ],
109
+ "content" => [
110
+ {
111
+ "type" => "text/html",
112
+ "value" => "<h1>Body Params</h1>"
113
+ }
114
+ ]
115
+ }
116
+
117
+ expect_valid_sg_api_request(request_body)
118
+ end
93
119
  end
94
- end
95
120
 
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
- }
121
+ context "setting body from rails template" do
122
+ let(:deliver) { described_class.rails_tpl_email.deliver_now! }
123
+
124
+ it "sends mail with valid body" do
125
+ request_body = {
126
+ "from" =>
127
+ {
128
+ "email" => "default-sender@platan.us"
129
+ },
130
+ "personalizations" => [
131
+ {
132
+ "subject" => "Rails tpl email"
133
+ }
134
+ ],
135
+ "content" => [
136
+ {
137
+ "type" => "text/html",
138
+ "value" => "<html>\n <body>\n Rails Template!\n\n </body>\n</html>\n"
139
+ }
140
+ ]
141
+ }
142
+
143
+ expect_valid_sg_api_request(request_body)
144
+ end
115
145
  end
116
146
 
117
- context "using params" do
118
- let(:deliver) { described_class.from_params_email.deliver_now! }
119
- let(:subject) { "From params email" }
147
+ context "overriding default from" do
148
+ let(:request_body) do
149
+ {
150
+ "from" =>
151
+ {
152
+ "email" => "override@platan.us"
153
+ },
154
+ "personalizations" => [
155
+ {
156
+ "subject" => subject
157
+ }
158
+ ],
159
+ "content" => [
160
+ {
161
+ "type" => "text/plain",
162
+ "value" => "X"
163
+ }
164
+ ]
165
+ }
166
+ end
167
+
168
+ context "using params" do
169
+ let(:deliver) { described_class.from_params_email.deliver_now! }
170
+ let(:subject) { "From params email" }
120
171
 
121
- it "sends mail with valid sender" do
122
- expect_valid_mail_sent(request_body)
172
+ it "sends mail with valid sender" do
173
+ expect_valid_sg_api_request(request_body)
174
+ end
123
175
  end
124
- end
125
176
 
126
- context "using methods" do
127
- let(:deliver) { described_class.from_email.deliver_now! }
128
- let(:subject) { "From email" }
177
+ context "using methods" do
178
+ let(:deliver) { described_class.from_email.deliver_now! }
179
+ let(:subject) { "From email" }
129
180
 
130
- it "sends mail with valid sender" do
131
- expect_valid_mail_sent(request_body)
181
+ it "sends mail with valid sender" do
182
+ expect_valid_sg_api_request(request_body)
183
+ end
132
184
  end
133
185
  end
134
- end
135
186
 
136
- context "setting recipients" do
137
- let(:request_body) do
138
- {
139
- "from" =>
140
- {
141
- "email" => "default-sender@platan.us"
142
- },
143
- "personalizations" => [
144
- {
145
- "to" => [
146
- {
147
- "email" => "r1@platan.us"
148
- },
149
- {
150
- "email" => "r2@platan.us"
151
- }
152
- ],
153
- "cc" => [
154
- {
155
- "email" => "r4@platan.us"
156
- }
157
- ],
158
- "bcc" => [
159
- {
160
- "email" => "r5@platan.us"
161
- }
162
- ],
163
- "subject" => subject
164
- }
165
- ],
166
- "content" => [
167
- {
168
- "type" => "text/plain",
169
- "value" => "X"
170
- }
171
- ]
172
- }
173
- end
187
+ context "setting recipients" do
188
+ let(:request_body) do
189
+ {
190
+ "from" =>
191
+ {
192
+ "email" => "default-sender@platan.us"
193
+ },
194
+ "personalizations" => [
195
+ {
196
+ "to" => [
197
+ {
198
+ "email" => "r1@platan.us"
199
+ },
200
+ {
201
+ "email" => "r2@platan.us"
202
+ }
203
+ ],
204
+ "cc" => [
205
+ {
206
+ "email" => "r4@platan.us"
207
+ }
208
+ ],
209
+ "bcc" => [
210
+ {
211
+ "email" => "r5@platan.us"
212
+ }
213
+ ],
214
+ "subject" => subject
215
+ }
216
+ ],
217
+ "content" => [
218
+ {
219
+ "type" => "text/plain",
220
+ "value" => "X"
221
+ }
222
+ ]
223
+ }
224
+ end
174
225
 
175
- context "using params" do
176
- let(:deliver) { described_class.recipients_params_email.deliver_now! }
177
- let(:subject) { "Recipients params email" }
226
+ context "using params" do
227
+ let(:deliver) { described_class.recipients_params_email.deliver_now! }
228
+ let(:subject) { "Recipients params email" }
178
229
 
179
- it "sends mail with valid recipients" do
180
- expect_valid_mail_sent(request_body)
230
+ it "sends mail with valid recipients" do
231
+ expect_valid_sg_api_request(request_body)
232
+ end
181
233
  end
182
- end
183
234
 
184
- context "using methods" do
185
- let(:deliver) { described_class.recipients_email.deliver_now! }
186
- let(:subject) { "Recipients email" }
235
+ context "using methods" do
236
+ let(:deliver) { described_class.recipients_email.deliver_now! }
237
+ let(:subject) { "Recipients email" }
187
238
 
188
- it "sends mail with valid recipients" do
189
- expect_valid_mail_sent(request_body)
239
+ it "sends mail with valid recipients" do
240
+ expect_valid_sg_api_request(request_body)
241
+ end
190
242
  end
191
243
  end
192
- end
193
244
 
194
- context "setting template id" do
195
- let(:request_body) do
196
- {
197
- "from" =>
198
- {
199
- "email" => "default-sender@platan.us"
200
- },
201
- "personalizations" => [
202
- {
203
- "subject" => subject
204
- }
205
- ],
206
- "template_id" => "XXX"
207
- }
208
- end
245
+ context "setting template id" do
246
+ let(:request_body) do
247
+ {
248
+ "from" =>
249
+ {
250
+ "email" => "default-sender@platan.us"
251
+ },
252
+ "personalizations" => [
253
+ {
254
+ "subject" => subject
255
+ }
256
+ ],
257
+ "template_id" => "XXX"
258
+ }
259
+ end
209
260
 
210
- context "using params" do
211
- let(:deliver) { described_class.template_id_params_email.deliver_now! }
212
- let(:subject) { "Template id params email" }
261
+ context "using params" do
262
+ let(:deliver) { described_class.template_id_params_email.deliver_now! }
263
+ let(:subject) { "Template id params email" }
213
264
 
214
- it "sends mail with valid template" do
215
- expect_valid_mail_sent(request_body)
265
+ it "sends mail with valid template" do
266
+ expect_valid_sg_api_request(request_body)
267
+ end
216
268
  end
217
- end
218
269
 
219
- context "using methods" do
220
- let(:deliver) { described_class.template_id_email.deliver_now! }
221
- let(:subject) { "Template id email" }
270
+ context "using methods" do
271
+ let(:deliver) { described_class.template_id_email.deliver_now! }
272
+ let(:subject) { "Template id email" }
222
273
 
223
- it "sends mail with valid template id" do
224
- expect_valid_mail_sent(request_body)
274
+ it "sends mail with valid template id" do
275
+ expect_valid_sg_api_request(request_body)
276
+ end
225
277
  end
226
278
  end
227
- end
228
279
 
229
- context "setting subject" do
230
- let(:request_body) do
231
- {
232
- "from" =>
233
- {
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"
245
- }
246
- ]
247
- }
248
- end
280
+ context "setting subject" do
281
+ let(:request_body) do
282
+ {
283
+ "from" =>
284
+ {
285
+ "email" => "default-sender@platan.us"
286
+ },
287
+ "personalizations" => [
288
+ {
289
+ "subject" => "My Subject"
290
+ }
291
+ ],
292
+ "content" => [
293
+ {
294
+ "type" => "text/plain",
295
+ "value" => "X"
296
+ }
297
+ ]
298
+ }
299
+ end
249
300
 
250
- context "using params" do
251
- let(:deliver) { described_class.subject_params_email.deliver_now! }
301
+ context "using params" do
302
+ let(:deliver) { described_class.subject_params_email.deliver_now! }
252
303
 
253
- it "sends mail with valid subject" do
254
- expect_valid_mail_sent(request_body)
304
+ it "sends mail with valid subject" do
305
+ expect_valid_sg_api_request(request_body)
306
+ end
255
307
  end
256
- end
257
308
 
258
- context "using methods" do
259
- let(:deliver) { described_class.subject_email.deliver_now! }
309
+ context "using methods" do
310
+ let(:deliver) { described_class.subject_email.deliver_now! }
260
311
 
261
- it "sends mail with valid subject" do
262
- expect_valid_mail_sent(request_body)
312
+ it "sends mail with valid subject" do
313
+ expect_valid_sg_api_request(request_body)
314
+ end
263
315
  end
264
316
  end
265
- end
266
317
 
267
- context "setting headers" do
268
- let(:request_body) do
269
- {
270
- "from" =>
271
- {
272
- "email" => "default-sender@platan.us"
273
- },
274
- "personalizations" => [
275
- {
276
- "subject" => subject,
277
- "headers" =>
278
- {
279
- "HEADER-1" => "VALUE-1",
280
- "HEADER-2" => "VALUE-2"
281
- }
282
- }
283
- ],
284
- "content" => [
285
- {
286
- "type" => "text/plain",
287
- "value" => "X"
288
- }
289
- ]
290
- }
291
- end
318
+ context "setting headers" do
319
+ let(:request_body) do
320
+ {
321
+ "from" =>
322
+ {
323
+ "email" => "default-sender@platan.us"
324
+ },
325
+ "personalizations" => [
326
+ {
327
+ "subject" => subject,
328
+ "headers" =>
329
+ {
330
+ "HEADER-1" => "VALUE-1",
331
+ "HEADER-2" => "VALUE-2"
332
+ }
333
+ }
334
+ ],
335
+ "content" => [
336
+ {
337
+ "type" => "text/plain",
338
+ "value" => "X"
339
+ }
340
+ ]
341
+ }
342
+ end
292
343
 
293
- context "using params" do
294
- let(:deliver) { described_class.headers_params_email.deliver_now! }
295
- let(:subject) { "Headers params email" }
344
+ context "using params" do
345
+ let(:deliver) { described_class.headers_params_email.deliver_now! }
346
+ let(:subject) { "Headers params email" }
296
347
 
297
- it "sends mail with valid headers" do
298
- expect_valid_mail_sent(request_body)
348
+ it "sends mail with valid headers" do
349
+ expect_valid_sg_api_request(request_body)
350
+ end
299
351
  end
300
- end
301
352
 
302
- context "using methods" do
303
- let(:deliver) { described_class.headers_email.deliver_now! }
304
- let(:subject) { "Headers email" }
353
+ context "using methods" do
354
+ let(:deliver) { described_class.headers_email.deliver_now! }
355
+ let(:subject) { "Headers email" }
305
356
 
306
- it "sends mail with valid headers" do
307
- expect_valid_mail_sent(request_body)
357
+ it "sends mail with valid headers" do
358
+ expect_valid_sg_api_request(request_body)
359
+ end
308
360
  end
309
361
  end
310
- end
311
-
312
- context "adding attachments" do
313
- let(:deliver) { described_class.add_attachments_email.deliver_now! }
314
362
 
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")
318
-
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"
342
- }
343
- ]
344
- }
363
+ context "adding attachments" do
364
+ let(:deliver) { described_class.add_attachments_email.deliver_now! }
365
+
366
+ it "sends mail with valid body" do
367
+ expect_any_instance_of(SendGrid::Attachment).to receive(:content).and_return("X")
368
+ expect_any_instance_of(SendGrid::Attachment).to receive(:content_id).and_return("A")
369
+
370
+ request_body = {
371
+ "from" =>
372
+ {
373
+ "email" => "default-sender@platan.us"
374
+ },
375
+ "personalizations" => [
376
+ {
377
+ "subject" => "Add attachments email"
378
+ }
379
+ ],
380
+ "content" => [
381
+ {
382
+ "type" => "text/plain",
383
+ "value" => "X"
384
+ }
385
+ ],
386
+ "attachments" => [
387
+ {
388
+ "content" => "X",
389
+ "type" => "image/png",
390
+ "filename" => "nana.png",
391
+ "disposition" => "attachment",
392
+ "content_id" => "A"
393
+ }
394
+ ]
395
+ }
396
+
397
+ expect_valid_sg_api_request(request_body)
398
+ end
399
+ end
345
400
 
346
- expect_valid_mail_sent(request_body)
401
+ context "adding substitutions" do
402
+ let(:deliver) { described_class.substitutions_email.deliver_now! }
403
+
404
+ it "sends mail with valid body" do
405
+ request_body = {
406
+ "from" =>
407
+ {
408
+ "email" => "default-sender@platan.us"
409
+ },
410
+ "personalizations" => [
411
+ {
412
+ "subject" => "Substitutions email",
413
+ "substitutions" =>
414
+ {
415
+ "%key1%" => "value1",
416
+ "%key2%" => "value2"
417
+ }
418
+ }
419
+ ],
420
+ "content" => [
421
+ {
422
+ "type" => "text/plain",
423
+ "value" => "X"
424
+ }
425
+ ]
426
+ }
427
+
428
+ expect_valid_sg_api_request(request_body)
429
+ end
347
430
  end
348
- end
349
431
 
350
- context "adding substitutions" do
351
- let(:deliver) { described_class.substitutions_email.deliver_now! }
432
+ context "working with recipient interceptor" do
433
+ let(:interceptor) { double(:interceptor, class: "RecipientInterceptor") }
434
+ let(:deliver) { described_class.recipients_email.deliver_now! }
435
+ let(:request_body) do
436
+ {
437
+ "from" =>
438
+ {
439
+ "email" => "default-sender@platan.us"
440
+ },
441
+ "personalizations" => [
442
+ {
443
+ "to" => [
444
+ { "email" => "interceptor1@platan.us" },
445
+ { "email" => "interceptor2@platan.us" }
446
+ ],
447
+ "subject" => "[STAGING] Recipients email",
448
+ "headers" =>
449
+ {
450
+ "X-Intercepted-To" => "r1@platan.us, r2@platan.us",
451
+ "X-Intercepted-Cc" => "r4@platan.us",
452
+ "X-Intercepted-Bcc" => "r5@platan.us"
453
+ }
454
+ }
455
+ ],
456
+ "content" => [
457
+ {
458
+ "type" => "text/plain",
459
+ "value" => "X"
460
+ }
461
+ ]
462
+ }
463
+ end
352
464
 
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" =>
363
- {
364
- "%key1%" => "value1",
365
- "%key2%" => "value2"
366
- }
367
- }
368
- ],
369
- "content" => [
370
- {
371
- "type" => "text/plain",
372
- "value" => "X"
373
- }
374
- ]
375
- }
465
+ before do
466
+ allow(interceptor).to receive(:instance_variable_get)
467
+ .with(:@recipients).and_return(["interceptor1@platan.us", "interceptor2@platan.us"])
468
+ allow(interceptor).to receive(:instance_variable_get)
469
+ .with(:@subject_prefix).and_return("[STAGING]")
470
+ allow(Mail).to receive(:class_variable_get)
471
+ .with(:@@delivery_interceptors).and_return([interceptor])
472
+ end
376
473
 
377
- expect_valid_mail_sent(request_body)
474
+ it "sends mail with valid recipients" do
475
+ expect_valid_sg_api_request(request_body)
476
+ end
378
477
  end
379
478
  end
380
479
 
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
386
-
387
- context "setting template name" do
388
- let(:deliver) { described_class.template_name_email.deliver_now! }
389
-
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)
393
-
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
- }
406
-
407
- expect_valid_mail_sent(request_body)
408
- end
480
+ context "with invalid API key" do
481
+ let(:deliver) { described_class.body_email.deliver_now! }
409
482
 
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")
483
+ before do
484
+ allow_any_instance_of(SendGridMailer::Deliverer).to receive(:api_key).and_return(nil)
414
485
  end
415
486
 
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")
421
- end
487
+ it { expect { deliver }.to raise_error(SendGridMailer::InvalidApiKey) }
422
488
  end
423
489
  end