adyen 0.3.8 → 1.0.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 (46) hide show
  1. data/.gitignore +4 -0
  2. data/.kick +35 -0
  3. data/LICENSE +3 -2
  4. data/README.rdoc +8 -4
  5. data/Rakefile +10 -0
  6. data/TODO +14 -4
  7. data/adyen.gemspec +9 -15
  8. data/lib/adyen.rb +10 -59
  9. data/lib/adyen/api.rb +281 -0
  10. data/lib/adyen/api/cacert.pem +3509 -0
  11. data/lib/adyen/api/payment_service.rb +258 -0
  12. data/lib/adyen/api/recurring_service.rb +126 -0
  13. data/lib/adyen/api/response.rb +54 -0
  14. data/lib/adyen/api/simple_soap_client.rb +118 -0
  15. data/lib/adyen/api/templates/payment_service.rb +103 -0
  16. data/lib/adyen/api/templates/recurring_service.rb +34 -0
  17. data/lib/adyen/api/test_helpers.rb +133 -0
  18. data/lib/adyen/api/xml_querier.rb +94 -0
  19. data/lib/adyen/configuration.rb +139 -0
  20. data/lib/adyen/form.rb +37 -109
  21. data/lib/adyen/formatter.rb +0 -10
  22. data/lib/adyen/matchers.rb +1 -1
  23. data/lib/adyen/notification_generator.rb +30 -0
  24. data/lib/adyen/railtie.rb +13 -0
  25. data/lib/adyen/templates/notification_migration.rb +29 -0
  26. data/lib/adyen/templates/notification_model.rb +70 -0
  27. data/spec/adyen_spec.rb +3 -45
  28. data/spec/api/api_spec.rb +139 -0
  29. data/spec/api/payment_service_spec.rb +439 -0
  30. data/spec/api/recurring_service_spec.rb +105 -0
  31. data/spec/api/response_spec.rb +35 -0
  32. data/spec/api/simple_soap_client_spec.rb +91 -0
  33. data/spec/api/spec_helper.rb +417 -0
  34. data/spec/api/test_helpers_spec.rb +83 -0
  35. data/spec/form_spec.rb +27 -23
  36. data/spec/functional/api_spec.rb +90 -0
  37. data/spec/functional/initializer.rb.sample +3 -0
  38. data/spec/spec_helper.rb +5 -5
  39. data/tasks/github-gem.rake +49 -55
  40. data/yard_extensions.rb +16 -0
  41. metadata +63 -82
  42. data/init.rb +0 -1
  43. data/lib/adyen/notification.rb +0 -151
  44. data/lib/adyen/soap.rb +0 -649
  45. data/spec/notification_spec.rb +0 -97
  46. data/spec/soap_spec.rb +0 -340
@@ -1,4 +1,4 @@
1
- require 'action_view'
1
+ require 'cgi'
2
2
 
3
3
  module Adyen
4
4
 
@@ -7,100 +7,22 @@ module Adyen
7
7
  # or a HTTP redirect (see {Adyen::Form.redirect_url}).
8
8
  #
9
9
  # Moreover, this module contains the method {Adyen::Form.redirect_signature_check} to
10
- # check the request that is made to your website after the visitor has made his payment
11
- # on the Adyen system for genuinity.
10
+ # check the request, that is made to your website after the visitor has made his payment
11
+ # on the Adyen system, for genuinity.
12
12
  #
13
13
  # You can use different skins in Adyen to define different payment environments. You can
14
14
  # register these skins under a custom name in the module. The other methods will automatically
15
15
  # use this information (i.e. the skin code and the shared secret) if it is available.
16
16
  # Otherwise, you have to provide it yourself for every method call you make. See
17
- # {Adyen::Form.register_skin} for more information.
17
+ # {Adyen::Configuration#register_form_skin} for more information.
18
18
  #
19
- # @see Adyen::Form.register_skin
19
+ # @see Adyen::Configuration#register_form_skin
20
20
  # @see Adyen::Form.hidden_fields
21
21
  # @see Adyen::Form.redirect_url
22
22
  # @see Adyen::Form.redirect_signature_check
23
23
  module Form
24
- include ActionView::Helpers::TagHelper
25
24
  extend self
26
25
 
