pagarme 2.0.2 → 2.1.0

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 (69) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +3 -2
  4. data/README.md +285 -4
  5. data/Rakefile +16 -19
  6. data/lib/pagarme.rb +17 -32
  7. data/lib/pagarme/core_ext.rb +9 -0
  8. data/lib/pagarme/errors.rb +39 -25
  9. data/lib/pagarme/model.rb +40 -45
  10. data/lib/pagarme/nested_model.rb +56 -0
  11. data/lib/pagarme/object.rb +133 -92
  12. data/lib/pagarme/request.rb +96 -46
  13. data/lib/pagarme/resources/address.rb +4 -0
  14. data/lib/pagarme/resources/antifraud_analysis.rb +4 -0
  15. data/lib/pagarme/resources/balance.rb +24 -0
  16. data/lib/pagarme/resources/balance_operation.rb +37 -0
  17. data/lib/pagarme/resources/bank_account.rb +4 -0
  18. data/lib/pagarme/resources/bulk_anticipation.rb +65 -0
  19. data/lib/pagarme/resources/card.rb +4 -0
  20. data/lib/pagarme/resources/company.rb +28 -0
  21. data/lib/pagarme/{customer.rb → resources/customer.rb} +0 -0
  22. data/lib/pagarme/resources/payable.rb +11 -0
  23. data/lib/pagarme/resources/phone.rb +4 -0
  24. data/lib/pagarme/{plan.rb → resources/plan.rb} +0 -2
  25. data/lib/pagarme/resources/postal_code.rb +15 -0
  26. data/lib/pagarme/resources/postback.rb +15 -0
  27. data/lib/pagarme/resources/recipient.rb +32 -0
  28. data/lib/pagarme/resources/split_rule.rb +4 -0
  29. data/lib/pagarme/resources/subscription.rb +43 -0
  30. data/lib/pagarme/resources/transaction.rb +41 -0
  31. data/lib/pagarme/{transfer.rb → resources/transfer.rb} +0 -3
  32. data/lib/pagarme/{phone.rb → resources/user.rb} +1 -1
  33. data/lib/pagarme/transaction_common.rb +39 -42
  34. data/lib/pagarme/version.rb +3 -0
  35. data/pagarme.gemspec +16 -13
  36. data/test/assertions.rb +195 -0
  37. data/test/fixtures.rb +222 -0
  38. data/test/pagarme/error_test.rb +13 -0
  39. data/test/pagarme/object_test.rb +19 -0
  40. data/test/pagarme/pagarme_test.rb +10 -0
  41. data/test/pagarme/resources/balance_test.rb +46 -0
  42. data/test/pagarme/resources/bank_account_test.rb +35 -0
  43. data/test/pagarme/resources/bulk_anticipation_test.rb +72 -0
  44. data/test/pagarme/resources/card_test.rb +22 -0
  45. data/test/pagarme/resources/payable_test.rb +30 -0
  46. data/test/pagarme/resources/plan_test.rb +57 -0
  47. data/test/pagarme/resources/postback_test.rb +18 -0
  48. data/test/pagarme/resources/recipient_test.rb +41 -0
  49. data/test/pagarme/resources/subscription_test.rb +100 -0
  50. data/test/pagarme/resources/transaction_test.rb +221 -0
  51. data/test/pagarme/resources/transfer_test.rb +23 -0
  52. data/test/pagarme/resources/zipcode_test.rb +15 -0
  53. data/test/test_helper.rb +52 -175
  54. metadata +102 -30
  55. data/lib/pagarme/address.rb +0 -4
  56. data/lib/pagarme/bank_account.rb +0 -9
  57. data/lib/pagarme/card.rb +0 -7
  58. data/lib/pagarme/subscription.rb +0 -43
  59. data/lib/pagarme/transaction.rb +0 -33
  60. data/lib/pagarme/util.rb +0 -78
  61. data/pagarme.rb +0 -12
  62. data/test/pagarme/bank_account.rb +0 -46
  63. data/test/pagarme/card.rb +0 -26
  64. data/test/pagarme/object.rb +0 -29
  65. data/test/pagarme/pagarme.rb +0 -10
  66. data/test/pagarme/plan.rb +0 -70
  67. data/test/pagarme/subscription.rb +0 -123
  68. data/test/pagarme/transaction.rb +0 -215
  69. data/test/pagarme/transfer.rb +0 -42
@@ -1,64 +1,59 @@
1
1
  module PagarMe
2
2
  class Model < PagarMeObject
3
3
 
4
- def self.class_name
5
- self.name.split('::')[-1]
4
+ def create
5
+ update PagarMe::Request.post(self.class.url, params: to_hash).run
6
+ self
6
7
  end
7
8
 
8
- def self.url()
9
- if self == Model
10
- raise PagarMeError.new('Cant request for model')
11
- end
12
- "/#{CGI.escape(class_name.downcase)}s"
9
+ def save
10
+ update PagarMe::Request.put(url, params: unsaved_attributes).run
11
+ self
13
12
  end
14
13
 
15
- def url
16
- raise PagarMeError.new("ID invalido", 'id') if !self.id
17
- "#{self.class.url}/#{CGI.escape(id.to_s)}"
14
+ def url(*params)
15
+ raise RequestError.new('Invalid ID') unless id.present?
16
+ self.class.url CGI.escape(id.to_s), *params
18
17
  end
19
18
 
20
- def create
21
- request = PagarMe::Request.new(self.class.url, 'POST')
22
- request.parameters = self.to_hash
23
- response = request.run
24
- update(response)
25
- end
19
+ class << self
26
20
 
27
- def save
28
- request = PagarMe::Request.new(self.url, 'PUT')
29
- request.parameters = self.unsaved_values
30
- response = request.run
31
- update(response)
32
- end
21
+ def create(*args, &block)
22
+ self.new(*args, &block).create
23
+ end
33
24
 
34
- def self.find_by_id(id)
35
- request = PagarMe::Request.new(self.url + "/#{id}", 'GET')
36
- response = request.run
37
- PagarMe::Util.convert_to_pagarme_object(response)
38
- end
25
+ def find_by_id(id)
26
+ raise RequestError.new('Invalid ID') unless id.present?
27
+ PagarMe::Request.get(url id).call
28
+ end
29
+ alias :find :find_by_id
39
30
 
40
- def self.find_by(hash, page = 1, count = 10)
41
- raise RequestError.new("Invalid page count") if page < 1 or count < 1
31
+ def find_by(hash, page = 1, count = 10)
32
+ raise RequestError.new('Invalid page count') if page < 1 or count < 1
42
33
 
43
- request = PagarMe::Request.new(self.url, 'GET')
34
+ PagarMe::Request.get(url, params: hash.merge(
35
+ page: page,
36
+ count: count
37
+ )).call
38
+ end
39
+ alias :find_by_hash :find_by
44
40
 
45
- request.parameters = hash
46
- request.parameters.merge!({:page => page, :count => count})
47
- response = request.run
48
- PagarMe::Util.convert_to_pagarme_object(response)
49
- end
41
+ def all(page = 1, count = 10)
42
+ find_by Hash.new, page, count
43
+ end
50
44
 
51
- def self.all(page = 1, count = 10)
52
- raise RequestError.new("Invalid page count") if page < 1 or count < 1
45
+ def url(*params)
46
+ ["/#{ CGI.escape underscored_class_name }s", *params].join '/'
47
+ end
48
+
49
+ def class_name
50
+ self.name.split('::').last
51
+ end
53
52
 
54
- request = PagarMe::Request.new(url, 'GET')
55
- request.parameters = {
56
- :page => page,
57
- :count => count
58
- }
53
+ def underscored_class_name
54
+ class_name.gsub(/[a-z0-9][A-Z]/){|s| "#{s[0]}_#{s[1]}"}.downcase
55
+ end
59
56
 
60
- response = request.run
61
- response.map { |obj_response| self.new(obj_response) }
62
57
  end
63
58
  end
64
- end
59
+ end
@@ -0,0 +1,56 @@
1
+ module PagarMe
2
+ class NestedModel < Model
3
+ attr_reader :parent_id
4
+
5
+ def initialize(hash = Hash.new)
6
+ hash = hash.dup
7
+ @parent_id = hash.delete(:parent_id) || hash.delete('parent_id')
8
+ super hash
9
+ end
10
+
11
+ def create
12
+ update PagarMe::Request.post(self.class.url(parent_id), params: to_hash).run
13
+ self
14
+ end
15
+
16
+ def url(*params)
17
+ raise RequestError.new('Invalid ID') unless id.present?
18
+ self.class.url parent_id, CGI.escape(id.to_s), *params
19
+ end
20
+
21
+ class << self
22
+
23
+ def parent_resource_name
24
+ raise NotImplementedError
25
+ end
26
+
27
+ def find_by_id(parent_id, id)
28
+ raise RequestError.new('Invalid ID') unless id.present?
29
+ raise RequestError.new('Invalid parent ID') unless parent_id.present?
30
+
31
+ PagarMe::Request.get(url parent_id, id).call
32
+ end
33
+ alias :find :find_by_id
34
+
35
+ def find_by(parent_id, hash, page = 1, count = 10)
36
+ raise RequestError.new('Invalid page count') if page < 1 or count < 1
37
+
38
+ PagarMe::Request.get(url(parent_id), params: hash.merge(
39
+ page: page,
40
+ count: count
41
+ )).call
42
+ end
43
+ alias :find_by_hash :find_by
44
+
45
+ def all(parent_id, page = 1, count = 10)
46
+ find_by parent_id, Hash.new, page, count
47
+ end
48
+
49
+ def url(parent_id, *params)
50
+ raise RequestError.new('Invalid parent ID') unless parent_id.present?
51
+ ["/#{parent_resource_name}", parent_id, "#{ CGI.escape underscored_class_name }s", *params].join '/'
52
+ end
53
+
54
+ end
55
+ end
56
+ end
@@ -1,94 +1,135 @@
1
- # encoding: utf-8
2
- require 'set'
3
-
4
1
  module PagarMe
5
- class PagarMeObject
6
- def initialize(response = {})
7
- #init @attributes - which are the attributes in the object
8
- @attributes = {}
9
-
10
- # Values that were changed in the object but weren't saved
11
- @unsaved_values = Set.new
12
-
13
- # Methods that already existed
14
- @@existing_methods = Array.new
15
-
16
- #Update object
17
- update(response)
18
- end
19
-
20
- def self.build(attributes)
21
- self.new(attributes)
22
- end
23
-
24
- def update(attributes)
25
- removed_attributes = @attributes.keys - attributes.keys
26
-
27
- removed_attributes.each do |key|
28
- @attributes.delete key
29
- end
30
-
31
- attributes.each do |key, value|
32
- key = key.to_s
33
-
34
- @attributes[key] = Util.convert_to_pagarme_object(value)
35
- @unsaved_values.delete key
36
- end
37
- end
38
-
39
- def each(&block)
40
- @attributes.each(&block)
41
- end
42
-
43
- def []=(key,value)
44
- @attributes[key] = value
45
- @unsaved_values.add key
46
- end
47
-
48
- def [](key)
49
- @attributes[key]
50
- end
51
-
52
- def to_hash_value(value, type)
53
- case value
54
- when PagarMeObject
55
- value.send type
56
- when Array
57
- value.map do |v|
58
- to_hash_value v, type
59
- end
60
- else
61
- value
62
- end
63
- end
64
-
65
- def unsaved_values
66
- Hash[@unsaved_values.map { |k| [k, to_hash_value(@attributes[k], 'unsaved_values')] }]
67
- end
68
-
69
- def to_hash
70
- Hash[@attributes.map { |k, v| [k, to_hash_value(v, 'to_hash')] }]
71
- end
72
-
73
- def respond_to?(name, include_all = false)
74
- return true if name.to_s.end_with? '='
75
-
76
- @attributes.has_key?(name.to_s) || super
77
- end
78
-
79
- protected
80
-
81
- def method_missing(name, *args)
82
- name = name.to_s
83
-
84
- if name.end_with? '='
85
- attribute_name = name[0...-1]
86
-
87
- self[attribute_name] = args[0]
88
- else
89
- self[name]
90
- end
91
- end
92
- end
2
+ class PagarMeObject
3
+ attr_reader :attributes, :unsaved_attributes
4
+
5
+ RESOURCES = Dir[File.expand_path('../resources/*.rb', __FILE__)].map do |path|
6
+ File.basename(path, '.rb').to_sym
7
+ end
8
+
9
+ def initialize(response = {})
10
+ @attributes = Hash.new
11
+ @unsaved_attributes = Set.new
12
+ update response
13
+ end
14
+
15
+ def []=(key,value)
16
+ @attributes[key] = value
17
+ @unsaved_attributes.add key
18
+ end
19
+
20
+ def empty?
21
+ @attributes.empty?
22
+ end
23
+
24
+ def ==(other)
25
+ self.class == other.class && id == other.id
26
+ end
27
+
28
+ def unsaved_attributes
29
+ Hash[@unsaved_attributes.map do |key|
30
+ [ key, to_hash_value(self[key], :unsaved_attributes) ]
31
+ end]
32
+ end
33
+
34
+ def to_hash
35
+ Hash[@attributes.map do |key, value|
36
+ [ key, to_hash_value(value, :to_hash) ]
37
+ end]
38
+ end
39
+
40
+ def respond_to?(name, include_all = false)
41
+ return true if name.to_s.end_with? '='
42
+
43
+ @attributes.has_key?(name.to_s) || super
44
+ end
45
+
46
+ def to_s
47
+ attributes_str = ''
48
+ (attributes.keys - ['id', 'object']).sort.each do |key|
49
+ attributes_str += " \033[1;33m#{key}:\033[0m#{self[key].inspect}" unless self[key].nil?
50
+ end
51
+ "\033[1;31m#<#{self.class.name}:\033[0;32m#{id}#{attributes_str}\033[0m\033[0m\033[1;31m>\033[0;32m"
52
+ end
53
+ alias :inspect :to_s
54
+
55
+ protected
56
+ def update(attributes)
57
+ removed_attributes = @attributes.keys - attributes.keys
58
+
59
+ removed_attributes.each do |key|
60
+ @attributes.delete key
61
+ end
62
+
63
+ attributes.each do |key, value|
64
+ key = key.to_s
65
+
66
+ @attributes[key] = PagarMeObject.convert(value)
67
+ @unsaved_attributes.delete key
68
+ end
69
+ end
70
+
71
+ def to_hash_value(value, type)
72
+ case value
73
+ when PagarMeObject
74
+ value.send type
75
+ when Array
76
+ value.map do |v|
77
+ to_hash_value v, type
78
+ end
79
+ else
80
+ value
81
+ end
82
+ end
83
+
84
+ def method_missing(name, *args, &block)
85
+ name = name.to_s
86
+
87
+ unless block_given?
88
+ if name.end_with?('=') && args.size == 1
89
+ attribute_name = name[0...-1]
90
+ return self[attribute_name] = args[0]
91
+ end
92
+
93
+ if args.size == 0
94
+ return self[name]
95
+ end
96
+ end
97
+
98
+ if attributes.respond_to? name
99
+ return attributes.public_send name, *args, &block
100
+ end
101
+
102
+ super name, *args, &block
103
+ end
104
+
105
+ class << self
106
+
107
+ def convert(response)
108
+ case response
109
+ when Array
110
+ response.map{ |i| convert i }
111
+ when Hash
112
+ resource_class_for(response['object']).new(response)
113
+ else
114
+ response
115
+ end
116
+ end
117
+
118
+ protected
119
+ def resource_class_for(resource_name)
120
+ return PagarMe::PagarMeObject if resource_name.nil?
121
+
122
+ if RESOURCES.include? resource_name.to_sym
123
+ Object.const_get "PagarMe::#{capitalize_name resource_name}"
124
+ else
125
+ PagarMe::PagarMeObject
126
+ end
127
+ end
128
+
129
+ def capitalize_name(name)
130
+ name.gsub(/(\A\w|\_\w)/){ |str| str.gsub('_', '').upcase }
131
+ end
132
+
133
+ end
134
+ end
93
135
  end
94
-
@@ -1,52 +1,102 @@
1
1
  require 'uri'
2
2
  require 'rest_client'
3
3
  require 'multi_json'
4
- require File.join(File.dirname(__FILE__), '.', 'util')
5
- require File.join(File.dirname(__FILE__), '.', 'errors')
6
4
 
7
5
  module PagarMe
