mailgun-ruby 1.4.1 → 1.4.2
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/Gemfile +3 -1
- data/README.md +1 -1
- data/Rakefile +5 -3
- 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 +47 -51
- data/lib/mailgun/domains/domains.rb +7 -8
- 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 +4 -6
- data/lib/mailgun/logs/logs.rb +4 -2
- data/lib/mailgun/messages/batch_message.rb +8 -9
- data/lib/mailgun/messages/message_builder.rb +36 -24
- data/lib/mailgun/metrics/metrics.rb +6 -4
- data/lib/mailgun/response.rb +11 -9
- data/lib/mailgun/subaccounts/subaccounts.rb +13 -8
- data/lib/mailgun/suppressions.rb +36 -43
- data/lib/mailgun/tags/analytics_tags.rb +33 -2
- data/lib/mailgun/tags/tags.rb +25 -17
- 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 +9 -14
- data/lib/railgun/errors.rb +2 -3
- data/lib/railgun/mailer.rb +35 -39
- data/lib/railgun/railtie.rb +2 -0
- data/lib/railgun.rb +2 -0
- data/mailgun.gemspec +12 -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 +6 -6
- data/spec/integration/email_validation_spec.rb +35 -34
- data/spec/integration/events_spec.rb +7 -5
- data/spec/integration/list_members_spec.rb +27 -26
- data/spec/integration/list_spec.rb +22 -21
- data/spec/integration/logs_spec.rb +48 -46
- data/spec/integration/mailer_spec.rb +7 -3
- data/spec/integration/mailgun_spec.rb +82 -90
- data/spec/integration/metrics_spec.rb +130 -130
- 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 +21 -20
- data/spec/integration/templates_spec.rb +14 -12
- data/spec/integration/unsubscribes_spec.rb +8 -6
- data/spec/integration/webhook_spec.rb +13 -12
- data/spec/spec_helper.rb +8 -8
- data/spec/unit/connection/test_client.rb +61 -55
- data/spec/unit/events/events_spec.rb +25 -22
- data/spec/unit/exceptions/exceptions_spec.rb +8 -7
- data/spec/unit/lists/opt_in_handler_spec.rb +8 -6
- data/spec/unit/mailgun_spec.rb +64 -63
- data/spec/unit/messages/batch_message_spec.rb +15 -15
- data/spec/unit/messages/message_builder_spec.rb +98 -94
- data/spec/unit/railgun/content_type_spec.rb +24 -23
- data/spec/unit/railgun/mailer_spec.rb +58 -58
- data/vcr_cassettes/analytics_tags.yml +187 -0
- metadata +49 -33
- data/.rubocop.yml +0 -8
- data/.rubocop_todo.yml +0 -22
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'spec_helper'
|
|
2
4
|
require 'mailgun'
|
|
3
5
|
|
|
@@ -37,65 +39,65 @@ describe Mailgun::Logs, vcr: vcr_opts do
|
|
|
37
39
|
it 'responds with account logs' do
|
|
38
40
|
expect(logs.account_logs(options)).to eq(
|
|
39
41
|
{
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
'start' => 'Wed, 25 Jun 2025 00:00:00 -0000',
|
|
43
|
+
'end' => 'Wed, 25 Jun 2025 23:00:00 -0000',
|
|
44
|
+
'items' => [
|
|
43
45
|
{
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
'id' => '123',
|
|
47
|
+
'event' => 'accepted',
|
|
48
|
+
'@timestamp' => '2025-06-25T17:19:51.166Z',
|
|
49
|
+
'account' => {
|
|
50
|
+
'id' => '123'
|
|
49
51
|
},
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
'method' => 'HTTP',
|
|
53
|
+
'originating-ip' => '123.123.12.123',
|
|
54
|
+
'api-key-id' => 'xxx',
|
|
55
|
+
'domain' => {
|
|
56
|
+
'name' => 'example.mailgun.org'
|
|
55
57
|
},
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
'recipient' => 'alex@example.com',
|
|
59
|
+
'recipient-domain' => 'example.com',
|
|
60
|
+
'envelope' => {
|
|
61
|
+
'sender' => 'example.mailgun.org',
|
|
62
|
+
'transport' => 'smtp',
|
|
63
|
+
'targets' => 'alex@example.com'
|
|
62
64
|
},
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
'storage' => {
|
|
66
|
+
'region' => 'us-east4',
|
|
67
|
+
'env' => 'production',
|
|
68
|
+
'key' => 'xxx',
|
|
69
|
+
'url' => ['https://storage.api.mailgun.net/v3/domains/example.mailgun.org/messages/123']
|
|
68
70
|
},
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
71
|
+
'log-level' => 'info',
|
|
72
|
+
'user-variables' => '{}',
|
|
73
|
+
'message' => {
|
|
74
|
+
'headers' => {
|
|
75
|
+
'to' => 'alex@example.com',
|
|
76
|
+
'message-id' => '123@example.mailgun.org',
|
|
77
|
+
'from' => 'bob@sending_domain.com+4',
|
|
78
|
+
'subject' => 'The Ruby SDK is awesome!'
|
|
77
79
|
},
|
|
78
|
-
|
|
80
|
+
'attachments' => [
|
|
79
81
|
{
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
82
|
+
'filename' => 'image.jpg',
|
|
83
|
+
'content-type' => 'image/jpeg',
|
|
84
|
+
'size' => 16_712
|
|
83
85
|
}
|
|
84
86
|
],
|
|
85
|
-
|
|
87
|
+
'size' => 23_476
|
|
86
88
|
},
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
89
|
+
'flags' => {
|
|
90
|
+
'is-authenticated' => true,
|
|
91
|
+
'is-system-test' => false,
|
|
92
|
+
'is-routed' => false,
|
|
93
|
+
'is-test-mode' => false,
|
|
94
|
+
'is-delayed-bounce' => false,
|
|
95
|
+
'is-callback' => false
|
|
94
96
|
}
|
|
95
97
|
}
|
|
96
98
|
],
|
|
97
|
-
|
|
98
|
-
|
|
99
|
+
'pagination' => {},
|
|
100
|
+
'aggregates' => {}
|
|
99
101
|
}
|
|
100
102
|
)
|
|
101
103
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'spec_helper'
|
|
2
4
|
require 'json'
|
|
3
5
|
require 'logger'
|
|
@@ -21,7 +23,7 @@ class IntegrationUnitTestMailer < ActionMailer::Base
|
|
|
21
23
|
end
|
|
22
24
|
end
|
|
23
25
|
|
|
24
|
-
vcr_opts = { :
|
|
26
|
+
vcr_opts = { cassette_name: 'message_deliver' }
|
|
25
27
|
|
|
26
28
|
describe 'Message deliver', vcr: vcr_opts do
|
|
27
29
|
let(:domain) { TESTDOMAIN || 'DOMAIN.TEST' }
|
|
@@ -43,7 +45,7 @@ describe 'Message deliver', vcr: vcr_opts do
|
|
|
43
45
|
end
|
|
44
46
|
end
|
|
45
47
|
|
|
46
|
-
vcr_opts = { :
|
|
48
|
+
vcr_opts = { cassette_name: 'mailer_invalid_domain' }
|
|
47
49
|
|
|
48
50
|
describe 'Invalid domain', vcr: vcr_opts do
|
|
49
51
|
let(:domain) { 'not-our-doma.in' }
|
|
@@ -56,6 +58,8 @@ describe 'Invalid domain', vcr: vcr_opts do
|
|
|
56
58
|
let(:mail) { IntegrationUnitTestMailer.plain_message('sally@not-our-doma.in', "bob@#{domain}", 'subject', {}) }
|
|
57
59
|
|
|
58
60
|
it 'raises expected error' do
|
|
59
|
-
expect
|
|
61
|
+
expect do
|
|
62
|
+
Railgun::Mailer.new(config).deliver!(mail)
|
|
63
|
+
end.to raise_error Mailgun::Unauthorized, /Invalid Domain or API key/
|
|
60
64
|
end
|
|
61
65
|
end
|
|
@@ -1,105 +1,99 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'spec_helper'
|
|
2
4
|
require 'mailgun'
|
|
3
5
|
require 'mailgun/exceptions/exceptions'
|
|
4
6
|
|
|
5
|
-
describe 'Mailgun instantiation', vcr: { :
|
|
7
|
+
describe 'Mailgun instantiation', vcr: { cassette_name: 'instance' } do
|
|
6
8
|
it 'instantiates an HttpClient object' do
|
|
7
|
-
expect {@mg_obj = Mailgun::Client.new(APIKEY, APIHOST, APIVERSION, SSL)}.not_to raise_error
|
|
9
|
+
expect { @mg_obj = Mailgun::Client.new(APIKEY, APIHOST, APIVERSION, SSL) }.not_to raise_error
|
|
8
10
|
end
|
|
9
11
|
end
|
|
10
12
|
|
|
11
|
-
describe 'Client exceptions', vcr: { :
|
|
13
|
+
describe 'Client exceptions', vcr: { cassette_name: 'exceptions' } do
|
|
12
14
|
before(:all) do
|
|
13
15
|
@mg_obj = Mailgun::Client.new(APIKEY, APIHOST, APIVERSION, SSL)
|
|
14
16
|
@domain = TESTDOMAIN || 'DOMAIN.TEST'
|
|
15
17
|
end
|
|
16
18
|
|
|
17
19
|
it 'display useful error information' do
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
fail
|
|
30
|
-
end
|
|
20
|
+
@mg_obj.send_message('not-our-doma.in', {
|
|
21
|
+
from: 'sally@not-our-doma.in',
|
|
22
|
+
to: "bob@#{@domain}",
|
|
23
|
+
subject: 'Exception Integration Test',
|
|
24
|
+
text: 'INTEGRATION TESTING'
|
|
25
|
+
})
|
|
26
|
+
rescue Mailgun::CommunicationError => e
|
|
27
|
+
expect(e.message).to include('404')
|
|
28
|
+
expect(e.message).to include('Domain not found: not-our-doma.in')
|
|
29
|
+
else
|
|
30
|
+
raise
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
-
describe 'Client exceptions', vcr: { :
|
|
34
|
+
describe 'Client exceptions', vcr: { cassette_name: 'exceptions-invalid-api-key' } do
|
|
35
35
|
before(:all) do
|
|
36
36
|
@mg_obj = Mailgun::Client.new(APIKEY, APIHOST, APIVERSION, SSL)
|
|
37
37
|
@domain = TESTDOMAIN || 'DOMAIN.TEST'
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
it 'displays error information that API key is invalid' do
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
fail
|
|
53
|
-
end
|
|
41
|
+
@mg_obj.send_message(@domain, {
|
|
42
|
+
from: "sally@#{@domain}",
|
|
43
|
+
to: "sally@#{@domain}",
|
|
44
|
+
subject: 'Exception Integration Test',
|
|
45
|
+
text: 'INTEGRATION TESTING'
|
|
46
|
+
})
|
|
47
|
+
rescue Mailgun::Unauthorized => e
|
|
48
|
+
expect(e.message).to include('401')
|
|
49
|
+
expect(e.message).to include('Invalid Domain or API key')
|
|
50
|
+
else
|
|
51
|
+
raise
|
|
54
52
|
end
|
|
55
53
|
end
|
|
56
54
|
|
|
57
|
-
describe 'Client exceptions', vcr: { :
|
|
55
|
+
describe 'Client exceptions', vcr: { cassette_name: 'exceptions-invalid-data' } do
|
|
58
56
|
before(:all) do
|
|
59
57
|
@mg_obj = Mailgun::Client.new(APIKEY, APIHOST, APIVERSION, SSL)
|
|
60
58
|
@domain = TESTDOMAIN || 'DOMAIN.TEST'
|
|
61
59
|
end
|
|
62
60
|
|
|
63
61
|
it 'display useful error information' do
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
fail
|
|
76
|
-
end
|
|
62
|
+
@mg_obj.send_message(@domain, {
|
|
63
|
+
from: "sally@#{@domain}",
|
|
64
|
+
to: "sally#{@domain}",
|
|
65
|
+
subject: 'Exception Integration Test',
|
|
66
|
+
text: 'INTEGRATION TESTING'
|
|
67
|
+
})
|
|
68
|
+
rescue Mailgun::BadRequest => e
|
|
69
|
+
expect(e.message).to include('400')
|
|
70
|
+
expect(e.message).to include('to parameter is not a valid address. please check documentation')
|
|
71
|
+
else
|
|
72
|
+
raise
|
|
77
73
|
end
|
|
78
74
|
end
|
|
79
75
|
|
|
80
|
-
describe 'Client exceptions', vcr: { :
|
|
76
|
+
describe 'Client exceptions', vcr: { cassette_name: 'exceptions-not-allowed' } do
|
|
81
77
|
before(:all) do
|
|
82
78
|
@mg_obj = Mailgun::Client.new(APIKEY, APIHOST, APIVERSION, SSL)
|
|
83
79
|
@domain = TESTDOMAIN || 'DOMAIN.TEST'
|
|
84
80
|
end
|
|
85
81
|
|
|
86
82
|
it 'display useful error information' do
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
fail
|
|
98
|
-
end
|
|
83
|
+
@mg_obj.send_message(@domain, {
|
|
84
|
+
from: "invalid@#{@domain}",
|
|
85
|
+
to: "invalid#{@domain}",
|
|
86
|
+
subject: 'Exception Integration Test',
|
|
87
|
+
text: 'INTEGRATION TESTING'
|
|
88
|
+
})
|
|
89
|
+
rescue Mailgun::CommunicationError => e
|
|
90
|
+
expect(e.message).to include('403')
|
|
91
|
+
else
|
|
92
|
+
raise
|
|
99
93
|
end
|
|
100
94
|
end
|
|
101
95
|
|
|
102
|
-
describe 'The method send_message()', vcr: { :
|
|
96
|
+
describe 'The method send_message()', vcr: { cassette_name: 'send_message' } do
|
|
103
97
|
before(:all) do
|
|
104
98
|
@mg_obj = Mailgun::Client.new(APIKEY, APIHOST, APIVERSION, SSL)
|
|
105
99
|
@domain = TESTDOMAIN || 'DOMAIN.TEST'
|
|
@@ -107,15 +101,14 @@ describe 'The method send_message()', vcr: { :cassette_name => "send_message" }
|
|
|
107
101
|
|
|
108
102
|
it 'sends a standard message in test mode.' do
|
|
109
103
|
@mg_obj.enable_test_mode!
|
|
110
|
-
result = @mg_obj.send_message(@domain, {:from => "bob@#{@domain}",
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
)
|
|
104
|
+
result = @mg_obj.send_message(@domain, { :from => "bob@#{@domain}",
|
|
105
|
+
:to => "sally@#{@domain}",
|
|
106
|
+
:subject => 'Hash Integration Test',
|
|
107
|
+
:text => 'INTEGRATION TESTING',
|
|
108
|
+
'o:testmode' => true })
|
|
116
109
|
result.to_h!
|
|
117
|
-
expect(result.body).to include(
|
|
118
|
-
expect(result.body).to include(
|
|
110
|
+
expect(result.body).to include('message')
|
|
111
|
+
expect(result.body).to include('id')
|
|
119
112
|
end
|
|
120
113
|
|
|
121
114
|
it 'fakes message send while in *client* test mode' do
|
|
@@ -123,10 +116,10 @@ describe 'The method send_message()', vcr: { :cassette_name => "send_message" }
|
|
|
123
116
|
|
|
124
117
|
expect(@mg_obj.test_mode?).to eq(true)
|
|
125
118
|
|
|
126
|
-
data = { :
|
|
127
|
-
:
|
|
128
|
-
:
|
|
129
|
-
:
|
|
119
|
+
data = { from: "joe@#{@domain}",
|
|
120
|
+
to: "bob@#{@domain}",
|
|
121
|
+
subject: 'Test',
|
|
122
|
+
text: 'Test Data' }
|
|
130
123
|
uuid = 'uuid'
|
|
131
124
|
|
|
132
125
|
allow(SecureRandom).to receive(:uuid).and_return(uuid)
|
|
@@ -135,27 +128,27 @@ describe 'The method send_message()', vcr: { :cassette_name => "send_message" }
|
|
|
135
128
|
|
|
136
129
|
result.to_h!
|
|
137
130
|
|
|
138
|
-
expect(result.body).to include(
|
|
139
|
-
expect(result.body).to include(
|
|
131
|
+
expect(result.body).to include('message')
|
|
132
|
+
expect(result.body).to include('id')
|
|
140
133
|
|
|
141
134
|
expect(result.code).to eq(200)
|
|
142
135
|
expect(result.body['id']).to eq("test-mode-mail-#{uuid}@localhost")
|
|
143
|
-
expect(result.body['message']).to eq(
|
|
136
|
+
expect(result.body['message']).to eq('Queued. Thank you.')
|
|
144
137
|
end
|
|
145
138
|
|
|
146
139
|
it 'sends a message builder message in test mode.' do
|
|
147
|
-
mb_obj = Mailgun::MessageBuilder.new
|
|
148
|
-
mb_obj.from("sender@#{@domain}", {'first' => 'Sending', 'last' => 'User'})
|
|
149
|
-
mb_obj.add_recipient(:to, "recipient@#{@domain}", {'first' => 'Recipient', 'last' => 'User'})
|
|
150
|
-
mb_obj.subject(
|
|
151
|
-
mb_obj.body_text(
|
|
140
|
+
mb_obj = Mailgun::MessageBuilder.new
|
|
141
|
+
mb_obj.from("sender@#{@domain}", { 'first' => 'Sending', 'last' => 'User' })
|
|
142
|
+
mb_obj.add_recipient(:to, "recipient@#{@domain}", { 'first' => 'Recipient', 'last' => 'User' })
|
|
143
|
+
mb_obj.subject('Message Builder Integration Test')
|
|
144
|
+
mb_obj.body_text('This is the text body.')
|
|
152
145
|
mb_obj.test_mode(true)
|
|
153
146
|
|
|
154
147
|
result = @mg_obj.send_message(@domain, mb_obj)
|
|
155
148
|
|
|
156
149
|
result.to_h!
|
|
157
|
-
expect(result.body).to include(
|
|
158
|
-
expect(result.body).to include(
|
|
150
|
+
expect(result.body).to include('message')
|
|
151
|
+
expect(result.body).to include('id')
|
|
159
152
|
end
|
|
160
153
|
|
|
161
154
|
it 'sends a custom MIME message in test mode.' do
|
|
@@ -175,15 +168,15 @@ Sender: me@samples.mailgun.org
|
|
|
175
168
|
|
|
176
169
|
Testing some Mailgun awesomness!'
|
|
177
170
|
|
|
178
|
-
message_params = {:
|
|
179
|
-
|
|
180
|
-
|
|
171
|
+
message_params = { from: "bobby@#{@domain}",
|
|
172
|
+
to: "sally@#{@domain}",
|
|
173
|
+
message: mime_string }
|
|
181
174
|
|
|
182
175
|
result = @mg_obj.send_message(@domain, message_params)
|
|
183
176
|
|
|
184
177
|
result.to_h!
|
|
185
|
-
expect(result.body).to include(
|
|
186
|
-
expect(result.body).to include(
|
|
178
|
+
expect(result.body).to include('message')
|
|
179
|
+
expect(result.body).to include('id')
|
|
187
180
|
end
|
|
188
181
|
|
|
189
182
|
it 'receives success response code' do
|
|
@@ -191,10 +184,10 @@ Testing some Mailgun awesomness!'
|
|
|
191
184
|
|
|
192
185
|
expect(@mg_obj.test_mode?).to eq(true)
|
|
193
186
|
|
|
194
|
-
data = { :
|
|
195
|
-
:
|
|
196
|
-
:
|
|
197
|
-
:
|
|
187
|
+
data = { from: "joe@#{@domain}",
|
|
188
|
+
to: "bob@#{@domain}",
|
|
189
|
+
subject: 'Test',
|
|
190
|
+
text: 'Test Data' }
|
|
198
191
|
|
|
199
192
|
result = @mg_obj.send_message(@domain, data)
|
|
200
193
|
result.to_h!
|
|
@@ -202,4 +195,3 @@ Testing some Mailgun awesomness!'
|
|
|
202
195
|
expect(result.success?).to be(true)
|
|
203
196
|
end
|
|
204
197
|
end
|
|
205
|
-
|