adyen 0.3.7 → 0.3.8

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -3,3 +3,4 @@
3
3
  /doc
4
4
  adyen-*.gem
5
5
  .yardoc
6
+ *.swp
data/README.rdoc CHANGED
@@ -15,14 +15,20 @@ automated test suite to assert the integration is working correctly.
15
15
 
16
16
  == Installation
17
17
 
18
- Add the following line to your <tt>environment.rb</tt> and run <tt>rake gems:install</tt>
18
+ <b>Bundler / Rails 3</b>: Add the following line to your <tt>Gemfile</tt>:
19
+
20
+ gem 'adyen'
21
+
22
+ <b>Rails 2.x</b>: Add the following line to your <tt>environment.rb</tt> and run <tt>rake gems:install</tt>
19
23
  to make the Adyen functionality available in your Rails project:
20
24
 
21
- config.gem 'adyen', :source => 'http://gemcutter.org
25
+ config.gem 'adyen'
22
26
 
23
27
  You can also install it as a Rails plugin (*deprecated*):
24
28
 
25
- script/plugin install git://github.com/wvanbergen/adyen.git
29
+ script/plugin install git://github.com/wvanbergen/adyen.git
30
+
31
+ Depending on your use case, you may also need the following gems: activerecord, handsoap and nokogiri.
26
32
 
27
33
  == Usage
28
34
 
@@ -36,5 +42,6 @@ RDoc documentation for the project can be found on http://rdoc.info/projects/wva
36
42
  == About
37
43
 
38
44
  This package is written by Michel Barbosa and Willem van Bergen for Floorplanner.com, and
39
- made public under the MIT license (see LICENSE). It comes without warranty of any kind, so
40
- use at your own risk.
45
+ made public under the MIT license (see LICENSE). Its is currently maintained by Willem van
46
+ Bergen, Stefan Borsje and Eloy Duran. We are not affiliated with Adyen B.V. The software
47
+ comes without warranty of any kind, so use at your own risk.
data/TODO ADDED
@@ -0,0 +1,10 @@
1
+ * Use require/autoload instead of const_missing
2
+ * Make sure Japansese yens work as expected (this is the only currency Adyen does not expect to be in cents)
3
+ * Ditch SOAP library dependency.
4
+ * Complete SOAP API.
5
+ * Add ActiveMerchant integration
6
+
7
+ * Split up gem to have more explicit dependency requirements, e.g.:
8
+ * adyen-soap
9
+ * adyen-railtie
10
+ * adyen-activemerchant
data/adyen.gemspec CHANGED
@@ -1,9 +1,9 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'adyen'
3
- s.version = "0.3.7"
4
- s.date = "2010-07-21"
3
+ s.version = "0.3.8"
4
+ s.date = "2010-09-23"
5
5
 
6
- s.summary = "Integrate Adyen payment services in you Ruby on Rails application."
6
+ s.summary = "Integrate Adyen payment services in your Ruby on Rails application."
7
7
  s.description = <<-EOS
8
8
  Package to simplify including the Adyen payments services into a Ruby on Rails application.
9
9
  The package provides functionality to create payment forms, handling and storing notifications
@@ -11,20 +11,26 @@ Gem::Specification.new do |s|
11
11
  methods, mocks and matchers to simpify writing tests/specsfor your code.
12
12
  EOS
13
13
 
14
- s.authors = ['Willem van Bergen', 'Michel Barbosa']
15
- s.email = ['willem@vanbergen.org', 'cicaboo@gmail.com']
14
+ s.authors = ['Willem van Bergen', 'Michel Barbosa', 'Stefan Borsje', 'Eloy Duran']
15
+ s.email = ['willem@vanbergen.org', 'cicaboo@gmail.com', 'mail@sborsje.nl', 'eloy.de.enige@gmail.com']
16
16
  s.homepage = 'http://wiki.github.com/wvanbergen/adyen'
17
17
 
18
+ s.add_development_dependency('rake')
18
19
  s.add_development_dependency('rspec', '>= 1.1.4')
19
20
  s.add_development_dependency('git', '>= 1.1.0')
21
+ s.add_development_dependency('gemcutter')
22
+
23
+ # Drop or make runtime dependency.
24
+ s.add_development_dependency('activerecord')
25
+ s.add_development_dependency('handsoap')
26
+ s.add_development_dependency('nokogiri')
20
27
 
21
28
  s.requirements << 'Handsoap is required for accessing the SOAP services. See http://github.com/troelskn/handsoap.'
22
- s.requirements << 'LibXML is required for using the RSpec matchers.'
23
29
  s.requirements << 'ActiveRecord is required for storing the notifications in your database.'
24
30
 
25
31
  s.rdoc_options << '--title' << s.name << '--main' << 'README.rdoc' << '--line-numbers' << '--inline-source'
26
32
  s.extra_rdoc_files = ['README.rdoc']
27
33
 
