adyen 0.1.4
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.
- data/.gitignore +4 -0
- data/LICENSE +20 -0
- data/README.rdoc +32 -0
- data/Rakefile +5 -0
- data/adyen.gemspec +21 -0
- data/init.rb +1 -0
- data/lib/adyen.rb +31 -0
- data/lib/adyen/encoding.rb +21 -0
- data/lib/adyen/form.rb +71 -0
- data/lib/adyen/formatter.rb +37 -0
- data/lib/adyen/matchers.rb +105 -0
- data/lib/adyen/notification.rb +99 -0
- data/lib/adyen/soap.rb +147 -0
- data/spec/adyen_spec.rb +53 -0
- data/spec/form_spec.rb +123 -0
- data/spec/notification_spec.rb +97 -0
- data/spec/soap_spec.rb +30 -0
- data/spec/spec_helper.rb +11 -0
- data/tasks/github-gem.rake +323 -0
- metadata +103 -0
data/lib/adyen/soap.rb
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
require "handsoap"
|
2
|
+
|
3
|
+
module Adyen
|
4
|
+
|
5
|
+
# The SOAP module contains classes that interact with the Adyen
|
6
|
+
# SOAP services. The clients are based on the Handsoap library.
|
7
|
+
# Shared functionality for all services is implemented in the
|
8
|
+
# Adyen::SOAP::Base class.
|
9
|
+
#
|
10
|
+
# Note that you'll need an Adyen notification PSP reference for
|
11
|
+
# most SOAP calls. Because of this, store all notifications that
|
12
|
+
# Adyen sends to you. (e.g. using the Adyen::Notification ActiveRecord
|
13
|
+
# class). Moreover, most SOAP calls do not respond that they were
|
14
|
+
# successful immediately, but a notifications to indicate that will
|
15
|
+
# be sent later on.
|
16
|
+
#
|
17
|
+
# You'll need to provide a username and password to interact
|
18
|
+
# with the Adyen SOAP services:
|
19
|
+
#
|
20
|
+
# Adyen::SOAP.username = 'ws@Company.MyAccount'
|
21
|
+
# Adyen::SOAP.password = 'very$ecret'
|
22
|
+
#
|
23
|
+
# You can setup default values for every SOAP call that needs them:
|
24
|
+
#
|
25
|
+
# Adyen::SOAP.default_arguments[:merchent_account] = 'MyMerchant'
|
26
|
+
#
|
27
|
+
# For now, only the recurring payment service client is implemented
|
28
|
+
# (Adyen::SOAP::RecurringService).
|
29
|
+
module SOAP
|
30
|
+
|
31
|
+
class << self
|
32
|
+
# Set up accessors for HTTP Basic Authentication and
|
33
|
+
# for adding default arguments to SOAP calls.
|
34
|
+
attr_accessor :username, :password, :default_arguments
|
35
|
+
end
|
36
|
+
|
37
|
+
# Use no default arguments by default
|
38
|
+
self.default_arguments = {}
|
39
|
+
|
40
|
+
# The base class sets up XML namespaces and HTTP authentication
|
41
|
+
# for all the Adyen SOAP services
|
42
|
+
class Base < Handsoap::Service
|
43
|
+
|
44
|
+
def self.inherited(klass)
|
45
|
+
# The version must be set to construct the request envelopes,
|
46
|
+
# the URI wil be set later using the correct Adyen.environment.
|
47
|
+
klass.endpoint :version => 1, :uri => 'bogus'
|
48
|
+
end
|
49
|
+
|
50
|
+
# Setup basic auth headers in the HTTP client
|
51
|
+
def on_after_create_http_client(http_client)
|
52
|
+
debug { |logger| logger.puts "Authorization: #{Adyen::SOAP.username}:#{Adyen::SOAP.password}..." }
|
53
|
+
# http_client.userpwd = "#{Adyen::SOAP.username}:#{Adyen::SOAP.password}"
|
54
|
+
http_client.set_auth Adyen::SOAP.username, Adyen::SOAP.password
|
55
|
+
end
|
56
|
+
|
57
|
+
# Setup XML namespaces for SOAP request body
|
58
|
+
def on_create_document(doc)
|
59
|
+
doc.alias 'payment', 'http://payment.services.adyen.com'
|
60
|
+
doc.alias 'recurring', 'http://recurring.services.adyen.com'
|
61
|
+
doc.alias 'common', 'http://common.services.adyen.com'
|
62
|
+
end
|
63
|
+
|
64
|
+
# Setup XML namespaces for SOAP response
|
65
|
+
def on_response_document(doc)
|
66
|
+
doc.add_namespace 'payment', 'http://payment.services.adyen.com'
|
67
|
+
doc.add_namespace 'recurring', 'http://recurring.services.adyen.com'
|
68
|
+
doc.add_namespace 'common', 'http://common.services.adyen.com'
|
69
|
+
end
|
70
|
+
|
71
|
+
# Set endpoint URI before dispatch, so that changes in environment
|
72
|
+
# are reflected correctly.
|
73
|
+
def on_before_dispatch
|
74
|
+
self.class.endpoint(:uri => self.class::ENDPOINT_URI % Adyen.environment.to_s, :version => 1)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# SOAP client to interact with the payment modification service of Adyen.
|
79
|
+
# At this moment, none of the calls are implemented.
|
80
|
+
class PaymentService < Base
|
81
|
+
|
82
|
+
ENDPOINT_URI = 'https://pal-%s.adyen.com/pal/servlet/soap/Payment'
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
# SOAP client to interact with the recurring payment service of Adyen.
|
87
|
+
# This client implements the submitRecurring call to submit payments
|
88
|
+
# for a recurring contract. Moreover, it implements the deactiveRecurring
|
89
|
+
# call to cancel a recurring contract.
|
90
|
+
#
|
91
|
+
# See the Adyen Recurring manual for more information about this SOAP service
|
92
|
+
class RecurringService < Base
|
93
|
+
|
94
|
+
ENDPOINT_URI = 'https://pal-%s.adyen.com/pal/servlet/soap/Recurring'
|
95
|
+
|
96
|
+
# Submits a recurring payment. Requires the following arguments as hash:
|
97
|
+
#
|
98
|
+
# * <tt>:currency</tt> The currency code (EUR, GBP, USD, etc)
|
99
|
+
# * <tt>:value</tt> The value of the payments in cents
|
100
|
+
# * <tt>:merchent_account</tt> The merchant account under which to place
|
101
|
+
# this payment.
|
102
|
+
# * <tt>:recurring_reference</tt> The psp_reference of the RECURRING_CONTRACT
|
103
|
+
# notification that was sent after the initial payment.
|
104
|
+
# * <tt>:reference</tt> The (merchant) reference for this payment.
|
105
|
+
# * <tt>:shopper_email</tt> The email address of the shopper.
|
106
|
+
# * <tt>:shopper_reference</tt> The refrence of the shopper. This should be
|
107
|
+
# the same as the reference that was used to create the recurring contract.
|
108
|
+
def submit(args = {})
|
109
|
+
invoke_args = Adyen::SOAP.default_arguments.merge(args)
|
110
|
+
response = invoke('recurring:submitRecurring') do |message|
|
111
|
+
message.add('recurring:recurringRequest') do |req|
|
112
|
+
req.add('recurring:amount') do |amount|
|
113
|
+
amount.add('common:currency', invoke_args[:currency])
|
114
|
+
amount.add('common:value', invoke_args[:value])
|
115
|
+
end
|
116
|
+
req.add('recurring:merchantAccount', invoke_args[:merchant_account])
|
117
|
+
req.add('recurring:recurringReference', invoke_args[:recurring_reference])
|
118
|
+
req.add('recurring:reference', invoke_args[:reference])
|
119
|
+
req.add('recurring:shopperEmail', invoke_args[:shopper_email])
|
120
|
+
req.add('recurring:shopperReference', invoke_args[:shopper_reference])
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# Deactivates a recurring payment contract. Requires the following arguments:
|
126
|
+
#
|
127
|
+
# * <tt>:merchent_account</tt> The merchant account under which to place
|
128
|
+
# this payment.
|
129
|
+
# * <tt>:recurring_reference</tt> The psp_reference of the RECURRING_CONTRACT
|
130
|
+
# notification that was sent after the initial payment.
|
131
|
+
# * <tt>:reference</tt> The (merchant) reference for this deactivation.
|
132
|
+
# * <tt>:shopper_reference</tt> The refrence of the shopper. This should be
|
133
|
+
# the same as the reference that was used to create the recurring contract.
|
134
|
+
def deactivate(args = {})
|
135
|
+
invoke_args = Adyen::SOAP.default_arguments.merge(args)
|
136
|
+
response = invoke('recurring:deactivateRecurring') do |message|
|
137
|
+
message.add('recurring:recurringRequest') do |req|
|
138
|
+
req.add('recurring:merchantAccount', invoke_args[:merchant_account])
|
139
|
+
req.add('recurring:recurringReference', invoke_args[:recurring_reference])
|
140
|
+
req.add('recurring:reference', invoke_args[:reference])
|
141
|
+
req.add('recurring:shopperReference', invoke_args[:shopper_reference])
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
data/spec/adyen_spec.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/spec_helper.rb"
|
2
|
+
|
3
|
+
describe Adyen do
|
4
|
+
describe Adyen::Encoding do
|
5
|
+
it "should a hmac_base64 correcly" do
|
6
|
+
encoded_str = Adyen::Encoding.hmac_base64('bla', 'bla')
|
7
|
+
encoded_str.should_not be_blank
|
8
|
+
encoded_str.size.should == 28
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should gzip_base64 correcly" do
|
12
|
+
encoded_str = Adyen::Encoding.gzip_base64('bla')
|
13
|
+
encoded_str.should_not be_blank
|
14
|
+
encoded_str.size.should == 32
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe Adyen::Formatter::DateTime do
|
19
|
+
it "should accept dates" do
|
20
|
+
Adyen::Formatter::DateTime.fmt_date(Date.today).should match(/^\d{4}-\d{2}-\d{2}$/)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should accept times" do
|
24
|
+
Adyen::Formatter::DateTime.fmt_time(Time.now).should match(/^\d{4}-\d{2}-\d{2}T\d{2}\:\d{2}\:\d{2}Z$/)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should accept valid time strings" do
|
28
|
+
Adyen::Formatter::DateTime.fmt_time('2009-01-01T11:11:11Z').should match(/^\d{4}-\d{2}-\d{2}T\d{2}\:\d{2}\:\d{2}Z$/)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should accept valid time strings" do
|
32
|
+
Adyen::Formatter::DateTime.fmt_date('2009-01-01').should match(/^\d{4}-\d{2}-\d{2}$/)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should raise on an invalid time string" do
|
36
|
+
lambda { Adyen::Formatter::DateTime.fmt_time('2009-01-01 11:11:11') }.should raise_error
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should raise on an invalid date string" do
|
40
|
+
lambda { Adyen::Formatter::DateTime.fmt_date('2009-1-1') }.should raise_error
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe Adyen::Formatter::Price do
|
45
|
+
it "should return a Fixnum with digits only when converting to cents" do
|
46
|
+
Adyen::Formatter::Price.in_cents(33.76).should be_kind_of(Fixnum)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should return a BigDecimal when converting from cents" do
|
50
|
+
Adyen::Formatter::Price.from_cents(1234).should be_kind_of(BigDecimal)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/spec/form_spec.rb
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/spec_helper.rb"
|
2
|
+
|
3
|
+
describe Adyen::Form do
|
4
|
+
|
5
|
+
describe 'Action URLs' do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
# Use autodetection for the environment unless otherwise specified
|
9
|
+
Adyen.environment = nil
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should generate correct the testing url" do
|
13
|
+
Adyen::Form.url.should eql('https://test.adyen.com/hpp/select.shtml')
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should generate a live url if the environemtn is set top live" do
|
17
|
+
Adyen.environment = :live
|
18
|
+
Adyen::Form.url.should eql('https://live.adyen.com/hpp/select.shtml')
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should generate correct live url in a production environment" do
|
22
|
+
Adyen.stub!(:autodetect_environment).and_return('live')
|
23
|
+
Adyen::Form.url.should eql('https://live.adyen.com/hpp/select.shtml')
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should generate correct live url if explicitely asked for" do
|
27
|
+
Adyen::Form.url(:live).should eql('https://live.adyen.com/hpp/select.shtml')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe 'redirect signature check' do
|
32
|
+
before(:each) do
|
33
|
+
# Example taken from integration manual
|
34
|
+
|
35
|
+
# Shared secret between you and Adyen, only valid for this skinCode!
|
36
|
+
@shared_secret = 'Kah942*$7sdp0)'
|
37
|
+
|
38
|
+
# Example get params sent back with redirect
|
39
|
+
@params = { :authResult => 'AUTHORISED', :pspReference => '1211992213193029',
|
40
|
+
:merchantReference => 'Internet Order 12345', :skinCode => '4aD37dJA',
|
41
|
+
:merchantSig => 'ytt3QxWoEhAskUzUne0P5VA9lPw='}
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should calculate the signature string correctly" do
|
45
|
+
Adyen::Form.redirect_signature_string(@params).should eql('AUTHORISED1211992213193029Internet Order 123454aD37dJA')
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should calculate the signature correctly" do
|
49
|
+
Adyen::Form.redirect_signature(@params, @shared_secret).should eql(@params[:merchantSig])
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should check the signature correctly" do
|
53
|
+
Adyen::Form.redirect_signature_check(@params, @shared_secret).should be_true
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should detect a tampered field" do
|
57
|
+
Adyen::Form.redirect_signature_check(@params.merge(:pspReference => 'tampered'), @shared_secret).should be_false
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should detect a tampered signature" do
|
61
|
+
Adyen::Form.redirect_signature_check(@params.merge(:merchantSig => 'tampered'), @shared_secret).should be_false
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
describe 'hidden fields generation' do
|
67
|
+
|
68
|
+
include ActionView::Helpers::TagHelper
|
69
|
+
|
70
|
+
before(:each) do
|
71
|
+
@attributes = { :currency_code => 'GBP', :payment_amount => 10000, :ship_before_date => Date.today,
|
72
|
+
:merchant_reference => 'Internet Order 12345', :skin_code => '4aD37dJA',
|
73
|
+
:merchant_account => 'TestMerchant', :session_validity => 1.hour.from_now }
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should generate a valid payment form" do
|
77
|
+
content_tag(:form, Adyen::Form.hidden_fields(@attributes.merge(:shared_secret => 'secret')),
|
78
|
+
:action => Adyen::Form.url, :method => :post).should have_adyen_payment_form
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe 'signature calculation' do
|
83
|
+
|
84
|
+
# This example is taken from the Adyen integration manual
|
85
|
+
|
86
|
+
before(:each) do
|
87
|
+
@attributes = { :currency_code => 'GBP', :payment_amount => 10000,
|
88
|
+
:ship_before_date => '2007-10-20', :merchant_reference => 'Internet Order 12345',
|
89
|
+
:skin_code => '4aD37dJA', :merchant_account => 'TestMerchant',
|
90
|
+
:session_validity => '2007-10-11T11:00:00Z' }
|
91
|
+
|
92
|
+
Adyen::Form.do_attribute_transformations!(@attributes)
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should construct the signature string correctly" do
|
96
|
+
signature_string = Adyen::Form.calculate_signature_string(@attributes)
|
97
|
+
signature_string.should eql("10000GBP2007-10-20Internet Order 123454aD37dJATestMerchant2007-10-11T11:00:00Z")
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should calculate the signature correctly" do
|
101
|
+
signature = Adyen::Form.calculate_signature(@attributes.merge(:shared_secret => 'Kah942*$7sdp0)'))
|
102
|
+
signature.should eql('x58ZcRVL1H6y+XSeBGrySJ9ACVo=')
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should calculate the signature correctly for a recurring payment" do
|
106
|
+
# Add the required recurrent payment attributes
|
107
|
+
@attributes.merge!(:recurring_contract => 'DEFAULT', :shopper_reference => 'grasshopper52', :shopper_email => 'gras.shopper@somewhere.org')
|
108
|
+
|
109
|
+
signature_string = Adyen::Form.calculate_signature_string(@attributes)
|
110
|
+
signature_string.should eql("10000GBP2007-10-20Internet Order 123454aD37dJATestMerchant2007-10-11T11:00:00Zgras.shopper@somewhere.orggrasshopper52DEFAULT")
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should calculate the signature correctly for a recurring payment" do
|
114
|
+
# Add the required recurrent payment attributes
|
115
|
+
@attributes.merge!(:recurring_contract => 'DEFAULT', :shopper_reference => 'grasshopper52', :shopper_email => 'gras.shopper@somewhere.org')
|
116
|
+
|
117
|
+
signature = Adyen::Form.calculate_signature(@attributes.merge(:shared_secret => 'Kah942*$7sdp0)'))
|
118
|
+
signature.should eql('F2BQEYbE+EUhiRGuPtcD16Gm7JY=')
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/spec_helper.rb"
|
2
|
+
|
3
|
+
describe Adyen::Notification do
|
4
|
+
|
5
|
+
before(:all) do
|
6
|
+
ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
|
7
|
+
|
8
|
+
ActiveRecord::Migration.verbose = false
|
9
|
+
Adyen::Notification::Migration.up
|
10
|
+
end
|
11
|
+
|
12
|
+
after(:all) do
|
13
|
+
Adyen::Notification::Migration.down
|
14
|
+
end
|
15
|
+
|
16
|
+
describe Adyen::Notification::HttpPost do
|
17
|
+
|
18
|
+
describe 'receiving payment authorization notification' do
|
19
|
+
|
20
|
+
before(:each) do
|
21
|
+
@request = mock('request')
|
22
|
+
@request.stub!(:params).and_return({
|
23
|
+
"merchantAccountCode"=>"FloorPlannerNL", "eventCode"=>"AUTHORISATION",
|
24
|
+
"paymentMethod"=>"mc", "eventDate"=>"2009-08-10T09:00:08.04Z",
|
25
|
+
"operations"=>"CANCEL,CAPTURE,REFUND", "merchantReference"=>"4",
|
26
|
+
"action"=>"process_adyen", "live"=>"false", "controller"=>"payment_notifications",
|
27
|
+
"value"=>"2500", "success"=>"false", "reason"=>"10676:1111:12/2012",
|
28
|
+
"originalReference"=>"", "pspReference"=>"8712498948081194", "currency"=>"USD"})
|
29
|
+
|
30
|
+
@notification = Adyen::Notification::HttpPost.log(@request)
|
31
|
+
end
|
32
|
+
|
33
|
+
after(:each) { @notification.destroy }
|
34
|
+
|
35
|
+
it "should have saved the notification record" do
|
36
|
+
@notification.should_not be_new_record
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should be an authorization" do
|
40
|
+
@notification.should be_authorisation
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should convert the amount to a bigdecimal" do
|
44
|
+
@notification.value.should eql(BigDecimal.new('25.00'))
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should convert live to a boolean" do
|
48
|
+
@notification.should_not be_live
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should convert success to a boolean" do
|
52
|
+
@notification.should_not be_success
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should not be a successfull authorization" do
|
56
|
+
@notification.should_not be_successful_authorization
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should convert the eventDate" do
|
60
|
+
@notification.event_date.should be_kind_of(Time)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should convert the empty original reference to NULL" do
|
64
|
+
@notification.original_reference.should be_nil
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context 'duplicate detection' do
|
69
|
+
before(:each) do
|
70
|
+
|
71
|
+
@fields = { "merchantAccountCode"=>"FloorPlannerNL", "eventCode"=>"AUTHORISATION",
|
72
|
+
"paymentMethod"=>"mc", "eventDate"=>"2009-08-10T09:00:08.04Z",
|
73
|
+
"operations"=>"CANCEL,CAPTURE,REFUND", "merchantReference"=>"4",
|
74
|
+
"action"=>"process_adyen", "live"=>"false", "controller"=>"payment_notifications",
|
75
|
+
"value"=>"2500", "success"=>"false", "reason"=>"10676:1111:12/2012",
|
76
|
+
"originalReference"=>"", "pspReference"=>"8712498948081194", "currency"=>"USD"}
|
77
|
+
|
78
|
+
@request = mock('request')
|
79
|
+
@request.stub!(:params).and_return(@fields)
|
80
|
+
@notification = Adyen::Notification::HttpPost.log(@request)
|
81
|
+
end
|
82
|
+
|
83
|
+
after(:each) { @notification.destroy }
|
84
|
+
|
85
|
+
it "should raise an error on a duplicate notification" do
|
86
|
+
lambda { Adyen::Notification::HttpPost.log(@request) }.should raise_error(ActiveRecord::RecordInvalid)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should not raise an error on a when success is set to true" do
|
90
|
+
second_request = mock('request')
|
91
|
+
second_request.stub!(:params).and_return(@fields.merge('success' => 'true'))
|
92
|
+
lambda { Adyen::Notification::HttpPost.log(second_request) }.should_not raise_error
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
data/spec/soap_spec.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/spec_helper.rb"
|
2
|
+
|
3
|
+
describe Adyen::SOAP::RecurringService do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
|
7
|
+
response_xml = <<-EOS
|
8
|
+
<?xml version="1.0" encoding="UTF-8" ?>
|
9
|
+
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
|
10
|
+
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema">
|
11
|
+
|
12
|
+
<soap:Body>
|
13
|
+
</soap:Body>
|
14
|
+
</soap:Envelope>
|
15
|
+
EOS
|
16
|
+
|
17
|
+
@response = mock('Handsoap::HTTP::Response')
|
18
|
+
@part = mock('Handsoap::HTTP::Part')
|
19
|
+
@part.stub!(:body).and_return(response_xml)
|
20
|
+
|
21
|
+
@response.stub!(:status).and_return(200)
|
22
|
+
@response.stub!(:primary_part).and_return(@part)
|
23
|
+
Adyen::SOAP::RecurringService.instance.stub!(:send_http_request).and_return(@response)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should send an HTTP request" do
|
27
|
+
Adyen::SOAP::RecurringService.instance.should_receive(:send_http_request).and_return(@response)
|
28
|
+
Adyen::SOAP::RecurringService.submit()
|
29
|
+
end
|
30
|
+
end
|