mailgun-ruby 1.1.9 → 1.2.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +0 -0
  3. data/.rubocop_todo.yml +0 -0
  4. data/.ruby-env.yml.example +0 -0
  5. data/.travis.yml +6 -5
  6. data/CHANGELOG.md +16 -0
  7. data/Gemfile +1 -1
  8. data/README.md +27 -3
  9. data/docs/Domains.md +3 -0
  10. data/docs/OptInHandler.md +1 -1
  11. data/docs/Snippets.md +54 -61
  12. data/docs/Webhooks.md +0 -0
  13. data/docs/railgun/Overview.md +11 -0
  14. data/docs/railgun/Parameters.md +83 -0
  15. data/docs/railgun/Templates.md +92 -0
  16. data/lib/mailgun/address.rb +3 -28
  17. data/lib/mailgun/chains.rb +0 -0
  18. data/lib/mailgun/client.rb +44 -9
  19. data/lib/mailgun/domains/domains.rb +20 -2
  20. data/lib/mailgun/events/events.rb +2 -2
  21. data/lib/mailgun/exceptions/exceptions.rb +28 -1
  22. data/lib/mailgun/messages/batch_message.rb +1 -0
  23. data/lib/mailgun/messages/message_builder.rb +56 -8
  24. data/lib/mailgun/response.rb +7 -0
  25. data/lib/mailgun/suppressions.rb +15 -8
  26. data/lib/mailgun/templates/templates.rb +187 -0
  27. data/lib/mailgun/version.rb +1 -1
  28. data/lib/mailgun/webhooks/webhooks.rb +2 -2
  29. data/lib/mailgun-ruby.rb +1 -1
  30. data/lib/mailgun.rb +4 -1
  31. data/lib/railgun/mailer.rb +83 -12
  32. data/lib/railgun/message.rb +2 -1
  33. data/lib/railgun/railtie.rb +3 -2
  34. data/mailgun.gemspec +15 -12
  35. data/spec/integration/bounces_spec.rb +3 -3
  36. data/spec/integration/campaign_spec.rb +0 -0
  37. data/spec/integration/complaints_spec.rb +0 -0
  38. data/spec/integration/domains_spec.rb +8 -0
  39. data/spec/integration/email_validation_spec.rb +10 -2
  40. data/spec/integration/events_spec.rb +1 -1
  41. data/spec/integration/list_members_spec.rb +0 -0
  42. data/spec/integration/list_spec.rb +0 -0
  43. data/spec/integration/mailer_spec.rb +67 -0
  44. data/spec/integration/mailgun_spec.rb +92 -1
  45. data/spec/integration/routes_spec.rb +0 -0
  46. data/spec/integration/stats_spec.rb +0 -0
  47. data/spec/integration/suppressions_spec.rb +18 -2
  48. data/spec/integration/templates_spec.rb +135 -0
  49. data/spec/integration/unsubscribes_spec.rb +0 -0
  50. data/spec/integration/webhook_spec.rb +0 -0
  51. data/spec/spec_helper.rb +3 -1
  52. data/spec/unit/connection/test_client.rb +18 -1
  53. data/spec/unit/events/events_spec.rb +19 -0
  54. data/spec/unit/mailgun_spec.rb +43 -2
  55. data/spec/unit/messages/batch_message_spec.rb +56 -40
  56. data/spec/unit/messages/message_builder_spec.rb +149 -16
  57. data/spec/unit/messages/sample_data/unknown.type +0 -0
  58. data/spec/unit/railgun/mailer_spec.rb +388 -0
  59. data/vcr_cassettes/bounces.yml +12 -12
  60. data/vcr_cassettes/complaints.yml +0 -0
  61. data/vcr_cassettes/domains.todo.yml +0 -0
  62. data/vcr_cassettes/domains.yml +51 -1
  63. data/vcr_cassettes/email_validation.yml +5 -5
  64. data/vcr_cassettes/events.yml +0 -0
  65. data/vcr_cassettes/exceptions-invalid-api-key.yml +52 -0
  66. data/vcr_cassettes/exceptions-invalid-data.yml +52 -0
  67. data/vcr_cassettes/exceptions-not-allowed.yml +54 -0
  68. data/vcr_cassettes/list_members.yml +0 -0
  69. data/vcr_cassettes/mailer_invalid_domain.yml +109 -0
  70. data/vcr_cassettes/mailing_list.todo.yml +0 -0
  71. data/vcr_cassettes/mailing_list.yml +0 -0
  72. data/vcr_cassettes/message_deliver.yml +149 -0
  73. data/vcr_cassettes/routes.yml +0 -0
  74. data/vcr_cassettes/send_message.yml +0 -0
  75. data/vcr_cassettes/stats.yml +0 -0
  76. data/vcr_cassettes/suppressions.yml +66 -15
  77. data/vcr_cassettes/templates.yml +1065 -0
  78. data/vcr_cassettes/unsubscribes.yml +0 -0
  79. data/vcr_cassettes/webhooks.yml +0 -0
  80. metadata +49 -29
  81. data/.ruby-version +0 -1
  82. /data/spec/unit/{railgun_spec.rb → railgun/content_type_spec.rb} +0 -0
