mailgun-ruby 1.1.9 → 1.2.13
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
|