mailgun-ruby 1.1.0 → 1.2.5
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 +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
|