allorails 0.4.2 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source :rubygems
2
+ gemspec
3
+ gem 'rspec'
4
+ gem 'nokogiri'
data/Gemfile.lock ADDED
@@ -0,0 +1,26 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ allorails (0.4.2)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.1.3)
10
+ nokogiri (1.5.5)
11
+ rspec (2.11.0)
12
+ rspec-core (~> 2.11.0)
13
+ rspec-expectations (~> 2.11.0)
14
+ rspec-mocks (~> 2.11.0)
15
+ rspec-core (2.11.1)
16
+ rspec-expectations (2.11.3)
17
+ diff-lcs (~> 1.1.3)
18
+ rspec-mocks (2.11.3)
19
+
20
+ PLATFORMS
21
+ ruby
22
+
23
+ DEPENDENCIES
24
+ allorails!
25
+ nokogiri
26
+ rspec
data/Manifest CHANGED
@@ -1,3 +1,6 @@
1
+ Gemfile
2
+ Gemfile.lock
3
+ Manifest
1
4
  README.md
2
5
  Rakefile
3
6
  allorails.gemspec
@@ -8,9 +11,12 @@ lib/allorails/core.rb
8
11
  lib/allorails/errors/errors.rb
9
12
  lib/allorails/rails.rb
10
13
  lib/allorails/request/request.rb
14
+ lib/allorails/response/api_mapping_response.rb
15
+ lib/allorails/response/api_response.rb
11
16
  lib/allorails/response/model.rb
12
- lib/allorails/response/response.rb
13
- test/allorails_spec.rb
14
- test/test-conf-sample.yml
15
- test/test-conf.yml
16
- Manifest
17
+ lib/allorails/response/onetime_button_response.rb
18
+ lib/allorails/response/onetime_pricing_response.rb
19
+ lib/allorails/response/onetime_validate_codes_response.rb
20
+ lib/allorails/response/product_detail_response.rb
21
+ lib/allorails/response/transaction_detail_response.rb
22
+ lib/allorails/response/transaction_prepare_response.rb
data/README.md CHANGED
@@ -54,7 +54,6 @@ You can put your configuration options in a yaml file located at `config/allorai
54
54
  # optional settings
55
55
  # (the values below are the defaults)
56
56
  default_hash: "sha1"
57
- default_format: "json"
58
57
  network_timeout: 20
59
58
  network_protocol: "http"
60
59
  network_port: 80
data/Rakefile CHANGED
@@ -2,13 +2,13 @@ require 'rubygems'
2
2
  require 'rake'
3
3
  require 'echoe'
4
4
 
5
- Echoe.new('allorails', '0.4.2') do |p|
6
- p.description = "Ruby client for the Allopass online payment REST API"
5
+ Echoe.new('allorails', '0.5.1') do |p|
6
+ p.description = "Ruby/Rails client for the Allopass online payment API"
7
7
  p.url = "http://github.com/davb/allorails"
8
8
  p.author = "Davide Bonapersona"
9
9
  p.email = "davide@feeligo.com"
10
- p.ignore_pattern = ["tmp/*", "script/*"]
10
+ p.ignore_pattern = ["tmp/*", "script/*", "spec/*"]
11
11
  p.development_dependencies = []
12
12
  end
13
13
 
14
- Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
14
+ Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
data/allorails.gemspec CHANGED
@@ -2,21 +2,21 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "allorails"
5
- s.version = "0.4.2"
5
+ s.version = "0.5.1"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Davide Bonapersona"]
9
- s.date = "2012-05-10"
10
- s.description = "Ruby client for the Allopass online payment REST API"
9
+ s.date = "2013-01-15"
10
+ s.description = "Ruby/Rails client for the Allopass online payment API"
11
11
  s.email = "davide@feeligo.com"
12
- s.extra_rdoc_files = ["README.md", "lib/allorails.rb", "lib/allorails/api/api.rb", "lib/allorails/core.rb", "lib/allorails/errors/errors.rb", "lib/allorails/rails.rb", "lib/allorails/request/request.rb", "lib/allorails/response/model.rb", "lib/allorails/response/response.rb"]
13
- s.files = ["README.md", "Rakefile", "allorails.gemspec", "init.rb", "lib/allorails.rb", "lib/allorails/api/api.rb", "lib/allorails/core.rb", "lib/allorails/errors/errors.rb", "lib/allorails/rails.rb", "lib/allorails/request/request.rb", "lib/allorails/response/model.rb", "lib/allorails/response/response.rb", "test/allorails_spec.rb", "test/test-conf-sample.yml", "test/test-conf.yml", "Manifest"]
12
+ s.extra_rdoc_files = ["README.md", "lib/allorails.rb", "lib/allorails/api/api.rb", "lib/allorails/core.rb", "lib/allorails/errors/errors.rb", "lib/allorails/rails.rb", "lib/allorails/request/request.rb", "lib/allorails/response/api_mapping_response.rb", "lib/allorails/response/api_response.rb", "lib/allorails/response/model.rb", "lib/allorails/response/onetime_button_response.rb", "lib/allorails/response/onetime_pricing_response.rb", "lib/allorails/response/onetime_validate_codes_response.rb", "lib/allorails/response/product_detail_response.rb", "lib/allorails/response/transaction_detail_response.rb", "lib/allorails/response/transaction_prepare_response.rb"]
13
+ s.files = ["Gemfile", "Gemfile.lock", "Manifest", "README.md", "Rakefile", "allorails.gemspec", "init.rb", "lib/allorails.rb", "lib/allorails/api/api.rb", "lib/allorails/core.rb", "lib/allorails/errors/errors.rb", "lib/allorails/rails.rb", "lib/allorails/request/request.rb", "lib/allorails/response/api_mapping_response.rb", "lib/allorails/response/api_response.rb", "lib/allorails/response/model.rb", "lib/allorails/response/onetime_button_response.rb", "lib/allorails/response/onetime_pricing_response.rb", "lib/allorails/response/onetime_validate_codes_response.rb", "lib/allorails/response/product_detail_response.rb", "lib/allorails/response/transaction_detail_response.rb", "lib/allorails/response/transaction_prepare_response.rb"]
14
14
  s.homepage = "http://github.com/davb/allorails"
15
15
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Allorails", "--main", "README.md"]
16
16
  s.require_paths = ["lib"]
17
17
  s.rubyforge_project = "allorails"
18
18
  s.rubygems_version = "1.8.21"
19
- s.summary = "Ruby client for the Allopass online payment REST API"
19
+ s.summary = "Ruby/Rails client for the Allopass online payment API"
20
20
 
21
21
  if s.respond_to? :specification_version then
22
22
  s.specification_version = 3
@@ -108,7 +108,7 @@ module Allorails
108
108
  # registers configuration options
109
109
  add_option :accounts, {}
110
110
  add_option :default_hash, 'sha1'
111
- add_option :default_format, 'json'
111
+ add_option :default_format, Allorails::Request::ApiRequest::MAPPING_FORMAT
112
112
  add_option :network_timeout, 20
113
113
  add_option :network_protocol, 'http'
114
114
  add_option :network_port, 80
@@ -8,7 +8,7 @@ module Allorails
8
8
  class ApiRequest
9
9
 
10
10
  # API response format needed to provide response object mapping
11
- MAPPING_FORMAT = 'json'
11
+ MAPPING_FORMAT = 'xml'
12
12
  # API remote base path
13
13
  API_PATH = '/rest'
14
14
 
@@ -0,0 +1,93 @@
1
+ require 'nokogiri'
2
+
3
+ module Allorails
4
+ module Response
5
+
6
+ ## Basis of an object mapped API response
7
+ class ApiMappingResponse < Allorails::Response::ApiResponse
8
+
9
+ attr_reader :xml
10
+
11
+ ##
12
+ # Constructor
13
+ # @param signature (string) Expected response signature
14
+ # @param headers (list) Response HTTP headers
15
+ # @param body (string) Raw response data
16
+ def initialize(signature, headers, body)
17
+ super(signature, headers, body)
18
+ # parse the XML response
19
+ @xml = Nokogiri.XML(body)
20
+ # error if no root element
21
+ raise Allorails::ApiWrongFormatResponseError if @xml.root.nil?
22
+ # verify the response
23
+ _verify
24
+ end
25
+
26
+ ##
27
+ # Internal method checking the response
28
+ # @throws ApiRemoteErrorError If response doesn't contain valid XML
29
+ def _verify
30
+ raise Allorails::ApiRemoteErrorError if @xml.root[:code] != '0'
31
+ # call the parent _verify method which will check the signature
32
+ super
33
+ end
34
+
35
+ ##
36
+ # Internal method allowing easy reading of XML nodes
37
+ # @param (sym) name of the node that needs to be read
38
+ # @param (Class) type to which the result should be cast
39
+ def self.node_reader(node_name, type = String)
40
+ # define a Proc to cast the node's text to the specified type
41
+ node_value = case true
42
+ when type == String then Proc.new{|x| x.text}
43
+ when type == Integer then Proc.new{|x| x.text.to_i}
44
+ when type == Float then Proc.new{|x| x.text.to_f}
45
+ when type == DateTime then Proc.new{|x|
46
+ if x.respond_to?(:attribute) && (ts = x.attribute('timestamp'))
47
+ DateTime.strptime(ts.value, "%s")
48
+ elsif x.respond_to?(:attribute) && (d = x.attribute('date'))
49
+ DateTime.strptime(d.value)
50
+ else
51
+ nil
52
+ end
53
+ }
54
+ else Proc.new{|x| type.new x}
55
+ end
56
+ # add a method accessing the node and casting the text
57
+ send :define_method, node_name do
58
+ node = xml.css(node_name.to_s).first
59
+ return node_value.call(node) unless node.nil?
60
+ end
61
+ end
62
+
63
+ ##
64
+ # Internal method allowing easy reading of XML attributes
65
+ # @param (sym) name of the attribute that needs to be read
66
+ # @param (Class) type to which the result should be cast
67
+ def self.attribute_reader(attr_name, type = String)
68
+ # define a Proc to cast the attribute's value to the specified type
69
+ attr_value = case true
70
+ when type == String then Proc.new{|x| x.value}
71
+ when type == Integer then Proc.new{|x| x.value.to_i}
72
+ when type == Float then Proc.new{|x| x.value.to_f}
73
+ when type == DateTime then Proc.new{|x|
74
+ if x.respond_to?(:attribute) && (ts = x.attribute('timestamp'))
75
+ DateTime.strptime(ts.value, "%s")
76
+ elsif x.respond_to?(:attribute) && (d = x.attribute('date'))
77
+ DateTime.strptime(d.value)
78
+ else
79
+ nil
80
+ end
81
+ }
82
+ else Proc.new{|x| type.new x}
83
+ end
84
+ # add a method accessing the node and casting the text
85
+ send :define_method, attr_name do
86
+ att = xml.attribute(attr_name.to_s)
87
+ return attr_value.call(att) unless att.nil?
88
+ end
89
+ end
90
+
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,27 @@
1
+ module Allorails
2
+ module Response
3
+ class ApiResponse
4
+
5
+ ##
6
+ # Constructor
7
+ # @param signature (string) Expected response signature
8
+ # @param headers (list) Response HTTP headers
9
+ # @param body (string) Raw response data
10
+ def initialize(signature, headers, body)
11
+ @_signature = signature
12
+ @_headers = headers
13
+ @_body = body
14
+ end
15
+
16
+ ##
17
+ # Internal method checking the response
18
+ # @throws ApiFalseResponseSignature If the expected signature is not found among response headers
19
+ def _verify
20
+ unless (@_headers['x-allopass-response-signature'] || []).include?(@_signature)
21
+ raise Allorails::ApiFalseResponseSignatureError
22
+ end
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -6,7 +6,7 @@ module Allorails
6
6
  class Base < Allorails::Response::ApiMappingResponse
7
7
 
8
8
  def initialize(node)
9
- @json = node
9
+ @xml = node
10
10
  end
11
11
 
12
12
  end
@@ -17,25 +17,25 @@ module Allorails
17
17
 
18
18
  ## Provides the website id
19
19
  # @return (int) website id
20
- node_reader :id, Integer
20
+ attribute_reader :id, Integer
21
21
 
22
22
  ## Provides the website name
23
23
  # @return (string) website name
24
- node_reader :name
24
+ attribute_reader :name
25
25
 
26
26
  ## Provides the website url
27
27
  # @return (string) website url
28
- node_reader :url
28
+ attribute_reader :url
29
29
 
30
30
  ## Checks wether the website's audience is restricted
31
31
  # @return (boolean) wether the website's audience is restricted
32
32
  def audience_restricted?
33
- @json.audience_restricted == 'true'
33
+ xml.attribute('audience_restricted') == 'true'
34
34
  end
35
35
 
36
36
  ## Provides the website category
37
37
  # @return (string) website category
38
- node_reader :category
38
+ attribute_reader :category
39
39
 
40
40
  end
41
41
 
@@ -45,11 +45,11 @@ module Allorails
45
45
 
46
46
  ## Provides the country code
47
47
  # @return (string) country code (two characters)
48
- node_reader :code
48
+ attribute_reader :code
49
49
 
50
50
  ## Provides the country name
51
51
  # @return (string) country name
52
- node_reader :name
52
+ attribute_reader :name
53
53
 
54
54
  end
55
55
 
@@ -59,12 +59,12 @@ module Allorails
59
59
 
60
60
  ## Provides the region name
61
61
  # @return (string) region name
62
- node_reader :name
62
+ attribute_reader :name
63
63
 
64
64
  ## Provides the countries in the region
65
65
  # @return (Array) region's countries
66
66
  def countries
67
- json.children.values.map{|c| ::Allorails::Country.new(c)}
67
+ xml.css('country').map{|c| Allorails::Country.new(c)}
68
68
  end
69
69
 
70
70
  end
@@ -75,16 +75,16 @@ module Allorails
75
75
 
76
76
  ## Provides the country code
77
77
  # @return (string) country code (two characters)
78
- node_reader :country_code
78
+ attribute_reader :country_code
79
79
 
80
80
  ## Provides the country name
81
81
  # @return (string) country name
82
- node_reader :country
82
+ attribute_reader :country
83
83
 
84
84
  ## Provides the pricepoints available in this market
85
85
  # @return (Array) available pricepoints (list of Pricepoint objects)
86
86
  def pricepoints
87
- json.pricepoint.map{|c| ::Allorails::Pricepoint.new(c)}
87
+ xml.css('pricepoint').map{|c| Allorails::Pricepoint.new(c)}
88
88
  end
89
89
 
90
90
  end
@@ -95,23 +95,23 @@ module Allorails
95
95
 
96
96
  ## Provides the currency
97
97
  # @return (string) currency (three characters)
98
- node_reader :currency
98
+ attribute_reader :currency
99
99
 
100
100
  ## Provides the amount
101
101
  # @return (float) amount
102
- node_reader :amount, Float
102
+ attribute_reader :amount, Float
103
103
 
104
104
  ## Provides the day's exchange rate
105
105
  # @return (float) exchange rate
106
- node_reader :exchange, Float
106
+ attribute_reader :exchange, Float
107
107
 
108
108
  ## Provides the reference currency
109
109
  # @return (string) reference currency
110
- node_reader :reference_currency
110
+ attribute_reader :reference_currency
111
111
 
112
112
  ## Provides the amount in the reference currency
113
113
  # @return (float) reference amount
114
- node_reader :reference_amount, Float
114
+ attribute_reader :reference_amount, Float
115
115
 
116
116
  end
117
117
 
@@ -120,23 +120,23 @@ module Allorails
120
120
 
121
121
  ## Provides the currency
122
122
  # @return (string) currency (three characters)
123
- node_reader :currency
123
+ attribute_reader :currency
124
124
 
125
125
  ## Provides the amount
126
126
  # @return (float) amount
127
- node_reader :amount, Float
127
+ attribute_reader :amount, Float
128
128
 
129
129
  ## Provides the day's exchange rate
130
130
  # @return (float) exchange rate
131
- node_reader :exchange, Float
131
+ attribute_reader :exchange, Float
132
132
 
133
133
  ## Provides the reference currency
134
134
  # @return (string) reference currency
135
- node_reader :reference_currency
135
+ attribute_reader :reference_currency
136
136
 
137
137
  ## Provides the amount in the reference currency
138
138
  # @return (float) reference amount
139
- node_reader :reference_amount, Float
139
+ attribute_reader :reference_amount, Float
140
140
 
141
141
  end
142
142
 
@@ -146,7 +146,7 @@ module Allorails
146
146
 
147
147
  ## Provides the phone number
148
148
  # @return (string) phone number
149
- node_reader :value
149
+ attribute_reader :value
150
150
 
151
151
  ## Provides the description of the phone number
152
152
  # @return (string) description
@@ -160,23 +160,23 @@ module Allorails
160
160
 
161
161
  ## Provides the keyword name
162
162
  # @return (string) keyword name
163
- node_reader :name
163
+ attribute_reader :name
164
164
 
165
165
  ## Provides the keyword's shortcode
166
166
  # @return (string) shortcode
167
- node_reader :shortcode
167
+ attribute_reader :shortcode
168
168
 
169
169
  ## Provides the keyword operators
170
170
  # @return (string) keyword operators
171
- node_reader :operators
171
+ attribute_reader :operators
172
172
 
173
173
  ## Provides the number of billed messages of the keyword
174
174
  # @return (int) number of billed messages
175
- node_reader :number_billed_messages, Integer
175
+ attribute_reader :number_billed_messages, Integer
176
176
 
177
177
  ## Provides a description of the keyword
178
178
  # @return (string) description
179
- node_reader :description
179
+ attribute_reader :description
180
180
 
181
181
  end
182
182
 
@@ -186,23 +186,23 @@ module Allorails
186
186
 
187
187
  ## Provides the pricepoint's id
188
188
  # @return (int) pricepoint id
189
- node_reader :id, Integer
189
+ attribute_reader :id, Integer
190
190
 
191
191
  ## Provides the pricepoint's type
192
192
  # @return (string) pricepoint type
193
- node_reader :type
193
+ attribute_reader :type
194
194
 
195
195
  ## Provides the pricepoint's country code
196
196
  # @return (string) country code (two characters)
197
- node_reader :country_code
197
+ attribute_reader :country_code
198
198
 
199
199
  ## Provides price information
200
200
  # @return (Price) price information
201
- node_reader :price, ::Allorails::Price
201
+ node_reader :price, Allorails::Price
202
202
 
203
203
  ## Provides the pricepoint's payout
204
204
  # @return (Payout) pricepoint's payout
205
- node_reader :payout, ::Allorails::Payout
205
+ node_reader :payout, Allorails::Payout
206
206
 
207
207
  ## Provides the buy url
208
208
  # @return (string) buy url
@@ -211,15 +211,13 @@ module Allorails
211
211
  ## Provides the pricepoint's phone numbers
212
212
  # @return (list) pricepoint's phone number (list of PhoneNumber objects)
213
213
  def phone_numbers
214
- return nil if json.phone_numbers.nil?
215
- json.phone_numbers.children.values.map{|c| ::Allorails::PhoneNumber(c)}
214
+ xml.css('phone_number').map{|c| Allorails::PhoneNumber.new(c)}
216
215
  end
217
216
 
218
217
  ## Provides the pricepoint's keywords
219
218
  # @return (list) pricepoint's keywords (list of Keyword objects)
220
219
  def keywords
221
- return nil if json.keywords.nil?
222
- json.keywords.children.values.map{|c| ::Allorails::Keyword(c)}
220
+ xml.css('keyword').map{|c| Allorails::Keyword.new(c)}
223
221
  end
224
222
 
225
223
  ## Provides the pricepoint's description
@@ -234,17 +232,18 @@ module Allorails
234
232
 
235
233
  ## Provides the partner id
236
234
  # @return (int) partner id
237
- node_reader :id, Integer
235
+ attribute_reader :id, Integer
238
236
 
239
237
  ## Provides the parnter's amount share
240
238
  # @return (float) parnter's amount share
241
- node_reader :share, Float
239
+ attribute_reader :share, Float
242
240
 
243
241
  ## Provides the associated map id
244
242
  # @return (int) map id
245
243
  def map
246
- return nil unless json.map.is_a?(String) && json.map.length > 0
247
- json.map.to_i
244
+ if (map = xml.attribute('map')) && map.text.length > 0
245
+ return map.to_i
246
+ end
248
247
  end
249
248
 
250
249
  end
@@ -259,19 +258,19 @@ module Allorails
259
258
 
260
259
  ## Provides the pricepoint's description
261
260
  # @return (string) pricepoint's description
262
- node_reader :pricepoint, ::Allorails::Pricepoint
261
+ node_reader :pricepoint, Allorails::Pricepoint
263
262
 
264
263
  ## Provides price information
265
264
  # @return (Price) price information
266
- node_reader :price, ::Allorails::Price
265
+ node_reader :price, Allorails::Price
267
266
 
268
267
  ## Provides paid price information
269
268
  # @return (Price) paid price information
270
- node_reader :paid, ::Allorails::Price
269
+ node_reader :paid, Allorails::Price
271
270
 
272
271
  ## Provides the pricepoint's payout
273
272
  # @return (Payout) pricepoint's payout
274
- node_reader :payout, ::Allorails::Payout
273
+ node_reader :payout, Allorails::Payout
275
274
 
276
275
  end
277
276
 
@@ -0,0 +1,28 @@
1
+ ## Class defining a onetime button request's response
2
+ class Allorails::Response::OnetimeButtonResponse < Allorails::Response::ApiMappingResponse
3
+
4
+ ## Provides access type
5
+ # @return (string) access type
6
+ node_reader :access_type
7
+
8
+ ## Provides the button id
9
+ # @return (string) button id
10
+ node_reader :button_id
11
+
12
+ ## Provides the creation date
13
+ # @return (datetime.datetime) Creation date
14
+ node_reader :creation_date, DateTime
15
+
16
+ ## Provides the website
17
+ # @return (Website) website
18
+ node_reader :website, Allorails::Website
19
+
20
+ ## Provides the buy url
21
+ # @return (string) buy url
22
+ node_reader :buy_url
23
+
24
+ ## Provides the checkout button
25
+ # @return (string) checkout button (html code)
26
+ node_reader :checkout_button
27
+
28
+ end
@@ -0,0 +1,37 @@
1
+ class Allorails::Response::OnetimePricingResponse < Allorails::Response::ApiMappingResponse
2
+
3
+ ## Provides the creation date
4
+ # @return (DateTime) Creation date
5
+ node_reader :creation_date, DateTime
6
+
7
+ ## Provides the customer ip
8
+ # @return (string) customer ip
9
+ node_reader :customer_ip
10
+
11
+ ## Provides the customer country
12
+ # @return (string) customer country
13
+ node_reader :customer_country
14
+
15
+ ## Provides the website
16
+ # @return (Website) website
17
+ node_reader :website, Allorails::Website
18
+
19
+ ## Provides the pricepoints by countries
20
+ # @return (Array) available countries (list of Country object)
21
+ def countries
22
+ xml.css('countries country').map{|c| Allorails::Country.new(c)}
23
+ end
24
+
25
+ ## Provides the pricepoints by region
26
+ # @return (Array) available regions (list of Regions object)
27
+ def regions
28
+ xml.css('countries region').map{|r| ::Allorails::Region.new(r)}
29
+ end
30
+
31
+ ## Provides the pricepoints by markets
32
+ # @return (list) available markets (list of Market object)
33
+ def markets
34
+ xml.css('markets market').map{|m| Allorails::Market.new(m)}
35
+ end
36
+
37
+ end