28
- s.files = %w(spec/spec_helper.rb spec/adyen_spec.rb lib/adyen/form.rb .gitignore spec/notification_spec.rb lib/adyen/soap.rb LICENSE spec/soap_spec.rb init.rb adyen.gemspec Rakefile spec/form_spec.rb README.rdoc lib/adyen/notification.rb lib/adyen/formatter.rb tasks/github-gem.rake lib/adyen/encoding.rb lib/adyen/matchers.rb lib/adyen.rb)
34
+ s.files = %w(spec/spec_helper.rb spec/adyen_spec.rb lib/adyen/form.rb .gitignore spec/notification_spec.rb lib/adyen/soap.rb LICENSE spec/soap_spec.rb init.rb adyen.gemspec Rakefile spec/form_spec.rb README.rdoc lib/adyen/notification.rb lib/adyen/formatter.rb tasks/github-gem.rake lib/adyen/encoding.rb TODO lib/adyen/matchers.rb lib/adyen.rb)
29
35
  s.test_files = %w(spec/adyen_spec.rb spec/notification_spec.rb spec/soap_spec.rb spec/form_spec.rb)
30
36
  end
data/lib/adyen.rb CHANGED
@@ -13,7 +13,7 @@ module Adyen
13
13
  # Version constant for the Adyen plugin.
14
14
  # DO NOT CHANGE THIS VALUE BY HAND. It will be updated automatically by
15
15
  # the gem:release rake task.
16
- VERSION = "0.3.7"
16
+ VERSION = "0.3.8"
17
17
 
18
18
  # Loads configuration settings from a Hash.
19
19
  #
@@ -47,9 +47,9 @@ module Adyen
47
47
  #
48
48
  # It will return the +override+ value if set, it will return the value set
49
49
  # using {Adyen.environment=} otherwise. If this value also isn't set, the
50
- # environemtn is determined with {Adyen.autodetect_environment}.
50
+ # environment is determined with {Adyen.autodetect_environment}.
51
51
  #
52
- # @param ['test', 'live'] override An environemt to override the default with.
52
+ # @param ['test', 'live'] override An environment to override the default with.
53
53
  # @return ['test', 'live'] The Adyen environment that is currently being used.
54
54
  def self.environment(override = nil)
55
55
  override || @environment || Adyen.autodetect_environment
data/lib/adyen/form.rb CHANGED
@@ -21,8 +21,8 @@ module Adyen
21
21
  # @see Adyen::Form.redirect_url
22
22
  # @see Adyen::Form.redirect_signature_check
23
23
  module Form
24
-
25
- extend ActionView::Helpers::TagHelper
24
+ include ActionView::Helpers::TagHelper
25
+ extend self
26
26
 
27
27
  ######################################################
28
28
  # SKINS
@@ -30,7 +30,7 @@ module Adyen
30
30
 
31
31
  # Returns all registered skins and their accompanying skin code and shared secret.
32
32
  # @return [Hash] The hash of registered skins.
33
- def self.skins
33
+ def skins
34
34
  @skins ||= {}
35
35
  end
36
36
 
@@ -38,7 +38,7 @@ module Adyen
38
38
  # @param [Hash<Symbol, Hash>] hash A hash with the skin name as key and the skin parameter hash
39
39
  # (which should include +:skin_code+ and +:shared_secret+) as value.
40
40
  # @see Adyen::Form.register_skin
41
- def self.skins=(hash)
41
+ def skins=(hash)
42
42
  @skins = hash.inject({}) do |skins, (name, skin)|
43
43
  skins[name.to_sym] = skin.merge(:name => name.to_sym)
44
44
  skins
@@ -58,28 +58,28 @@ module Adyen
58
58
  # @param [String] skin_code The skin code for this skin, as defined by Adyen.
59
59
  # @param [String] shared_secret The shared secret used for signature calculation.
60
60
  # @see Adyen.load_config
61
- def self.register_skin(name, skin_code, shared_secret)
62
- self.skins[name.to_sym] = {:name => name.to_sym, :skin_code => skin_code, :shared_secret => shared_secret }
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
63
  end
64
64
 
65
65
  # Returns skin information given a skin name.
66
66
  # @param [Symbol] skin_name The name of the skin
67
67
  # @return [Hash, nil] A hash with the skin information, or nil if not found.
68
- def self.skin_by_name(skin_name)
69
- self.skins[skin_name.to_sym]
68
+ def skin_by_name(skin_name)
69
+ skins[skin_name.to_sym]
70
70
  end
71
71
 
72
72
  # Returns skin information given a skin code.
73
73
  # @param [String] skin_code The skin code of the skin
74
74
  # @return [Hash, nil] A hash with the skin information, or nil if not found.
75
- def self.skin_by_code(skin_code)
76
- self.skins.detect { |(name, skin)| skin[:skin_code] == skin_code }.last rescue nil
75
+ def skin_by_code(skin_code)
76
+ skins.detect { |(name, skin)| skin[:skin_code] == skin_code }.last rescue nil
77
77
  end
78
78
 
79
79
  # Returns the shared secret belonging to a skin code.
80
80
  # @param [String] skin_code The skin code of the skin
81
81
  # @return [String, nil] The shared secret for the skin, or nil if not found.
82
- def self.lookup_shared_secret(skin_code)
82
+ def lookup_shared_secret(skin_code)
83
83
  skin = skin_by_code(skin_code)[:shared_secret] rescue nil
84
84
  end
85
85
 
@@ -90,14 +90,14 @@ module Adyen
90
90
  # Returns the default parameters to use, unless they are overridden.
91
91
  # @see Adyen::Form.default_parameters
92
92
  # @return [Hash] The hash of default parameters
93
- def self.default_parameters
93
+ def default_parameters
94
94
  @default_arguments ||= {}
