mailgun-ruby 1.1.9 → 1.2.13
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/.rubocop.yml +0 -0
- data/.rubocop_todo.yml +0 -0
- data/.ruby-env.yml.example +1 -0
- data/.travis.yml +6 -5
- data/CHANGELOG.md +16 -0
- data/Gemfile +1 -1
- data/README.md +30 -3
- data/docs/Domains.md +3 -0
- data/docs/EmailValidation.md +34 -0
- data/docs/OptInHandler.md +1 -1
- data/docs/Snippets.md +54 -61
- data/docs/Subaccounts.md +68 -0
- data/docs/Suppressions.md +10 -0
- data/docs/Webhooks.md +0 -0
- data/docs/railgun/EmailValidation.md +34 -0
- data/docs/railgun/Overview.md +11 -0
- data/docs/railgun/Parameters.md +83 -0
- data/docs/railgun/Templates.md +92 -0
- data/lib/mailgun/address.rb +3 -28
- data/lib/mailgun/chains.rb +0 -0
- data/lib/mailgun/client.rb +55 -9
- data/lib/mailgun/domains/domains.rb +20 -2
- data/lib/mailgun/events/events.rb +2 -2
- data/lib/mailgun/exceptions/exceptions.rb +28 -1
- data/lib/mailgun/messages/batch_message.rb +1 -0
- data/lib/mailgun/messages/message_builder.rb +56 -8
- data/lib/mailgun/response.rb +7 -0
- data/lib/mailgun/subaccounts/subaccounts.rb +84 -0
- data/lib/mailgun/suppressions.rb +15 -8
- data/lib/mailgun/templates/templates.rb +187 -0
- data/lib/mailgun/version.rb +1 -1
- data/lib/mailgun/webhooks/webhooks.rb +2 -2
- data/lib/mailgun-ruby.rb +1 -1
- data/lib/mailgun.rb +5 -1
- data/lib/railgun/mailer.rb +85 -12
- data/lib/railgun/message.rb +2 -1
- data/lib/railgun/railtie.rb +3 -2
- data/mailgun.gemspec +15 -12
- data/spec/integration/bounces_spec.rb +3 -3
- data/spec/integration/campaign_spec.rb +0 -0
- data/spec/integration/complaints_spec.rb +0 -0
- data/spec/integration/domains_spec.rb +8 -0
- data/spec/integration/email_validation_spec.rb +10 -2
- data/spec/integration/events_spec.rb +1 -1
- data/spec/integration/list_members_spec.rb +0 -0
- data/spec/integration/list_spec.rb +0 -0
- data/spec/integration/mailer_spec.rb +67 -0
- data/spec/integration/mailgun_spec.rb +92 -1
- data/spec/integration/routes_spec.rb +0 -0
- data/spec/integration/stats_spec.rb +0 -0
- data/spec/integration/subaccounts_spec.rb +58 -0
- data/spec/integration/suppressions_spec.rb +18 -2
- data/spec/integration/templates_spec.rb +135 -0
- data/spec/integration/unsubscribes_spec.rb +0 -0
- data/spec/integration/webhook_spec.rb +0 -0
- data/spec/spec_helper.rb +3 -1
- data/spec/unit/connection/test_client.rb +18 -1
- data/spec/unit/events/events_spec.rb +19 -0
- data/spec/unit/mailgun_spec.rb +43 -2
- data/spec/unit/messages/batch_message_spec.rb +56 -40
- data/spec/unit/messages/message_builder_spec.rb +149 -16
- data/spec/unit/messages/sample_data/unknown.type +0 -0
- data/spec/unit/railgun/mailer_spec.rb +388 -0
- data/vcr_cassettes/bounces.yml +12 -12
- data/vcr_cassettes/complaints.yml +0 -0
- data/vcr_cassettes/domains.todo.yml +0 -0
- data/vcr_cassettes/domains.yml +51 -1
- data/vcr_cassettes/email_validation.yml +5 -5
- data/vcr_cassettes/events.yml +0 -0
- data/vcr_cassettes/exceptions-invalid-api-key.yml +52 -0
- data/vcr_cassettes/exceptions-invalid-data.yml +52 -0
- data/vcr_cassettes/exceptions-not-allowed.yml +54 -0
- data/vcr_cassettes/list_members.yml +0 -0
- data/vcr_cassettes/mailer_invalid_domain.yml +109 -0
- data/vcr_cassettes/mailing_list.todo.yml +0 -0
- data/vcr_cassettes/mailing_list.yml +0 -0
- data/vcr_cassettes/message_deliver.yml +149 -0
- data/vcr_cassettes/routes.yml +0 -0
- data/vcr_cassettes/send_message.yml +0 -0
- data/vcr_cassettes/stats.yml +0 -0
- data/vcr_cassettes/subaccounts.yml +270 -0
- data/vcr_cassettes/suppressions.yml +66 -15
- data/vcr_cassettes/templates.yml +1065 -0
- data/vcr_cassettes/unsubscribes.yml +0 -0
- data/vcr_cassettes/webhooks.yml +0 -0
- metadata +56 -29
- data/.ruby-version +0 -1
- /data/spec/unit/{railgun_spec.rb → railgun/content_type_spec.rb} +0 -0
data/lib/railgun/mailer.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'action_mailer'
|
2
|
+
require 'json'
|
2
3
|
require 'mailgun'
|
3
4
|
require 'rails'
|
4
5
|
require 'railgun/errors'
|
@@ -9,6 +10,9 @@ module Railgun
|
|
9
10
|
# Mailgun.
|
10
11
|
class Mailer
|
11
12
|
|
13
|
+
# List of the headers that will be ignored when copying headers from `mail.header_fields`
|
14
|
+
IGNORED_HEADERS = %w[ to from subject reply-to mime-version template ]
|
15
|
+
|
12
16
|
# [Hash] config ->
|
13
17
|
# Requires *at least* `api_key` and `domain` keys.
|
14
18
|
attr_accessor :config, :domain, :settings
|
@@ -23,7 +27,14 @@ module Railgun
|
|
23
27
|
raise Railgun::ConfigurationError.new("Config requires `#{k}` key", @config) unless @config.has_key?(k)
|
24
28
|
end
|
25
29
|
|
26
|
-
@mg_client = Mailgun::Client.new(
|
30
|
+
@mg_client = Mailgun::Client.new(
|
31
|
+
config[:api_key],
|
32
|
+
config[:api_host] || 'api.mailgun.net',
|
33
|
+
config[:api_version] || 'v3',
|
34
|
+
config[:api_ssl].nil? ? true : config[:api_ssl],
|
35
|
+
false,
|
36
|
+
config[:timeout]
|
37
|
+
)
|
27
38
|
@domain = @config[:domain]
|
28
39
|
|
29
40
|
# To avoid exception in mail gem v2.6
|
@@ -36,8 +47,16 @@ module Railgun
|
|
36
47
|
end
|
37
48
|
|
38
49
|
def deliver!(mail)
|
50
|
+
@mg_domain = set_mg_domain(mail)
|
51
|
+
@mg_client.set_api_key(mail[:api_key].value) if mail[:api_key].present?
|
52
|
+
@mg_client.set_subaccount(mail[:subaccount_id].value) if mail[:subaccount_id].present?
|
53
|
+
|
54
|
+
mail[:domain] = nil if mail[:domain].present?
|
55
|
+
mail[:api_key] = nil if mail[:api_key].present?
|
56
|
+
mail[:subaccount_id] = nil if mail[:subaccount_id].present?
|
57
|
+
|
39
58
|
mg_message = Railgun.transform_for_mailgun(mail)
|
40
|
-
response = @mg_client.send_message(@
|
59
|
+
response = @mg_client.send_message(@mg_domain, mg_message)
|
41
60
|
|
42
61
|
if response.code == 200 then
|
43
62
|
mg_id = response.to_h['id']
|
@@ -47,7 +66,15 @@ module Railgun
|
|
47
66
|
end
|
48
67
|
|
49
68
|
def mailgun_client
|
50
|
-
@
|
69
|
+
@mg_client
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
# Set @mg_domain from mail[:domain] header if present, then remove it to prevent being sent.
|
75
|
+
def set_mg_domain(mail)
|
76
|
+
return mail[:domain].value if mail[:domain]
|
77
|
+
domain
|
51
78
|
end
|
52
79
|
|
53
80
|
end
|
@@ -58,24 +85,60 @@ module Railgun
|
|
58
85
|
# After prefixing them with the proper option type, they are added to
|
59
86
|
# the message hash where they will then be sent to the API as JSON.
|
60
87
|
#
|
88
|
+
# It is important to note that headers set in `mailgun_headers` on the message
|
89
|
+
# WILL overwrite headers set via `mail.headers()`.
|
90
|
+
#
|
61
91
|
# @param [Mail::Message] mail message to transform
|
62
92
|
#
|
63
93
|
# @return [Hash] transformed message hash
|
64
94
|
def transform_for_mailgun(mail)
|
65
95
|
message = build_message_object(mail)
|
66
96
|
|
67
|
-
# v:* attributes (variables)
|
68
|
-
mail.mailgun_variables.try(:each) do |k, v|
|
69
|
-
message["v:#{k}"] = v
|
70
|
-
end
|
71
|
-
|
72
97
|
# o:* attributes (options)
|
73
98
|
mail.mailgun_options.try(:each) do |k, v|
|
74
|
-
message["o:#{k}"] = v
|
99
|
+
message["o:#{k}"] = v.dup
|
75
100
|
end
|
76
101
|
|
102
|
+
# t:* attributes (options)
|
103
|
+
mail.mailgun_template_variables.try(:each) do |k, v|
|
104
|
+
message["t:#{k}"] = v.dup
|
105
|
+
end
|
106
|
+
|
107
|
+
# support for using ActionMailer's `headers()` inside of the mailer
|
108
|
+
# note: this will filter out parameters such as `from`, `to`, and so forth
|
109
|
+
# as they are accepted as POST parameters on the message endpoint.
|
110
|
+
|
111
|
+
msg_headers = Hash.new
|
112
|
+
|
77
113
|
# h:* attributes (headers)
|
78
|
-
|
114
|
+
|
115
|
+
# Let's set all of these headers on the [Mail::Message] so that
|
116
|
+
# the are created inside of a [Mail::Header] instance and processed there.
|
117
|
+
mail.headers(mail.mailgun_headers || {})
|
118
|
+
mail.header_fields.each do |field|
|
119
|
+
header = field.name.downcase
|
120
|
+
if msg_headers.include? header
|
121
|
+
msg_headers[header] = [msg_headers[header], field.value].flatten
|
122
|
+
else
|
123
|
+
msg_headers[header] = field.value
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
msg_headers.each do |k, v|
|
128
|
+
if Railgun::Mailer::IGNORED_HEADERS.include? k.downcase
|
129
|
+
Rails.logger.debug("[railgun] ignoring header (using envelope instead): #{k}")
|
130
|
+
next
|
131
|
+
end
|
132
|
+
|
133
|
+
# Cover cases like `cc`, `bcc` where parameters are valid
|
134
|
+
# headers BUT they are submitted as separate POST params
|
135
|
+
# and already exist on the message because of the call to
|
136
|
+
# `build_message_object`.
|
137
|
+
if message.include? k.downcase
|
138
|
+
Rails.logger.debug("[railgun] ignoring header (already set): #{k}")
|
139
|
+
next
|
140
|
+
end
|
141
|
+
|
79
142
|
message["h:#{k}"] = v
|
80
143
|
end
|
81
144
|
|
@@ -84,7 +147,12 @@ module Railgun
|
|
84
147
|
|
85
148
|
# reject blank values
|
86
149
|
message.delete_if do |k, v|
|
87
|
-
|
150
|
+
next true if v.nil?
|
151
|
+
|
152
|
+
# if it's an array remove empty elements
|
153
|
+
v.delete_if { |i| i.respond_to?(:empty?) && i.empty? } if v.is_a?(Array)
|
154
|
+
|
155
|
+
v.respond_to?(:empty?) && v.empty?
|
88
156
|
end
|
89
157
|
|
90
158
|
return message
|
@@ -101,6 +169,7 @@ module Railgun
|
|
101
169
|
|
102
170
|
mb.from mail[:from]
|
103
171
|
mb.reply_to(mail[:reply_to].to_s) if mail[:reply_to].present?
|
172
|
+
mb.template(mail[:template].to_s) if mail[:template].present?
|
104
173
|
mb.subject mail.subject
|
105
174
|
mb.body_html extract_body_html(mail)
|
106
175
|
mb.body_text extract_body_text(mail)
|
@@ -120,6 +189,11 @@ module Railgun
|
|
120
189
|
end
|
121
190
|
end
|
122
191
|
|
192
|
+
# v:* attributes (variables)
|
193
|
+
mail.mailgun_variables.try(:each) do |name, value|
|
194
|
+
mb.variable(name, value)
|
195
|
+
end
|
196
|
+
|
123
197
|
return mb.message if mail.attachments.empty?
|
124
198
|
|
125
199
|
mail.attachments.each do |attach|
|
@@ -181,5 +255,4 @@ module Railgun
|
|
181
255
|
return mail.html_part if mail.multipart?
|
182
256
|
(mail.mime_type =~ /^text\/html$/i) && mail
|
183
257
|
end
|
184
|
-
|
185
258
|
end
|
data/lib/railgun/message.rb
CHANGED
data/lib/railgun/railtie.rb
CHANGED
@@ -2,8 +2,9 @@ require 'railgun/mailer'
|
|
2
2
|
|
3
3
|
module Railgun
|
4
4
|
class Railtie < ::Rails::Railtie
|
5
|
-
|
6
|
-
|
5
|
+
ActiveSupport.on_load(:action_mailer) do
|
6
|
+
add_delivery_method :mailgun, Railgun::Mailer
|
7
|
+
ActiveSupport.run_load_hooks(:mailgun_mailer, Railgun::Mailer)
|
7
8
|
end
|
8
9
|
end
|
9
10
|
end
|
data/mailgun.gemspec
CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |spec|
|
|
7
7
|
|
8
8
|
spec.name = 'mailgun-ruby'
|
9
9
|
spec.version = Mailgun::VERSION
|
10
|
-
spec.homepage = '
|
10
|
+
spec.homepage = 'https://www.mailgun.com/'
|
11
11
|
spec.platform = Gem::Platform::RUBY
|
12
12
|
spec.license = 'Apache-2.0'
|
13
13
|
|
@@ -17,21 +17,24 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.authors = ['Mailgun', 'Travis Swientek']
|
18
18
|
spec.email = 'support@mailgunhq.com'
|
19
19
|
|
20
|
+
spec.metadata['documentation_uri'] = 'https://documentation.mailgun.com/'
|
21
|
+
spec.metadata['source_code_uri'] = 'https://github.com/mailgun/mailgun-ruby'
|
22
|
+
|
20
23
|
spec.files = `git ls-files -z`.split("\x0")
|
21
24
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
22
25
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
23
26
|
spec.require_paths = ["lib"]
|
24
27
|
|
25
|
-
spec.required_ruby_version = '>= 2.
|
26
|
-
|
27
|
-
spec.add_development_dependency 'bundler', '
|
28
|
-
spec.add_development_dependency 'rspec', '~> 3.0'
|
29
|
-
spec.add_development_dependency 'rake', '~>
|
30
|
-
spec.add_development_dependency 'webmock', '~>
|
31
|
-
spec.add_development_dependency 'pry', '~> 0.
|
32
|
-
spec.add_development_dependency 'vcr', '~> 3.0'
|
33
|
-
spec.add_development_dependency 'simplecov', '~> 0.
|
34
|
-
spec.add_development_dependency
|
35
|
-
spec.add_dependency 'rest-client', '
|
28
|
+
spec.required_ruby_version = '>= 2.2.2'
|
29
|
+
|
30
|
+
spec.add_development_dependency 'bundler', '>= 1.16.2'
|
31
|
+
spec.add_development_dependency 'rspec', '~> 3.8.0'
|
32
|
+
spec.add_development_dependency 'rake', '~> 12.3.2'
|
33
|
+
spec.add_development_dependency 'webmock', '~> 3.7'
|
34
|
+
spec.add_development_dependency 'pry', '~> 0.11.3'
|
35
|
+
spec.add_development_dependency 'vcr', '~> 3.0.3'
|
36
|
+
spec.add_development_dependency 'simplecov', '~> 0.16.1'
|
37
|
+
spec.add_development_dependency 'rails'
|
38
|
+
spec.add_dependency 'rest-client', '>= 2.0.2'
|
36
39
|
|
37
40
|
end
|
@@ -7,7 +7,7 @@ describe 'For the Bounces endpoint', order: :defined, vcr: vcr_opts do
|
|
7
7
|
before(:all) do
|
8
8
|
@mg_obj = Mailgun::Client.new(APIKEY, APIHOST, APIVERSION, SSL)
|
9
9
|
@domain = TESTDOMAIN
|
10
|
-
@email = "integration-test
|
10
|
+
@email = "integration-test+email@#{TESTDOMAIN}"
|
11
11
|
end
|
12
12
|
|
13
13
|
it 'creates a bounce' do
|
@@ -22,7 +22,7 @@ describe 'For the Bounces endpoint', order: :defined, vcr: vcr_opts do
|
|
22
22
|
end
|
23
23
|
|
24
24
|
it 'get a bounce.' do
|
25
|
-
result = @mg_obj.get("#{@domain}/bounces/#{@email}")
|
25
|
+
result = @mg_obj.get("#{@domain}/bounces/#{CGI.escape(@email)}")
|
26
26
|
|
27
27
|
result.to_h!
|
28
28
|
expect(result.body["code"]).to eq("550")
|
@@ -38,7 +38,7 @@ describe 'For the Bounces endpoint', order: :defined, vcr: vcr_opts do
|
|
38
38
|
end
|
39
39
|
|
40
40
|
it 'deletes a bounce' do
|
41
|
-
@mg_obj.delete("#{@domain}/bounces/#{@email}")
|
41
|
+
@mg_obj.delete("#{@domain}/bounces/#{CGI.escape(@email)}")
|
42
42
|
end
|
43
43
|
|
44
44
|
end
|
File without changes
|
File without changes
|
@@ -36,4 +36,12 @@ describe 'For the domains endpoint', vcr: vcr_opts do
|
|
36
36
|
|
37
37
|
expect(result).to be_truthy
|
38
38
|
end
|
39
|
+
|
40
|
+
it 'updates the domain' do
|
41
|
+
result = @mg_obj.update(@domain, { spam_action: 'block', web_scheme: 'https', wildcard: true })
|
42
|
+
|
43
|
+
expect(result['domain']["spam_action"]).to eq('block')
|
44
|
+
expect(result['domain']["web_scheme"]).to eq('https')
|
45
|
+
expect(result['domain']["wildcard"]).to eq(true)
|
46
|
+
end
|
39
47
|
end
|
@@ -7,7 +7,7 @@ vcr_opts = { :cassette_name => "email_validation" }
|
|
7
7
|
|
8
8
|
describe 'For the email validation endpoint', order: :defined, vcr: vcr_opts do
|
9
9
|
before(:all) do
|
10
|
-
@mg_obj = Mailgun::Address.new
|
10
|
+
@mg_obj = Mailgun::Address.new
|
11
11
|
|
12
12
|
@valid = ["Alice <alice@example.com>", "bob@example.com"]
|
13
13
|
@invalid = ["example.org"]
|
@@ -19,7 +19,7 @@ describe 'For the email validation endpoint', order: :defined, vcr: vcr_opts do
|
|
19
19
|
res = @mg_obj.parse(@all_addrs)
|
20
20
|
|
21
21
|
expect(res["parsed"]).to eq(@valid)
|
22
|
-
expect(res["
|
22
|
+
expect(res["unparsable"]).to eq(@invalid)
|
23
23
|
end
|
24
24
|
|
25
25
|
it 'validates alice@mailgun.net with info' do
|
@@ -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,
|
File without changes
|
File without changes
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'json'
|
3
|
+
require 'logger'
|
4
|
+
require 'railgun'
|
5
|
+
require 'mailgun'
|
6
|
+
require 'mailgun/exceptions/exceptions'
|
7
|
+
|
8
|
+
ActionMailer::Base.raise_delivery_errors = true
|
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, from, subject, headers)
|
16
|
+
headers(headers)
|
17
|
+
mail(to: address, from: from, 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
|
+
end
|
23
|
+
|
24
|
+
vcr_opts = { :cassette_name => 'message_deliver' }
|
25
|
+
|
26
|
+
describe 'Message deliver', vcr: vcr_opts do
|
27
|
+
let(:domain) { TESTDOMAIN }
|
28
|
+
let(:config) do
|
29
|
+
{
|
30
|
+
api_key: APIKEY,
|
31
|
+
domain: domain
|
32
|
+
}
|
33
|
+
end
|
34
|
+
let(:mail) { UnitTestMailer.plain_message("bob@#{domain}", "bob@#{domain}", 'subject', {}) }
|
35
|
+
|
36
|
+
it 'successfully delivers message' do
|
37
|
+
result = Railgun::Mailer.new(config).deliver!(mail)
|
38
|
+
result.to_h!
|
39
|
+
|
40
|
+
expect(result.body['message']).to eq('Queued. Thank you.')
|
41
|
+
expect(result.body).to include('id')
|
42
|
+
expect(result.code).to eq(200)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
vcr_opts = { :cassette_name => 'mailer_invalid_domain' }
|
47
|
+
|
48
|
+
describe 'Invalid domain', vcr: vcr_opts do
|
49
|
+
let(:domain) { 'not-our-doma.in' }
|
50
|
+
let(:config) do
|
51
|
+
{
|
52
|
+
api_key: APIKEY,
|
53
|
+
domain: domain
|
54
|
+
}
|
55
|
+
end
|
56
|
+
let(:mail) { UnitTestMailer.plain_message("bob@#{domain}", 'sally@not-our-doma.in' 'subject', {}) }
|
57
|
+
|
58
|
+
it 'raises expected error' do
|
59
|
+
|
60
|
+
Railgun::Mailer.new(config).deliver!(mail)
|
61
|
+
rescue Mailgun::CommunicationError => err
|
62
|
+
expect(err.message).to eq('401 Unauthorized: Forbidden - Invalid Domain or API key')
|
63
|
+
else
|
64
|
+
fail
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
@@ -34,6 +34,78 @@ describe 'Client exceptions', vcr: vcr_opts do
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
+
vcr_opts = { :cassette_name => "exceptions-invalid-api-key" }
|
38
|
+
|
39
|
+
describe 'Client exceptions', vcr: vcr_opts do
|
40
|
+
before(:all) do
|
41
|
+
@mg_obj = Mailgun::Client.new(APIKEY, APIHOST, APIVERSION, SSL)
|
42
|
+
@domain = TESTDOMAIN
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'displays error information that API key is invalid' do
|
46
|
+
begin
|
47
|
+
@mg_obj.send_message(@domain, {
|
48
|
+
:from => "sally@#{@domain}",
|
49
|
+
:to => "sally@#{@domain}",
|
50
|
+
:subject => 'Exception Integration Test',
|
51
|
+
:text => 'INTEGRATION TESTING'
|
52
|
+
})
|
53
|
+
rescue Mailgun::Unauthorized => err
|
54
|
+
expect(err.message).to eq('401 Unauthorized - Invalid Domain or API key: Forbidden')
|
55
|
+
else
|
56
|
+
fail
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
vcr_opts = { :cassette_name => "exceptions-invalid-data" }
|
62
|
+
|
63
|
+
describe 'Client exceptions', vcr: vcr_opts do
|
64
|
+
before(:all) do
|
65
|
+
@mg_obj = Mailgun::Client.new(APIKEY, APIHOST, APIVERSION, SSL)
|
66
|
+
@domain = TESTDOMAIN
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'display useful error information' do
|
70
|
+
begin
|
71
|
+
@mg_obj.send_message(@domain, {
|
72
|
+
:from => "sally@#{@domain}",
|
73
|
+
:to => "sally#{@domain}",
|
74
|
+
:subject => 'Exception Integration Test',
|
75
|
+
:text => 'INTEGRATION TESTING'
|
76
|
+
})
|
77
|
+
rescue Mailgun::BadRequest => err
|
78
|
+
expect(err.message).to eq('400 Bad Request: to parameter is not a valid address. please check documentation')
|
79
|
+
else
|
80
|
+
fail
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
vcr_opts = { :cassette_name => "exceptions-not-allowed" }
|
86
|
+
|
87
|
+
describe 'Client exceptions', vcr: vcr_opts do
|
88
|
+
before(:all) do
|
89
|
+
@mg_obj = Mailgun::Client.new(APIKEY, APIHOST, APIVERSION, SSL)
|
90
|
+
@domain = TESTDOMAIN
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'display useful error information' do
|
94
|
+
begin
|
95
|
+
@mg_obj.send_message(@domain, {
|
96
|
+
:from => "invalid@#{@domain}",
|
97
|
+
:to => "invalid#{@domain}",
|
98
|
+
:subject => 'Exception Integration Test',
|
99
|
+
:text => 'INTEGRATION TESTING'
|
100
|
+
})
|
101
|
+
rescue Mailgun::CommunicationError => err
|
102
|
+
expect(err.message).to include('403 Forbidden')
|
103
|
+
else
|
104
|
+
fail
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
37
109
|
vcr_opts = { :cassette_name => "send_message" }
|
38
110
|
|
39
111
|
describe 'The method send_message()', vcr: vcr_opts do
|
@@ -63,6 +135,9 @@ describe 'The method send_message()', vcr: vcr_opts do
|
|
63
135
|
:to => "bob@#{@domain}",
|
64
136
|
:subject => "Test",
|
65
137
|
:text => "Test Data" }
|
138
|
+
uuid = 'uuid'
|
139
|
+
|
140
|
+
allow(SecureRandom).to receive(:uuid).and_return(uuid)
|
66
141
|
|
67
142
|
result = @mg_obj.send_message(@domain, data)
|
68
143
|
|
@@ -72,7 +147,7 @@ describe 'The method send_message()', vcr: vcr_opts do
|
|
72
147
|
expect(result.body).to include("id")
|
73
148
|
|
74
149
|
expect(result.code).to eq(200)
|
75
|
-
expect(result.body['id']).to eq("test-mode-mail@localhost")
|
150
|
+
expect(result.body['id']).to eq("test-mode-mail-#{uuid}@localhost")
|
76
151
|
expect(result.body['message']).to eq("Queued. Thank you.")
|
77
152
|
end
|
78
153
|
|
@@ -117,5 +192,21 @@ Testing some Mailgun awesomness!'
|
|
117
192
|
expect(result.body).to include("message")
|
118
193
|
expect(result.body).to include("id")
|
119
194
|
end
|
195
|
+
|
196
|
+
it 'receives success response code' do
|
197
|
+
@mg_obj.enable_test_mode!
|
198
|
+
|
199
|
+
expect(@mg_obj.test_mode?).to eq(true)
|
200
|
+
|
201
|
+
data = { :from => "joe@#{@domain}",
|
202
|
+
:to => "bob@#{@domain}",
|
203
|
+
:subject => "Test",
|
204
|
+
:text => "Test Data" }
|
205
|
+
|
206
|
+
result = @mg_obj.send_message(@domain, data)
|
207
|
+
result.to_h!
|
208
|
+
|
209
|
+
expect(result.success?).to be(true)
|
210
|
+
end
|
120
211
|
end
|
121
212
|
|
File without changes
|
File without changes
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'mailgun'
|
3
|
+
|
4
|
+
vcr_opts = { :cassette_name => "subaccounts" }
|
5
|
+
|
6
|
+
describe 'For the subaccounts endpoints', vcr: vcr_opts do
|
7
|
+
let(:name) { 'test.subaccount' }
|
8
|
+
let(:subaccount_id) { 'xxx' }
|
9
|
+
|
10
|
+
before(:all) do
|
11
|
+
mg_client = Mailgun::Client.new(APIKEY, APIHOST, 'v5')
|
12
|
+
@mg_obj = Mailgun::Subaccounts.new mg_client
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#list' do
|
16
|
+
it 'returns a list of templates' do
|
17
|
+
result = @mg_obj.list
|
18
|
+
|
19
|
+
expect(result).to eq({"subaccounts"=>[{"id"=>"xxx", "name"=>"test-ruby-lib", "status"=>"open"}], "total"=>1})
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#create' do
|
24
|
+
it 'creates the subaccount' do
|
25
|
+
result = @mg_obj.create(name)
|
26
|
+
|
27
|
+
expect(result).to eq({"subaccount"=>{"id"=>"xxx", "name"=>"test.subaccount", "status"=>"open"}})
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
describe '#info' do
|
33
|
+
it 'gets the templates info' do
|
34
|
+
result = @mg_obj.info(subaccount_id)
|
35
|
+
|
36
|
+
expect(result).to eq({"subaccount"=>{"id"=>"xxx", "name"=>"test-ruby-lib", "status"=>"open"}})
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
describe '#enable' do
|
43
|
+
it 'enables the subaccount' do
|
44
|
+
result = @mg_obj.enable(subaccount_id)
|
45
|
+
|
46
|
+
expect(result).to eq({"subaccount"=>{"id"=>"xxx", "name"=>"test-ruby-lib", "status"=>"open"}})
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe '#disable' do
|
51
|
+
it 'disables the subaccount' do
|
52
|
+
result = @mg_obj.disable(subaccount_id)
|
53
|
+
|
54
|
+
expect(result).to eq({"subaccount"=>{"id"=>"xxx", "name"=>"test-ruby-lib", "status"=>"disabled"}})
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
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
|
-
|