27
- ######################################################
28
- # SKINS
29
- ######################################################
30
-
31
- # Returns all registered skins and their accompanying skin code and shared secret.
32
- # @return [Hash] The hash of registered skins.
33
- def skins
34
- @skins ||= {}
35
- end
36
-
37
- # Sets the registered skins.
38
- # @param [Hash<Symbol, Hash>] hash A hash with the skin name as key and the skin parameter hash
39
- # (which should include +:skin_code+ and +:shared_secret+) as value.
40
- # @see Adyen::Form.register_skin
41
- def skins=(hash)
42
- @skins = hash.inject({}) do |skins, (name, skin)|
43
- skins[name.to_sym] = skin.merge(:name => name.to_sym)
44
- skins
45
- end
46
- end
47
-
48
- # Registers a skin for later use.
49
- #
50
- # You can store a skin using a self defined symbol. Once the skin is registered,
51
- # you can refer to it using this symbol instead of the hard-to-remember skin code.
52
- # Moreover, the skin's shared_secret will be looked up automatically for calculting
53
- # signatures.
54
- #
55
- # @example
56
- # Adyen::Form.register_skin(:my_skin, 'dsfH67PO', 'Dfs*7uUln9')
57
- # @param [Symbol] name The name of the skin.
58
- # @param [String] skin_code The skin code for this skin, as defined by Adyen.
59
- # @param [String] shared_secret The shared secret used for signature calculation.
60
- # @see Adyen.load_config
61
- def register_skin(name, skin_code, shared_secret)
62
- skins[name.to_sym] = {:name => name.to_sym, :skin_code => skin_code, :shared_secret => shared_secret }
63
- end
64
-
65
- # Returns skin information given a skin name.
66
- # @param [Symbol] skin_name The name of the skin
67
- # @return [Hash, nil] A hash with the skin information, or nil if not found.
68
- def skin_by_name(skin_name)
69
- skins[skin_name.to_sym]
70
- end
71
-
72
- # Returns skin information given a skin code.
73
- # @param [String] skin_code The skin code of the skin
74
- # @return [Hash, nil] A hash with the skin information, or nil if not found.
75
- def skin_by_code(skin_code)
76
- skins.detect { |(name, skin)| skin[:skin_code] == skin_code }.last rescue nil
77
- end
78
-
79
- # Returns the shared secret belonging to a skin code.
80
- # @param [String] skin_code The skin code of the skin
81
- # @return [String, nil] The shared secret for the skin, or nil if not found.
82
- def lookup_shared_secret(skin_code)
83
- skin = skin_by_code(skin_code)[:shared_secret] rescue nil
84
- end
85
-
86
- ######################################################
87
- # DEFAULT FORM / REDIRECT PARAMETERS
88
- ######################################################
89
-
90
- # Returns the default parameters to use, unless they are overridden.
91
- # @see Adyen::Form.default_parameters
92
- # @return [Hash] The hash of default parameters
93
- def default_parameters
94
- @default_arguments ||= {}
95
- end
96
-
97
- # Sets the default parameters to use.
98
- # @see Adyen::Form.default_parameters
99
- # @param [Hash] hash The hash of default parameters
100
- def default_parameters=(hash)
101
- @default_arguments = hash
102
- end
103
-
104
26
  ######################################################
105
27
  # ADYEN FORM URL
106
28
  ######################################################
@@ -118,7 +40,7 @@ module Adyen
118
40
  # @see Adyen::Form.environment
119
41
  # @see Adyen::Form.redirect_url
120
42
  def url(environment = nil)
121
- environment ||= Adyen.environment
43
+ environment ||= Adyen.configuration.environment
122
44
  Adyen::Form::ACTION_URL % environment.to_s
123
45
  end
124
46
 
@@ -126,24 +48,22 @@ module Adyen
126
48
  # POSTING/REDIRECTING TO ADYEN
127
49
  ######################################################
128
50
 
129
- # Transforms the payment parameters hash to be in the correct format.
130
- # It will also include the default_parameters hash. Finally, switches
131
- # the +:skin+ parameter out for the +:skin_code+ and +:shared_secret+
132
- # parameter using the list of registered skins.
51
+ # Transforms the payment parameters hash to be in the correct format. It will also
52
+ # include the Adyen::Configuration#default_form_params hash. Finally, switches the
53
+ # +:skin+ parameter out for the +:skin_code+ and +:shared_secret+ parameter using
54
+ # the list of registered skins.
133
55
  #