95
95
  end
96
96
 
97
97
  # Sets the default parameters to use.
98
98
  # @see Adyen::Form.default_parameters
99
99
  # @param [Hash] hash The hash of default parameters
100
- def self.default_parameters=(hash)
100
+ def default_parameters=(hash)
101
101
  @default_arguments = hash
102
102
  end
103
103
 
@@ -117,7 +117,7 @@ module Adyen
117
117
  # for payment forms or redirects.
118
118
  # @see Adyen::Form.environment
119
119
  # @see Adyen::Form.redirect_url
120
- def self.url(environment = nil)
120
+ def url(environment = nil)
121
121
  environment ||= Adyen.environment
122
122
  Adyen::Form::ACTION_URL % environment.to_s
123
123
  end
@@ -133,7 +133,7 @@ module Adyen
133
133
  #
134
134
  # @private
135
135
  # @param [Hash] parameters The payment parameters hash to transform
136
- def self.do_parameter_transformations!(parameters = {})
136
+ def do_parameter_transformations!(parameters = {})
137
137
  raise "YENs are not yet supported!" if parameters[:currency_code] == 'JPY' # TODO: fixme
138
138
 
139
139
  parameters.replace(default_parameters.merge(parameters))
@@ -160,7 +160,7 @@ module Adyen
160
160
  # is provided as the +:shared_secret+ parameter.
161
161
  # @return [Hash] The payment parameters with the +:merchant_signature+ parameter set.
162
162
  # @raise [StandardError] Thrown if some parameter health check fails.
163
- def self.payment_parameters(parameters = {}, shared_secret = nil)
163
+ def payment_parameters(parameters = {}, shared_secret = nil)
164
164
  do_parameter_transformations!(parameters)
165
165
 
166
166
  raise "Cannot generate form: :currency code attribute not found!" unless parameters[:currency_code]
@@ -204,8 +204,8 @@ module Adyen
204
204
  #
205
205
  # @param [Hash] parameters The payment parameters to include in the payment request.
206
206
  # @return [String] An absolute URL to redirect to the Adyen payment system.
