mailgun-ruby 1.1.8 → 1.2.3

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.
data/mailgun.gemspec CHANGED
@@ -22,16 +22,16 @@ Gem::Specification.new do |spec|
22
22
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
23
23
  spec.require_paths = ["lib"]
24
24
 
25
- spec.required_ruby_version = '>= 2.0.0'
26
-
27
- spec.add_development_dependency 'bundler', '~> 1.5'
28
- spec.add_development_dependency 'rspec', '~> 3.0'
29
- spec.add_development_dependency 'rake', '~> 10.0'
30
- spec.add_development_dependency 'webmock', '~> 1.22'
31
- spec.add_development_dependency 'pry', '~> 0.9'
32
- spec.add_development_dependency 'vcr', '~> 3.0'
33
- spec.add_development_dependency 'simplecov', '~> 0.11'
34
-
35
- spec.add_dependency 'rest-client', '~> 2.0'
25
+ spec.required_ruby_version = '>= 2.2.2'
26
+
27
+ spec.add_development_dependency 'bundler', '>= 1.16.2'
28
+ spec.add_development_dependency 'rspec', '~> 3.8.0'
29
+ spec.add_development_dependency 'rake', '~> 12.3.2'
30
+ spec.add_development_dependency 'webmock', '~> 3.4.2'
31
+ spec.add_development_dependency 'pry', '~> 0.11.3'
32
+ spec.add_development_dependency 'vcr', '~> 3.0.3'
33
+ spec.add_development_dependency 'simplecov', '~> 0.16.1'
34
+ spec.add_development_dependency 'rails'
35
+ spec.add_dependency 'rest-client', '>= 2.0.2'
36
36
 
37
37
  end
