send_grid_mailer 0.5.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.circleci/config.yml +102 -0
- data/.circleci/setup-rubygems.sh +3 -0
- data/.rubocop.yml +31 -591
- data/.ruby-version +1 -1
- data/CHANGELOG.md +39 -0
- data/README.md +69 -8
- data/lib/send_grid_mailer/api.rb +42 -0
- data/lib/send_grid_mailer/definition.rb +35 -23
- data/lib/send_grid_mailer/deliverer.rb +12 -35
- data/lib/send_grid_mailer/dev_deliverer.rb +70 -0
- data/lib/send_grid_mailer/engine.rb +7 -3
- data/lib/send_grid_mailer/errors.rb +20 -1
- data/lib/send_grid_mailer/interceptor/recipient_interceptor.rb +42 -0
- data/lib/send_grid_mailer/interceptors_handler.rb +14 -0
- data/lib/send_grid_mailer/logger.rb +36 -40
- data/lib/send_grid_mailer/mailer_base_ext.rb +18 -7
- data/lib/send_grid_mailer/version.rb +1 -1
- data/send_grid_mailer.gemspec +12 -6
- data/spec/dummy/Rakefile +1 -1
- data/spec/dummy/app/assets/config/manifest.js +3 -0
- data/spec/dummy/app/assets/stylesheets/application.css +3 -3
- data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
- data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
- data/spec/dummy/app/controllers/application_controller.rb +0 -3
- data/spec/dummy/app/{assets/javascripts → javascript/packs}/application.js +3 -1
- data/spec/dummy/app/jobs/application_job.rb +7 -0
- data/spec/dummy/app/mailers/application_mailer.rb +1 -1
- data/spec/dummy/app/mailers/test_mailer.rb +12 -5
- data/spec/dummy/app/models/application_record.rb +3 -0
- data/spec/dummy/app/views/layouts/application.html.erb +10 -9
- data/spec/dummy/bin/rails +3 -3
- data/spec/dummy/bin/rake +2 -2
- data/spec/dummy/bin/setup +18 -14
- data/spec/dummy/config.ru +3 -1
- data/spec/dummy/config/application.rb +12 -22
- data/spec/dummy/config/boot.rb +3 -3
- data/spec/dummy/config/cable.yml +10 -0
- data/spec/dummy/config/database.yml +2 -2
- data/spec/dummy/config/environment.rb +1 -1
- data/spec/dummy/config/environments/development.rb +48 -18
- data/spec/dummy/config/environments/production.rb +63 -22
- data/spec/dummy/config/environments/test.rb +29 -12
- data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
- data/spec/dummy/config/initializers/assets.rb +4 -3
- data/spec/dummy/config/initializers/backtrace_silencers.rb +4 -3
- data/spec/dummy/config/initializers/content_security_policy.rb +28 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +2 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +3 -1
- data/spec/dummy/config/initializers/permissions_policy.rb +11 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +2 -2
- data/spec/dummy/config/locales/en.yml +11 -1
- data/spec/dummy/config/puma.rb +43 -0
- data/spec/dummy/config/routes.rb +1 -54
- data/spec/dummy/config/storage.yml +34 -0
- data/spec/dummy/public/404.html +6 -6
- data/spec/dummy/public/422.html +6 -6
- data/spec/dummy/public/500.html +6 -6
- data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
- data/spec/dummy/public/apple-touch-icon.png +0 -0
- data/spec/dummy/spec/lib/send_grid_mailer/definition_spec.rb +52 -23
- data/spec/dummy/spec/mailers/test_mailer_spec.rb +558 -327
- data/spec/rails_helper.rb +5 -7
- metadata +127 -43
- data/.hound.yml +0 -4
- data/.travis.yml +0 -15
- data/lib/send_grid_mailer/mail_message_ext.rb +0 -7
- data/spec/dummy/bin/bundle +0 -3
- data/spec/dummy/config/initializers/session_store.rb +0 -3
- data/spec/dummy/config/secrets.yml +0 -22
- data/spec/dummy/db/schema.rb +0 -16
- 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
|
-
|
5
|
-
|
6
|
-
|
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
|
10
|
-
result = double(status_code:
|
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
|
-
|
19
|
-
|
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
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
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
|
-
|
41
|
-
|
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
|
45
|
-
|
54
|
+
context "when setting delivery_method to :sendgrid" do
|
55
|
+
before { allow(TestMailer).to receive(:delivery_method).and_return(:sendgrid) }
|
46
56
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
"
|
54
|
-
{
|
55
|
-
"
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
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
|
-
|
67
|
-
|
68
|
-
|
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
|
-
|
71
|
-
|
97
|
+
context "when setting body" do
|
98
|
+
let(:deliver) { described_class.body_email.deliver_now! }
|
72
99
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
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
|
-
|
93
|
-
|
94
|
-
|
119
|
+
expect_valid_sg_api_send_mail_request(request_body)
|
120
|
+
end
|
121
|
+
end
|
95
122
|
|
96
|
-
|
97
|
-
|
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
|
-
|
118
|
-
|
119
|
-
|
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
|
-
|
122
|
-
|
145
|
+
expect_valid_sg_api_send_mail_request(request_body)
|
146
|
+
end
|
123
147
|
end
|
124
|
-
end
|
125
148
|
|
126
|
-
|
127
|
-
|
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
|
-
|
131
|
-
|
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
|
-
|
137
|
-
|
138
|
-
{
|
139
|
-
"from" =>
|
175
|
+
context "when overriding default from" do
|
176
|
+
let(:request_body) do
|
140
177
|
{
|
141
|
-
"
|
142
|
-
},
|
143
|
-
"personalizations" => [
|
144
|
-
{
|
145
|
-
"to" => [
|
178
|
+
"from" =>
|
146
179
|
{
|
147
|
-
"email" => "
|
180
|
+
"email" => "override@platan.us"
|
148
181
|
},
|
182
|
+
"personalizations" => [
|
149
183
|
{
|
150
|
-
"
|
184
|
+
"subject" => subject
|
151
185
|
}
|
152
186
|
],
|
153
|
-
"
|
187
|
+
"content" => [
|
154
188
|
{
|
155
|
-
"
|
189
|
+
"type" => "text/plain",
|
190
|
+
"value" => "X"
|
156
191
|
}
|
157
|
-
]
|
158
|
-
|
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
|
-
"
|
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
|
-
"
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
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
|
-
|
176
|
-
|
177
|
-
|
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
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
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
|
-
|
185
|
-
|
186
|
-
|
263
|
+
context "when using methods" do
|
264
|
+
let(:deliver) { described_class.recipients_email.deliver_now! }
|
265
|
+
let(:subject) { "Recipients email" }
|
187
266
|
|
188
|
-
|
189
|
-
|
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
|
-
|
195
|
-
|
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
|
-
"
|
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
|
-
|
211
|
-
|
212
|
-
|
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
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
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
|
-
|
220
|
-
|
221
|
-
|
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
|
-
|
224
|
-
|
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
|
-
|
230
|
-
|
231
|
-
{
|
232
|
-
"from" =>
|
308
|
+
context "when setting subject" do
|
309
|
+
let(:request_body) do
|
233
310
|
{
|
234
|
-
"
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
"
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
"
|
244
|
-
|
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
|
-
|
251
|
-
|
329
|
+
context "when using params" do
|
330
|
+
let(:deliver) { described_class.subject_params_email.deliver_now! }
|
252
331
|
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
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
|
-
|
259
|
-
|
337
|
+
context "when using methods" do
|
338
|
+
let(:deliver) { described_class.subject_email.deliver_now! }
|
260
339
|
|
261
|
-
|
262
|
-
|
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
|
-
|
268
|
-
|
269
|
-
{
|
270
|
-
"from" =>
|
346
|
+
context "when setting headers" do
|
347
|
+
let(:request_body) do
|
271
348
|
{
|
272
|
-
"
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
"
|
277
|
-
"headers" =>
|
349
|
+
"from" =>
|
350
|
+
{
|
351
|
+
"email" => "default-sender@platan.us"
|
352
|
+
},
|
353
|
+
"personalizations" => [
|
278
354
|
{
|
279
|
-
"
|
280
|
-
"
|
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
|
-
|
294
|
-
|
295
|
-
|
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
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
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
|
-
|
303
|
-
|
304
|
-
|
381
|
+
context "when using methods" do
|
382
|
+
let(:deliver) { described_class.headers_email.deliver_now! }
|
383
|
+
let(:subject) { "Headers email" }
|
305
384
|
|
306
|
-
|
307
|
-
|
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
|
-
|
313
|
-
|
391
|
+
context "when adding attachments" do
|
392
|
+
let(:deliver) { described_class.add_attachments_email.deliver_now! }
|
314
393
|
|
315
|
-
|
316
|
-
|
317
|
-
|
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
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
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
|
-
|
347
|
-
|
348
|
-
|
425
|
+
expect_valid_sg_api_send_mail_request(request_body)
|
426
|
+
end
|
427
|
+
end
|
349
428
|
|
350
|
-
|
351
|
-
|
429
|
+
context "when adding substitutions" do
|
430
|
+
let(:deliver) { described_class.substitutions_email.deliver_now! }
|
352
431
|
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
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
|
-
"
|
365
|
-
"
|
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
|
-
|
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
|
-
"
|
372
|
-
|
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
|
-
|
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
|
-
|
382
|
-
|
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
|
-
|
388
|
-
|
511
|
+
before do
|
512
|
+
allow_any_instance_of(SendGridMailer::Deliverer).to receive(:api_key).and_return(nil)
|
513
|
+
end
|
389
514
|
|
390
|
-
|
391
|
-
|
392
|
-
|
515
|
+
it { expect { deliver }.to raise_error(SendGridMailer::InvalidApiKey) }
|
516
|
+
end
|
517
|
+
end
|
393
518
|
|
394
|
-
|
395
|
-
|
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
|
-
|
408
|
-
|
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
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
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
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
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
|