mailgun-ruby 1.4.2 → 1.4.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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +30 -8
  3. data/.rubocop.yml +68 -0
  4. data/Gemfile +1 -1
  5. data/README.md +1 -1
  6. data/Rakefile +0 -5
  7. data/lib/mailgun/client.rb +12 -8
  8. data/lib/mailgun/domains/domains.rb +4 -2
  9. data/lib/mailgun/lists/opt_in_handler.rb +2 -4
  10. data/lib/mailgun/messages/batch_message.rb +2 -1
  11. data/lib/mailgun/messages/message_builder.rb +4 -32
  12. data/lib/mailgun/metrics/metrics.rb +6 -2
  13. data/lib/mailgun/response.rb +2 -2
  14. data/lib/mailgun/tags/analytics_tags.rb +9 -5
  15. data/lib/mailgun/tags/tags.rb +4 -2
  16. data/lib/mailgun/version.rb +1 -1
  17. data/lib/railgun/attachment.rb +4 -6
  18. data/lib/railgun/mailer.rb +2 -2
  19. data/mailgun.gemspec +4 -1
  20. data/spec/integration/analytics_tags_spec.rb +1 -1
  21. data/spec/integration/domains_spec.rb +7 -13
  22. data/spec/integration/events_spec.rb +1 -3
  23. data/spec/integration/list_members_spec.rb +1 -1
  24. data/spec/integration/logs_spec.rb +1 -1
  25. data/spec/integration/mailgun_spec.rb +3 -2
  26. data/spec/integration/metrics_spec.rb +9 -3
  27. data/spec/integration/suppressions_spec.rb +203 -26
  28. data/spec/integration/webhook_spec.rb +7 -2
  29. data/spec/spec_helper.rb +7 -0
  30. data/spec/unit/client_spec.rb +424 -0
  31. data/spec/unit/connection/test_client.rb +60 -13
  32. data/spec/unit/events/events_spec.rb +25 -9
  33. data/spec/unit/helpers/api_version_checker_spec.rb +206 -0
  34. data/spec/unit/lists/opt_in_handler_spec.rb +4 -2
  35. data/spec/unit/mailgun_spec.rb +7 -5
  36. data/spec/unit/messages/batch_message_spec.rb +25 -24
  37. data/spec/unit/messages/message_builder_spec.rb +83 -86
  38. data/spec/unit/railgun/content_type_spec.rb +7 -7
  39. data/spec/unit/railgun/mailer_spec.rb +17 -14
  40. data/spec/unit/response_spec.rb +225 -0
  41. data/vcr_cassettes/For_the_suppressions_handling_class/creates_a_single_bounce.yml +55 -0
  42. data/vcr_cassettes/suppressions.yml +1053 -170
  43. metadata +55 -5