207
- def self.redirect_url(parameters = {})
208
- self.url + '?' + payment_parameters(parameters).map { |(k, v)|
207
+ def redirect_url(parameters = {})
208
+ url + '?' + payment_parameters(parameters).map { |(k, v)|
209
209
  "#{k.to_s.camelize(:lower)}=#{CGI.escape(v.to_s)}" }.join('&')
210
210
  end
211
211
 
@@ -230,12 +230,14 @@ module Adyen
230
230
  # @param [Hash] parameters The payment parameters to include in the payment request.
231
231
  # @return [String] An HTML snippet that can be included in a form that POSTs to the
232
232
  # Adyen payment system.
233
- def self.hidden_fields(parameters = {})
233
+ def hidden_fields(parameters = {})
234
234
 
235
235
  # Generate a hidden input tag per parameter, join them by newlines.
236
- payment_parameters(parameters).map { |key, value|
237
- self.tag(:input, :type => 'hidden', :name => key.to_s.camelize(:lower), :value => value)
236
+ form_str = payment_parameters(parameters).map { |key, value|
237
+ tag(:input, :type => 'hidden', :name => key.to_s.camelize(:lower), :value => value)
238
238
  }.join("\n")
239
+
240
+ form_str.respond_to?(:html_safe) ? form_str.html_safe : form_str
239
241
  end
240
242
 
241
243
  ######################################################
@@ -246,7 +248,7 @@ module Adyen
246
248
  # is used by Adyen to check whether the request is genuinely originating from you.
247
249
  # @param [Hash] parameters The parameters that will be included in the payment request.
248
250
  # @return [String] The string for which the siganture is calculated.
249
- def self.calculate_signature_string(parameters)
251
+ def calculate_signature_string(parameters)
250
252
  merchant_sig_string = ""
251
253
  merchant_sig_string << parameters[:payment_amount].to_s << parameters[:currency_code].to_s <<
252
254
  parameters[:ship_before_date].to_s << parameters[:merchant_reference].to_s <<
@@ -270,7 +272,7 @@ module Adyen
270
272
  # It should correspond with the skin_code parameter. This parameter can be
271
273
  # left out if the shared_secret is included as key in the parameters.
272
274
  # @return [String] The signature of the payment request
273
- def self.calculate_signature(parameters, shared_secret = nil)
275
+ def calculate_signature(parameters, shared_secret = nil)
274
276
  shared_secret ||= parameters.delete(:shared_secret)
275
277
  Adyen::Encoding.hmac_base64(shared_secret, calculate_signature_string(parameters))
276
278
  end
@@ -282,7 +284,7 @@ module Adyen
282
284
  # Generates the string for which the redirect signature is calculated, using the request paramaters.
283
285
  # @param [Hash] params A hash of HTTP GET parameters for the redirect request.
284
286
  # @return [String] The signature string.
285
- def self.redirect_signature_string(params)
287
+ def redirect_signature_string(params)
286
288
  params[:authResult].to_s + params[:pspReference].to_s + params[:merchantReference].to_s + params[:skinCode].to_s
287
289
  end
288
290
 
@@ -294,7 +296,7 @@ module Adyen
294
296
  # the original payment form. You can leave this out of the skin is registered
295
297
  # using the {Adyen::Form.register_skin} method.
296
298
  # @return [String] The redirect signature
297
- def self.redirect_signature(params, shared_secret = nil)
299
+ def redirect_signature(params, shared_secret = nil)
298
300
  shared_secret ||= lookup_shared_secret(params[:skinCode])
299
301
  Adyen::Encoding.hmac_base64(shared_secret, redirect_signature_string(params))
300
302
  end
@@ -329,7 +331,7 @@ module Adyen
329
331
  # the original payment form. You can leave this out of the skin is registered
330
332
  # using the {Adyen::Form.register_skin} method.
331
333
  # @return [true, false] Returns true only if the signature in the parameters is correct.
332
- def self.redirect_signature_check(params, shared_secret = nil)
334
+ def redirect_signature_check(params, shared_secret = nil)
333
335
  params[:merchantSig] == redirect_signature(params, shared_secret)
334
336
  end
335
337
  end
@@ -1,4 +1,5 @@
1
- require 'xml'
1
+ require 'rexml/document'
2
+ require 'rexml/xpath'
2
3
 
3
4
  module Adyen
4
5
  module Matchers
@@ -31,12 +32,10 @@ module Adyen
31
32
 
32
33
  def self.document(subject)
33
34
  if String === subject
34
- XML::HTMLParser.string(subject).parse
35
+ REXML::Document.new(subject.to_s)
35
36
  elsif subject.respond_to?(:body)
36
- XML::HTMLParser.string(subject.body).parse
37
- elsif XML::Node === subject
38
- subject
39
- elsif XML::Document === subject
37
+ REXML::Document.new(subject.body.to_s)
38
+ elsif REXML::Document === subject
40
39
  subject
41
40
  else
42
41
  raise "Cannot handle this XML input type"
@@ -44,7 +43,7 @@ module Adyen
44
43
  end
45
44
 
46
45
  def self.check(subject, checks = {})
47
- document(subject).find_first(build_xpath_query(checks))
46
+ !!REXML::XPath.first(document(subject), build_xpath_query(checks))
48
47
  end
49
48
  end
50
49
 
@@ -105,15 +105,15 @@ module Adyen
105
105
  end
106
106
 
107
107
  def live=(value)
108
- self.write_attribute(:live, [true, 1, '1', 'true'].include?(value))
108
+ super([true, 1, '1', 'true'].include?(value))
109
109
  end
110
110
 
111
111
  def success=(value)
112
- self.write_attribute(:success, [true, 1, '1', 'true'].include?(value))
112
+ super([true, 1, '1', 'true'].include?(value))
113
113
  end
114
114
 
115
115
  def value=(value)
116
- self.write_attribute(:value, Adyen::Formatter::Price.from_cents(value)) unless value.blank?
116
+ super(Adyen::Formatter::Price.from_cents(value)) unless value.blank?
117
117
  end
118
118
  end
119
119
 
data/spec/adyen_spec.rb CHANGED
@@ -1,4 +1,4 @@
1
- require "#{File.dirname(__FILE__)}/spec_helper.rb"
1
+ require 'spec_helper'
2
2
 
3
3
  describe Adyen do
4
4
 
data/spec/form_spec.rb CHANGED
@@ -1,4 +1,4 @@
1
- require "#{File.dirname(__FILE__)}/spec_helper.rb"
1
+ require 'spec_helper'
2
2
 
3
3
  describe Adyen::Form do
4
4
 
@@ -1,4 +1,4 @@
1
- require "#{File.dirname(__FILE__)}/spec_helper.rb"
1
+ require 'spec_helper'
2
2
 
3
3
  describe Adyen::Notification do
4
4
 
data/spec/soap_spec.rb CHANGED
@@ -1,31 +1,31 @@
1
- require "#{File.dirname(__FILE__)}/spec_helper.rb"
1
+ require 'spec_helper'
2
2
 
3
3
  describe Adyen::SOAP::PaymentService do
4
4
 
5
5
  describe '#authorise' do
6
6
  before(:all) do
7
- setup_mock_driver(<<EOF)
8
- <?xml version="1.0" encoding="UTF-8"?>
9
- <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
10
- <soap:Body>
11
- <ns1:authoriseResponse xmlns:ns1="http://payment.services.adyen.com">
12
- <ns1:paymentResult>
13
- <additionalData xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
14
- <authCode xmlns="http://payment.services.adyen.com">1234</authCode>
15
- <dccAmount xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
16
- <dccSignature xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
17
- <fraudResult xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
18
- <issuerUrl xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
19
- <md xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
20
- <paRequest xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
21
- <pspReference xmlns="http://payment.services.adyen.com">9876543210987654</pspReference>
22
- <refusalReason xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
23
- <resultCode xmlns="http://payment.services.adyen.com">Authorised</resultCode>
24
- </ns1:paymentResult>
25
- </ns1:authoriseResponse>
26
- </soap:Body>
27
- </soap:Envelope>
28
- EOF
7
+ setup_mock_driver(<<-XML)
8
+ <?xml version="1.0" encoding="UTF-8"?>
9
+ <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
10
+ <soap:Body>
11
+ <ns1:authoriseResponse xmlns:ns1="http://payment.services.adyen.com">
12
+ <ns1:paymentResult>
13
+ <additionalData xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
14
+ <authCode xmlns="http://payment.services.adyen.com">1234</authCode>
15
+ <dccAmount xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
16
+ <dccSignature xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
17
+ <fraudResult xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
18
+ <issuerUrl xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
19
+ <md xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
20
+ <paRequest xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
21
+ <pspReference xmlns="http://payment.services.adyen.com">9876543210987654</pspReference>
22
+ <refusalReason xmlns="http://payment.services.adyen.com" xsi:nil="true"/>
23
+ <resultCode xmlns="http://payment.services.adyen.com">Authorised</resultCode>
24
+ </ns1:paymentResult>
25
+ </ns1:authoriseResponse>
26
+ </soap:Body>
27
+ </soap:Envelope>
28
+ XML
29
29
 
30
30
  @response = Adyen::SOAP::PaymentService.authorise({
31
31
  :selected_recurring_detail_reference => '6543210987654321',
@@ -93,19 +93,19 @@ EOF
93
93
 
94
94
  describe '#capture' do
95
95
  before(:all) do
96
- setup_mock_driver(<<EOF)
97
- <?xml version="1.0" encoding="UTF-8"?>
98
- <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
99
- <soap:Body>
100
- <ns1:captureResponse xmlns:ns1="http://payment.services.adyen.com">
101
- <ns1:captureResult>
102
- <pspReference xmlns="http://payment.services.adyen.com">9876543210987654</pspReference>
103
- <response xmlns="http://payment.services.adyen.com">[capture-received]</response>
104
- </ns1:captureResult>
105
- </ns1:captureResponse>
106
- </soap:Body>
107
- </soap:Envelope>
108
- EOF
96
+ setup_mock_driver(<<-XML)
97
+ <?xml version="1.0" encoding="UTF-8"?>
98
+ <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
99
+ <soap:Body>
100
+ <ns1:captureResponse xmlns:ns1="http://payment.services.adyen.com">
101
+ <ns1:captureResult>
102
+ <pspReference xmlns="http://payment.services.adyen.com">9876543210987654</pspReference>
103
+ <response xmlns="http://payment.services.adyen.com">[capture-received]</response>
104
+ </ns1:captureResult>
105
+ </ns1:captureResponse>
106
+ </soap:Body>
107
+ </soap:Envelope>
108
+ XML
109
109
 
110
110
  @response = Adyen::SOAP::PaymentService.capture({
111
111
  :merchant_account => 'YourMerchantAccount',
@@ -154,19 +154,19 @@ EOF
154
154
 
155
155
  describe "#cancel" do
156
156
  before(:all) do
157
- setup_mock_driver(<<EOF)
158
- <?xml version="1.0" encoding="UTF-8"?>
159
- <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
160
- <soap:Body>
161
- <ns1:cancelResponse xmlns:ns1="http://payment.services.adyen.com">
162
- <ns1:cancelResult>
163
- <pspReference xmlns="http://payment.services.adyen.com">9876543210987654</pspReference>
164
- <response xmlns="http://payment.services.adyen.com">[cancel-received]</response>
165
- </ns1:cancelResult>
166
- </ns1:cancelResponse>
167
- </soap:Body>
168
- </soap:Envelope>
169
- EOF
157
+ setup_mock_driver(<<-XML)
158
+ <?xml version="1.0" encoding="UTF-8"?>
159
+ <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
160
+ <soap:Body>
161
+ <ns1:cancelResponse xmlns:ns1="http://payment.services.adyen.com">
162
+ <ns1:cancelResult>
163
+ <pspReference xmlns="http://payment.services.adyen.com">9876543210987654</pspReference>
164
+ <response xmlns="http://payment.services.adyen.com">[cancel-received]</response>
165
+ </ns1:cancelResult>
166
+ </ns1:cancelResponse>
167
+ </soap:Body>
168
+ </soap:Envelope>
169
+ XML
170
170
 
171
171
  @response = Adyen::SOAP::PaymentService.cancel({
172
172
  :merchant_account => 'YourMerchantAccount',
@@ -205,19 +205,19 @@ EOF
205
205
 
206
206
  describe "#refund" do
207
207
  before(:all) do
208
- setup_mock_driver(<<EOF)
209
- <?xml version="1.0" encoding="UTF-8"?>
210
- <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
211
- <soap:Body>
212
- <ns1:refundResponse xmlns:ns1="http://payment.services.adyen.com">
213
- <ns1:refundResult>
214
- <pspReference xmlns="http://payment.services.adyen.com">9876543210987654</pspReference>
215
- <response xmlns="http://payment.services.adyen.com">[refund-received]</response>
216
- </ns1:refundResult>
217
- </ns1:refundResponse>
218
- </soap:Body>
219
- </soap:Envelope>
220
- EOF
208
+ setup_mock_driver(<<-XML)
209
+ <?xml version="1.0" encoding="UTF-8"?>
210
+ <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
211
+ <soap:Body>
212
+ <ns1:refundResponse xmlns:ns1="http://payment.services.adyen.com">
213
+ <ns1:refundResult>
214
+ <pspReference xmlns="http://payment.services.adyen.com">9876543210987654</pspReference>
215
+ <response xmlns="http://payment.services.adyen.com">[refund-received]</response>
216
+ </ns1:refundResult>
217
+ </ns1:refundResponse>
218
+ </soap:Body>
219
+ </soap:Envelope>
220
+ XML
221
221
 
222
222
  @response = Adyen::SOAP::PaymentService.refund({
223
223
  :merchant_account => 'YourMerchantAccount',
@@ -261,20 +261,20 @@ EOF
261
261
 
262
262
  describe "#cancel_or_refund" do
263
263
  before(:all) do
264
- setup_mock_driver(<<EOF)
265
- <?xml version="1.0" encoding="UTF-8"?>
266
- <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
267
- <soap:Body>
268
- <ns1:cancelOrRefundResponse xmlns:ns1="http://payment.services.adyen.com">
269
- <ns1:cancelOrRefundResult>
270
- <pspReference xmlns="http://payment.services.adyen.com">9876543210987654</pspReference>
271
- <response xmlns="http://payment.services.adyen.com">[cancelOrRefund-received]</response>
272
- </ns1:cancelOrRefundResult>
273
- </ns1:cancelOrRefundResponse>
274
- </soap:Body>
275
- </soap:Envelope>
276
- EOF
277
-
264
+ setup_mock_driver(<<-XML)
265
+ <?xml version="1.0" encoding="UTF-8"?>
266
+ <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
267
+ <soap:Body>
268
+ <ns1:cancelOrRefundResponse xmlns:ns1="http://payment.services.adyen.com">
269
+ <ns1:cancelOrRefundResult>
270
+ <pspReference xmlns="http://payment.services.adyen.com">9876543210987654</pspReference>
271
+ <response xmlns="http://payment.services.adyen.com">[cancelOrRefund-received]</response>
272
+ </ns1:cancelOrRefundResult>
273
+ </ns1:cancelOrRefundResponse>
274
+ </soap:Body>
275
+ </soap:Envelope>
276
+ XML
277
+
278
278
  @response = Adyen::SOAP::PaymentService.cancel_or_refund({
279
279
  :merchant_account => 'YourMerchantAccount',
280
280
  :original_reference => '1234567890123456'
@@ -320,7 +320,7 @@ private
320
320
  'Server: Apache',
321
321
  'Content-Type: text/xml;charset=UTF-8'
322
322
  ].join("\r\n"),
323
- :content => content
323
+ :content => content.strip
324
324
  })
325
325
  Handsoap.http_driver = :mock
326
326
  end
data/spec/spec_helper.rb CHANGED
@@ -1,4 +1,4 @@
1
- $: << File.join(File.dirname(__FILE__), '..', 'lib')
1
+ require 'spec_helper'
2
2
 
3
3
  require 'rubygems'
4
4
  require 'spec'
@@ -6,6 +6,7 @@ require 'spec/autorun'
6
6
  require 'active_support'
7
7
 
8
8
  require 'adyen'
9
+ require 'adyen/matchers'
9
10
 
10
11
  Spec::Runner.configure do |config|
11
12
  config.include Adyen::Matchers
@@ -119,24 +119,43 @@ module GithubGem
119
119
  checks = [:check_current_branch, :check_clean_status, :check_not_diverged, :check_version]
120
120
  checks.unshift('spec:basic') if has_specs?
121
121
  checks.unshift('test:basic') if has_tests?
122
- checks.push << [:check_rubyforge] if gemspec.rubyforge_project
122
+ # checks.push << [:check_rubyforge] if gemspec.rubyforge_project
123
123
 
124
124
  desc "Perform all checks that would occur before a release"
125
125
  task(:release_checks => checks)
126
126
 
127
127
  release_tasks = [:release_checks, :set_version, :build, :github_release, :gemcutter_release]
128
- release_tasks << [:rubyforge_release] if gemspec.rubyforge_project
128
+ # release_tasks << [:rubyforge_release] if gemspec.rubyforge_project
129
129
 
130
- desc "Release a new verison of the gem"
130
+ desc "Release a new version of the gem using the VERSION environment variable"
131
131
  task(:release => release_tasks) { release_task }
132
+
133
+ namespace(:release) do
134
+ desc "Release the next version of the gem, by incrementing the last version segment by 1"
135
+ task(:next => [:next_version] + release_tasks) { release_task }
132
136
 
133
- task(:check_rubyforge) { check_rubyforge_task }
134
- task(:rubyforge_release) { rubyforge_release_task }
137
+ desc "Release the next version of the gem, using a patch increment (0.0.1)"
138
+ task(:patch => [:next_patch_version] + release_tasks) { release_task }
139
+
140
+ desc "Release the next version of the gem, using a minor increment (0.1.0)"
141
+ task(:minor => [:next_minor_version] + release_tasks) { release_task }
142
+
143
+ desc "Release the next version of the gem, using a major increment (1.0.0)"
144
+ task(:major => [:next_major_version] + release_tasks) { release_task }
145
+ end
146
+
147
+ # task(:check_rubyforge) { check_rubyforge_task }
148
+ # task(:rubyforge_release) { rubyforge_release_task }
135
149
  task(:gemcutter_release) { gemcutter_release_task }
136
150
  task(:github_release => [:commit_modified_files, :tag_version]) { github_release_task }
137
151
  task(:tag_version) { tag_version_task }
138
152
  task(:commit_modified_files) { commit_modified_files_task }
139
153
 
154
+ task(:next_version) { next_version_task }
155
+ task(:next_patch_version) { next_version_task(:patch) }
156
+ task(:next_minor_version) { next_version_task(:minor) }
157
+ task(:next_major_version) { next_version_task(:major) }
158
+
140
159
  desc "Updates the gem release tasks with the latest version on Github"
141
160
  task(:update_tasks) { update_tasks_task }
142
161
  end
@@ -160,6 +179,32 @@ module GithubGem
160
179
  sh "mv #{gemspec.name}-#{gemspec.version}.gem pkg/#{gemspec.name}-#{gemspec.version}.gem"
161
180
  end
162
181
 
182
+ def newest_version
183
+ git.tags.map { |tag| tag.name.split('-').last }.compact.map { |v| Gem::Version.new(v) }.max || Gem::Version.new('0.0.0')
184
+ end
185
+
186
+ def next_version(increment = nil)
187
+ next_version = newest_version.segments
188
+ increment_index = case increment
189
+ when :micro then 3
190
+ when :patch then 2
191
+ when :minor then 1
192
+ when :major then 0
193
+ else next_version.length - 1
194
+ end
195
+
196
+ next_version[increment_index] ||= 0
197
+ next_version[increment_index] = next_version[increment_index].succ
198
+ ((increment_index + 1)...next_version.length).each { |i| next_version[i] = 0 }
199
+
200
+ Gem::Version.new(next_version.join('.'))
201
+ end
202
+
203
+ def next_version_task(increment = nil)
204
+ ENV['VERSION'] = next_version(increment).version
205
+ puts "Releasing version #{ENV['VERSION']}..."
206
+ end
207
+
163
208
  # Updates the version number in the gemspec file, the VERSION constant in the main
164
209
  # include file and the contents of the VERSION file.
165
210
  def version_task
@@ -172,10 +217,8 @@ module GithubGem
172
217
 
173
218
  def check_version_task
174
219
  raise "#{ENV['VERSION']} is not a valid version number!" if ENV['VERSION'] && !Gem::Version.correct?(ENV['VERSION'])
175
- proposed_version = Gem::Version.new(ENV['VERSION'] || gemspec.version)
176
- # Loads the latest version number using the created tags
177
- newest_version = git.tags.map { |tag| tag.name.split('-').last }.compact.map { |v| Gem::Version.new(v) }.max
178
- raise "This version (#{proposed_version}) is not higher than the highest tagged version (#{newest_version})" if newest_version && newest_version >= proposed_version
220
+ proposed_version = Gem::Version.new(ENV['VERSION'].dup || gemspec.version)
221
+ raise "This version (#{proposed_version}) is not higher than the highest tagged version (#{newest_version})" if newest_version >= proposed_version
179
222
  end
180
223
 
181
224
  # Checks whether the current branch is not diverged from the remote branch
@@ -216,19 +259,19 @@ module GithubGem
216
259
  git.push(remote, remote_branch, true)
217
260
  end
218
261
 
219
- # Checks whether Rubyforge is configured properly
220
- def check_rubyforge_task
221
- # Login no longer necessary when using rubyforge 2.0.0 gem
222
- # raise "Could not login on rubyforge!" unless `rubyforge login 2>&1`.strip.empty?
223
- output = `rubyforge names`.split("\n")
224
- raise "Rubyforge group not found!" unless output.any? { |line| %r[^groups\s*\:.*\b#{Regexp.quote(gemspec.rubyforge_project)}\b.*] =~ line }
225
- raise "Rubyforge package not found!" unless output.any? { |line| %r[^packages\s*\:.*\b#{Regexp.quote(gemspec.name)}\b.*] =~ line }
226
- end
227
-
228
- # Task to release the .gem file toRubyforge.
229
- def rubyforge_release_task
230
- sh 'rubyforge', 'add_release', gemspec.rubyforge_project, gemspec.name, gemspec.version.to_s, "pkg/#{gemspec.name}-#{gemspec.version}.gem"
231
- end
262
+ # # Checks whether Rubyforge is configured properly
263
+ # def check_rubyforge_task
264
+ # # Login no longer necessary when using rubyforge 2.0.0 gem
265
+ # # raise "Could not login on rubyforge!" unless `rubyforge login 2>&1`.strip.empty?
266
+ # output = `rubyforge names`.split("\n")
267
+ # raise "Rubyforge group not found!" unless output.any? { |line| %r[^groups\s*\:.*\b#{Regexp.quote(gemspec.rubyforge_project)}\b.*] =~ line }
268
+ # raise "Rubyforge package not found!" unless output.any? { |line| %r[^packages\s*\:.*\b#{Regexp.quote(gemspec.name)}\b.*] =~ line }
269
+ # end
270
+
271
+ # # Task to release the .gem file toRubyforge.
272
+ # def rubyforge_release_task
273
+ # sh 'rubyforge', 'add_release', gemspec.rubyforge_project, gemspec.name, gemspec.version.to_s, "pkg/#{gemspec.name}-#{gemspec.version}.gem"
274
+ # end
232
275
 
233
276
  def gemcutter_release_task
234
277
  sh "gem push pkg/#{gemspec.name}-#{gemspec.version}.gem"
metadata CHANGED
@@ -1,55 +1,134 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: adyen
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 3
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
8
  - 3
8
- - 7
9
- version: 0.3.7
9
+ - 8
10
+ version: 0.3.8
10
11
  platform: ruby
11
12
  authors:
12
13
  - Willem van Bergen
13
14
  - Michel Barbosa
15
+ - Stefan Borsje
16
+ - Eloy Duran
14
17
  autorequire:
15
18
  bindir: bin
16
19
  cert_chain: []
17
20
 
18
- date: 2010-07-21 00:00:00 +02:00
21
+ date: 2010-09-23 00:00:00 +02:00
19
22
  default_executable:
20
23
  dependencies:
21
24
  - !ruby/object:Gem::Dependency
22
- name: rspec
25
+ name: rake
23
26
  prerelease: false
24
27
  requirement: &id001 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ hash: 3
33
+ segments:
34
+ - 0
35
+ version: "0"
36
+ type: :development
37
+ version_requirements: *id001
38
+ - !ruby/object:Gem::Dependency
39
+ name: rspec
40
+ prerelease: false
41
+ requirement: &id002 !ruby/object:Gem::Requirement
42
+ none: false
25
43
  requirements:
26
44
  - - ">="
27
45
  - !ruby/object:Gem::Version
46
+ hash: 27
28
47
  segments:
29
48
  - 1
30
49
  - 1
31
50
  - 4
32
51
  version: 1.1.4
33
52
  type: :development
34
- version_requirements: *id001
53
+ version_requirements: *id002
35
54
  - !ruby/object:Gem::Dependency
36
55
  name: git
37
56
  prerelease: false
38
- requirement: &id002 !ruby/object:Gem::Requirement
57
+ requirement: &id003 !ruby/object:Gem::Requirement
58
+ none: false
39
59
  requirements:
40
60
  - - ">="
41
61
  - !ruby/object:Gem::Version
62
+ hash: 19
42
63
  segments:
43
64
  - 1
44
65
  - 1
45
66
  - 0
46
67
  version: 1.1.0
47
68
  type: :development
48
- version_requirements: *id002
69
+ version_requirements: *id003
70
+ - !ruby/object:Gem::Dependency
71
+ name: gemcutter
72
+ prerelease: false
73
+ requirement: &id004 !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ hash: 3
79
+ segments:
80
+ - 0
81
+ version: "0"
82
+ type: :development
83
+ version_requirements: *id004
84
+ - !ruby/object:Gem::Dependency
85
+ name: activerecord
86
+ prerelease: false
87
+ requirement: &id005 !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ hash: 3
93
+ segments:
94
+ - 0
95
+ version: "0"
96
+ type: :development
97
+ version_requirements: *id005
98
+ - !ruby/object:Gem::Dependency
99
+ name: handsoap
100
+ prerelease: false
101
+ requirement: &id006 !ruby/object:Gem::Requirement
102
+ none: false
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ hash: 3
107
+ segments:
108
+ - 0
109
+ version: "0"
110
+ type: :development
111
+ version_requirements: *id006
112
+ - !ruby/object:Gem::Dependency
113
+ name: nokogiri
114
+ prerelease: false
115
+ requirement: &id007 !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ hash: 3
121
+ segments:
122
+ - 0
123
+ version: "0"
124
+ type: :development
125
+ version_requirements: *id007
49
126
  description: " Package to simplify including the Adyen payments services into a Ruby on Rails application.\n The package provides functionality to create payment forms, handling and storing notifications \n sent by Adyen and consuming the SOAP services provided by Adyen. Moreover, it contains helper\n methods, mocks and matchers to simpify writing tests/specsfor your code.\n"
50
127
  email:
51
128
  - willem@vanbergen.org
52
129
  - cicaboo@gmail.com
130
+ - mail@sborsje.nl
131
+ - eloy.de.enige@gmail.com
53
132
  executables: []
54
133
 
55
134
  extensions: []
@@ -74,6 +153,7 @@ files:
74
153
  - lib/adyen/formatter.rb
75
154
  - tasks/github-gem.rake
76
155
  - lib/adyen/encoding.rb
156
+ - TODO
77
157
  - lib/adyen/matchers.rb
78
158
  - lib/adyen.rb
79
159
  has_rdoc: true
@@ -91,28 +171,31 @@ rdoc_options:
91
171
  require_paths:
92
172
  - lib
93
173
  required_ruby_version: !ruby/object:Gem::Requirement
174
+ none: false
94
175
  requirements:
95
176
  - - ">="
96
177
  - !ruby/object:Gem::Version
178
+ hash: 3
97
179
  segments:
98
180
  - 0
99
181
  version: "0"
100
182
  required_rubygems_version: !ruby/object:Gem::Requirement
183
+ none: false
101
184
  requirements:
102
185
  - - ">="
103
186
  - !ruby/object:Gem::Version
187
+ hash: 3
104
188
  segments:
105
189
  - 0
106
190
  version: "0"
107
191
  requirements:
108
192
  - Handsoap is required for accessing the SOAP services. See http://github.com/troelskn/handsoap.
109
- - LibXML is required for using the RSpec matchers.
110
193
  - ActiveRecord is required for storing the notifications in your database.
111
194
  rubyforge_project:
112
- rubygems_version: 1.3.6
195
+ rubygems_version: 1.3.7
113
196
  signing_key:
114
197
  specification_version: 3
115
- summary: Integrate Adyen payment services in you Ruby on Rails application.
198
+ summary: Integrate Adyen payment services in your Ruby on Rails application.
116
199
  test_files:
117
200
  - spec/adyen_spec.rb
118
201
  - spec/notification_spec.rb