134
56
  # @private
135
57
  # @param [Hash] parameters The payment parameters hash to transform
136
58
  def do_parameter_transformations!(parameters = {})
137
- raise "YENs are not yet supported!" if parameters[:currency_code] == 'JPY' # TODO: fixme
138
-
139
- parameters.replace(default_parameters.merge(parameters))
59
+ parameters.replace(Adyen.configuration.default_form_params.merge(parameters))
140
60
  parameters[:recurring_contract] = 'RECURRING' if parameters.delete(:recurring) == true
141
61
  parameters[:order_data] = Adyen::Encoding.gzip_base64(parameters.delete(:order_data_raw)) if parameters[:order_data_raw]
142
62
  parameters[:ship_before_date] = Adyen::Formatter::DateTime.fmt_date(parameters[:ship_before_date])
143
63
  parameters[:session_validity] = Adyen::Formatter::DateTime.fmt_time(parameters[:session_validity])
144
64
 
145
65
  if parameters[:skin]
146
- skin = Adyen::Form.skin_by_name(parameters.delete(:skin))
66
+ skin = Adyen.configuration.form_skin_by_name(parameters.delete(:skin))
147
67
  parameters[:skin_code] ||= skin[:skin_code]
148
68
  parameters[:shared_secret] ||= skin[:shared_secret]
149
69
  end
@@ -153,24 +73,24 @@ module Adyen
153
73
  # signature parameter. It also does some basic health checks on the parameters hash.
154
74
  #
155
75
  # @param [Hash] parameters The payment parameters. The parameters set in the
156
- # {Adyen::Form.default_parameters} hash will be included automatically.
76
+ # {Adyen::Configuration#default_form_params} hash will be included automatically.
157
77
  # @param [String] shared_secret The shared secret that should be used to calculate
158
78
  # the payment request signature. This parameter can be left if the skin that is
159
- # used is registered (see {Adyen::Form.register_skin}), or if the shared secret
160
- # is provided as the +:shared_secret+ parameter.
79
+ # used is registered (see {Adyen::Configuration#register_form_skin}), or if the
80
+ # shared secret is provided as the +:shared_secret+ parameter.
161
81
  # @return [Hash] The payment parameters with the +:merchant_signature+ parameter set.
162
- # @raise [StandardError] Thrown if some parameter health check fails.
82
+ # @raise [ArgumentError] Thrown if some parameter health check fails.
163
83
  def payment_parameters(parameters = {}, shared_secret = nil)
164
84
  do_parameter_transformations!(parameters)
165
85
 
166
- raise "Cannot generate form: :currency code attribute not found!" unless parameters[:currency_code]
167
- raise "Cannot generate form: :payment_amount code attribute not found!" unless parameters[:payment_amount]
168
- raise "Cannot generate form: :merchant_account attribute not found!" unless parameters[:merchant_account]
169
- raise "Cannot generate form: :skin_code attribute not found!" unless parameters[:skin_code]
86
+ raise ArgumentError, "Cannot generate form: :currency code attribute not found!" unless parameters[:currency_code]
87
+ raise ArgumentError, "Cannot generate form: :payment_amount code attribute not found!" unless parameters[:payment_amount]
88
+ raise ArgumentError, "Cannot generate form: :merchant_account attribute not found!" unless parameters[:merchant_account]
89
+ raise ArgumentError, "Cannot generate form: :skin_code attribute not found!" unless parameters[:skin_code]
170
90
 
171
91
  # Calculate the merchant signature using the shared secret.
172
92
  shared_secret ||= parameters.delete(:shared_secret)
173
- raise "Cannot calculate payment request signature without shared secret!" unless shared_secret
93
+ raise ArgumentError, "Cannot calculate payment request signature without shared secret!" unless shared_secret
174
94
  parameters[:merchant_sig] = calculate_signature(parameters, shared_secret)
175
95
 
176
96
  return parameters
@@ -180,8 +100,8 @@ module Adyen
180
100
  # as GET parameters in the URL. The URL also depends on the current Adyen enviroment.
181
101
  #
182
102
  # The payment parameters that are provided to this method will be merged with the
183
- # {Adyen::Form.default_parameters} hash. The default parameter values will be overrided
184
- # if another value is provided to this method.
103
+ # {Adyen::Configuration#default_form_params} hash. The default parameter values will be
104
+ # overrided if another value is provided to this method.
185
105
  #