@@ -28,7 +28,11 @@ describe 'For the email validation endpoint', order: :defined, vcr: vcr_opts do
28
28
  expected = {
29
29
  "address" => "alice@mailgun.net",
30
30
  "did_you_mean" => nil,
31
+ "is_disposable_address" => false,
32
+ "is_role_address" => false,
31
33
  "is_valid" => true,
34
+ "mailbox_verification" => "true",
35
+ "reason" => nil,
32
36
  "parts" => {
33
37
  "display_name" => nil,
34
38
  "domain" => "mailgun.net",
@@ -50,7 +54,11 @@ describe 'For the email validation endpoint', order: :defined, vcr: vcr_opts do
50
54
  expected = {
51
55
  "address" => "example.org",
52
56
  "did_you_mean" => nil,
57
+ "is_disposable_address" => false,
58
+ "is_role_address" => false,
53
59
  "is_valid" => false,
60
+ "mailbox_verification" => "unknown",
61
+ "reason" => "Validation failed for 'example.org', reason: 'malformed address; missing @ sign'",
54
62
  "parts" => {
55
63
  "display_name" => nil,
56
64
  "domain" => nil,
@@ -22,7 +22,7 @@ describe 'For the Events endpoint', vcr: vcr_opts do
22
22
 
23
23
  it 'can iterate over all events with `each`' do
24
24
  @events.each do |e|
25
- expect(e.id).to eq("JAx9z641TuGGUyaJlD9sCQ")
25
+ expect(e["id"]).to eq("JAx9z641TuGGUyaJlD9sCQ")
26
26
  end
27
27
  end
28
28
  end
@@ -52,7 +52,7 @@ describe 'For the suppressions handling class', order: :defined, vcr: vcr_opts d
52
52
  end
53
53
  end
54
54
 
55
- it 'can batch-add unsubscribes' do
55
+ it 'can batch-add unsubscribes with tags as string' do
56
56
  unsubscribes = []
57
57
  @addresses.each do |addr|
58
58
  unsubscribes.push({
@@ -69,6 +69,23 @@ describe 'For the suppressions handling class', order: :defined, vcr: vcr_opts d
69
69
  expect(nested.length).to eq(0)
70
70
  end
71
71
 
72
+ it 'can batch-add unsubscribes with tags as array' do
73
+ unsubscribes = []
74
+ @addresses.each do |addr|
75
+ unsubscribes.push({
76
+ :address => addr,
77
+ :tags => ['integration'],
78
+ })
79
+ end
80
+
81
+ response, nested = @suppress.create_unsubscribes unsubscribes
82
+ response.to_h!
83
+
84
+ expect(response.code).to eq(200)
85
+ expect(response.body['message']).to eq('4 addresses have been added to the unsubscribes table')
86
+ expect(nested.length).to eq(0)
87
+ end
88
+
72
89
  it 'raises ParameterError if no unsubscribe[:address] is present' do
73
90
  unsubscribes = []
74
91
  unsubscribes.push({
@@ -123,4 +140,3 @@ describe 'For the suppressions handling class', order: :defined, vcr: vcr_opts d
123
140
 
124
141
  # TODO: Add tests for pagination support.
125
142
  end
126
-
data/spec/spec_helper.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'rubygems'
2
+ require 'base64'
2
3
  require 'bundler'
3
4
  require 'bundler/setup'
4
5
  Bundler.setup(:development)
@@ -37,9 +38,10 @@ TESTDOMAIN = envs['MAILGUN_TESTDOMAIN']
37
38
  VCR.configure do |c|
38
39
  c.cassette_library_dir = 'vcr_cassettes'
39
40
  c.hook_into :webmock
40
- c.configure_rspec_metadata!
41
41
  c.default_cassette_options = { record: :new_episodes }
42
42
  c.filter_sensitive_data('<APIKEY>') { APIKEY }
43
43
  c.filter_sensitive_data('DOMAIN.TEST') { TESTDOMAIN }
44
44
  c.filter_sensitive_data('<PUBKEY>') { PUB_APIKEY }
45
+
46
+ c.configure_rspec_metadata!
45
47
  end
@@ -11,6 +11,25 @@ describe 'The method get' do
11
11
  end
12
12
  end
13
13
 
14
+ describe 'Pagination' do
15
+ it 'should return a proper hash of log data.' do
16
+ @mg_obj = Mailgun::UnitClient.new('events')
17
+ events = Mailgun::Events.new(@mg_obj, "samples.mailgun.org")
18
+ result = events.get()
19
+
20
+ json = JSON.parse(result.body)
21
+ expect(json).to include("paging")
22
+ expect(json["paging"]).to include("next")
23
+ expect(json["paging"]).to include{"previous"}
24
+ end
25
+
26
+ it 'should calculate proper next-page url' do
27
+ events = Mailgun::Events.new(@mg_obj, "samples.mailgun.org")
28
+ output = events.send(:extract_endpoint_from, '/v3/samples.mailgun.org/events/W3siYiI6ICIyMDE3LTA1LTEwVDIwOjA2OjU0LjU3NiswMDowMCIsICJlIjogIjIwMTctMDUtMDhUMjA6MDY6NTQuNTc3KzAwOjAwIn0sIHsiYiI6ICIyMDE3LTA1LTEwVDIwOjA2OjU0LjU3NiswMDowMCIsICJlIjogIjIwMTctMDUtMDhUMjA6MDY6NTQuNTc3KzAwOjAwIn0sIFsiZiJdLCBudWxsLCBbWyJhY2NvdW50LmlkIiwgIjU4MDUyMTg2NzhmYTE2MTNjNzkwYjUwZiJdLCBbImRvbWFpbi5uYW1lIiwgInNhbmRib3gyOTcwMTUyYWYzZDM0NTU5YmZjN2U3MTcwM2E2Y2YyNC5tYWlsZ3VuLm9yZyJdXSwgMTAwLCBudWxsXQ==')
29
+
30
+ expect(output).to eq 'W3siYiI6ICIyMDE3LTA1LTEwVDIwOjA2OjU0LjU3NiswMDowMCIsICJlIjogIjIwMTctMDUtMDhUMjA6MDY6NTQuNTc3KzAwOjAwIn0sIHsiYiI6ICIyMDE3LTA1LTEwVDIwOjA2OjU0LjU3NiswMDowMCIsICJlIjogIjIwMTctMDUtMDhUMjA6MDY6NTQuNTc3KzAwOjAwIn0sIFsiZiJdLCBudWxsLCBbWyJhY2NvdW50LmlkIiwgIjU4MDUyMTg2NzhmYTE2MTNjNzkwYjUwZiJdLCBbImRvbWFpbi5uYW1lIiwgInNhbmRib3gyOTcwMTUyYWYzZDM0NTU5YmZjN2U3MTcwM2E2Y2YyNC5tYWlsZ3VuLm9yZyJdXSwgMTAwLCBudWxsXQ=='
31
+ end
32
+ end
14
33
 
15
34
  describe 'The method next' do
16
35
  it 'should return the next series of data.' do
@@ -95,6 +95,7 @@ describe 'The method add_recipient' do
95
95
  expect(@mb_obj.counters[:recipients][recipient_type]).to eq(1000)
96
96
  @mb_obj.finalize
97
97
 
98
+ expect(@mb_obj.recipient_variables).to eq({})
98
99
  expect(@mb_obj.message['recipient-variables'].length).to eq(0)
99
100
  expect(@mb_obj.message[:to].length).to eq(0)
100
101
  expect(@mb_obj.counters[:recipients][recipient_type]).to eq(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)
@@ -196,7 +206,7 @@ describe 'The method from' do
196
206
  expect(@mb_obj.message[:from]).to eq([the_from_address])
197
207
  end
198
208
 
199
- it 'sets the from address with metadata' do
209
+ it 'sets the from address with first/last metadata' do
200
210
  the_from_address = 'test@mailgun.com'
201
211
  the_first_name = 'Magilla'
202
212
  the_last_name = 'Gorilla'
@@ -204,6 +214,21 @@ describe 'The method from' do
204
214
 
205
215
  expect(@mb_obj.message[:from]).to eq(["'#{the_first_name} #{the_last_name}' <#{the_from_address}>"])
206
216
  end
217
+
218
+ it 'sets the from address with full name metadata' do
219
+ the_from_address = 'test@mailgun.com'
220
+ full_name = 'Magilla Gorilla'
221
+ @mb_obj.from(the_from_address, {'full_name' => full_name})
222
+
223
+ expect(@mb_obj.message[:from]).to eq(["'#{full_name}' <#{the_from_address}>"])
224
+ end
225
+
226
+ it 'fails when first/last and full_name are used' do
227
+ the_from_address = 'test@mailgun.com'
228
+ full_name = 'Magilla Gorilla'
229
+ first_name = 'Magilla'
230
+ expect{@mb_obj.from(the_from_address, {'full_name' => full_name, 'first' => first_name})}.to raise_error(Mailgun::ParameterError)
231
+ end
207
232
  end
208
233
 
209
234
  describe 'The method add_attachment' do
@@ -231,6 +256,16 @@ describe 'The method add_attachment' do
231
256
  expect(@mb_obj.message[:attachment].length).to eq(1)
232
257
  expect(@mb_obj.message[:attachment].first.original_filename).to eq 'mailgun_icon.png'
233
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
234
269
  end
235
270
 
236
271
  describe 'The method add_inline_image' do
@@ -425,19 +460,19 @@ describe 'The method track_opens' do
425
460
  it 'enables/disables open tracking on a per message basis.' do
426
461
  @mb_obj.track_opens('Yes')
427
462
 
428
- expect(@mb_obj.message["o:tracking-opens"][0]).to eq("yes")
463
+ expect(@mb_obj.message["o:tracking-opens"]).to eq("yes")
429
464
 
430
465
  @mb_obj.track_opens('No')
431
466
 
432
- expect(@mb_obj.message["o:tracking-opens"][0]).to eq("no")
467
+ expect(@mb_obj.message["o:tracking-opens"]).to eq("no")
433
468
 
434
469
  @mb_obj.track_opens(true)
435
470
 
436
- expect(@mb_obj.message["o:tracking-opens"][0]).to eq("yes")
471
+ expect(@mb_obj.message["o:tracking-opens"]).to eq("yes")
437
472
 
438
473
  @mb_obj.track_opens(false)
439
474
 
440
- expect(@mb_obj.message["o:tracking-opens"][0]).to eq("no")
475
+ expect(@mb_obj.message["o:tracking-opens"]).to eq("no")
441
476
  end
442
477
  end
443
478
 
@@ -456,23 +491,23 @@ describe 'The method track_clicks' do
456
491
  it 'enables/disables click tracking on a per message basis.' do
457
492
  @mb_obj.track_clicks('Yes')
458
493
 
459
- expect(@mb_obj.message["o:tracking-clicks"][0]).to eq("yes")
494
+ expect(@mb_obj.message["o:tracking-clicks"]).to eq("yes")
460
495
 
461
496
  @mb_obj.track_clicks('No')
462
497
 
463
- expect(@mb_obj.message["o:tracking-clicks"][0]).to eq("no")
498
+ expect(@mb_obj.message["o:tracking-clicks"]).to eq("no")
464
499
 
465
500
  @mb_obj.track_clicks(true)
466
501
 
467
- expect(@mb_obj.message["o:tracking-clicks"][0]).to eq("yes")
502
+ expect(@mb_obj.message["o:tracking-clicks"]).to eq("yes")
468
503
 
469
504
  @mb_obj.track_clicks(false)
470
505
 
471
- expect(@mb_obj.message["o:tracking-clicks"][0]).to eq("no")
506
+ expect(@mb_obj.message["o:tracking-clicks"]).to eq("no")
472
507
 
473
508
  @mb_obj.track_clicks('html')
474
509
 
475
- expect(@mb_obj.message["o:tracking-clicks"][0]).to eq("html")
510
+ expect(@mb_obj.message["o:tracking-clicks"]).to eq("html")
476
511
  end
477
512
  end
478
513
 
File without changes
@@ -0,0 +1,71 @@
1
+ require 'spec_helper'
2
+ require 'mailgun'
3
+ require 'railgun'
4
+
5
+ describe 'extract_body' do
6
+
7
+ let(:text_mail_option) {
8
+ {
9
+ from: 'bob@example.com',
10
+ to: 'sally@example.com',
11
+ subject: 'RAILGUN TEST SAMPLE',
12
+ body: text_content,
13
+ content_type: 'text/plain',
14
+ }
15
+ }
16
+ let(:text_content) { '[TEST] Hello, world.' }
17
+
18
+ let(:html_mail_option) {
19
+ {
20
+ from: 'bob@example.com',
21
+ to: 'sally@example.com',
22
+ subject: 'RAILGUN TEST SAMPLE',
23
+ body: html_content,
24
+ content_type: 'text/html',
25
+ }
26
+ }
27
+ let(:html_content) { '<h3> [TEST] </h3> <br/> Hello, world!' }
28
+
29
+ context 'with <Content-Type: text/plain>' do
30
+ let(:sample_mail) { Mail.new(text_mail_option) }
31
+
32
+ it 'should return body text' do
33
+ expect(Railgun.extract_body_text(sample_mail)).to eq(text_content)
34
+ end
35
+
36
+ it 'should not return body html' do
37
+ expect(Railgun.extract_body_html(sample_mail)).to be_nil
38
+ end
39
+ end
40
+
41
+ context 'with <Content-Type: text/html>' do
42
+ let(:sample_mail) { Mail.new(html_mail_option) }
43
+
44
+ it 'should not return body text' do
45
+ expect(Railgun.extract_body_text(sample_mail)).to be_nil
46
+ end
47
+
48
+ it 'should return body html' do
49
+ expect(Railgun.extract_body_html(sample_mail)).to eq(html_content)
50
+ end
51
+ end
52
+
53
+ context 'with <Content-Type: multipart/alternative>' do
54
+ let(:text_mail) { Mail.new(text_mail_option) }
55
+ let(:html_mail) { Mail.new(html_mail_option) }
56
+
57
+ before do
58
+ @sample_mail = Mail::Part.new(content_type: "multipart/alternative")
59
+ @sample_mail.add_part text_mail
60
+ @sample_mail.add_part html_mail
61
+ end
62
+
63
+ it 'should return body text' do
64
+ expect(Railgun.extract_body_text(@sample_mail)).to eq(text_content)
65
+ end
66
+
67
+ it 'should return body html' do
68
+ expect(Railgun.extract_body_html(@sample_mail)).to eq(html_content)
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,229 @@
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
+ end
35
+
36
+ describe 'Railgun::Mailer' do
37
+
38
+ it 'has a mailgun_client property which returns a Mailgun::Client' do
39
+ config = {
40
+ api_key: {},
41
+ domain: {}
42
+ }
43
+ @mailer_obj = Railgun::Mailer.new(config)
44
+
45
+ expect(@mailer_obj.mailgun_client).to be_a(Mailgun::Client)
46
+ end
47
+
48
+ it 'properly creates a message body' do
49
+ message = UnitTestMailer.plain_message('test@example.org', 'Test!', {})
50
+ body = Railgun.transform_for_mailgun(message)
51
+
52
+ [:from, :subject, :text, :html, 'to'].each do |param|
53
+ expect(body).to include(param)
54
+ end
55
+
56
+ expect(body[:from][0].value).to eq('unittest@example.org')
57
+ expect(body['to']).to eq(['test@example.org'])
58
+ expect(body[:subject]).to eq(['Test!'])
59
+ expect(body[:text]).to eq(['Test!'])
60
+ expect(body[:html]).to eq(['<p>Test!</p>'.html_safe])
61
+ end
62
+
63
+ it 'adds options to message body' do
64
+ message = UnitTestMailer.plain_message('test@example.org', '', {})
65
+ message.mailgun_options ||= {
66
+ 'tracking-opens' => 'true',
67
+ }
68
+
69
+ body = Railgun.transform_for_mailgun(message)
70
+
71
+ expect(body).to include('o:tracking-opens')
72
+ expect(body['o:tracking-opens']).to eq('true')
73
+ end
74
+
75
+ it 'accepts frozen options to message body' do
76
+ message = UnitTestMailer.plain_message('test@example.org', '', {})
77
+ message.mailgun_options ||= {
78
+ 'tags' => ['some-tag']
79
+ }
80
+
81
+ body = Railgun.transform_for_mailgun(message)
82
+
83
+ expect(body).to include('o:tags')
84
+ expect(body['o:tags']).to eq(['some-tag'])
85
+ end
86
+
87
+ it 'adds variables to message body' do
88
+ message = UnitTestMailer.plain_message('test@example.org', '', {})
89
+ message.mailgun_variables ||= {
90
+ 'user' => {:id => '1', :name => 'tstark'},
91
+ }
92
+
93
+ body = Railgun.transform_for_mailgun(message)
94
+
95
+ expect(body).to include('v:user')
96
+
97
+ var_body = JSON.load(body['v:user'])
98
+ expect(var_body).to include('id')
99
+ expect(var_body).to include('name')
100
+ expect(var_body['id']).to eq('1')
101
+ expect(var_body['name']).to eq('tstark')
102
+ end
103
+
104
+ it 'adds headers to message body' do
105
+ message = UnitTestMailer.plain_message('test@example.org', '', {})
106
+ message.mailgun_headers ||= {
107
+ 'x-unit-test' => 'true',
108
+ }
109
+
110
+ body = Railgun.transform_for_mailgun(message)
111
+
112
+ expect(body).to include('h:x-unit-test')
113
+ expect(body['h:x-unit-test']).to eq('true')
114
+ end
115
+
116
+ it 'adds headers to message body from mailer' do
117
+ message = UnitTestMailer.plain_message('test@example.org', '', {
118
+ 'x-unit-test-2' => 'true',
119
+ })
120
+
121
+ body = Railgun.transform_for_mailgun(message)
122
+
123
+ expect(body).to include('h:x-unit-test-2')
124
+ expect(body['h:x-unit-test-2']).to eq('true')
125
+ end
126
+
127
+ it 'properly handles headers that are passed as separate POST params' do
128
+ message = UnitTestMailer.plain_message('test@example.org', 'Test!', {
129
+ # `From`, `To`, and `Subject` are set on the envelope, so they should be ignored as headers
130
+ 'From' => 'units@example.net',
131
+ 'To' => 'user@example.com',
132
+ 'Subject' => 'This should disappear',
133
+ # If `Bcc` or `Cc` are set as headers, they should be carried over as POST params, not headers
134
+ 'Bcc' => ['list@example.org'],
135
+ 'Cc' => ['admin@example.com'],
136
+ # This is an arbitrary header and should be carried over properly
137
+ 'X-Source' => 'unit tests',
138
+ })
139
+
140
+ body = Railgun.transform_for_mailgun(message)
141
+
142
+ ['From', 'To', 'Subject'].each do |header|
143
+ expect(body).not_to include("h:#{header}")
144
+ end
145
+
146
+ ['bcc', 'cc', 'to', 'h:x-source'].each do |param|
147
+ expect(body).to include(param)
148
+ end
149
+
150
+ expect(body[:from][0].value).to eq('unittest@example.org')
151
+ expect(body['to']).to eq(['test@example.org'])
152
+ expect(body[:subject]).to eq(['Test!'])
153
+ expect(body[:text]).to eq(['Test!'])
154
+ expect(body[:html]).to eq(['<p>Test!</p>'.html_safe])
155
+ expect(body['bcc']).to eq(['list@example.org'])
156
+ expect(body['cc']).to eq(['admin@example.com'])
157
+ expect(body['h:x-source']).to eq('unit tests')
158
+ end
159
+
160
+ it 'properly adds attachments' do
161
+ message = UnitTestMailer.message_with_attachment('test@example.org', '')
162
+ body = Railgun.transform_for_mailgun(message)
163
+
164
+ expect(body).to include(:attachment)
165
+ attachment = body[:attachment][0]
166
+
167
+ expect(attachment.filename).to eq('info.txt')
168
+ expect(attachment.content_type).to eq('text/plain')
169
+ end
170
+
171
+ it 'delivers!' do
172
+ message = UnitTestMailer.plain_message('test@example.org', '', {})
173
+ message.deliver_now
174
+
175
+ expect(ActionMailer::Base.deliveries).to include(message)
176
+ end
177
+
178
+ it 'ignores `reply-to` in headers' do
179
+ message = UnitTestMailer.plain_message('test@example.org', '', {
180
+ 'reply-to' => 'user@example.com',
181
+ })
182
+ message.mailgun_headers = {
183
+ 'Reply-To' => 'administrator@example.org',
184
+ }
185
+ message.headers({'REPLY-TO' => 'admin@example.net'})
186
+ message.reply_to = "dude@example.com.au"
187
+
188
+ body = Railgun.transform_for_mailgun(message)
189
+ expect(body).to include('h:reply-to')
190
+ expect(body).not_to include('h:Reply-To')
191
+ expect(body['h:reply-to']).to eq('dude@example.com.au')
192
+ end
193
+
194
+ it 'treats `headers()` names as case-insensitve' do
195
+ message = UnitTestMailer.plain_message('test@example.org', '', {
196
+ 'X-BIG-VALUE' => 1,
197
+ })
198
+
199
+ body = Railgun.transform_for_mailgun(message)
200
+ expect(body).to include('h:x-big-value')
201
+ expect(body['h:x-big-value']).to eq("1")
202
+ end
203
+
204
+ it 'treats `mailgun_headers` names as case-insensitive' do
205
+ message = UnitTestMailer.plain_message('test@example.org', '', {})
206
+ message.mailgun_headers = {
207
+ 'X-BIG-VALUE' => 1,
208
+ }
209
+
210
+ body = Railgun.transform_for_mailgun(message)
211
+ expect(body).to include('h:x-big-value')
212
+ expect(body['h:x-big-value']).to eq("1")
213
+ end
214
+
215
+ it 'handles multi-value, mixed case headers correctly' do
216
+ message = UnitTestMailer.plain_message('test@example.org', '', {})
217
+ message.headers({
218
+ 'x-neat-header' => 'foo',
219
+ 'X-Neat-Header' => 'bar',
220
+ 'X-NEAT-HEADER' => 'zoop',
221
+ })
222
+
223
+ body = Railgun.transform_for_mailgun(message)
224
+ expect(body).to include('h:x-neat-header')
225
+ expect(body['h:x-neat-header']).to include('foo')
226
+ expect(body['h:x-neat-header']).to include('bar')
227
+ expect(body['h:x-neat-header']).to include('zoop')
228
+ end
229
+ end