@@ -50,6 +50,16 @@ describe 'The method add_recipient' do
50
50
  expect(@mb_obj.counters[:recipients][recipient_type]).to eq(1)
51
51
  end
52
52
 
53
+ context 'when variables is empty and recepeint type - "to"' do
54
+ it 'adds email address as "to" recipient type and increments counter' do
55
+ recipient_type = :to
56
+ @mb_obj.add_recipient(recipient_type, @address, {})
57
+
58
+ expect(@mb_obj.message[recipient_type][0]).to eq("#{@address}")
59
+ expect(@mb_obj.counters[:recipients][recipient_type]).to eq(1)
60
+ end
61
+ end
62
+
53
63
  it 'adds a "cc" recipient type to the message body and counter is incremented' do
54
64
  recipient_type = :cc
55
65
  @mb_obj.add_recipient(recipient_type, @address, @variables)
@@ -246,6 +256,16 @@ describe 'The method add_attachment' do
246
256
  expect(@mb_obj.message[:attachment].length).to eq(1)
247
257
  expect(@mb_obj.message[:attachment].first.original_filename).to eq 'mailgun_icon.png'
248
258
  end
259
+
260
+ context 'when attachment has unknown type' do
261
+ it 'sets content type application/octet-stream for attachment' do
262
+ file = File.dirname(__FILE__) + "/sample_data/unknown.type"
263
+
264
+ @mb_obj.add_attachment(file)
265
+
266
+ expect(@mb_obj.message[:attachment][0].content_type).to eq('application/octet-stream')
267
+ end
268
+ end
249
269
  end
250
270
 
251
271
  describe 'The method add_inline_image' do
@@ -293,7 +313,7 @@ describe 'The method set_test_mode' do
293
313
  it 'warns of set_test_mode deprecation' do
294
314
  @mb_obj = Mailgun::MessageBuilder.new
295
315
  expect(@mb_obj).to receive :warn
296
- @mb_obj.set_test_mode 'warn on set_test_mode'
316
+ @mb_obj.set_test_mode 'Yes'
297
317
  end
298
318
  end
299
319
 
@@ -335,7 +355,7 @@ describe 'The method set_dkim' do
335
355
  it 'warns of set_dkim deprecation' do
336
356
  @mb_obj = Mailgun::MessageBuilder.new
337
357
  expect(@mb_obj).to receive :warn
338
- @mb_obj.set_dkim 'warn on set_dkim'
358
+ @mb_obj.set_dkim 'Yes'
339
359
  end
340
360
  end
341
361
 
@@ -429,7 +449,7 @@ describe 'The method set_open_tracking' do
429
449
  it 'warns of set_open_tracking deprecation' do
430
450
  @mb_obj = Mailgun::MessageBuilder.new
431
451
  expect(@mb_obj).to receive :warn