@@ -0,0 +1,206 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ require 'mailgun'
6
+ require 'mailgun/helpers/api_version_checker'
7
+
8
+ describe Mailgun::ApiVersionChecker do
9
+ # Build a minimal host class that includes the module, with a controllable
10
+ # @client so we can set api_version per example.
11
+ subject(:instance) { host_class.new(client) }
12
+
13
+ let(:client) { double(:client) }
14
+
15
+ let(:host_class) do
16
+ Class.new do
17
+ include Mailgun::ApiVersionChecker
18
+
19
+ attr_reader :result
20
+
21
+ def initialize(client)
22
+ @client = client
23
+ end
24
+
25
+ def do_something(arg = nil)
26
+ @result = arg || :called
27
+ end
28
+ end
29
+ end
30
+
31
+ # ──────────────────────────────────────────────────────────────────────────
32
+ # .included / module structure
33
+ # ──────────────────────────────────────────────────────────────────────────
34
+
35
+ describe '.included' do
36
+ it 'extends the including class with ClassMethods' do
37
+ expect(host_class).to respond_to(:requires_api_version)
38
+ expect(host_class).to respond_to(:enforces_api_version)
39
+ end
40
+
41
+ it 'does not expose ClassMethods as instance methods' do
42
+ expect(instance).not_to respond_to(:requires_api_version)
43
+ expect(instance).not_to respond_to(:enforces_api_version)
44
+ end
45
+ end
46
+
47
+ # ──────────────────────────────────────────────────────────────────────────
48
+ # .requires_api_version (warns but still calls through)
49
+ # ──────────────────────────────────────────────────────────────────────────
50
+
51
+ describe '.requires_api_version' do
52
+ before { host_class.requires_api_version('v3', :do_something) }
53
+
54
+ context 'when the client is on the expected version' do
55
+ before { allow(client).to receive(:api_version).and_return('v3') }
56
+
57
+ it 'does not emit a warning' do
58
+ expect { instance.do_something }.not_to output.to_stderr
59
+ end
60
+
61
+ it 'still calls the original method' do
62
+ instance.do_something(:payload)
63
+ expect(instance.result).to eq(:payload)
64
+ end
65
+
66
+ it 'forwards all arguments to the original method' do
67
+ instance.do_something(:forwarded_arg)
68
+ expect(instance.result).to eq(:forwarded_arg)
69
+ end
70
+ end
71
+
72
+ context 'when the client is on a different version' do
73
+ before { allow(client).to receive(:api_version).and_return('v4') }
74
+
75
+ it 'emits a warning to stderr' do
76
+ expect { instance.do_something }
77
+ .to output(/WARN: Client api version must be v3/).to_stderr
78
+ end
79
+
80
+ it 'still calls the original method despite the warning' do
81
+ instance.do_something(:payload)
82
+ expect(instance.result).to eq(:payload)
83
+ end
84
+
85
+ it 'warning message includes the expected version' do
86
+ expect { instance.do_something }
87
+ .to output(/v3/).to_stderr
88
+ end
89
+ end
90
+
91
+ it 'wraps multiple methods when given a list' do
92
+ host_class.class_eval { def do_other = @result = :other }
93
+ host_class.requires_api_version('v3', :do_something, :do_other)
94
+
95
+ allow(client).to receive(:api_version).and_return('v4')
96
+
97
+ expect { instance.do_something }.to output(/v3/).to_stderr
98
+ expect { instance.do_other }.to output(/v3/).to_stderr
99
+ end
100
+
101
+ it 'wraps only the listed methods, leaving others unwrapped' do
102
+ host_class.class_eval { def unwrapped = @result = :unwrapped }
103
+ host_class.requires_api_version('v3', :do_something)
104
+
105
+ allow(client).to receive(:api_version).and_return('v4')
106
+
107
+ # unwrapped should not warn
108
+ expect { instance.unwrapped }.not_to output.to_stderr
109
+ end
110
+ end
111
+
112
+ # ──────────────────────────────────────────────────────────────────────────
113
+ # .enforces_api_version (raises on version mismatch)
114
+ # ──────────────────────────────────────────────────────────────────────────
115
+
116
+ describe '.enforces_api_version' do
117
+ before { host_class.enforces_api_version('v3', :do_something) }
118
+
119
+ context 'when the client is on the expected version' do
120
+ before { allow(client).to receive(:api_version).and_return('v3') }
121
+
122
+ it 'does not raise' do
123
+ expect { instance.do_something }.not_to raise_error
124
+ end
125
+
126
+ it 'calls the original method' do
127
+ instance.do_something(:payload)
128
+ expect(instance.result).to eq(:payload)
129
+ end
130
+
131
+ it 'forwards all arguments to the original method' do
132
+ instance.do_something(:forwarded_arg)
133
+ expect(instance.result).to eq(:forwarded_arg)
134
+ end
135
+ end
136
+
137
+ context 'when the client is on a different version' do
138
+ before { allow(client).to receive(:api_version).and_return('v4') }
139
+
140
+ it 'raises Mailgun::ParameterError' do
141
+ expect { instance.do_something }
142
+ .to raise_error(Mailgun::ParameterError)
143
+ end
144
+
145
+ it 'raises with a message including the expected version' do
146
+ expect { instance.do_something }
147
+ .to raise_error(Mailgun::ParameterError, /v3/)
148
+ end
149
+
150
+ it 'does not call the original method' do
151
+ begin
152
+ instance.do_something
153
+ rescue StandardError
154
+ nil
155
+ end
156
+ expect(instance.result).to be_nil
157
+ end
158
+ end
159
+
160
+ it 'wraps multiple methods when given a list' do
161
+ host_class.class_eval { def do_other = @result = :other }
162
+ host_class.enforces_api_version('v3', :do_something, :do_other)
163
+
164
+ allow(client).to receive(:api_version).and_return('v4')
165
+
166
+ expect { instance.do_something }.to raise_error(Mailgun::ParameterError)
167
+ expect { instance.do_other }.to raise_error(Mailgun::ParameterError)
168
+ end
169
+
170
+ it 'wraps only the listed methods, leaving others unwrapped' do
171
+ host_class.class_eval { def unwrapped = @result = :unwrapped }
172
+ host_class.enforces_api_version('v3', :do_something)
173
+
174
+ allow(client).to receive(:api_version).and_return('v4')
175
+
176
+ expect { instance.unwrapped }.not_to raise_error
177
+ end
178
+ end
179
+
180
+ # ──────────────────────────────────────────────────────────────────────────
181
+ # requires vs enforces contrast
182
+ # ──────────────────────────────────────────────────────────────────────────
183
+
184
+ describe 'requires_api_version vs enforces_api_version' do
185
+ before do
186
+ host_class.class_eval do
187
+ def soft_method = @result = :soft
188
+ def hard_method = @result = :hard
189
+ end
190
+ host_class.requires_api_version('v3', :soft_method)
191
+ host_class.enforces_api_version('v3', :hard_method)
192
+
193
+ allow(client).to receive(:api_version).and_return('v4')
194
+ end
195
+
196
+ it 'requires_api_version warns but does not raise' do
197
+ expect { instance.soft_method }.to output(/v3/).to_stderr
198
+ expect(instance.result).to eq(:soft)
199
+ end
200
+
201
+ it 'enforces_api_version raises and does not call through' do
202
+ expect { instance.hard_method }.to raise_error(Mailgun::ParameterError)
203
+ expect(instance.result).not_to eq(:hard)
204
+ end
205
+ end
206
+ end
@@ -3,11 +3,13 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe 'The method generate_hash' do
6
- before(:each) do
6
+ before do
7
7
  @mailing_list = 'mylist@example.com'
