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.
Files changed (57) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -0
  3. data/.ruby-env.yml.example +1 -1
  4. data/.travis.yml +23 -7
  5. data/Gemfile +2 -0
  6. data/README.md +79 -18
  7. data/{Domains.md → docs/Domains.md} +18 -0
  8. data/{Events.md → docs/Events.md} +0 -0
  9. data/{MessageBuilder.md → docs/MessageBuilder.md} +32 -13
  10. data/{Messages.md → docs/Messages.md} +3 -3
  11. data/{OptInHandler.md → docs/OptInHandler.md} +0 -0
  12. data/{Snippets.md → docs/Snippets.md} +21 -2
  13. data/docs/Suppressions.md +82 -0
  14. data/{Webhooks.md → docs/Webhooks.md} +1 -1
  15. data/docs/railgun/Overview.md +11 -0
  16. data/docs/railgun/Parameters.md +83 -0
  17. data/lib/mailgun/address.rb +48 -0
  18. data/lib/mailgun/client.rb +85 -8
  19. data/lib/mailgun/events/events.rb +40 -12
  20. data/lib/mailgun/exceptions/exceptions.rb +21 -7
  21. data/lib/mailgun/lists/opt_in_handler.rb +0 -1
  22. data/lib/mailgun/messages/batch_message.rb +3 -2
  23. data/lib/mailgun/messages/message_builder.rb +139 -30
  24. data/lib/mailgun/response.rb +7 -0
  25. data/lib/mailgun/suppressions.rb +273 -0
  26. data/lib/mailgun/version.rb +1 -1
  27. data/lib/mailgun/webhooks/webhooks.rb +1 -1
  28. data/lib/mailgun-ruby.rb +2 -0
  29. data/lib/mailgun.rb +1 -0
  30. data/lib/railgun/attachment.rb +56 -0
  31. data/lib/railgun/errors.rb +27 -0
  32. data/lib/railgun/mailer.rb +253 -0
  33. data/lib/railgun/message.rb +18 -0
  34. data/lib/railgun/railtie.rb +10 -0
  35. data/lib/railgun.rb +8 -0
  36. data/mailgun.gemspec +12 -13
  37. data/spec/integration/email_validation_spec.rb +57 -15
  38. data/spec/integration/events_spec.rb +9 -1
  39. data/spec/integration/mailer_spec.rb +67 -0
  40. data/spec/integration/mailgun_spec.rb +51 -1
  41. data/spec/integration/suppressions_spec.rb +142 -0
  42. data/spec/spec_helper.rb +3 -1
  43. data/spec/unit/connection/test_client.rb +16 -0
  44. data/spec/unit/events/events_spec.rb +36 -2
  45. data/spec/unit/mailgun_spec.rb +32 -10
  46. data/spec/unit/messages/batch_message_spec.rb +56 -40
  47. data/spec/unit/messages/message_builder_spec.rb +267 -81
  48. data/spec/unit/messages/sample_data/unknown.type +0 -0
  49. data/spec/unit/railgun/content_type_spec.rb +71 -0
  50. data/spec/unit/railgun/mailer_spec.rb +388 -0
  51. data/vcr_cassettes/email_validation.yml +136 -25
  52. data/vcr_cassettes/events.yml +48 -1
  53. data/vcr_cassettes/exceptions.yml +45 -0
  54. data/vcr_cassettes/mailer_invalid_domain.yml +109 -0
  55. data/vcr_cassettes/message_deliver.yml +149 -0
  56. data/vcr_cassettes/suppressions.yml +727 -0
  57. 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 = '>= 1.9.3'
26
-
27
- spec.add_development_dependency 'bundler', '~> 1.5'
28
- spec.add_development_dependency 'rspec', '~> 3.0'
29
- spec.add_development_dependency 'rake', '~> 10.0'
30
- spec.add_development_dependency 'webmock', '~> 1.22'
31
- spec.add_development_dependency 'pry', '~> 0.9'
32
- spec.add_development_dependency 'vcr', '~> 3.0'
33
- spec.add_development_dependency 'simplecov', '~> 0.11'
34
-
35
- spec.add_dependency 'rest-client', '~> 1.6'
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 Email Validation endpoint', vcr: vcr_opts do
8
+ describe 'For the email validation endpoint', order: :defined, vcr: vcr_opts do
7
9
  before(:all) do
8
- @mg_obj = Mailgun::Client.new(PUB_APIKEY)
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 an address.' do
12
- result = @mg_obj.get("address/validate",
13
- {:address => "test@#{TESTDOMAIN}"})
25
+ it 'validates alice@mailgun.net with info' do
26
+ res = @mg_obj.validate("alice@mailgun.net")
14
27
 
15
- result.to_h!
16
- expect(result.body["is_valid"]).to eq(true)
17
- expect(result.body["address"]).to eq("test@#{TESTDOMAIN}")
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 'parses an address.' do
21
- result = @mg_obj.get("address/parse",
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
- result.to_h!
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
@@ -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
- 'to' => 'bob@example.com',
29
- 'subject' => 'Test',
30
- 'text' => 'Test Data'}
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 = {'to' => 'joe@test.com',
41
- 'message' => 'Sample Data/mime.txt'}
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