432
- @mb_obj.set_open_tracking 'warn on set_open_tracking'
452
+ @mb_obj.set_open_tracking 'Yes'
433
453
  end
434
454
  end
435
455
 
@@ -440,19 +460,20 @@ describe 'The method track_opens' do
440
460
  it 'enables/disables open tracking on a per message basis.' do
441
461
  @mb_obj.track_opens('Yes')
442
462
 
443
- expect(@mb_obj.message["o:tracking-opens"][0]).to eq("yes")
463
+ expect(@mb_obj.message["o:tracking-opens"]).to eq("yes")
464
+ expect(@mb_obj.message["o:tracking"]).to eq(["yes"])
444
465
 
445
466
  @mb_obj.track_opens('No')
446
467
 
447
- expect(@mb_obj.message["o:tracking-opens"][0]).to eq("no")
468
+ expect(@mb_obj.message["o:tracking-opens"]).to eq("no")
448
469
 
449
470
  @mb_obj.track_opens(true)
450
471
 
451
- expect(@mb_obj.message["o:tracking-opens"][0]).to eq("yes")
472
+ expect(@mb_obj.message["o:tracking-opens"]).to eq("yes")
452
473
 
453
474
  @mb_obj.track_opens(false)
454
475
 
455
- expect(@mb_obj.message["o:tracking-opens"][0]).to eq("no")
476
+ expect(@mb_obj.message["o:tracking-opens"]).to eq("no")
456
477
  end
457
478
  end
458
479
 
@@ -460,7 +481,7 @@ describe 'The method set_click_tracking' do
460
481
  it 'warns of set_click_tracking deprecation' do
461
482
  @mb_obj = Mailgun::MessageBuilder.new
462
483
  expect(@mb_obj).to receive :warn
463
- @mb_obj.set_click_tracking 'warn on set_click_tracking'
484
+ @mb_obj.set_click_tracking 'Yes'
464
485
  end
465
486
  end
466
487
 
@@ -471,23 +492,31 @@ describe 'The method track_clicks' do
471
492
  it 'enables/disables click tracking on a per message basis.' do
472
493
  @mb_obj.track_clicks('Yes')
473
494
 
474
- expect(@mb_obj.message["o:tracking-clicks"][0]).to eq("yes")
495
+ expect(@mb_obj.message["o:tracking-clicks"]).to eq("yes")
496
+ expect(@mb_obj.message["o:tracking"]).to eq(["yes"])
475
497
 
476
498
  @mb_obj.track_clicks('No')
477
499
 
478
- expect(@mb_obj.message["o:tracking-clicks"][0]).to eq("no")
500
+ expect(@mb_obj.message["o:tracking-clicks"]).to eq("no")
479
501
 
480
502
  @mb_obj.track_clicks(true)
481
503
 
482
- expect(@mb_obj.message["o:tracking-clicks"][0]).to eq("yes")
504
+ expect(@mb_obj.message["o:tracking-clicks"]).to eq("yes")
483
505
 
484
506
  @mb_obj.track_clicks(false)
485
507
 
486
- expect(@mb_obj.message["o:tracking-clicks"][0]).to eq("no")
508
+ expect(@mb_obj.message["o:tracking-clicks"]).to eq("no")
487
509
 
488
510
  @mb_obj.track_clicks('html')
489
511
 
490
- expect(@mb_obj.message["o:tracking-clicks"][0]).to eq("html")
512
+ expect(@mb_obj.message["o:tracking-clicks"]).to eq("html")
513
+ end
514
+
515
+ context 'when unexpected value is provided' do
516
+ it 'warns about preferred values' do
517
+ expect(@mb_obj).to receive :warn
518
+ @mb_obj.track_clicks('random')
519
+ end
491
520
  end
492
521
  end
493
522
 
@@ -547,9 +576,13 @@ describe 'The method variable' do
547
576
  expect(@mb_obj.message["v:my-data"]).to be_kind_of(String)
548
577
  expect(@mb_obj.message["v:my-data"].to_s).to eq('{"key":"value"}')
549
578
  end
