mailgun-ruby 1.4.1 → 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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +30 -8
- data/.rubocop.yml +64 -4
- data/Gemfile +3 -1
- data/README.md +1 -1
- data/Rakefile +5 -8
- data/docs/AnalyticsTags.md +63 -0
- data/lib/mailgun/address.rb +5 -5
- data/lib/mailgun/chains.rb +2 -3
- data/lib/mailgun/client.rb +56 -56
- data/lib/mailgun/domains/domains.rb +11 -10
- data/lib/mailgun/events/events.rb +4 -3
- data/lib/mailgun/exceptions/exceptions.rb +12 -15
- data/lib/mailgun/helpers/api_version_checker.rb +6 -1
- data/lib/mailgun/lists/opt_in_handler.rb +6 -10
- data/lib/mailgun/logs/logs.rb +4 -2
- data/lib/mailgun/messages/batch_message.rb +10 -10
- data/lib/mailgun/messages/message_builder.rb +40 -56
- data/lib/mailgun/metrics/metrics.rb +12 -6
- data/lib/mailgun/response.rb +12 -10
- data/lib/mailgun/subaccounts/subaccounts.rb +13 -8
- data/lib/mailgun/suppressions.rb +36 -43
- data/lib/mailgun/tags/analytics_tags.rb +37 -2
- data/lib/mailgun/tags/tags.rb +29 -19
- data/lib/mailgun/templates/templates.rb +40 -29
- data/lib/mailgun/version.rb +3 -1
- data/lib/mailgun/webhooks/webhooks.rb +22 -19
- data/lib/mailgun-ruby.rb +2 -0
- data/lib/mailgun.rb +4 -4
- data/lib/railgun/attachment.rb +12 -19
- data/lib/railgun/errors.rb +2 -3
- data/lib/railgun/mailer.rb +37 -41
- data/lib/railgun/railtie.rb +2 -0
- data/lib/railgun.rb +2 -0
- data/mailgun.gemspec +15 -11
- data/spec/integration/analytics_tags_spec.rb +54 -0
- data/spec/integration/bounces_spec.rb +12 -11
- data/spec/integration/campaign_spec.rb +20 -18
- data/spec/integration/complaints_spec.rb +8 -6
- data/spec/integration/domains_spec.rb +12 -18
- data/spec/integration/email_validation_spec.rb +35 -34
- data/spec/integration/events_spec.rb +8 -8
- data/spec/integration/list_members_spec.rb +27 -26
- data/spec/integration/list_spec.rb +22 -21
- data/spec/integration/logs_spec.rb +49 -47
- data/spec/integration/mailer_spec.rb +7 -3
- data/spec/integration/mailgun_spec.rb +85 -92
- data/spec/integration/metrics_spec.rb +137 -131
- data/spec/integration/routes_spec.rb +41 -40
- data/spec/integration/stats_spec.rb +4 -2
- data/spec/integration/subaccounts_spec.rb +9 -10
- data/spec/integration/suppressions_spec.rb +222 -44
- data/spec/integration/templates_spec.rb +14 -12
- data/spec/integration/unsubscribes_spec.rb +8 -6
- data/spec/integration/webhook_spec.rb +18 -12
- data/spec/spec_helper.rb +15 -8
- data/spec/unit/client_spec.rb +424 -0
- data/spec/unit/connection/test_client.rb +108 -55
- data/spec/unit/events/events_spec.rb +48 -29
- data/spec/unit/exceptions/exceptions_spec.rb +8 -7
- data/spec/unit/helpers/api_version_checker_spec.rb +206 -0
- data/spec/unit/lists/opt_in_handler_spec.rb +11 -7
- data/spec/unit/mailgun_spec.rb +71 -68
- data/spec/unit/messages/batch_message_spec.rb +37 -36
- data/spec/unit/messages/message_builder_spec.rb +170 -169
- data/spec/unit/railgun/content_type_spec.rb +31 -30
- data/spec/unit/railgun/mailer_spec.rb +62 -59
- data/spec/unit/response_spec.rb +225 -0
- data/vcr_cassettes/For_the_suppressions_handling_class/creates_a_single_bounce.yml +55 -0
- data/vcr_cassettes/analytics_tags.yml +187 -0
- data/vcr_cassettes/suppressions.yml +1053 -170
- metadata +95 -29
- data/.rubocop_todo.yml +0 -22
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'spec_helper'
|
|
2
4
|
require 'mailgun'
|
|
3
5
|
|
|
4
|
-
vcr_opts = { :
|
|
6
|
+
vcr_opts = { cassette_name: 'unsubscribes' }
|
|
5
7
|
|
|
6
8
|
describe 'For the Unsubscribes endpoint', order: :defined, vcr: vcr_opts do
|
|
7
9
|
before(:all) do
|
|
@@ -14,22 +16,22 @@ describe 'For the Unsubscribes endpoint', order: :defined, vcr: vcr_opts do
|
|
|
14
16
|
result = @mg_obj.post "#{@domain}/unsubscribes", address: @email, tag: '*'
|
|
15
17
|
|
|
16
18
|
result.to_h!
|
|
17
|
-
expect(result.body[
|
|
18
|
-
expect(result.body[
|
|
19
|
+
expect(result.body['message']).to eq('Address has been added to the unsubscribes table')
|
|
20
|
+
expect(result.body['address']).to eq(@email)
|
|
19
21
|
end
|
|
20
22
|
|
|
21
23
|
it 'get an unsubscribee.' do
|
|
22
24
|
result = @mg_obj.get "#{@domain}/unsubscribes/#{@email}"
|
|
23
25
|
|
|
24
26
|
result.to_h!
|
|
25
|
-
expect(result.body[
|
|
27
|
+
expect(result.body['address']).to eq(@email)
|
|
26
28
|
end
|
|
27
29
|
|
|
28
30
|
it 'gets a list of unsubscribes.' do
|
|
29
31
|
result = @mg_obj.get "#{@domain}/unsubscribes"
|
|
30
32
|
|
|
31
33
|
result.to_h!
|
|
32
|
-
expect(result.body[
|
|
34
|
+
expect(result.body['items'].length).to be > 0
|
|
33
35
|
end
|
|
34
36
|
|
|
35
37
|
it 'removes an unsubscribee' do
|
|
@@ -37,6 +39,6 @@ describe 'For the Unsubscribes endpoint', order: :defined, vcr: vcr_opts do
|
|
|
37
39
|
|
|
38
40
|
result.to_h!
|
|
39
41
|
expect(result.body['address']).to eq(@email)
|
|
40
|
-
expect(result.body[
|
|
42
|
+
expect(result.body['message']).to eq('Unsubscribe event has been removed')
|
|
41
43
|
end
|
|
42
44
|
end
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'spec_helper'
|
|
2
4
|
require 'mailgun'
|
|
3
5
|
|
|
4
|
-
vcr_opts = { :
|
|
6
|
+
vcr_opts = { cassette_name: 'webhooks' }
|
|
5
7
|
|
|
6
8
|
describe 'For the webhooks endpoint', order: :defined, vcr: vcr_opts do
|
|
7
9
|
before(:all) do
|
|
@@ -13,42 +15,46 @@ describe 'For the webhooks endpoint', order: :defined, vcr: vcr_opts do
|
|
|
13
15
|
|
|
14
16
|
it 'creates a webhook' do
|
|
15
17
|
result = @mg_obj.post("domains/#{@domain}/webhooks", { id: @testhook,
|
|
16
|
-
url: "http://example.com/mailgun/events/#{@testhook}" }
|
|
18
|
+
url: "http://example.com/mailgun/events/#{@testhook}" })
|
|
17
19
|
|
|
18
20
|
result.to_h!
|
|
19
|
-
expect(result.body[
|
|
20
|
-
expect(result.body[
|
|
21
|
+
expect(result.body['message']).to eq('Webhook has been created')
|
|
22
|
+
expect(result.body['webhook']['urls']).to include("http://example.com/mailgun/events/#{@testhook}")
|
|
21
23
|
end
|
|
22
24
|
|
|
23
25
|
it 'gets a webhook.' do
|
|
24
26
|
result = @mg_obj.get("domains/#{@domain}/webhooks/#{@testhook}")
|
|
25
27
|
|
|
26
28
|
result.to_h!
|
|
27
|
-
expect(result.body[
|
|
29
|
+
expect(result.body['webhook']['urls']).to include("http://example.com/mailgun/events/#{@testhook}")
|
|
28
30
|
end
|
|
29
31
|
|
|
30
32
|
it 'gets a list of all webhooks.' do
|
|
31
33
|
result = @mg_obj.get("domains/#{@domain}/webhooks")
|
|
32
34
|
|
|
33
35
|
result.to_h!
|
|
34
|
-
expect(result.body[
|
|
36
|
+
expect(result.body['webhooks']['accepted']['urls']).to include("http://example.com/mailgun/events/#{@testhook}")
|
|
35
37
|
end
|
|
36
38
|
|
|
37
39
|
it 'updates a webhook.' do
|
|
38
|
-
result = @mg_obj.put(
|
|
39
|
-
|
|
40
|
+
result = @mg_obj.put(
|
|
41
|
+
"domains/#{@domain}/webhooks/#{@testhook}",
|
|
42
|
+
{
|
|
43
|
+
id: @testhook,
|
|
44
|
+
url: "http://example.com/mailgun/events/#{@testhookup}"
|
|
45
|
+
}
|
|
46
|
+
)
|
|
40
47
|
|
|
41
48
|
result.to_h!
|
|
42
|
-
expect(result.body[
|
|
43
|
-
expect(result.body[
|
|
49
|
+
expect(result.body['message']).to eq('Webhook has been updated')
|
|
50
|
+
expect(result.body['webhook']['urls']).to include("http://example.com/mailgun/events/#{@testhookup}")
|
|
44
51
|
end
|
|
45
52
|
|
|
46
53
|
it 'removes a webhook' do
|
|
47
54
|
result = @mg_obj.delete("domains/#{@domain}/webhooks/#{@testhook}")
|
|
48
55
|
|
|
49
56
|
result.to_h!
|
|
50
|
-
expect(result.body['message']).to eq(
|
|
57
|
+
expect(result.body['message']).to eq('Webhook has been deleted')
|
|
51
58
|
expect(result.body['webhook']['urls']).to include("http://example.com/mailgun/events/#{@testhookup}")
|
|
52
59
|
end
|
|
53
|
-
|
|
54
60
|
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'simplecov'
|
|
4
|
+
require 'simplecov-json'
|
|
5
|
+
SimpleCov.formatters = SimpleCov::Formatter::MultiFormatter.new(
|
|
6
|
+
[
|
|
7
|
+
SimpleCov::Formatter::HTMLFormatter,
|
|
8
|
+
SimpleCov::Formatter::JSONFormatter
|
|
9
|
+
]
|
|
10
|
+
)
|
|
2
11
|
|
|
3
12
|
SimpleCov.start do
|
|
4
|
-
add_filter
|
|
13
|
+
add_filter '/spec/'
|
|
5
14
|
end
|
|
6
15
|
|
|
7
16
|
require 'mailgun'
|
|
@@ -10,22 +19,20 @@ require 'vcr'
|
|
|
10
19
|
require 'webmock/rspec'
|
|
11
20
|
require 'rspec/its'
|
|
12
21
|
|
|
13
|
-
#WebMock.disable_net_connect!(allow_localhost: true)
|
|
22
|
+
# WebMock.disable_net_connect!(allow_localhost: true)
|
|
14
23
|
require_relative 'unit/connection/test_client'
|
|
15
24
|
|
|
16
|
-
RSpec.configure
|
|
17
|
-
c.raise_errors_for_deprecations!
|
|
18
|
-
end
|
|
25
|
+
RSpec.configure(&:raise_errors_for_deprecations!)
|
|
19
26
|
|
|
20
|
-
APIHOST =
|
|
21
|
-
APIVERSION =
|
|
27
|
+
APIHOST = 'api.mailgun.net'
|
|
28
|
+
APIVERSION = 'v3'
|
|
22
29
|
SSL = true
|
|
23
30
|
|
|
24
31
|
# For integration tests modify .ruby-env.yml
|
|
25
32
|
# use .ruby-env.yml.example for an example
|
|
26
33
|
# alternatively
|
|
27
34
|
# set environment variables as named in .ruby-env.yml.example
|
|
28
|
-
envfile = File.join(File.dirname(__FILE__), '..','.ruby-env.yml')
|
|
35
|
+
envfile = File.join(File.dirname(__FILE__), '..', '.ruby-env.yml')
|
|
29
36
|
envs = File.exist?(envfile) ? YAML.load_file(envfile) : ENV
|
|
30
37
|
APIKEY = envs['MAILGUN_APIKEY']
|
|
31
38
|
PUB_APIKEY = envs['MAILGUN_PUB_APIKEY']
|
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
require 'mailgun'
|
|
5
|
+
require 'mailgun/exceptions/exceptions'
|
|
6
|
+
|
|
7
|
+
describe Mailgun::Client do
|
|
8
|
+
# ---------------------------------------------------------------------------
|
|
9
|
+
# Shared helpers
|
|
10
|
+
# ---------------------------------------------------------------------------
|
|
11
|
+
# Build a client in test mode so no real HTTP calls are ever made.
|
|
12
|
+
subject(:client) { described_class.new(api_key, 'api.mailgun.net', 'v3', true, true) }
|
|
13
|
+
|
|
14
|
+
let(:api_key) { 'test-api-key-abc123' }
|
|
15
|
+
let(:message_params) do
|
|
16
|
+
{
|
|
17
|
+
from: 'bob@example.com',
|
|
18
|
+
to: 'sally@example.com',
|
|
19
|
+
subject: 'Hello!',
|
|
20
|
+
text: 'Test body.'
|
|
21
|
+
}
|
|
22
|
+
end
|
|
23
|
+
let(:domain) { 'example.com' }
|
|
24
|
+
|
|
25
|
+
# Fake HTTP response double reusable across examples
|
|
26
|
+
def fake_http_response(body: '{"message":"ok"}', status: 200)
|
|
27
|
+
double('http_response', body: body, status: status)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# ---------------------------------------------------------------------------
|
|
31
|
+
# .new / #initialize
|
|
32
|
+
# ---------------------------------------------------------------------------
|
|
33
|
+
describe '#initialize' do
|
|
34
|
+
it 'instantiates without raising' do
|
|
35
|
+
expect { described_class.new(api_key) }.not_to raise_error
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it 'stores the api_version' do
|
|
39
|
+
c = described_class.new(api_key, 'api.mailgun.net', 'v3')
|
|
40
|
+
expect(c.api_version).to eq('v3')
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it 'defaults test_mode to false when not specified' do
|
|
44
|
+
# Pass test_mode = false explicitly to avoid picking up global config
|
|
45
|
+
c = described_class.new(api_key, 'api.mailgun.net', 'v3', true, false)
|
|
46
|
+
expect(c.test_mode?).to be(false)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it 'accepts test_mode = true' do
|
|
50
|
+
c = described_class.new(api_key, 'api.mailgun.net', nil, true, true)
|
|
51
|
+
expect(c.test_mode?).to be(true)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it 'supports EU api host' do
|
|
55
|
+
expect { described_class.new(api_key, 'api.eu.mailgun.net') }.not_to raise_error
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# ---------------------------------------------------------------------------
|
|
60
|
+
# #test_mode?
|
|
61
|
+
# ---------------------------------------------------------------------------
|
|
62
|
+
describe '#test_mode?' do
|
|
63
|
+
it 'returns true when the client is in test mode' do
|
|
64
|
+
expect(client.test_mode?).to be(true)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it 'returns false when test mode has been disabled' do
|
|
68
|
+
client.disable_test_mode!
|
|
69
|
+
expect(client.test_mode?).to be(false)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# ---------------------------------------------------------------------------
|
|
74
|
+
# #enable_test_mode!
|
|
75
|
+
# ---------------------------------------------------------------------------
|
|
76
|
+
describe '#enable_test_mode!' do
|
|
77
|
+
subject(:non_test_client) do
|
|
78
|
+
described_class.new(api_key, 'api.mailgun.net', 'v3', true, false)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it 'sets test_mode to true' do
|
|
82
|
+
non_test_client.enable_test_mode!
|
|
83
|
+
expect(non_test_client.test_mode?).to be(true)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# ---------------------------------------------------------------------------
|
|
88
|
+
# #disable_test_mode!
|
|
89
|
+
# ---------------------------------------------------------------------------
|
|
90
|
+
describe '#disable_test_mode!' do
|
|
91
|
+
it 'sets test_mode to false' do
|
|
92
|
+
client.disable_test_mode!
|
|
93
|
+
expect(client.test_mode?).to be(false)
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# ---------------------------------------------------------------------------
|
|
98
|
+
# .deliveries
|
|
99
|
+
# ---------------------------------------------------------------------------
|
|
100
|
+
describe '.deliveries' do
|
|
101
|
+
before { described_class.deliveries.clear }
|
|
102
|
+
|
|
103
|
+
it 'returns an Array' do
|
|
104
|
+
expect(described_class.deliveries).to be_an(Array)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it 'accumulates messages sent in test mode' do
|
|
108
|
+
client.send_message(domain, message_params)
|
|
109
|
+
expect(described_class.deliveries).not_to be_empty
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
it 'stores the message data sent in test mode' do
|
|
113
|
+
client.send_message(domain, message_params)
|
|
114
|
+
expect(described_class.deliveries.last).to include(from: 'bob@example.com')
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
it 'accumulates multiple deliveries' do
|
|
118
|
+
2.times { client.send_message(domain, message_params) }
|
|
119
|
+
expect(described_class.deliveries.size).to eq(2)
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# ---------------------------------------------------------------------------
|
|
124
|
+
# #send_message — test mode
|
|
125
|
+
# ---------------------------------------------------------------------------
|
|
126
|
+
describe '#send_message (test mode)' do
|
|
127
|
+
before { described_class.deliveries.clear }
|
|
128
|
+
|
|
129
|
+
it 'returns a Mailgun::Response' do
|
|
130
|
+
result = client.send_message(domain, message_params)
|
|
131
|
+
expect(result).to be_a(Mailgun::Response)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it 'returns a 200 status response in test mode' do
|
|
135
|
+
result = client.send_message(domain, message_params)
|
|
136
|
+
expect(result.code).to eq(200)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
it 'returns a body containing the Queued message in test mode' do
|
|
140
|
+
result = client.send_message(domain, message_params)
|
|
141
|
+
body = JSON.parse(result.body)
|
|
142
|
+
expect(body['message']).to eq('Queued. Thank you.')
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
it 'returns a body with a unique test-mode message id' do
|
|
146
|
+
result = client.send_message(domain, message_params)
|
|
147
|
+
body = JSON.parse(result.body)
|
|
148
|
+
expect(body['id']).to match(/test-mode-mail-.+@localhost/)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
it 'does not make real HTTP calls in test mode' do
|
|
152
|
+
expect(client.instance_variable_get(:@http_client)).not_to receive(:post)
|
|
153
|
+
client.send_message(domain, message_params)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
it 'records a copy of message data in .deliveries' do
|
|
157
|
+
client.send_message(domain, message_params)
|
|
158
|
+
expect(described_class.deliveries.last[:subject]).to eq('Hello!')
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
context 'with a MessageBuilder object' do
|
|
162
|
+
it 'stores the MessageBuilder in .deliveries' do
|
|
163
|
+
mb = Mailgun::MessageBuilder.new
|
|
164
|
+
mb.set_from_address('bob@example.com')
|
|
165
|
+
mb.add_recipient(:to, 'sally@example.com')
|
|
166
|
+
mb.set_subject('Hello via builder!')
|
|
167
|
+
mb.set_text_body('Body text.')
|
|
168
|
+
|
|
169
|
+
result = client.send_message(domain, mb)
|
|
170
|
+
expect(result).to be_a(Mailgun::Response)
|
|
171
|
+
expect(described_class.deliveries.last).to be_a(Mailgun::MessageBuilder)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
it 'raises a Mailgun::ParameterError when mb is empty' do
|
|
175
|
+
mb = Mailgun::MessageBuilder.new
|
|
176
|
+
|
|
177
|
+
expect { client.send_message(domain, mb) }
|
|
178
|
+
.to raise_error(Mailgun::ParameterError)
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
it 'raises a Mailgun::ParameterError when from is missing' do
|
|
182
|
+
mb = Mailgun::MessageBuilder.new
|
|
183
|
+
mb.add_recipient(:to, 'sally@example.com')
|
|
184
|
+
|
|
185
|
+
expect { client.send_message(domain, mb) }
|
|
186
|
+
.to raise_error(Mailgun::ParameterError)
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# ---------------------------------------------------------------------------
|
|
192
|
+
# #send_message — live mode (HTTP mocked at the Faraday level)
|
|
193
|
+
# ---------------------------------------------------------------------------
|
|
194
|
+
describe '#send_message (live mode)' do
|
|
195
|
+
subject(:live_client) do
|
|
196
|
+
described_class.new(api_key, 'api.mailgun.net', 'v3', true, false)
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
let(:success_response) { fake_http_response }
|
|
200
|
+
|
|
201
|
+
before do
|
|
202
|
+
allow(live_client.instance_variable_get(:@http_client))
|
|
203
|
+
.to receive(:post)
|
|
204
|
+
.and_return(success_response)
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
it 'posts to the messages endpoint and returns a Response' do
|
|
208
|
+
result = live_client.send_message(domain, message_params)
|
|
209
|
+
expect(result).to be_a(Mailgun::Response)
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
it 'strips nil values from the data hash before posting' do
|
|
213
|
+
params_with_nil = message_params.merge(cc: nil)
|
|
214
|
+
http = live_client.instance_variable_get(:@http_client)
|
|
215
|
+
expect(http).to receive(:post) do |_path, data, *|
|
|
216
|
+
expect(data).not_to have_key(:cc)
|
|
217
|
+
success_response
|
|
218
|
+
end
|
|
219
|
+
live_client.send_message(domain, params_with_nil)
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
it 'raises CommunicationError when the underlying request fails' do
|
|
223
|
+
allow(live_client.instance_variable_get(:@http_client))
|
|
224
|
+
.to receive(:post)
|
|
225
|
+
.and_raise(StandardError, 'connection refused')
|
|
226
|
+
|
|
227
|
+
expect { live_client.send_message(domain, message_params) }
|
|
228
|
+
.to raise_error(Mailgun::CommunicationError)
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
context 'with a MessageBuilder object' do
|
|
232
|
+
it 'posts to the messages endpoint and returns a Response' do
|
|
233
|
+
mb = Mailgun::MessageBuilder.new
|
|
234
|
+
mb.set_from_address('bob@example.com')
|
|
235
|
+
mb.add_recipient(:to, 'sally@example.com')
|
|
236
|
+
mb.set_subject('Hello via builder!')
|
|
237
|
+
mb.set_text_body('Body text.')
|
|
238
|
+
|
|
239
|
+
result = live_client.send_message(domain, mb)
|
|
240
|
+
expect(result).to be_a(Mailgun::Response)
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
# ---------------------------------------------------------------------------
|
|
246
|
+
# #get
|
|
247
|
+
# ---------------------------------------------------------------------------
|
|
248
|
+
describe '#get' do
|
|
249
|
+
let(:http_response) { fake_http_response }
|
|
250
|
+
|
|
251
|
+
before do
|
|
252
|
+
allow(client.instance_variable_get(:@http_client))
|
|
253
|
+
.to receive(:get)
|
|
254
|
+
.and_return(http_response)
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
it 'returns a Mailgun::Response' do
|
|
258
|
+
result = client.get("#{domain}/events", { event: 'delivered' })
|
|
259
|
+
expect(result).to be_a(Mailgun::Response)
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
it 'passes the resource path through to the http client' do
|
|
263
|
+
http = client.instance_variable_get(:@http_client)
|
|
264
|
+
expect(http).to receive(:get).with("#{domain}/events", anything, anything)
|
|
265
|
+
.and_return(http_response)
|
|
266
|
+
client.get("#{domain}/events")
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
it 'raises CommunicationError on failure' do
|
|
270
|
+
allow(client.instance_variable_get(:@http_client))
|
|
271
|
+
.to receive(:get)
|
|
272
|
+
.and_raise(StandardError, 'timeout')
|
|
273
|
+
|
|
274
|
+
expect { client.get("#{domain}/events") }
|
|
275
|
+
.to raise_error(Mailgun::CommunicationError)
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
# ---------------------------------------------------------------------------
|
|
280
|
+
# #post
|
|
281
|
+
# ---------------------------------------------------------------------------
|
|
282
|
+
describe '#post' do
|
|
283
|
+
let(:http_response) { fake_http_response }
|
|
284
|
+
|
|
285
|
+
before do
|
|
286
|
+
allow(client.instance_variable_get(:@http_client))
|
|
287
|
+
.to receive(:post)
|
|
288
|
+
.and_return(http_response)
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
it 'returns a Mailgun::Response' do
|
|
292
|
+
result = client.post("#{domain}/messages", message_params)
|
|
293
|
+
expect(result).to be_a(Mailgun::Response)
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
it 'raises CommunicationError on failure' do
|
|
297
|
+
allow(client.instance_variable_get(:@http_client))
|
|
298
|
+
.to receive(:post)
|
|
299
|
+
.and_raise(StandardError, 'connection error')
|
|
300
|
+
|
|
301
|
+
expect { client.post("#{domain}/messages", message_params) }
|
|
302
|
+
.to raise_error(Mailgun::CommunicationError)
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
# ---------------------------------------------------------------------------
|
|
307
|
+
# #put
|
|
308
|
+
# ---------------------------------------------------------------------------
|
|
309
|
+
describe '#put' do
|
|
310
|
+
let(:http_response) { fake_http_response }
|
|
311
|
+
|
|
312
|
+
before do
|
|
313
|
+
allow(client.instance_variable_get(:@http_client))
|
|
314
|
+
.to receive(:put)
|
|
315
|
+
.and_return(http_response)
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
it 'returns a Mailgun::Response' do
|
|
319
|
+
result = client.put("#{domain}/routes/abc123", { description: 'updated' })
|
|
320
|
+
expect(result).to be_a(Mailgun::Response)
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
it 'raises CommunicationError on failure' do
|
|
324
|
+
allow(client.instance_variable_get(:@http_client))
|
|
325
|
+
.to receive(:put)
|
|
326
|
+
.and_raise(StandardError, 'connection error')
|
|
327
|
+
|
|
328
|
+
expect { client.put("#{domain}/routes/abc123", {}) }
|
|
329
|
+
.to raise_error(Mailgun::CommunicationError)
|
|
330
|
+
end
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
# ---------------------------------------------------------------------------
|
|
334
|
+
# #delete
|
|
335
|
+
# ---------------------------------------------------------------------------
|
|
336
|
+
describe '#delete' do
|
|
337
|
+
let(:http_response) { fake_http_response(body: '{"message":"Bounced address has been removed"}') }
|
|
338
|
+
|
|
339
|
+
before do
|
|
340
|
+
allow(client.instance_variable_get(:@http_client))
|
|
341
|
+
.to receive(:delete)
|
|
342
|
+
.and_return(http_response)
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
it 'returns a Mailgun::Response' do
|
|
346
|
+
result = client.delete("#{domain}/bounces/test@example.com")
|
|
347
|
+
expect(result).to be_a(Mailgun::Response)
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
it 'raises CommunicationError on failure' do
|
|
351
|
+
allow(client.instance_variable_get(:@http_client))
|
|
352
|
+
.to receive(:delete)
|
|
353
|
+
.and_raise(StandardError, 'connection error')
|
|
354
|
+
|
|
355
|
+
expect { client.delete("#{domain}/bounces/test@example.com") }
|
|
356
|
+
.to raise_error(Mailgun::CommunicationError)
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
it 'sends params in the request' do
|
|
360
|
+
result = client.delete("#{domain}/bounces/test@example.com", params: 'test')
|
|
361
|
+
expect(result).to be_a(Mailgun::Response)
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
it 'sends params in the request when body_params truthy' do
|
|
365
|
+
result = client.delete("#{domain}/bounces/test@example.com", params: 'test', body_params: true)
|
|
366
|
+
expect(result).to be_a(Mailgun::Response)
|
|
367
|
+
end
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
# ---------------------------------------------------------------------------
|
|
371
|
+
# #set_api_key
|
|
372
|
+
# ---------------------------------------------------------------------------
|
|
373
|
+
describe '#set_api_key' do
|
|
374
|
+
it 'does not raise when updating the api key' do
|
|
375
|
+
expect { client.set_api_key('new-key-xyz') }.not_to raise_error
|
|
376
|
+
end
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
# ---------------------------------------------------------------------------
|
|
380
|
+
# #set_subaccount / #reset_subaccount
|
|
381
|
+
# ---------------------------------------------------------------------------
|
|
382
|
+
describe '#set_subaccount' do
|
|
383
|
+
it 'adds the subaccount header to the http client' do
|
|
384
|
+
client.set_subaccount('subaccount-id-123')
|
|
385
|
+
headers = client.instance_variable_get(:@http_client).headers
|
|
386
|
+
expect(headers[Mailgun::Client::SUBACCOUNT_HEADER]).to eq('subaccount-id-123')
|
|
387
|
+
end
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
describe '#reset_subaccount' do
|
|
391
|
+
it 'removes the subaccount header from the http client' do
|
|
392
|
+
client.set_subaccount('subaccount-id-123')
|
|
393
|
+
client.reset_subaccount
|
|
394
|
+
headers = client.instance_variable_get(:@http_client).headers
|
|
395
|
+
expect(headers[Mailgun::Client::SUBACCOUNT_HEADER]).to be_nil
|
|
396
|
+
end
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
# ---------------------------------------------------------------------------
|
|
400
|
+
# #suppressions
|
|
401
|
+
# ---------------------------------------------------------------------------
|
|
402
|
+
describe '#suppressions' do
|
|
403
|
+
it 'returns a Mailgun::Suppressions instance' do
|
|
404
|
+
expect(client.suppressions(domain)).to be_a(Mailgun::Suppressions)
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
it 'scopes the suppressions client to the given domain' do
|
|
408
|
+
suppressions = client.suppressions(domain)
|
|
409
|
+
expect(suppressions).to be_a(Mailgun::Suppressions)
|
|
410
|
+
end
|
|
411
|
+
end
|
|
412
|
+
|
|
413
|
+
# ---------------------------------------------------------------------------
|
|
414
|
+
# Mailgun.configure integration
|
|
415
|
+
# ---------------------------------------------------------------------------
|
|
416
|
+
describe 'Mailgun.configure integration' do
|
|
417
|
+
after { Mailgun.instance_variable_set(:@configuration, nil) }
|
|
418
|
+
|
|
419
|
+
it 'picks up the api_key from Mailgun.configure' do
|
|
420
|
+
Mailgun.configure { |config| config.api_key = 'configured-key' }
|
|
421
|
+
expect { described_class.new }.not_to raise_error
|
|
422
|
+
end
|
|
423
|
+
end
|
|
424
|
+
end
|