8
8
  @secret_app_id = 'mysupersecretpassword'
9
9
  @recipient_address = 'bob@example.com'
10
- @precalculated_hash = 'eyJoIjoiMmY3ZmY1MzFlOGJmMjA0OWNhMTI3ZmU4ZTQyNjZkOTljYzhkMTdk%0AMiIsInAiOiJleUpzSWpvaWJYbHNhWE4wUUdWNFlXMXdiR1V1WTI5dElpd2lj%0AaUk2SW1KdllrQmxlR0Z0Y0d4bExtTnZcbmJTSjlcbiJ9%0A'
10
+ @precalculated_hash =
11
+ "eyJoIjoiMmY3ZmY1MzFlOGJmMjA0OWNhMTI3ZmU4ZTQyNjZkOTljYzhkMTdk%0AMiIsInAiOiJleUpzSWpv\
12
+ aWJYbHNhWE4wUUdWNFlXMXdiR1V1WTI5dElpd2lj%0AaUk2SW1KdllrQmxlR0Z0Y0d4bExtTnZcbmJTSjlcbiJ9%0A"
11
13
  end
12
14
 
13
15
  it 'generates a web safe hash for the recipient wishing to subscribe' do
@@ -9,7 +9,7 @@ describe 'Mailgun instantiation' do
9
9
  end
10
10
 
11
11
  describe 'The method send_message()' do
12
- before(:each) do
12
+ before do
13
13
  @mg_obj = Mailgun::UnitClient.new('messages')
14
14
  @domain = 'test.com'
15
15
  @list_address = 'mylist@test.com'
@@ -73,10 +73,11 @@ describe 'The method send_message()' do
73
73
  end
