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.
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