550
- it 'throws an exception on broken JSON.' do
551
- data = 'This is some crappy JSON.'
552
- expect {@mb_obj.variable('my-data', data)}.to raise_error(Mailgun::ParameterError)
579
+ it 'accepts string values' do
580
+ data = 'String Value.'
581
+
582
+ @mb_obj.variable('my-data', data)
583
+
584
+ expect(@mb_obj.message["v:my-data"]).to be_kind_of(String)
585
+ expect(@mb_obj.message["v:my-data"].to_s).to eq('String Value.')
553
586
  end
554
587
  end
555
588
 
@@ -597,3 +630,103 @@ describe 'The method message_id' do
597
630
  expect(@mb_obj.message.has_key?('h:Message-Id')).to eq(false)
598
631
  end
599
632
  end
633
+
634
+ describe 'The method template' do
635
+ before(:each) do
636
+ @mb_obj = Mailgun::MessageBuilder.new
637
+ end
638
+ context 'when template name is passed' do
639
+ it 'sets `template` to the message' do
640
+ template_name = 'template.name'
641
+ @mb_obj.template(template_name)
642
+
643
+ expect(@mb_obj.message['template']).to eq(template_name)
644
+ end
645
+ end
646
+
647
+ context 'when multiple values are passed' do
648
+ it 'sets the last value as message template' do
649
+ template_name_1 = 'template.name_1'
650
+ template_name_2 = 'template.name_2'
651
+
652
+ @mb_obj.template(template_name_1)
653
+ @mb_obj.template(template_name_2)
654
+
655
+ expect(@mb_obj.message['template']).to eq(template_name_2)
656
+ end
657
+ end
658
+
659
+ context 'when template name is not passed' do
660
+ it 'it deletes `template` key from the message' do
661
+ @mb_obj.template('template.name')
662
+
663
+ expect(@mb_obj.message.has_key?('template')).to eq(true)
664
+
665
+ @mb_obj.template
666
+
667
+ expect(@mb_obj.message.has_key?('template')).to eq(false)
668
+ end
669
+ end
670
+ end
671
+
672
+ describe 'The method template_version' do
673
+ before(:each) do
674
+ @mb_obj = Mailgun::MessageBuilder.new
675
+ end
676
+ context 'when template version is passed' do
677
+ it 'adds `t:version` key value to the message' do
678
+ version = 'version_1'
679
+ @mb_obj.template_version(version)
680
+
681
+ expect(@mb_obj.message['t:version']).to eq(version)
682
+ end
683
+ end
684
+
685
+ context 'when multiple values are passed' do
686
+ it 'adds the last value as `t:version` key value to the message' do
687
+ version_1 = 'version_1'
688
+ version_2 = 'version_2'
689
+
690
+ @mb_obj.template_version(version_1)
691
+ @mb_obj.template_version(version_2)
692
+
693
+ expect(@mb_obj.message['t:version']).to eq(version_2)
694
+ end
695
+ end
696
+
697
+ context 'when version is not passed' do
698
+ it 'it deletes `t:version` key from the message' do
699
+ @mb_obj.template_version('version')
700
+
701
+ expect(@mb_obj.message.has_key?('t:version')).to eq(true)
702
+
703
+ @mb_obj.template_version
704
+
705
+ expect(@mb_obj.message.has_key?('t:version')).to eq(false)
706
+ end
707
+ end
708
+ end
709
+
710
+ describe 'The method template_text' do
711
+ before(:each) do
712
+ @mb_obj = Mailgun::MessageBuilder.new
713
+ end
714
+
715
+ it 'enables/disables rendering in the text part of the message in case of template sending' do
716
+ @mb_obj.template_text('Yes')
717
+
718
+ expect(@mb_obj.message["t:text"]).to eq("yes")
719
+
720
+ @mb_obj.template_text('No')
721
+
722
+ expect(@mb_obj.message["t:text"]).to eq("no")
723
+
724
+ @mb_obj.template_text(true)
725
+
726
+ expect(@mb_obj.message["t:text"]).to eq("yes")
727
+
728
+ @mb_obj.template_text(false)
729
+
730
+ expect(@mb_obj.message["t:text"]).to eq("no")
731
+ end
732
+ end
File without changes
@@ -0,0 +1,388 @@
1
+ require 'json'
2
+ require 'logger'
3
+ require 'spec_helper'
4
+ require 'mailgun'
5
+ require 'railgun'
6
+
7
+ ActionMailer::Base.raise_delivery_errors = true
8
+ ActionMailer::Base.delivery_method = :test
9
+ Rails.logger = Logger.new('/dev/null')
10
+ Rails.logger.level = Logger::DEBUG
11
+
12
+ class UnitTestMailer < ActionMailer::Base
13
+ default from: 'unittest@example.org'
14
+
15
+ def plain_message(address, subject, headers)
16
+ headers(headers)
17
+ mail(to: address, subject: subject) do |format|
18
+ format.text { render plain: "Test!" }
19
+ format.html { render html: "<p>Test!</p>".html_safe }
20
+ end
21
+ end
22
+
23
+ def message_with_attachment(address, subject)
24
+ attachments['info.txt'] = {
25
+ :content => File.read('docs/railgun/Overview.md'),
26
+ :mime_type => 'text/plain',
27
+ }
28
+ mail(to: address, subject: subject) do |format|
29
+ format.text { render plain: "Test!" }
30
+ format.html { render html: "<p>Test!</p>".html_safe }
31
+ end
32
+ end
33
+
34
+ def message_with_template(address, subject, template_name)
35
+ mail(to: address, subject: subject, template: template_name) do |format|
36
+ format.text { render plain: "Test!" }
37
+ end
38
+ end
39
+
40
+ def message_with_domain(address, subject, domain)
41
+ mail(to: address, subject: subject, domain: domain) do |format|
42
+ format.text { render plain: "Test!" }
43
+ end
44
+ end
45
+
46
+ end
47
+
48
+ describe 'Railgun::Mailer' do
49
+
50
+ it 'has a mailgun_client property which returns a Mailgun::Client' do
51
+ config = {
52
+ api_key: {},
53
+ domain: {}
54
+ }
55
+ @mailer_obj = Railgun::Mailer.new(config)
56
+
57
+ expect(@mailer_obj.mailgun_client).to be_a(Mailgun::Client)
58
+ end
59
+
60
+ context 'when config does not have api_key or domain' do
61
+ it 'raises configuration error' do
62
+ config = {
63
+ api_key: {}
64
+ }
65
+
66
+ expect { Railgun::Mailer.new(config) }.to raise_error(Railgun::ConfigurationError)
67
+ end
68
+ end
69
+
70
+ context 'when fake_message_send is present in config' do
71
+ it 'enables test mode' do
72
+ config = {
73
+ api_key: {},
74
+ domain: {},
75
+ fake_message_send: true
76
+ }
77
+ client_double = double(Mailgun::Client)
78
+ allow(Mailgun::Client).to receive(:new).and_return(client_double)
79
+ expect(client_double).to receive(:enable_test_mode!)
80
+
81
+ Railgun::Mailer.new(config)
82
+ end
83
+ end
84
+
85
+ it 'properly creates a message body' do
86
+ message = UnitTestMailer.plain_message('test@example.org', 'Test!', {})
87
+ body = Railgun.transform_for_mailgun(message)
88
+
89
+ [:from, :subject, :text, :html, 'to'].each do |param|
90
+ expect(body).to include(param)
91
+ end
92
+
93
+ expect(body[:from][0].value).to eq('unittest@example.org')
94
+ expect(body['to']).to eq(['test@example.org'])
95
+ expect(body[:subject]).to eq(['Test!'])
96
+ expect(body[:text]).to eq(['Test!'])
97
+ expect(body[:html]).to eq(['<p>Test!</p>'.html_safe])
98
+ end
99
+
100
+ it 'adds options to message body' do
101
+ message = UnitTestMailer.plain_message('test@example.org', '', {})
102
+ message.mailgun_options ||= {
103
+ 'tracking-opens' => 'true',
104
+ }
105
+
106
+ body = Railgun.transform_for_mailgun(message)
107
+
108
+ expect(body).to include('o:tracking-opens')
109
+ expect(body['o:tracking-opens']).to eq('true')
110
+ end
111
+
112
+ it 'accepts frozen options to message body' do
113
+ message = UnitTestMailer.plain_message('test@example.org', '', {})
114
+ message.mailgun_options ||= {
115
+ 'tags' => ['some-tag']
116
+ }
117
+
118
+ body = Railgun.transform_for_mailgun(message)
119
+
120
+ expect(body).to include('o:tags')
121
+ expect(body['o:tags']).to eq(['some-tag'])
122
+ end
123
+
124
+ it 'adds variables to message body' do
125
+ message = UnitTestMailer.plain_message('test@example.org', '', {})
126
+ message.mailgun_variables ||= {
127
+ 'user' => {:id => '1', :name => 'tstark'},
128
+ }
129
+
130
+ body = Railgun.transform_for_mailgun(message)
131
+
132
+ expect(body).to include('v:user')
133
+
134
+ var_body = JSON.load(body['v:user'])
135
+ expect(var_body).to include('id')
136
+ expect(var_body).to include('name')
137
+ expect(var_body['id']).to eq('1')
138
+ expect(var_body['name']).to eq('tstark')
139
+ end
140
+
141
+ it 'adds headers to message body' do
142
+ message = UnitTestMailer.plain_message('test@example.org', '', {})
143
+ message.mailgun_headers ||= {
144
+ 'x-unit-test' => 'true',
145
+ }
146
+
147
+ body = Railgun.transform_for_mailgun(message)
148
+
149
+ expect(body).to include('h:x-unit-test')
150
+ expect(body['h:x-unit-test']).to eq('true')
151
+ end
152
+
153
+ it 'adds headers to message body from mailer' do
154
+ message = UnitTestMailer.plain_message('test@example.org', '', {
155
+ 'x-unit-test-2' => 'true',
156
+ })
157
+
158
+ body = Railgun.transform_for_mailgun(message)
159
+
160
+ expect(body).to include('h:x-unit-test-2')
161
+ expect(body['h:x-unit-test-2']).to eq('true')
162
+ end
163
+
164
+ it 'properly handles headers that are passed as separate POST params' do
165
+ message = UnitTestMailer.plain_message('test@example.org', 'Test!', {
166
+ # `From`, `To`, and `Subject` are set on the envelope, so they should be ignored as headers
167
+ 'From' => 'units@example.net',
168
+ 'To' => 'user@example.com',
169
+ 'Subject' => 'This should disappear',
170
+ # If `Bcc` or `Cc` are set as headers, they should be carried over as POST params, not headers
171
+ 'Bcc' => ['list@example.org'],
172
+ 'Cc' => ['admin@example.com'],
173
+ # This is an arbitrary header and should be carried over properly
174
+ 'X-Source' => 'unit tests',
175
+ })
176
+
177
+ body = Railgun.transform_for_mailgun(message)
178
+
179
+ ['From', 'To', 'Subject'].each do |header|
180
+ expect(body).not_to include("h:#{header}")
181
+ end
182
+
183
+ ['bcc', 'cc', 'to', 'h:x-source'].each do |param|
184
+ expect(body).to include(param)
185
+ end
186
+
187
+ expect(body[:from][0].value).to eq('unittest@example.org')
188
+ expect(body['to']).to eq(['test@example.org'])
189
+ expect(body[:subject]).to eq(['Test!'])
190
+ expect(body[:text]).to eq(['Test!'])
191
+ expect(body[:html]).to eq(['<p>Test!</p>'.html_safe])
192
+ expect(body['bcc']).to eq(['list@example.org'])
193
+ expect(body['cc']).to eq(['admin@example.com'])
194
+ expect(body['h:x-source']).to eq('unit tests')
195
+ end
196
+
197
+ context 'when mailgun_variables are present' do
198
+ it 'accepts valid JSON and stores it as message[param].' do
199
+ message = UnitTestMailer.plain_message('test@example.org', '', {}).tap do |message|
200
+ message.mailgun_variables = {
201
+ 'my-data' => '{"key":"value"}'
202
+ }
203
+ end
204
+ body = Railgun.transform_for_mailgun(message)
205
+ expect(body["v:my-data"]).to be_kind_of(String)
206
+ expect(body["v:my-data"].to_s).to eq('{"key":"value"}')
207
+ end
208
+
209
+ it 'accepts a hash and appends as data to the message.' do
210
+ message = UnitTestMailer.plain_message('test@example.org', '', {}).tap do |message|
211
+ message.mailgun_variables = {
212
+ 'my-data' => {'key' => 'value'}
213
+ }
214
+ end
215
+ body = Railgun.transform_for_mailgun(message)
216
+
217
+ expect(body["v:my-data"]).to be_kind_of(String)
218
+ expect(body["v:my-data"].to_s).to eq('{"key":"value"}')
219
+ end
220
+
221
+ it 'accepts string values' do
222
+ message = UnitTestMailer.plain_message('test@example.org', '', {}).tap do |message|
223
+ message.mailgun_variables = {
224
+ 'my-data' => 'String Value.'
225
+ }
226
+ end
227
+ body = Railgun.transform_for_mailgun(message)
228
+
229
+ expect(body["v:my-data"]).to be_kind_of(String)
230
+ expect(body["v:my-data"].to_s).to eq('String Value.')
231
+ end
232
+ end
233
+
234
+ it 'properly adds attachments' do
235
+ message = UnitTestMailer.message_with_attachment('test@example.org', '')
236
+ body = Railgun.transform_for_mailgun(message)
237
+
238
+ expect(body).to include(:attachment)
239
+ attachment = body[:attachment][0]
240
+
241
+ expect(attachment.filename).to eq('info.txt')
242
+ expect(attachment.content_type).to eq('text/plain')
243
+ end
244
+
245
+ it 'delivers!' do
246
+ message = UnitTestMailer.plain_message('test@example.org', '', {})
247
+ message.deliver_now
248
+
249
+ expect(ActionMailer::Base.deliveries).to include(message)
250
+ end
251
+
252
+ it 'ignores `reply-to` in headers' do
253
+ message = UnitTestMailer.plain_message('test@example.org', '', {
254
+ 'reply-to' => 'user@example.com',
255
+ })
256
+ message.mailgun_headers = {
257
+ 'Reply-To' => 'administrator@example.org',
258
+ }
259
+ message.headers({'REPLY-TO' => 'admin@example.net'})
260
+ message.reply_to = "dude@example.com.au"
261
+
262
+ body = Railgun.transform_for_mailgun(message)
263
+ expect(body).to include('h:reply-to')
264
+ expect(body).not_to include('h:Reply-To')
265
+ expect(body['h:reply-to']).to eq('dude@example.com.au')
266
+ end
267
+
268
+ it 'ignores `mime-version` in headers' do
269
+ message = UnitTestMailer.plain_message('test@example.org', '', {
270
+ 'mime-version' => '1.0',
271
+ })
272
+ message.mailgun_headers = {
273
+ 'Mime-Version' => '1.1',
274
+ }
275
+ message.headers({'MIME-VERSION' => '1.2'})
276
+
277
+ body = Railgun.transform_for_mailgun(message)
278
+ expect(body).not_to include('h:mime-version')
279
+ end
280
+
281
+ it 'treats `headers()` names as case-insensitve' do
282
+ message = UnitTestMailer.plain_message('test@example.org', '', {
283
+ 'X-BIG-VALUE' => 1,
284
+ })
285
+
286
+ body = Railgun.transform_for_mailgun(message)
287
+ expect(body).to include('h:x-big-value')
288
+ expect(body['h:x-big-value']).to eq("1")
289
+ end
290
+
291
+ it 'treats `mailgun_headers` names as case-insensitive' do
292
+ message = UnitTestMailer.plain_message('test@example.org', '', {})
293
+ message.mailgun_headers = {
294
+ 'X-BIG-VALUE' => 1,
295
+ }
296
+
297
+ body = Railgun.transform_for_mailgun(message)
298
+ expect(body).to include('h:x-big-value')
299
+ expect(body['h:x-big-value']).to eq("1")
300
+ end
301
+
302
+ it 'handles multi-value, mixed case headers correctly' do
303
+ message = UnitTestMailer.plain_message('test@example.org', '', {})
304
+ message.headers({
305
+ 'x-neat-header' => 'foo',
306
+ 'X-Neat-Header' => 'bar',
307
+ 'X-NEAT-HEADER' => 'zoop',
308
+ })
309
+
310
+ body = Railgun.transform_for_mailgun(message)
311
+ expect(body).to include('h:x-neat-header')
312
+ expect(body['h:x-neat-header']).to include('foo')
313
+ expect(body['h:x-neat-header']).to include('bar')
314
+ expect(body['h:x-neat-header']).to include('zoop')
315
+ end
316
+
317
+ context 'when message with template' do
318
+ it 'adds template header to message from mailer params' do
319
+ template_name = 'template.name'
320
+ message = UnitTestMailer.message_with_template('test@example.org', '', template_name)
321
+
322
+ body = Railgun.transform_for_mailgun(message)
323
+
324
+ expect(body).to include('template')
325
+ expect(body['template']).to eq(template_name)
326
+ end
327
+
328
+ context 'when mailgun_template_variables are assigned' do
329
+ it 'adds template variables to message body' do
330
+ message = UnitTestMailer.message_with_template('test@example.org', '', 'template.name')
331
+ version = 'version_1'
332
+ message.mailgun_template_variables ||= {
333
+ 'version' => version,
334
+ 'text' => 'yes'
335
+ }
336
+
337
+ body = Railgun.transform_for_mailgun(message)
338
+
339
+ expect(body).to include('t:version')
340
+ expect(body['t:version']).to eq('version_1')
341
+ expect(body).to include('t:text')
342
+ expect(body['t:text']).to eq('yes')
343
+ end
344
+ end
345
+ end
346
+
347
+ describe 'deliver!' do
348
+ let(:config) do
349
+ {
350
+ api_key: 'api_key',
351
+ domain: 'domain'
352
+ }
353
+ end
354
+ let(:mail) { UnitTestMailer.plain_message('test@example.org', '', {}) }
355
+ let(:response) do
356
+ response = Struct.new(:code, :id)
357
+ response.new(200, rand(50..100))
358
+ end
359
+
360
+ it 'initiates client message send' do
361
+ result = { from: 'test@example.org' }
362
+ allow(Railgun).to receive(:transform_for_mailgun).and_return(result)
363
+
364
+ expect_any_instance_of(Mailgun::Client).to receive(:send_message)
365
+ .with(config[:domain], result)
366
+ .and_return(response)
367
+ Railgun::Mailer.new(config).deliver!(mail)
368
+ end
369
+
370
+ it 'returns response' do
371
+ expect_any_instance_of(Mailgun::Client).to receive(:send_message).and_return(response)
372
+ expect(Railgun::Mailer.new(config).deliver!(mail)).to eq(response)
373
+ end
374
+
375
+ context 'when domain is provided in arguments' do
376
+ let(:new_domain) { 'new_domain' }
377
+ let(:mail) { UnitTestMailer.message_with_domain('test@example.org', '', new_domain) }
378
+
379
+ it 'uses provided domain' do
380
+ result = { from: 'test@example.org' }
381
+ allow(Railgun).to receive(:transform_for_mailgun).and_return(result)
382
+ expect_any_instance_of(Mailgun::Client).to receive(:send_message)
383
+ .with(new_domain, result).and_return(response)
384
+ Railgun::Mailer.new(config).deliver!(mail)
385
+ end
386
+ end
387
+ end
388
+ end