74
74
 
75
75
  describe 'The method post()' do
76
- before(:each) do
76
+ before do
77
77
  @mg_obj = Mailgun::UnitClient.new('messages')
78
78
  @domain = 'test.com'
79
79
  end
80
+
80
81
  it 'in this case, sends a simple message.' do
81
82
  data = { 'from' => 'joe@test.com',
82
83
  'to' => 'bob@example.com',
@@ -111,7 +112,7 @@ describe 'The method post()' do
111
112
  end
112
113
 
113
114
  describe 'The method put()' do
114
- before(:each) do
115
+ before do
115
116
  @mg_obj = Mailgun::UnitClient.new('lists')
116
117
  @domain = 'test.com'
117
118
  @list_address = 'mylist@test.com'
@@ -136,10 +137,11 @@ describe 'The method put()' do
136
137
  end
137
138
 
138
139
  describe 'The method get()' do
139
- before(:each) do
140
+ before do
140
141
  @mg_obj = Mailgun::UnitClient.new('bounces')
141
142
  @domain = 'test.com'
142
143
  end
144
+
143
145
  it 'in this case, obtains a list of bounces for the domain, limit of 5, skipping the first 10.' do
144
146
  query_string = { 'skip' => '10',
145
147
  'limit' => '5' }
@@ -153,7 +155,7 @@ describe 'The method get()' do
153
155
  end
154
156
 
155
157
  describe 'The method delete()' do
156
- before(:each) do
158
+ before do
157
159
  @mg_obj = Mailgun::UnitClient.new('campaigns')
158
160
  @domain = 'test.com'
159
161
  end
@@ -3,7 +3,7 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe 'BatchMessage attribute readers' do
6
- it 'should be readable' do
6
+ it 'is readable' do
7
7
  @mb_client = Mailgun::UnitClient.new('messages')
8
8
  @mb_obj = Mailgun::BatchMessage.new(@mb_client, 'example.com')
9
9
 
@@ -16,7 +16,7 @@ describe 'BatchMessage attribute readers' do
16
16
  end
17
17
 
18
18
  describe 'The instantiation of Batch Message' do
19
- before(:each) do
19
+ before do
20
20
  @mb_client = Mailgun::UnitClient.new('messages')
21
21
  @mb_obj = Mailgun::BatchMessage.new(@mb_client, 'example.com')
22
22
  end
@@ -63,30 +63,31 @@ describe 'The instantiation of Batch Message' do
63
63
  end
64
64
 
65
65
  describe 'The method add_recipient' do
66
- before(:each) do
66
+ before do
67
67
  @mb_client = Mailgun::UnitClient.new('messages')
68
68
  @mb_obj = Mailgun::BatchMessage.new(@mb_client, 'example.com')
69
- @address_1 = 'jane@example.com'
70
- @variables_1 = { 'first' => 'Jane', 'last' => 'Doe', 'tracking' => 'ABC123' }
71
- @address_2 = 'bob@example.com'
72
- @variables_2 = { 'first' => 'Bob', 'last' => 'Doe', 'tracking' => 'DEF123' }
73
- @address_3 = 'sam@example.com'
74
- @variables_3 = { 'first' => 'Sam', 'last' => 'Doe', 'tracking' => 'GHI123' }
69
+ @address1 = 'jane@example.com'
70
+ @variables1 = { 'first' => 'Jane', 'last' => 'Doe', 'tracking' => 'ABC123' }
71
+ @address2 = 'bob@example.com'
72
+ @variables2 = { 'first' => 'Bob', 'last' => 'Doe', 'tracking' => 'DEF123' }
73
+ @address3 = 'sam@example.com'
74
+ @variables3 = { 'first' => 'Sam', 'last' => 'Doe', 'tracking' => 'GHI123' }
75
75
  end
76
+
76
77
  context 'when from is present' do
77
- before(:each) do
78
+ before do
78
79
  @mb_obj.from('example@email.com')
79
80
  end
80
81
 
81
82
  it 'adds 1,000 recipients to the message body and validates counter is incremented then reset' do
82
83
  recipient_type = :to
83
84
  1000.times do
84
- @mb_obj.add_recipient(recipient_type, @address_1, @variables_1)
85
+ @mb_obj.add_recipient(recipient_type, @address1, @variables1)
85
86
  end
86
87
 
87
88
  expect(@mb_obj.counters[:recipients][recipient_type]).to eq(1000)
88
89
 
89
- @mb_obj.add_recipient(recipient_type, @address_1, @variables_1)
90
+ @mb_obj.add_recipient(recipient_type, @address1, @variables1)
90
91
 
91
92
  expect(@mb_obj.counters[:recipients][recipient_type]).to eq(1)
92
93
  end
@@ -94,7 +95,7 @@ describe 'The method add_recipient' do
94
95
  it 'adds recipients to the message, calls finalize, and cleans up' do
95
96
  recipient_type = :to
96
97
  1000.times do
97
- @mb_obj.add_recipient(recipient_type, @address_1, @variables_1)
98
+ @mb_obj.add_recipient(recipient_type, @address1, @variables1)
98
99
  end
99
100
 
100
101
  expect(@mb_obj.counters[:recipients][recipient_type]).to eq(1000)
@@ -109,7 +110,7 @@ describe 'The method add_recipient' do
109
110
  it 'adds 5,005 recipients to the message body and validates we receive message_ids back' do
110
111
  recipient_type = :to
111
112
  5005.times do
112
- @mb_obj.add_recipient(recipient_type, @address_1, @variables_1)
113
+ @mb_obj.add_recipient(recipient_type, @address1, @variables1)
113
114
  end
114
115
  @mb_obj.finalize
115
116
 
@@ -118,28 +119,28 @@ describe 'The method add_recipient' do
118
119
 
119
120
  it 'sets recipient-variables, for batch expansion' do
120
121
  recipient_type = :to
121
- @mb_obj.add_recipient(recipient_type, @address_1, @variables_1)
122
+ @mb_obj.add_recipient(recipient_type, @address1, @variables1)
122
123
 
123
- expect(@mb_obj.recipient_variables[@address_1]).to eq(@variables_1)
124
+ expect(@mb_obj.recipient_variables[@address1]).to eq(@variables1)
124
125
  end
125
126
 
126
127
  it 'sets multiple recipient-variables, for batch expansion' do
127
128
  recipient_type = :to
128
- @mb_obj.add_recipient(recipient_type, @address_1, @variables_1)
129
- @mb_obj.add_recipient(recipient_type, @address_2, @variables_2)
130
- @mb_obj.add_recipient(recipient_type, @address_3, @variables_3)
129
+ @mb_obj.add_recipient(recipient_type, @address1, @variables1)
130
+ @mb_obj.add_recipient(recipient_type, @address2, @variables2)
131
+ @mb_obj.add_recipient(recipient_type, @address3, @variables3)
131
132
 
132
- expect(@mb_obj.recipient_variables[@address_1]).to eq(@variables_1)
133
- expect(@mb_obj.recipient_variables[@address_2]).to eq(@variables_2)
134
- expect(@mb_obj.recipient_variables[@address_3]).to eq(@variables_3)
133
+ expect(@mb_obj.recipient_variables[@address1]).to eq(@variables1)
134
+ expect(@mb_obj.recipient_variables[@address2]).to eq(@variables2)
135
+ expect(@mb_obj.recipient_variables[@address3]).to eq(@variables3)
135
136
  end
136
137
  end
137
138
 
138
139
  context 'when from is empty' do
139
140
  it 'shows error message' do
140
141
  recipient_type = :to
141
- @mb_obj.add_recipient(recipient_type, @address_1, @variables_1)
142
- @mb_obj.add_recipient(recipient_type, @address_2, @variables_2)
142
+ @mb_obj.add_recipient(recipient_type, @address1, @variables1)
143
+ @mb_obj.add_recipient(recipient_type, @address2, @variables2)
143
144
  expect(@mb_client).to receive(:raise)
144
145
  @mb_obj.finalize
145
146
  end