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