balanced 0.3.3 → 0.3.4

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.
data/.travis.yml CHANGED
@@ -1,3 +1,6 @@
1
1
  language: ruby
2
+ bundler_args: --without development
3
+ script: "bundle exec rake spec"
2
4
  rvm:
5
+ - 1.9.2
3
6
  - 1.9.3
data/Gemfile CHANGED
@@ -1,7 +1,19 @@
1
- source 'https://rubygems.org'
2
-
1
+ source :rubygems
3
2
 
4
3
  # Specify your gem's dependencies in balanced.gemspec
5
- gemspec
6
4
 
7
- gem 'rspec'
5
+ gem "faraday"
6
+ gem "faraday_middleware"
7
+
8
+ group :development do
9
+ gem "yard"
10
+ gem "ruby-debug19"
11
+ gem "guard", '~> 1.1.1'
12
+ gem "guard-rspec", '~> 1.0.0'
13
+ end
14
+
15
+ group :test do
16
+ gem "rspec", '~> 2.10'
17
+ gem "rake", '~> 0.9.2'
18
+ gem "vcr", '~> 2.2.0'
19
+ end
data/Rakefile CHANGED
@@ -3,8 +3,10 @@ require "rake"
3
3
  require "rspec/core/rake_task"
4
4
  require "bundler/gem_tasks"
5
5
 
6
- RSpec::Core::RakeTask.new
6
+ desc "Run spec suite"
7
+ RSpec::Core::RakeTask.new(:spec) { |t| }
7
8
 
9
+ desc "Default the task to run the spec"
8
10
  task :default => [:spec]
9
11
 
10
12
 
data/balanced.gemspec CHANGED
@@ -1,9 +1,11 @@
1
+ #!/usr/bin/env gem build
1
2
  # -*- encoding: utf-8 -*-
3
+ require "base64"
2
4
  require File.expand_path('../lib/balanced/version', __FILE__)
3
5
 
4
6
  Gem::Specification.new do |gem|
5
7
  gem.authors = ["Mahmoud Abdelkader"]
