mailgun-ruby 1.1.0 → 1.2.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/.ruby-env.yml.example +1 -1
- data/.travis.yml +23 -7
- data/Gemfile +2 -0
- data/README.md +79 -18
- data/{Domains.md → docs/Domains.md} +18 -0
- data/{Events.md → docs/Events.md} +0 -0
- data/{MessageBuilder.md → docs/MessageBuilder.md} +32 -13
- data/{Messages.md → docs/Messages.md} +3 -3
- data/{OptInHandler.md → docs/OptInHandler.md} +0 -0
- data/{Snippets.md → docs/Snippets.md} +21 -2
- data/docs/Suppressions.md +82 -0
- data/{Webhooks.md → docs/Webhooks.md} +1 -1
- data/docs/railgun/Overview.md +11 -0
- data/docs/railgun/Parameters.md +83 -0
- data/lib/mailgun/address.rb +48 -0
- data/lib/mailgun/client.rb +85 -8
- data/lib/mailgun/events/events.rb +40 -12
- data/lib/mailgun/exceptions/exceptions.rb +21 -7
- data/lib/mailgun/lists/opt_in_handler.rb +0 -1
- data/lib/mailgun/messages/batch_message.rb +3 -2
- data/lib/mailgun/messages/message_builder.rb +139 -30
- data/lib/mailgun/response.rb +7 -0
- data/lib/mailgun/suppressions.rb +273 -0
- data/lib/mailgun/version.rb +1 -1
- data/lib/mailgun/webhooks/webhooks.rb +1 -1
- data/lib/mailgun-ruby.rb +2 -0
- data/lib/mailgun.rb +1 -0
- data/lib/railgun/attachment.rb +56 -0
- data/lib/railgun/errors.rb +27 -0
- data/lib/railgun/mailer.rb +253 -0
- data/lib/railgun/message.rb +18 -0
- data/lib/railgun/railtie.rb +10 -0
- data/lib/railgun.rb +8 -0
- data/mailgun.gemspec +12 -13
- data/spec/integration/email_validation_spec.rb +57 -15
- data/spec/integration/events_spec.rb +9 -1
- data/spec/integration/mailer_spec.rb +67 -0
- data/spec/integration/mailgun_spec.rb +51 -1
- data/spec/integration/suppressions_spec.rb +142 -0
- data/spec/spec_helper.rb +3 -1
- data/spec/unit/connection/test_client.rb +16 -0
- data/spec/unit/events/events_spec.rb +36 -2
- data/spec/unit/mailgun_spec.rb +32 -10
- data/spec/unit/messages/batch_message_spec.rb +56 -40
- data/spec/unit/messages/message_builder_spec.rb +267 -81
- data/spec/unit/messages/sample_data/unknown.type +0 -0
- data/spec/unit/railgun/content_type_spec.rb +71 -0
- data/spec/unit/railgun/mailer_spec.rb +388 -0
- data/vcr_cassettes/email_validation.yml +136 -25
- data/vcr_cassettes/events.yml +48 -1
- data/vcr_cassettes/exceptions.yml +45 -0
- data/vcr_cassettes/mailer_invalid_domain.yml +109 -0
- data/vcr_cassettes/message_deliver.yml +149 -0
- data/vcr_cassettes/suppressions.yml +727 -0
- metadata +65 -40
data/mailgun.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.version = Mailgun::VERSION
|
10
10
|
spec.homepage = 'http://www.mailgun.com'
|
11
11
|
spec.platform = Gem::Platform::RUBY
|
12
|
-
spec.license = 'Apache'
|
12
|
+
spec.license = 'Apache-2.0'
|
13
13
|
|
14
14
|
spec.summary = "Mailgun's Official Ruby SDK"
|
15
15
|
spec.description = "Mailgun's Official Ruby SDK for interacting with the Mailgun API."
|
@@ -22,17 +22,16 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
23
23
|
spec.require_paths = ["lib"]
|
24
24
|
|
25
|
-
spec.required_ruby_version = '>=
|
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
|
-
|
35
|
-
spec.add_dependency 'rest-client', '
|
36
|
-
spec.add_dependency 'json', '~> 1.8'
|
25
|
+
spec.required_ruby_version = '>= 2.2.2'
|
26
|
+
|
27
|
+
spec.add_development_dependency 'bundler', '>= 1.16.2'
|
28
|
+
spec.add_development_dependency 'rspec', '~> 3.8.0'
|
29
|
+
spec.add_development_dependency 'rake', '~> 12.3.2'
|
30
|
+
spec.add_development_dependency 'webmock', '~> 3.4.2'
|
31
|
+
spec.add_development_dependency 'pry', '~> 0.11.3'
|
32
|
+
spec.add_development_dependency 'vcr', '~> 3.0.3'
|
33
|
+
spec.add_development_dependency 'simplecov', '~> 0.16.1'
|
34
|
+
spec.add_development_dependency 'rails'
|
35
|
+
spec.add_dependency 'rest-client', '>= 2.0.2'
|
37
36
|
|
38
37
|
end
|
@@ -1,29 +1,71 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
|
2
3
|
require 'mailgun'
|
4
|
+
require 'mailgun/address'
|
3
5
|
|
4
6
|
vcr_opts = { :cassette_name => "email_validation" }
|
5
7
|
|
6
|
-
describe 'For the
|
8
|
+
describe 'For the email validation endpoint', order: :defined, vcr: vcr_opts do
|
7
9
|
before(:all) do
|
8
|
-
@mg_obj = Mailgun::
|
10
|
+
@mg_obj = Mailgun::Address.new(PUB_APIKEY)
|
11
|
+
|
12
|
+
@valid = ["Alice <alice@example.com>", "bob@example.com"]
|
13
|
+
@invalid = ["example.org"]
|
14
|
+
|
15
|
+
@all_addrs = @valid + @invalid
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'returns parsed and unparsable lists' do
|
19
|
+
res = @mg_obj.parse(@all_addrs)
|
20
|
+
|
21
|
+
expect(res["parsed"]).to eq(@valid)
|
22
|
+
expect(res["unparseable"]).to eq(@invalid)
|
9
23
|
end
|
10
24
|
|
11
|
-
it 'validates
|
12
|
-
|
13
|
-
{:address => "test@#{TESTDOMAIN}"})
|
25
|
+
it 'validates alice@mailgun.net with info' do
|
26
|
+
res = @mg_obj.validate("alice@mailgun.net")
|
14
27
|
|
15
|
-
|
16
|
-
|
17
|
-
|
28
|
+
expected = {
|
29
|
+
"address" => "alice@mailgun.net",
|
30
|
+
"did_you_mean" => nil,
|
31
|
+
"is_disposable_address" => false,
|
32
|
+
"is_role_address" => false,
|
33
|
+
"is_valid" => true,
|
34
|
+
"mailbox_verification" => "true",
|
35
|
+
"reason" => nil,
|
36
|
+
"parts" => {
|
37
|
+
"display_name" => nil,
|
38
|
+
"domain" => "mailgun.net",
|
39
|
+
"local_part" => "alice",
|
40
|
+
},
|
41
|
+
}
|
42
|
+
expect(res).to eq(expected)
|
18
43
|
end
|
19
44
|
|
20
|
-
it '
|
21
|
-
|
22
|
-
{:addresses => "Alice <alice@#{TESTDOMAIN}>,bob@#{TESTDOMAIN},#{TESTDOMAIN}"})
|
45
|
+
it 'performs mailbox validation for alice@mailgun.net' do
|
46
|
+
res = @mg_obj.validate("alice@mailgun.net", true)
|
23
47
|
|
24
|
-
|
25
|
-
expect(result.body["parsed"]).to include("Alice <alice@#{TESTDOMAIN}>")
|
26
|
-
expect(result.body["parsed"]).to include("bob@#{TESTDOMAIN}")
|
27
|
-
expect(result.body["unparseable"]).to include("#{TESTDOMAIN}")
|
48
|
+
expect(res["mailbox_verification"]).to eq("true")
|
28
49
|
end
|
50
|
+
|
51
|
+
it 'fails to validate example.org' do
|
52
|
+
res = @mg_obj.validate("example.org")
|
53
|
+
|
54
|
+
expected = {
|
55
|
+
"address" => "example.org",
|
56
|
+
"did_you_mean" => nil,
|
57
|
+
"is_disposable_address" => false,
|
58
|
+
"is_role_address" => false,
|
59
|
+
"is_valid" => false,
|
60
|
+
"mailbox_verification" => "unknown",
|
61
|
+
"reason" => "Validation failed for 'example.org', reason: 'malformed address; missing @ sign'",
|
62
|
+
"parts" => {
|
63
|
+
"display_name" => nil,
|
64
|
+
"domain" => nil,
|
65
|
+
"local_part" => nil,
|
66
|
+
},
|
67
|
+
}
|
68
|
+
expect(res).to eq(expected)
|
69
|
+
end
|
70
|
+
|
29
71
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'mailgun'
|
3
|
+
require 'mailgun/events/events'
|
3
4
|
|
4
5
|
vcr_opts = { :cassette_name => "events" }
|
5
6
|
|
@@ -7,9 +8,10 @@ describe 'For the Events endpoint', vcr: vcr_opts do
|
|
7
8
|
before(:all) do
|
8
9
|
@mg_obj = Mailgun::Client.new(APIKEY, APIHOST, APIVERSION, SSL)
|
9
10
|
@domain = TESTDOMAIN
|
11
|
+
@events = Mailgun::Events.new(@mg_obj, @domain)
|
10
12
|
end
|
11
13
|
|
12
|
-
it 'get an event.' do
|
14
|
+
it 'can get an event.' do
|
13
15
|
result = @mg_obj.get("#{@domain}/events", {:limit => 1})
|
14
16
|
|
15
17
|
result.to_h!
|
@@ -17,4 +19,10 @@ describe 'For the Events endpoint', vcr: vcr_opts do
|
|
17
19
|
expect(result.body["paging"]).to include("next")
|
18
20
|
expect(result.body["paging"]).to include("previous")
|
19
21
|
end
|
22
|
+
|
23
|
+
it 'can iterate over all events with `each`' do
|
24
|
+
@events.each do |e|
|
25
|
+
expect(e["id"]).to eq("JAx9z641TuGGUyaJlD9sCQ")
|
26
|
+
end
|
27
|
+
end
|
20
28
|
end
|
@@ -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
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'mailgun'
|
3
|
+
require 'mailgun/exceptions/exceptions'
|
3
4
|
|
4
5
|
vcr_opts = { :cassette_name => "instance" }
|
5
6
|
|
@@ -9,6 +10,30 @@ describe 'Mailgun instantiation', vcr: vcr_opts do
|
|
9
10
|
end
|
10
11
|
end
|
11
12
|
|
13
|
+
vcr_opts = { :cassette_name => "exceptions" }
|
14
|
+
|
15
|
+
describe 'Client exceptions', vcr: vcr_opts do
|
16
|
+
before(:all) do
|
17
|
+
@mg_obj = Mailgun::Client.new(APIKEY, APIHOST, APIVERSION, SSL)
|
18
|
+
@domain = TESTDOMAIN
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'display useful error information' do
|
22
|
+
begin
|
23
|
+
@mg_obj.send_message("not-our-doma.in", {
|
24
|
+
:from => "sally@not-our-doma.in",
|
25
|
+
:to => "bob@#{@domain}",
|
26
|
+
:subject => 'Exception Integration Test',
|
27
|
+
:text => 'INTEGRATION TESTING'
|
28
|
+
})
|
29
|
+
rescue Mailgun::CommunicationError => err
|
30
|
+
expect(err.message).to eq('404 Not Found: Domain not found: not-our-doma.in')
|
31
|
+
else
|
32
|
+
fail
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
12
37
|
vcr_opts = { :cassette_name => "send_message" }
|
13
38
|
|
14
39
|
describe 'The method send_message()', vcr: vcr_opts do
|
@@ -16,7 +41,7 @@ describe 'The method send_message()', vcr: vcr_opts do
|
|
16
41
|
@mg_obj = Mailgun::Client.new(APIKEY, APIHOST, APIVERSION, SSL)
|
17
42
|
@domain = TESTDOMAIN
|
18
43
|
end
|
19
|
-
|
44
|
+
|
20
45
|
it 'sends a standard message in test mode.' do
|
21
46
|
result = @mg_obj.send_message(@domain, {:from => "bob@#{@domain}",
|
22
47
|
:to => "sally@#{@domain}",
|
@@ -29,6 +54,31 @@ describe 'The method send_message()', vcr: vcr_opts do
|
|
29
54
|
expect(result.body).to include("id")
|
30
55
|
end
|
31
56
|
|
57
|
+
it 'fakes message send while in *client* test mode' do
|
58
|
+
@mg_obj.enable_test_mode!
|
59
|
+
|
60
|
+
expect(@mg_obj.test_mode?).to eq(true)
|
61
|
+
|
62
|
+
data = { :from => "joe@#{@domain}",
|
63
|
+
:to => "bob@#{@domain}",
|
64
|
+
:subject => "Test",
|
65
|
+
:text => "Test Data" }
|
66
|
+
uuid = 'uuid'
|
67
|
+
|
68
|
+
allow(SecureRandom).to receive(:uuid).and_return(uuid)
|
69
|
+
|
70
|
+
result = @mg_obj.send_message(@domain, data)
|
71
|
+
|
72
|
+
result.to_h!
|
73
|
+
|
74
|
+
expect(result.body).to include("message")
|
75
|
+
expect(result.body).to include("id")
|
76
|
+
|
77
|
+
expect(result.code).to eq(200)
|
78
|
+
expect(result.body['id']).to eq("test-mode-mail-#{uuid}@localhost")
|
79
|
+
expect(result.body['message']).to eq("Queued. Thank you.")
|
80
|
+
end
|
81
|
+
|
32
82
|
it 'sends a message builder message in test mode.' do
|
33
83
|
mb_obj = Mailgun::MessageBuilder.new()
|
34
84
|
mb_obj.from("sender@#{@domain}", {'first' => 'Sending', 'last' => 'User'})
|
@@ -0,0 +1,142 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'mailgun'
|
4
|
+
require 'mailgun/suppressions'
|
5
|
+
|
6
|
+
vcr_opts = { :cassette_name => 'suppressions' }
|
7
|
+
|
8
|
+
describe 'For the suppressions handling class', order: :defined, vcr: vcr_opts do
|
9
|
+
|
10
|
+
before(:all) do
|
11
|
+
@mg_obj = Mailgun::Client.new(APIKEY)
|
12
|
+
@suppress = Mailgun::Suppressions.new(@mg_obj, TESTDOMAIN)
|
13
|
+
|
14
|
+
@addresses = ['test1@example.com', 'test2@example.org', 'test3@example.net', 'test4@example.info']
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'can batch-add bounces' do
|
18
|
+
bounces = []
|
19
|
+
@addresses.each do |addr|
|
20
|
+
bounces.push({
|
21
|
+
:address => addr,
|
22
|
+
:code => 500,
|
23
|
+
:error => 'integration testing',
|
24
|
+
})
|
25
|
+
end
|
26
|
+
|
27
|
+
response, nested = @suppress.create_bounces bounces
|
28
|
+
response.to_h!
|
29
|
+
|
30
|
+
expect(response.code).to eq(200)
|
31
|
+
expect(response.body['message']).to eq('4 addresses have been added to the bounces table')
|
32
|
+
expect(nested.length).to eq(0)
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'raises ParameterError if no bounce[:address] is present' do
|
36
|
+
bounces = []
|
37
|
+
bounces.push({
|
38
|
+
:code => 500,
|
39
|
+
:error => 'integration testing',
|
40
|
+
})
|
41
|
+
|
42
|
+
expect { @suppress.create_bounces bounces }.to raise_error(Mailgun::ParameterError)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'removes a single bounce address' do
|
46
|
+
@addresses.each do |addr|
|
47
|
+
response = @suppress.delete_bounce addr
|
48
|
+
response.to_h!
|
49
|
+
|
50
|
+
expect(response.code).to eq(200)
|
51
|
+
expect(response.body['message']).to eq('Bounced address has been removed')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'can batch-add unsubscribes with tags as string' do
|
56
|
+
unsubscribes = []
|
57
|
+
@addresses.each do |addr|
|
58
|
+
unsubscribes.push({
|
59
|
+
:address => addr,
|
60
|
+
:tag => 'integration',
|
61
|
+
})
|
62
|
+
end
|
63
|
+
|
64
|
+
response, nested = @suppress.create_unsubscribes unsubscribes
|
65
|
+
response.to_h!
|
66
|
+
|
67
|
+
expect(response.code).to eq(200)
|
68
|
+
expect(response.body['message']).to eq('4 addresses have been added to the unsubscribes table')
|
69
|
+
expect(nested.length).to eq(0)
|
70
|
+
end
|
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
|
+
|
89
|
+
it 'raises ParameterError if no unsubscribe[:address] is present' do
|
90
|
+
unsubscribes = []
|
91
|
+
unsubscribes.push({
|
92
|
+
:tag => 'integration',
|
93
|
+
})
|
94
|
+
|
95
|
+
expect { @suppress.create_unsubscribes unsubscribes }.to raise_error(Mailgun::ParameterError)
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'removes a single unsubscribe address' do
|
99
|
+
@addresses.each do |addr|
|
100
|
+
response = @suppress.delete_unsubscribe addr
|
101
|
+
response.to_h!
|
102
|
+
|
103
|
+
expect(response.code).to eq(200)
|
104
|
+
expect(response.body['message']).to eq('Unsubscribe event has been removed')
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'can batch-add complaints' do
|
109
|
+
complaints = []
|
110
|
+
@addresses.each do |addr|
|
111
|
+
complaints.push :address => addr
|
112
|
+
end
|
113
|
+
|
114
|
+
response, nested = @suppress.create_complaints complaints
|
115
|
+
response.to_h!
|
116
|
+
|
117
|
+
expect(response.code).to eq(200)
|
118
|
+
expect(response.body['message']).to eq('4 complaint addresses have been added to the complaints table')
|
119
|
+
expect(nested.length).to eq(0)
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'raises ParameterError if no complaint[:address] is present' do
|
123
|
+
complaints = []
|
124
|
+
complaints.push({
|
125
|
+
:tag => 'integration',
|
126
|
+
})
|
127
|
+
|
128
|
+
expect { @suppress.create_complaints complaints }.to raise_error(Mailgun::ParameterError)
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'removes a single complaint address' do
|
132
|
+
@addresses.each do |addr|
|
133
|
+
response = @suppress.delete_complaint addr
|
134
|
+
response.to_h!
|
135
|
+
|
136
|
+
expect(response.code).to eq(200)
|
137
|
+
expect(response.body['message']).to eq('Spam complaint has been removed')
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
# TODO: Add tests for pagination support.
|
142
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'rubygems'
|
2
|
+
require 'base64'
|
2
3
|
require 'bundler'
|
3
4
|
require 'bundler/setup'
|
4
5
|
Bundler.setup(:development)
|
@@ -37,9 +38,10 @@ TESTDOMAIN = envs['MAILGUN_TESTDOMAIN']
|
|
37
38
|
VCR.configure do |c|
|
38
39
|
c.cassette_library_dir = 'vcr_cassettes'
|
39
40
|
c.hook_into :webmock
|
40
|
-
c.configure_rspec_metadata!
|
41
41
|
c.default_cassette_options = { record: :new_episodes }
|
42
42
|
c.filter_sensitive_data('<APIKEY>') { APIKEY }
|
43
43
|
c.filter_sensitive_data('DOMAIN.TEST') { TESTDOMAIN }
|
44
44
|
c.filter_sensitive_data('<PUBKEY>') { PUB_APIKEY }
|
45
|
+
|
46
|
+
c.configure_rspec_metadata!
|
45
47
|
end
|
@@ -23,6 +23,7 @@ module Mailgun
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def send_message(working_domain, data)
|
26
|
+
perform_data_validation(working_domain, data)
|
26
27
|
case data
|
27
28
|
when Hash
|
28
29
|
if data.has_key?(:message)
|
@@ -75,6 +76,21 @@ module Mailgun
|
|
75
76
|
|
76
77
|
private
|
77
78
|
|
79
|
+
def perform_data_validation(working_domain, data)
|
80
|
+
fail ParameterError.new('Missing working domain', working_domain) unless working_domain
|
81
|
+
return true unless data.is_a?(Hash) && data.present?
|
82
|
+
message = data.respond_to?(:message) ? data.message : data
|
83
|
+
|
84
|
+
fail ParameterError.new(
|
85
|
+
'Missing `to` recipient, message should containg at least 1 recipient',
|
86
|
+
working_domain
|
87
|
+
) if message.fetch('to', []).empty? && message.fetch(:to, []).empty?
|
88
|
+
fail ParameterError.new(
|
89
|
+
'Missing a `from` sender, message should containg at least 1 `from` sender',
|
90
|
+
working_domain
|
91
|
+
) if message.fetch('from', []).empty? && message.fetch(:from, []).empty?
|
92
|
+
end
|
93
|
+
|
78
94
|
def response_generator(resource_endpoint)
|
79
95
|
if resource_endpoint == "messages"
|
80
96
|
t = Time.now
|
@@ -5,19 +5,38 @@ describe 'The method get' do
|
|
5
5
|
@mg_obj = Mailgun::UnitClient.new('events')
|
6
6
|
events = Mailgun::Events.new(@mg_obj, "samples.mailgun.org")
|
7
7
|
result = events.get()
|
8
|
-
|
8
|
+
|
9
9
|
expect(result.body).to include("items")
|
10
10
|
expect(result.body).to include("paging")
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
+
describe 'Pagination' do
|
15
|
+
it 'should return a proper hash of log data.' do
|
16
|
+
@mg_obj = Mailgun::UnitClient.new('events')
|
17
|
+
events = Mailgun::Events.new(@mg_obj, "samples.mailgun.org")
|
18
|
+
result = events.get()
|
19
|
+
|
20
|
+
json = JSON.parse(result.body)
|
21
|
+
expect(json).to include("paging")
|
22
|
+
expect(json["paging"]).to include("next")
|
23
|
+
expect(json["paging"]).to include{"previous"}
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should calculate proper next-page url' do
|
27
|
+
events = Mailgun::Events.new(@mg_obj, "samples.mailgun.org")
|
28
|
+
output = events.send(:extract_endpoint_from, '/v3/samples.mailgun.org/events/W3siYiI6ICIyMDE3LTA1LTEwVDIwOjA2OjU0LjU3NiswMDowMCIsICJlIjogIjIwMTctMDUtMDhUMjA6MDY6NTQuNTc3KzAwOjAwIn0sIHsiYiI6ICIyMDE3LTA1LTEwVDIwOjA2OjU0LjU3NiswMDowMCIsICJlIjogIjIwMTctMDUtMDhUMjA6MDY6NTQuNTc3KzAwOjAwIn0sIFsiZiJdLCBudWxsLCBbWyJhY2NvdW50LmlkIiwgIjU4MDUyMTg2NzhmYTE2MTNjNzkwYjUwZiJdLCBbImRvbWFpbi5uYW1lIiwgInNhbmRib3gyOTcwMTUyYWYzZDM0NTU5YmZjN2U3MTcwM2E2Y2YyNC5tYWlsZ3VuLm9yZyJdXSwgMTAwLCBudWxsXQ==')
|
29
|
+
|
30
|
+
expect(output).to eq 'W3siYiI6ICIyMDE3LTA1LTEwVDIwOjA2OjU0LjU3NiswMDowMCIsICJlIjogIjIwMTctMDUtMDhUMjA6MDY6NTQuNTc3KzAwOjAwIn0sIHsiYiI6ICIyMDE3LTA1LTEwVDIwOjA2OjU0LjU3NiswMDowMCIsICJlIjogIjIwMTctMDUtMDhUMjA6MDY6NTQuNTc3KzAwOjAwIn0sIFsiZiJdLCBudWxsLCBbWyJhY2NvdW50LmlkIiwgIjU4MDUyMTg2NzhmYTE2MTNjNzkwYjUwZiJdLCBbImRvbWFpbi5uYW1lIiwgInNhbmRib3gyOTcwMTUyYWYzZDM0NTU5YmZjN2U3MTcwM2E2Y2YyNC5tYWlsZ3VuLm9yZyJdXSwgMTAwLCBudWxsXQ=='
|
31
|
+
end
|
32
|
+
end
|
14
33
|
|
15
34
|
describe 'The method next' do
|
16
35
|
it 'should return the next series of data.' do
|
17
36
|
@mg_obj = Mailgun::UnitClient.new('events')
|
18
37
|
events = Mailgun::Events.new(@mg_obj, "samples.mailgun.org")
|
19
38
|
result = events.next()
|
20
|
-
|
39
|
+
|
21
40
|
expect(result.body).to include("items")
|
22
41
|
expect(result.body).to include("paging")
|
23
42
|
end
|
@@ -33,3 +52,18 @@ describe 'The method previous' do
|
|
33
52
|
expect(result.body).to include("paging")
|
34
53
|
end
|
35
54
|
end
|
55
|
+
|
56
|
+
describe 'The method each' do
|
57
|
+
it 'should iterate over all event items.' do
|
58
|
+
@mg_obj = Mailgun::UnitClient.new('events')
|
59
|
+
events = Mailgun::Events.new(@mg_obj, "samples.mailgun.org")
|
60
|
+
# Events from the UnitClient are actually empty.
|
61
|
+
count = 0
|
62
|
+
events.each do |e|
|
63
|
+
count = count + 1
|
64
|
+
end
|
65
|
+
|
66
|
+
# Better than nothing..
|
67
|
+
expect(count).to eq(0)
|
68
|
+
end
|
69
|
+
end
|
data/spec/unit/mailgun_spec.rb
CHANGED
@@ -25,9 +25,9 @@ describe 'The method send_message()' do
|
|
25
25
|
|
26
26
|
it 'sends a message' do
|
27
27
|
data = { 'from' => 'joe@test.com',
|
28
|
-
|
29
|
-
|
30
|
-
|
28
|
+
'to' => 'bob@example.com',
|
29
|
+
'subject' => 'Test',
|
30
|
+
'text' => 'Test Data' }
|
31
31
|
result = @mg_obj.send_message("testdomain.com", data)
|
32
32
|
|
33
33
|
result.to_h!
|
@@ -37,15 +37,37 @@ describe 'The method send_message()' do
|
|
37
37
|
end
|
38
38
|
|
39
39
|
it 'opens the message MIME and sends the MIME message.' do
|
40
|
-
data = {
|
41
|
-
|
40
|
+
data = {
|
41
|
+
'to' => 'joe@test.com',
|
42
|
+
'message' => 'Sample Data/mime.txt',
|
43
|
+
'from' => 'joe@test.com'
|
44
|
+
}
|
42
45
|
result = @mg_obj.send_message("testdomain.com", data)
|
43
46
|
|
44
47
|
result.to_h!
|
45
|
-
|
48
|
+
|
46
49
|
expect(result.body).to include("message")
|
47
50
|
expect(result.body).to include("id")
|
48
51
|
end
|
52
|
+
|
53
|
+
context 'when domain is missing' do
|
54
|
+
it 'shows failure message' do
|
55
|
+
expect(@mg_obj).to receive(:fail)
|
56
|
+
@mg_obj.send_message(nil, {})
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'when to is missing' do
|
61
|
+
it 'shows failure message' do
|
62
|
+
data = {
|
63
|
+
'to' => '',
|
64
|
+
'message' => 'Sample Data/mime.txt',
|
65
|
+
'from' => 'joe@test.com'
|
66
|
+
}
|
67
|
+
expect(@mg_obj).to receive(:fail)
|
68
|
+
@mg_obj.send_message("testdomain.com", data)
|
69
|
+
end
|
70
|
+
end
|
49
71
|
end
|
50
72
|
|
51
73
|
describe 'The method post()' do
|
@@ -61,7 +83,7 @@ describe 'The method post()' do
|
|
61
83
|
result = @mg_obj.post("#{@domain}/messages", data)
|
62
84
|
|
63
85
|
result.to_h!
|
64
|
-
|
86
|
+
|
65
87
|
expect(result.body).to include("message")
|
66
88
|
expect(result.body).to include("id")
|
67
89
|
end
|
@@ -81,7 +103,7 @@ describe 'The method put()' do
|
|
81
103
|
result = @mg_obj.put("lists/#{@list_address}/members#{@member_address}", data)
|
82
104
|
|
83
105
|
result.to_h!
|
84
|
-
|
106
|
+
|
85
107
|
expect(result.body).to include("member")
|
86
108
|
expect(result.body["member"]).to include("vars")
|
87
109
|
expect(result.body["member"]["vars"]).to include("age")
|
@@ -104,7 +126,7 @@ describe 'The method get()' do
|
|
104
126
|
result = @mg_obj.get("#{@domain}/bounces", query_string)
|
105
127
|
|
106
128
|
result.to_h!
|
107
|
-
|
129
|
+
|
108
130
|
expect(result.body).to include("total_count")
|
109
131
|
expect(result.body).to include("items")
|
110
132
|
end
|
@@ -120,7 +142,7 @@ describe 'The method delete()' do
|
|
120
142
|
result = @mg_obj.delete("#{@domain}/campaigns/ABC123")
|
121
143
|
|
122
144
|
result.to_h!
|
123
|
-
|
145
|
+
|
124
146
|
expect(result.body).to include("message")
|
125
147
|
expect(result.body).to include("id")
|
126
148
|
end
|