186
106
  # You do not have to provide the +:merchant_sig+ parameter: it will be calculated automatically
187
107
  # if you provide either a registered skin name as the +:skin+ parameter or provide both the
@@ -206,15 +126,15 @@ module Adyen
206
126
  # @return [String] An absolute URL to redirect to the Adyen payment system.
207
127
  def redirect_url(parameters = {})
208
128
  url + '?' + payment_parameters(parameters).map { |(k, v)|
209
- "#{k.to_s.camelize(:lower)}=#{CGI.escape(v.to_s)}" }.join('&')
129
+ "#{camelize(k)}=#{CGI.escape(v.to_s)}" }.join('&')
210
130
  end
211
131
 
212
132
  # Returns a HTML snippet of hidden INPUT tags with the provided payment parameters.
213
133
  # The snippet can be included in a payment form that POSTs to the Adyen payment system.
214
134
  #
215
135
  # The payment parameters that are provided to this method will be merged with the
216
- # {Adyen::Form.default_parameters} hash. The default parameter values will be overrided
217
- # if another value is provided to this method.
136
+ # {Adyen::Configuration#default_form_params} hash. The default parameter values will be
137
+ # overrided if another value is provided to this method.
218
138
  #
219
139
  # You do not have to provide the +:merchant_sig+ parameter: it will be calculated automatically
220
140
  # if you provide either a registered skin name as the +:skin+ parameter or provide both the
@@ -234,7 +154,7 @@ module Adyen
234
154
 
235
155
  # Generate a hidden input tag per parameter, join them by newlines.
236
156
  form_str = payment_parameters(parameters).map { |key, value|
237
- tag(:input, :type => 'hidden', :name => key.to_s.camelize(:lower), :value => value)
157
+ "<input type=\"hidden\" name=\"#{CGI.escapeHTML(camelize(key))}\" value=\"#{CGI.escapeHTML(value.to_s)}\" />"
238
158
  }.join("\n")
239
159
 
240
160
  form_str.respond_to?(:html_safe) ? form_str.html_safe : form_str
@@ -297,7 +217,7 @@ module Adyen
297
217
  # using the {Adyen::Form.register_skin} method.
298
218
  # @return [String] The redirect signature
299
219
  def redirect_signature(params, shared_secret = nil)
300
- shared_secret ||= lookup_shared_secret(params[:skinCode])
220
+ shared_secret ||= Adyen.configuration.form_skin_shared_secret_by_code(params[:skinCode])
301
221
  Adyen::Encoding.hmac_base64(shared_secret, redirect_signature_string(params))
302
222
  end
303
223
 
@@ -329,10 +249,18 @@ module Adyen
329
249
  # should include the +:merchantSig+ parameter, which contains the signature.
330
250
  # @param [String] shared_secret The shared secret for the Adyen skin that was used for
331
251
  # the original payment form. You can leave this out of the skin is registered
332
- # using the {Adyen::Form.register_skin} method.
252
+ # using the {Adyen::Configuration#register_form_skin} method.
333
253
  # @return [true, false] Returns true only if the signature in the parameters is correct.
334
254
  def redirect_signature_check(params, shared_secret = nil)
335
255
  params[:merchantSig] == redirect_signature(params, shared_secret)
336
256
  end
257
+
258
+ # Returns the camelized version of a string.
259
+ # @param [:to_s] identifier The identifier to turn to camelcase
260
+ # @return [String] The camelcase version of the identifier provided.
261
+ def camelize(identifier)
262
+ identifier.to_s.gsub(/_(.)/) { $1.upcase }
263
+ end
264
+
337
265
  end
338
266
  end
@@ -23,15 +23,5 @@ module Adyen
23
23
  end
24
24
  end
25
25
  end
26
-
27
- module Price
28
- def self.in_cents(price)
29
- ((price * 100).round).to_i
30
- end
31
-
32
- def self.from_cents(price)
33
- BigDecimal.new(price.to_s) / 100
34
- end
35
- end
36
26
  end
37
27
  end
@@ -22,7 +22,7 @@ module Adyen
22
22
 
23
23
  # Add a check for all the other fields specified
24
24
  checks.each do |key, value|
25
- condition = "descendant::input[@type='hidden'][@name='#{key.to_s.camelize(:lower)}']"
25
+ condition = "descendant::input[@type='hidden'][@name='#{Adyen::Form.camelize(key)}']"
26
26
  condition << "[@value='#{value}']" unless value == :anything
27
27
  xpath_query << "[#{condition}]"
28
28
  end
@@ -0,0 +1,30 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/migration'
3
+
4
+ # @private
5
+ class Adyen::NotificationGenerator < Rails::Generators::Base
6
+ include Rails::Generators::Migration
7
+
8
+ def self.source_root
9
+ @source_root ||= File.join(File.dirname(__FILE__), 'templates')
10
+ end
11
+
12
+ # Implement the required interface for Rails::Generators::Migration.
13
+ # taken from http://github.com/rails/rails/blob/master/activerecord/lib/generators/active_record.rb
14
+ def self.next_migration_number(dirname)
15
+ if ActiveRecord::Base.timestamped_migrations
16
+ Time.now.utc.strftime("%Y%m%d%H%M%S")
17
+ else
18
+ "%.3d" % (current_migration_number(dirname) + 1)
19
+ end
20
+ end
21
+
22
+ # Create a migration file for the adyen_notifications table
23
+ def create_migration_file
24
+ migration_template 'notification_migration.rb', 'db/migrate/create_adyen_notifications.rb'
25
+ end
26
+
27
+ def create_model_file
28
+ template 'notification_model.rb', 'app/models/adyen_notification.rb'
29
+ end
30
+ end
@@ -0,0 +1,13 @@
1
+ require 'rails'
2
+
3
+ # @private
4
+ class Adyen::Railtie < ::Rails::Railtie
5
+
6
+ generators do
7
+ require 'adyen/notification_generator'
8
+ end
9
+
10
+ config.before_configuration do
11
+ config.adyen = Adyen.configuration
12
+ end
13
+ end
@@ -0,0 +1,29 @@
1
+ # @private
2
+ class CreateAdyenNotifications < ActiveRecord::Migration
3
+
4
+ def self.up
5
+ create_table :adyen_notifications do |t|
6
+ t.boolean :live, :null => false, :default => false
7
+ t.string :event_code, :null => false
8
+ t.string :psp_reference, :null => false
9
+ t.string :original_reference, :null => true
10
+ t.string :merchant_reference, :null => false
11
+ t.string :merchant_account_code, :null => false
12
+ t.datetime :event_date, :null => false
13
+ t.boolean :success, :null => false, :default => false
14
+ t.string :payment_method, :null => true
15
+ t.string :operations, :null => true
16
+ t.text :reason, :null => true
17
+ t.string :currency, :null => true, :limit => 3
18
+ t.integer :value, :null => true
19
+ t.boolean :processed, :null => false, :default => false
20
+ t.timestamps
21
+ end
22
+
23
+ add_index :adyen_notifications, [:psp_reference, :event_code, :success], :unique => true, :name => 'adyen_notification_uniqueness'
24
+ end
25
+
26
+ def self.down
27
+ drop_table :adyen_notifications
28
+ end
29
+ end
@@ -0,0 +1,70 @@
1
+ # The +AdyenNotification+ class handles notifications sent by Adyen to your servers.
2
+ #
3
+ # Because notifications contain important payment status information, you should store
4
+ # these notifications in your database. For this reason, +AdyenNotification+ inherits
5
+ # from +ActiveRecord::Base+, and a migration is included to simply create a suitable table
6
+ # to store the notifications in.
7
+ #
8
+ # Adyen can either send notifications to you via HTTP POST requests, or SOAP requests.
9
+ # Because SOAP is not really well supported in Rails and setting up a SOAP server is
10
+ # not trivial, only handling HTTP POST notifications is currently supported.
11
+ #
12
+ # @example
13
+ # @notification = AdyenNotification.log(request)
14
+ # if @notification.successful_authorisation?
15
+ # @invoice = Invoice.find(@notification.merchant_reference)
16
+ # @invoice.set_paid!
17
+ # end
18
+ class AdyenNotification < ActiveRecord::Base
19
+
20
+ # A notification should always include an event_code
21
+ validates_presence_of :event_code
22
+
23
+ # A notification should always include a psp_reference
24
+ validates_presence_of :psp_reference
25
+
26
+ # A notification should be unique using the composed key of
27
+ # [:psp_reference, :event_code, :success]
28
+ validates_uniqueness_of :success, :scope => [:psp_reference, :event_code]
29
+
30
+ # Make sure we don't end up with an original_reference with an empty string
31
+ before_validation { |notification| notification.original_reference = nil if notification.original_reference.blank? }
32
+
33
+ # Logs an incoming notification into the database.
34
+ #
35
+ # @param [Hash] params The notification parameters that should be stored in the database.
36
+ # @return [Adyen::Notification] The initiated and persisted notification instance.
37
+ # @raise This method will raise an exception if the notification cannot be stored.
38
+ # @see Adyen::Notification::HttpPost.log
39
+ def self.log(params)
40
+ converted_params = {}
41
+
42
+ # Convert each attribute from CamelCase notation to under_score notation
43
+ # For example, merchantReference will be converted to merchant_reference
44
+ params.each do |key, value|
45
+ column_name = key.to_s.underscore
46
+ converted_params[column_name] = value if self.column_names.include?(column_name)
47
+ end
48
+
49
+ self.create!(converted_params)
50
+ end
51
+
52
+ # Returns true if this notification is an AUTHORISATION notification
53
+ # @return [true, false] true iff event_code == 'AUTHORISATION'
54
+ # @see Adyen.notification#successful_authorisation?
55
+ def authorisation?
56
+ event_code == 'AUTHORISATION'
57
+ end
58
+
59
+ alias :authorization? :authorisation?
60
+
61
+ # Returns true if this notification is an AUTHORISATION notification and
62
+ # the success status indicates that the authorization was successfull.
63
+ # @return [true, false] true iff the notification is an authorization
64
+ # and the authorization was successful according to the success field.
65
+ def successful_authorisation?
66
+ event_code == 'AUTHORISATION' && success?
67
+ end
68
+
69
+ alias :successful_authorization? :successful_authorisation?
70
+ end
@@ -1,41 +1,9 @@
1
+ # encoding: UTF-8
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Adyen do
4
-
5
- describe '.load_config' do
6
-
7
- it "should set the environment correctly from the gonfiguration" do
8
- Adyen.load_config(:environment => 'from_config')
9
- Adyen.environment.should == 'from_config'
10
- end
11
-
12
- it "should recursively set settings for submodules" do
13
- Adyen.load_config(:SOAP => { :username => 'foo', :password => 'bar' },
14
- :Form => { :default_parameters => { :merchant_account => 'us' }})
15
- Adyen::SOAP.username.should == 'foo'
16
- Adyen::SOAP.password.should == 'bar'
17
- Adyen::Form.default_parameters.should == { :merchant_account => 'us' }
18
- end
19
-
20
- it "should raise an error when using a non-existing module" do
21
- lambda { Adyen.load_config(:Unknown => { :a => 'b' }) }.should raise_error
22
- end
23
-
24
- it "should raise an error when using a non-existing setting" do
25
- lambda { Adyen.load_config(:blah => 1234) }.should raise_error
26
- end
27
-
28
- it "should set skins from a hash configuration" do
29
- Adyen.load_config(:Form => {:skins => {
30
- :first => { :skin_code => '1234', :shared_secret => 'abcd' },
31
- :second => { :skin_code => '5678', :shared_secret => 'efgh' }}})
32
-
33
- Adyen::Form.skins.should == {
34
- :first => {:skin_code => "1234", :name => :first, :shared_secret => "abcd" },
35
- :second => {:skin_code => "5678", :name => :second, :shared_secret => "efgh" }}
36
- end
37
- end
38
-
6
+
39
7
  describe Adyen::Encoding do
40
8
  it "should a hmac_base64 correcly" do
41
9
  encoded_str = Adyen::Encoding.hmac_base64('bla', 'bla')
@@ -73,14 +41,4 @@ describe Adyen do
73
41
  lambda { Adyen::Formatter::DateTime.fmt_date('2009-1-1') }.should raise_error
74
42
  end
75
43
  end
76
-
77
- describe Adyen::Formatter::Price do
78
- it "should return a Fixnum with digits only when converting to cents" do
79
- Adyen::Formatter::Price.in_cents(33.76).should be_kind_of(Fixnum)
80
- end
81
-
82
- it "should return a BigDecimal when converting from cents" do
83
- Adyen::Formatter::Price.from_cents(1234).should be_kind_of(BigDecimal)
84
- end
85
- end
86
44
  end