6
- gem.email = %w(mahmoud@poundpay.com)
8
+ gem.email = ["bWFobW91ZEBwb3VuZHBheS5jb20="].map { |i| Base64.decode64(i) }
7
9
  gem.description = %q{Balanced is the payments platform for marketplaces.
8
10
  Integrate a payments experience just like Amazon for your marketplace.
9
11
  Forget about dealing with banking systems, compliance, fraud, and security.
@@ -14,17 +16,10 @@ Gem::Specification.new do |gem|
14
16
  gem.add_dependency("faraday", '~> 0.8')
15
17
  gem.add_dependency("faraday_middleware", '~> 0.8.7')
16
18
 
17
- gem.add_development_dependency("rspec", '~> 2.10')
18
- gem.add_development_dependency("vcr", '~> 2.2.0')
19
- gem.add_development_dependency("guard", '~> 1.1.1')
20
- gem.add_development_dependency("guard-rspec", '~> 1.0.0')
21
- gem.add_development_dependency("yard")
22
- gem.add_development_dependency("ruby-debug19")
23
-
24
19
  gem.files = `git ls-files`.split($\)
25
20
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
26
21
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
27
22
  gem.name = "balanced"
28
23
  gem.require_paths = %w(lib)
29
24
  gem.version = Balanced::VERSION
30
- end
25
+ end
data/examples/examples.rb CHANGED
@@ -116,5 +116,3 @@ bank_account['is_valid'] = false
116
116
  bank_account.save
117
117
 
118
118
  raise "This card is INCORRECTLY VALID" if bank_account.is_valid
119
-
120
- puts "and there you have it :)"
@@ -1,7 +1,9 @@
1
- require 'logger'
1
+ require "logger"
2
2
  require "uri"
3
3
  require "faraday"
4
4
  require "faraday_middleware"
5
+ require "balanced_exception_middleware"
6
+
5
7
 
6
8
  module Balanced
7
9
  class Client
@@ -27,12 +29,16 @@ module Balanced
27
29
  logger = Logger.new(STDOUT)
28
30
  logger.level = Logger.const_get(DEFAULTS[:logging_level].to_s)
29
31
 
32
+ Faraday.register_middleware :response,
33
+ :handle_balanced_errors => lambda {Faraday::Response::RaiseBalancedError}
34
+
30
35
  @conn = Faraday.new url do |cxn|
31
36
  cxn.request :json
32
37
 
33
38
  cxn.response :logger, logger
39
+ cxn.response :handle_balanced_errors
34
40
  cxn.response :json
35
- cxn.response :raise_error # raise exceptions on 40x, 50x responses
41
+ # cxn.response :raise_error # raise exceptions on 40x, 50x responses
36
42
  cxn.adapter Faraday.default_adapter
37
43
  end
38
44
  conn.path_prefix = '/'
@@ -0,0 +1,85 @@
1
+ module Balanced
2
+
3
+ # Custom error class for rescuing from all Balanced errors
4
+ class Error < StandardError
5
+ attr_reader :response
6
+
7
+ def initialize(response)
8
+ @response = response
9
+ super error_message
10
+ end
11
+
12
+ def body
13
+ Utils.hash_with_indifferent_read_access response[:body]
14
+ end
15
+
16
+ def error_message
17
+ set_attrs
18
+ extra = body[:additional] ? " -- #{body[:additional]}" : ""
19
+ "#{self.class.name}(#{response[:status]})::#{body[:status]}:: "\
20
+ "#{response[:method].to_s.upcase} #{response[:url].to_s}: "\
21
+ "#{body[:category_code]}: #{body[:description]} #{extra}"
22
+ end
23
+
24
+ private
25
+ def set_attrs
26
+ body.keys.each do |name|
27
+ self.class.instance_eval {
28
+ define_method(name) { body[name] } # Get.
29
+ define_method("#{name}?") { !!body[name].nil? } # Present.
30
+ }
31
+ end
32
+ end
33
+ end
34
+
35
+ class MoreInformationRequired < Error
36
+ def redirect_uri
37
+ response.headers['Location']
38
+ end
39
+
40
+ def error_message
41
+ set_attrs
42
+ "#{self.class.name} :: #{response[:method].to_s.upcase} #{response[:url].to_s}: "\
43
+ "#{response[:status]}: \n#{body[:friendly_html]}"
44
+ end
45
+ end
46
+
47
+ # Raised when Balanced returns a 400 HTTP status code
48
+ class BadRequest < Error; end
49
+
50
+ # Raised when Balanced returns a 401 HTTP status code
51
+ class Unauthorized < Error; end
52
+
53
+ # Raised when Balanced returns a 402 HTTP status code
54
+ class PaymentRequired < Error; end
55
+
56
+ # Raised when Balanced returns a 403 HTTP status code
57
+ class Forbidden < Error; end
58
+
59
+ # Raised when Balanced returns a 404 HTTP status code
60
+ class NotFound < Error; end
61
+
62
+ # Raised when Balanced returns a 405 HTTP status code
63
+ class MethodNotAllowed < Error; end
64
+
65
+ # Raised when Balanced returns a 409 HTTP status code
66
+ class Conflict < Error; end
67
+
68
+ # Raised when Balanced returns a 410 HTTP status code
69
+ class Gone < Error; end
70
+
71
+ # Raised when Balanced returns a 500 HTTP status code
72
+ class InternalServerError < Error; end
73
+
74
+ # Raised when Balanced returns a 501 HTTP status code
75
+ class NotImplemented < Error; end
76
+
77
+ # Raised when Balanced returns a 502 HTTP status code
78
+ class BadGateway < Error; end
79
+
80
+ # Raised when Balanced returns a 503 HTTP status code
81
+ class ServiceUnavailable < Error; end
82
+
83
+ # Raised when Balanced returns a 504 HTTP status code
84
+ class GatewayTimeout < Error; end
85
+ end
@@ -7,18 +7,6 @@ module Balanced
7
7
  class Account
8
8
  include Balanced::Resource
9
9
 
10
- class MoreInformationRequiredError < StandardError
11
- attr_reader :response
12
-
13
- def initialize(response)
14
- @response = response
15
- end
16
-
17
- def redirect_uri
18
- response.headers['Location']
19
- end
20
- end
21
-
22
10
  def initialize attributes = {}
23
11
  Balanced::Utils.stringify_keys! attributes
24
12
  unless attributes.has_key? 'uri'
@@ -27,6 +15,17 @@ module Balanced
27
15
  super attributes
28
16
  end
29
17
 
18
+ # Attempts to find an existing buyer account by email
19
+ #
20
+ # @param [String] email An email of a buyer account
21
+ # @return [Account] if buyer is found
22
+ # @return [nil] if buyer is not found
23
+ def self.find_by_email email
24
+ response = Balanced.get Balanced::Marketplace.my_marketplace.accounts_uri, {email_address: email}
25
+ record = response.body["items"].first
26
+ construct_from_response(record) unless record.nil?
27
+ end
28
+
30
29
  def save
31
30
  the_response = super
32
31
  if response.status == 300
@@ -0,0 +1,33 @@
1
+ require 'faraday'
2
+ require 'balanced/error'
3
+
4
+ # @api private
5
+ module Faraday
6
+
7
+ class Response::RaiseBalancedError < Response::Middleware
8
+
9
+ HTTP_STATUS_CODES = {
10
+ 300 => Balanced::MoreInformationRequired,
11
+ 400 => Balanced::BadRequest,
12
+ 401 => Balanced::Unauthorized,
13
+ 402 => Balanced::PaymentRequired,
14
+ 403 => Balanced::Forbidden,
15
+ 404 => Balanced::NotFound,
16
+ 405 => Balanced::MethodNotAllowed,
17
+ 409 => Balanced::Conflict,
18
+ 410 => Balanced::Gone,
19
+ 500 => Balanced::InternalServerError,
20
+ 501 => Balanced::NotImplemented,
21
+ 502 => Balanced::BadGateway,
22
+ 503 => Balanced::ServiceUnavailable,
23
+ 504 => Balanced::GatewayTimeout,
24
+ }
25
+ def on_complete(response)
26
+ status_code = response[:status].to_i
27
+ error_class = HTTP_STATUS_CODES[status_code]
28
+ raise error_class.new(response) if error_class
29
+ end
30
+
31
+ end
32
+
33
+ end
@@ -31,8 +31,15 @@ module Balanced
31
31
  end
32
32
 
33
33
  def hash_with_indifferent_read_access base = {}
34
- indifferent = Hash.new { |hash, key| hash[key.to_s] if key.is_a? Symbol }
35
- base.each_pair { |key, value| indifferent[key.to_s] = value }
34
+ indifferent = Hash.new do |hash, key|
35
+ hash[key.to_s] if key.is_a? Symbol
36
+ end
37
+ base.each_pair do |key, value|
38
+ if value.is_a? Hash
39
+ value = hash_with_indifferent_read_access value
40
+ end
41
+ indifferent[key.to_s] = value
42
+ end
36
43
  indifferent
37
44
  end
38
45
 
@@ -1,3 +1,3 @@
1
1
  module Balanced
2
- VERSION = '0.3.3'
2
+ VERSION = '0.3.4'
3
3
  end
data/lib/balanced.rb CHANGED
@@ -1,10 +1,12 @@
1
1
  $:.unshift File.join(File.dirname(__FILE__), "balanced", "resources")
2
+ $:.unshift File.join(File.dirname(__FILE__), "balanced", "response")
2
3
 
3
4
  require 'uri'
4
5
  require 'balanced/version' unless defined? Balanced::VERSION
5
6
  require 'balanced/client'
6
7
  require 'balanced/utils'
7
8
  require 'balanced/resources'
9
+ require 'balanced/error'
8
10
 
9
11
  module Balanced
10
12
 
@@ -419,4 +419,36 @@ describe Balanced::Account do
419
419
 
420
420
  end
421
421
  end
422
+
423
+ describe ".find_by_email" do
424
+ use_vcr_cassette
425
+ before do
426
+ api_key = Balanced::ApiKey.new.save
427
+ Balanced.configure api_key.secret
428
+ @marketplace = Balanced::Marketplace.new.save
429
+ card = Balanced::Card.new(
430
+ :card_number => "5105105105105100",
431
+ :expiration_month => "12",
432
+ :expiration_year => "2015",
433
+ ).save
434
+ buyer = Balanced::Marketplace.my_marketplace.create_buyer(
435
+ "john.doe@example.com",
436
+ card.uri
437
+ )
438
+ end
439
+
440
+ context "email address is in system" do
441
+ use_vcr_cassette
442
+ it "should return account object" do
443
+ Balanced::Account.find_by_email("john.doe@example.com").should be_instance_of Balanced::Account
444
+ end
445
+ end
446
+
447
+ context "email address does not exist" do
448
+ use_vcr_cassette
449
+ it "should return nil" do
450
+ Balanced::Account.find_by_email("foo@bar.com").should be_nil
451
+ end
452
+ end
453
+ end
422
454
  end
@@ -0,0 +1,47 @@
1
+ require "spec_helper"
2
+ require "faraday"
3
+
4
+ describe Faraday::Response::RaiseBalancedError, :type => :response do
5
+ context "when used" do
6
+ let(:raise_server_error) { described_class.new }
7
+ end
8
+
9
+ context "integration test" do
10
+
11
+ before(:each) do
12
+ Faraday.register_middleware :response,
13
+ :handle_balanced_errors => lambda { described_class }
14
+ VCR.turn_off!
15
+ end
16
+
17
+ after(:each) do
18
+ VCR.turn_on!
19
+ end
20
+
21
+ let(:stubs) { Faraday::Adapter::Test::Stubs.new }
22
+ let(:connection) do
23
+ Faraday::Connection.new do |builder|
24
+ builder.response :handle_balanced_errors
25
+ builder.response :json
26
+ builder.adapter :test, stubs
27
+ end
28
+ end
29
+
30
+ it "should raise exceptions on bad request errors" do
31
+ stubs.get("/error") {
32
+ [400, {}, JSON.dump({
33
+ :status =>"Bad Request",
34
+ :status_code =>400,
35
+ :description => "Missing expected field expiration_year Your request "\
36
+ "id is OHM62bf258abfea11e1aaba026ba7e5e72e.",
37
+ :request_id => "OHM62bf258abfea11e1aaba026ba7e5e72e"
38
+ })]
39
+ }
40
+
41
+ lambda {
42
+ connection.get('/error')
43
+ }.should raise_error(Balanced::BadRequest)
44
+ end
45
+
46
+ end
47
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,9 +1,15 @@
1
1
  require 'rubygems'
2
2
  require 'bundler/setup'
3
- require 'ruby-debug'
4
3
  require 'balanced'
5
4
  require 'vcr'
6
5
 
6
+ begin
7
+ require 'ruby-debug'
8
+ rescue LoadError
9
+ # ignored
10
+ end
11
+
12
+
7
13
  VCR.configure do |c|
8
14
  c.cassette_library_dir = 'spec/cassettes'
9
15
  c.hook_into :faraday
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: balanced
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 0.3.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-21 00:00:00.000000000 Z
12
+ date: 2012-06-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: faraday
@@ -43,102 +43,6 @@ dependencies:
43
43
  - - ~>
44
44
  - !ruby/object:Gem::Version
45
45
  version: 0.8.7
46
- - !ruby/object:Gem::Dependency
47
- name: rspec
48
- requirement: !ruby/object:Gem::Requirement
49
- none: false
50
- requirements:
51
- - - ~>
52
- - !ruby/object:Gem::Version
53
- version: '2.10'
54
- type: :development
55
- prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
- requirements:
59
- - - ~>
60
- - !ruby/object:Gem::Version
61
- version: '2.10'
62
- - !ruby/object:Gem::Dependency
63
- name: vcr
64
- requirement: !ruby/object:Gem::Requirement
65
- none: false
66
- requirements:
67
- - - ~>
68
- - !ruby/object:Gem::Version
69
- version: 2.2.0
70
- type: :development
71
- prerelease: false
72
- version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
- requirements:
75
- - - ~>
76
- - !ruby/object:Gem::Version
77
- version: 2.2.0
78
- - !ruby/object:Gem::Dependency
79
- name: guard
80
- requirement: !ruby/object:Gem::Requirement
81
- none: false
82
- requirements:
83
- - - ~>
84
- - !ruby/object:Gem::Version
85
- version: 1.1.1
86
- type: :development
87
- prerelease: false
88
- version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
- requirements:
91
- - - ~>
92
- - !ruby/object:Gem::Version
93
- version: 1.1.1
94
- - !ruby/object:Gem::Dependency
95
- name: guard-rspec
96
- requirement: !ruby/object:Gem::Requirement
97
- none: false
98
- requirements:
99
- - - ~>
100
- - !ruby/object:Gem::Version
101
- version: 1.0.0
102
- type: :development
103
- prerelease: false
104
- version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
- requirements:
107
- - - ~>
108
- - !ruby/object:Gem::Version
109
- version: 1.0.0
110
- - !ruby/object:Gem::Dependency
111
- name: yard
112
- requirement: !ruby/object:Gem::Requirement
113
- none: false
114
- requirements:
115
- - - ! '>='
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
- requirements:
123
- - - ! '>='
124
- - !ruby/object:Gem::Version
125
- version: '0'
126
- - !ruby/object:Gem::Dependency
127
- name: ruby-debug19
128
- requirement: !ruby/object:Gem::Requirement
129
- none: false
130
- requirements:
131
- - - ! '>='
132
- - !ruby/object:Gem::Version
133
- version: '0'
134
- type: :development
135
- prerelease: false
136
- version_requirements: !ruby/object:Gem::Requirement
137
- none: false
138
- requirements:
139
- - - ! '>='
140
- - !ruby/object:Gem::Version
141
- version: '0'
142
46
  description: ! "Balanced is the payments platform for marketplaces.\n Integrate
143
47
  a payments experience just like Amazon for your marketplace.\n Forget about dealing
144
48
  with banking systems, compliance, fraud, and security.\n "
@@ -172,6 +76,7 @@ files:
172
76
  - examples/examples.rb
173
77
  - lib/balanced.rb
174
78
  - lib/balanced/client.rb
79
+ - lib/balanced/error.rb
175
80
  - lib/balanced/resources.rb
176
81
  - lib/balanced/resources/account.rb
177
82
  - lib/balanced/resources/api_key.rb
@@ -185,12 +90,14 @@ files:
185
90
  - lib/balanced/resources/refund.rb
186
91
  - lib/balanced/resources/resource.rb
187
92
  - lib/balanced/resources/transaction.rb
93
+ - lib/balanced/response/balanced_exception_middleware.rb
188
94
  - lib/balanced/utils.rb
189
95
  - lib/balanced/version.rb
190
96
  - spec/balanced/resources/account_spec.rb
191
97
  - spec/balanced/resources/api_key_spec.rb
192
98
  - spec/balanced/resources/hold_spec.rb
193
99
  - spec/balanced/resources/marketplace_spec.rb
100
+ - spec/balanced/response/balanced_exception_middleware_spec.rb
194
101
  - spec/balanced_spec.rb
195
102
  - spec/client_spec.rb
196
103
  - spec/spec_helper.rb
@@ -225,7 +132,9 @@ test_files:
225
132
  - spec/balanced/resources/api_key_spec.rb
226
133
  - spec/balanced/resources/hold_spec.rb
227
134
  - spec/balanced/resources/marketplace_spec.rb
135
+ - spec/balanced/response/balanced_exception_middleware_spec.rb
228
136
  - spec/balanced_spec.rb
229
137
  - spec/client_spec.rb
230
138
  - spec/spec_helper.rb
231
139
  - spec/utils_spec.rb
140
+ has_rdoc: