pagarme 2.0.2 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
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