8
- class Request
9
- attr_accessor :path, :method, :parameters, :headers, :query
10
-
11
- def initialize(path, method)
12
- self.path = path
13
- self.method = method
14
- self.parameters = {}
15
- self.query = {}
16
- self.headers = {}
17
- end
18
-
19
- def run
20
- raise PagarMeError, "You need to configure a API key before performing requests." unless PagarMe.api_key
21
-
22
- begin
23
- response = RestClient::Request.execute({
24
- :method => self.method,
25
- :user => PagarMe.api_key,
26
- :password => 'x',
27
- :url => PagarMe.full_api_url(self.path) + '?' + URI.encode_www_form(query),
28
- :payload => MultiJson.encode(parameters),
29
- :open_timeout => 30,
30
- :timeout => 90,
31
- :ssl_ca_file => File.join(File.dirname(__FILE__), '..', '..', 'certs', 'cabundle.pem'),
32
- :headers => {
33
- 'Content-Type' => 'application/json; charset=utf8',
34
- 'Accept' => 'application/json',
35
- 'User-Agent' => 'pagarme-ruby/1.0'
36
- }
37
- })
38
- rescue RestClient::ExceptionWithResponse => e
39
- parsed_error = MultiJson.decode(e.http_body)
40
-
41
- if parsed_error['errors']
42
- raise PagarMeError.fromServerResponse(parsed_error)
43
- else
44
- raise PagarMeError.new(e.http_body)
45
- end
46
- end
47
-
48
- MultiJson.decode response.body
49
- end
50
- end
51
- end
6
+ class Request
7
+ attr_accessor :path, :method, :parameters, :headers, :query
8
+
9
+ SSL_CA_FILEPATH = File.join File.dirname(__FILE__), '..', '..', 'certs', 'cabundle.pem'
10
+ DEFAULT_HEADERS = {
11
+ 'Content-Type' => 'application/json; charset=utf8',
12
+ 'Accept' => 'application/json',
13
+ 'User-Agent' => "pagarme-ruby/#{PagarMe::VERSION}"
14
+ }
15
+
16
+ def initialize(path, method, options={})
17
+ raise PagarMe::RequestError, 'You need to configure a API key before performing requests.' unless PagarMe.api_key
18
+
19
+ @path = path
20
+ @method = method
21
+ @parameters = options[:params] || Hash.new
22
+ @query = options[:query] || Hash.new
23
+ @headers = options[:headers] || Hash.new
24
+ end
25
+
26
+ def run
27
+ response = RestClient::Request.execute request_params
28
+ MultiJson.decode response.body
29
+ rescue RestClient::Exception => error
30
+ begin
31
+ parsed_error = MultiJson.decode error.http_body
32
+
33
+ if error.is_a? RestClient::ResourceNotFound
34
+ if parsed_error['errors']
35
+ raise PagarMe::NotFound.new(parsed_error, request_params, error)
36
+ else
37
+ raise PagarMe::NotFound.new(nil, request_params, error)
38
+ end
39
+ else
40
+ if parsed_error['errors']
41
+ raise PagarMe::ValidationError.new parsed_error
42
+ else
43
+ raise PagarMe::ResponseError.new(request_params, error)
44
+ end
45
+ end
46
+ rescue MultiJson::ParseError
47
+ raise PagarMe::ResponseError.new(request_params, error)
48
+ end
49
+ rescue MultiJson::ParseError
50
+ raise PagarMe::ResponseError.new(request_params, response)
51
+ rescue SocketError
52
+ raise PagarMe::ConnectionError.new $!
53
+ rescue RestClient::ServerBrokeConnection
54
+ raise PagarMe::ConnectionError.new $!
55
+ end
56
+
57
+ def call
58
+ PagarMeObject.convert run
59
+ end
60
+
61
+ def self.get(url, options={})
62
+ self.new url, 'GET', options
63
+ end
52
64
 
65
+ def self.post(url, options={})
66
+ self.new url, 'POST', options
67
+ end
68
+
69
+ def self.put(url, options={})
70
+ self.new url, 'PUT', options
71
+ end
72
+
73
+ def self.delete(url, options={})
74
+ self.new url, 'DELETE', options
75
+ end
76
+
77
+ protected
78
+ def request_params
79
+ {
80
+ method: method,
81
+ user: PagarMe.api_key,
82
+ password: 'x',
83
+ url: full_api_url,
84
+ payload: MultiJson.encode(parameters),
85
+ open_timeout: PagarMe.open_timeout,
86
+ timeout: PagarMe.timeout,
87
+ ssl_ca_file: SSL_CA_FILEPATH,
88
+ headers: DEFAULT_HEADERS.merge(headers)
89
+ }
90
+ end
91
+
92
+ def full_api_url
93
+ url = PagarMe.api_endpoint + path
94
+
95
+ if query.present?
96
+ url += '?' + URI.encode_www_form(query)
97
+ end
98
+
99
+ url
100
+ end
101
+ end
102
+ end