breadmachine 0.0.0 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. data/README.rdoc +48 -4
  2. data/lib/breadmachine/dto/card.rb +23 -9
  3. data/lib/breadmachine/dto/customer_info.rb +19 -5
  4. data/lib/breadmachine/dto/order_info.rb +18 -5
  5. data/lib/breadmachine/extensions/string.rb +11 -0
  6. data/lib/breadmachine/extensions.rb +2 -1
  7. data/lib/breadmachine/secure_trading/auth_request.rb +4 -2
  8. data/lib/breadmachine/secure_trading/auth_reversal_request.rb +3 -5
  9. data/lib/breadmachine/secure_trading/auth_reversal_response.rb +6 -1
  10. data/lib/breadmachine/secure_trading/card_xml.rb +13 -9
  11. data/lib/breadmachine/secure_trading/payment_methods.rb +18 -6
  12. data/lib/breadmachine/secure_trading/st_3d_auth_request.rb +32 -10
  13. data/lib/breadmachine/secure_trading/st_3d_auth_response.rb +20 -11
  14. data/lib/breadmachine/secure_trading/st_3d_card_query_request.rb +28 -9
  15. data/lib/breadmachine/secure_trading/st_3d_card_query_response.rb +122 -23
  16. data/lib/breadmachine/secure_trading/xpay.rb +121 -10
  17. data/lib/breadmachine/secure_trading/xpay_response.rb +29 -0
  18. data/lib/breadmachine/secure_trading/xpay_socket.rb +5 -1
  19. data/lib/breadmachine/secure_trading.rb +4 -2
  20. data/lib/breadmachine.rb +7 -2
  21. data/spec/secure_trading/auth_request_spec.rb +12 -7
  22. data/spec/secure_trading/card_xml_spec.rb +43 -17
  23. data/spec/secure_trading/order_info_xml_spec.rb +2 -2
  24. data/spec/secure_trading/st_3d_auth_request_spec.rb +12 -7
  25. data/spec/secure_trading/st_3d_card_query_request_spec.rb +19 -8
  26. data/spec/secure_trading/st_3d_card_query_response_spec.rb +87 -30
  27. data/spec/secure_trading/st_auth_reversal_request_spec.rb +42 -0
  28. data/spec/secure_trading/xpay_response_spec.rb +26 -0
  29. data/spec/secure_trading/xpay_socket_spec.rb +15 -2
  30. data/spec/secure_trading/xpay_spec.rb +19 -2
  31. metadata +35 -3
  32. data/spec/secure_trading/st_auth_request_spec.rb +0 -0
@@ -2,24 +2,135 @@ module BreadMachine
2
2
  module SecureTrading
3
3
 
4
4
  class XPay
5
+
6
+ # A class method which wraps the individual request block with the
7
+ # necessary xml for the XPay gateway. Once the request is wrapped, this
8
+ # method writes it to the Xpay client and returns the response.
9
+ #
5
10
  def self.exchange(request)
6
-
11
+ xpay = self.new
12
+ xpay.exchange(request)
13
+ end
14
+
15
+ def exchange(request, retries = 3)
16
+ request_xml = generate_xml(request)
17
+ begin
18
+ response_xml = exchange_with_xpay_client(request_xml)
19
+ response = request.response(response_xml)
20
+ handle_errors(response)
21
+ return response
22
+ rescue BreadMachine::GatewayConnectionError
23
+ retry unless (retries -= 1) == 0
24
+ raise
25
+ end
26
+ end
27
+
28
+ protected
29
+
30
+ def generate_xml(request)
7
31
  xml = Builder::XmlMarkup.new(:indent => 2)
32
+ xml.instruct!
8
33
  xml.RequestBlock('Version' => '3.51') do |request_block|
9
34
  request_block << request.to_xml
10
35
  xml.Certificate BreadMachine::SecureTrading::configuration.site_reference
11
36
  end
12
-
13
- response_xml = nil
14
-
37
+ return xml.to_s
38
+ end
39
+
40
+ def exchange_with_xpay_client(request_xml)
15
41
  XPaySocket.open("localhost", 5000) do |socket|
16
- socket.write xml.xml
17
- response_xml = socket.read
42
+ socket.write request_xml
43
+ socket.read
44
+ end
45
+ end
46
+
47
+ # Error codes from Xpay API documentation
48
+ #
49
+ # 100 Timeout reading from socket:
50
+ # ST Xpay did not receive the full XML in the given time from your
51
+ # application.
52
+ #
53
+ # 101 Error reading from socket:
54
+ # ST Xpay did not receive a correct connection request from your
55
+ # application.
56
+ #
57
+ # 1000 Failed to connect to a payment gateway:
58
+ # The ST Xpay client was unable to find a payment gateway.
59
+ #
60
+ # 1100 Failed to receive from payment gateway:
61
+ # ST Xpay did not receive any response from the payment gateway.
62
+ #
63
+ # 2100 Missing SiteReference or Certificate tag:
64
+ # The XML ST Xpay received was missing the site reference and/or
65
+ # your secure ST Xpay certificate.
66
+ #
67
+ # 2500 [Various messages - One of the fields contains an invalid value]:
68
+ # The information returned contains the field name that was omitted
69
+ # from the request or contained incorrect information.
70
+ #
71
+ # 3000 Gateway error:
72
+ # A SecureTrading payment gateway failed to receive a full ST Xpay
73
+ # request.
74
+ #
75
+ # 3010 Transaction Not Received Successfully:
76
+ # A SecureTrading payment gateway obtained the request but failed to
77
+ # decrypt it.
78
+ #
79
+ # 3100 Error with transaction details:
80
+ # The data retrieved was incorrectly defined.
81
+ #
82
+ # 3100 Error in XML: Unknown Transaction Type:
83
+ # The Request Type attribute was incorrect.
84
+ #
85
+ # 3100 Error Parsing XML (invalid site reference for this certificate):
86
+ # The certificate included in the XML request is invalid for the
87
+ # SecureTrading sitereference included in the XML.
88
+ #
89
+ # 3100 Gateway Connection Error:
90
+ # The data obtained by ST Xpay was incorrect.
91
+ #
92
+ # 3100 Error parsing XML: [+reason]
93
+ # The gateway obtained invalid XML.
94
+ #
95
+ # 3100 Invalid Merchant Configuration:
96
+ # Merchant data on the gateway is inconsistent with merchant
97
+ # information in the XML (For example. invalid currency,
98
+ # payment type, etc).
99
+ #
100
+ # 3330 Transaction storage failure. Please try again later:
101
+ # Gateway failed to store the transaction details before
102
+ # authorisation.
103
+ #
104
+ # 3350 Transaction acceptance failure. Please try again later:
105
+ # Gateway failed to update the transaction details after performing
106
+ # the authorisation.
107
+ #
108
+ # 5000 Transport Error:
109
+ # Failed to connect to acquiring bank or the acquiring bank did not
110
+ # respond.
111
+ #
112
+ # 5100 Missing TransactionReference:
113
+ # The transaction cannot be found in the database.
114
+ #
115
+ # 10500 Various Message:
116
+ # Xpay4 was unable to process your request.
117
+ #
118
+ def handle_errors(response)
119
+ if response.error?
120
+ message = response.message
121
+ case message.match(/\((\d+)\)/)[1].to_i
122
+ when 100, 101, 1000, 1100, 3000, 3010, 3330, 3350, 5000:
123
+ raise BreadMachine::GatewayConnectionError.new(message)
124
+ when 2100, 3100:
125
+ raise BreadMachine::MerchantConfigurationError.new(message)
126
+ when 2500, 5100, 10500:
127
+ raise BreadMachine::MerchantRequestError.new(message)
128
+ end
18
129
  end
19
-
20
- request.response(response_xml)
21
130
  end
131
+
22
132
  end
23
-
133
+
24
134
  end
25
- end
135
+ end
136
+
@@ -0,0 +1,29 @@
1
+ module BreadMachine
2
+ module SecureTrading
3
+
4
+ class XpayResponse
5
+
6
+ def initialize(xml)
7
+ @xml = Nokogiri::XML.parse(xml)
8
+ end
9
+
10
+ # Checks whether there has been an error somewhere in the chain of servers
11
+ # which are processing your request (for example, if Visa's server cacked,
12
+ # or XPay had an internal error, this would come back as true).
13
+ #
14
+ def error?
15
+ result == '0'
16
+ end
17
+
18
+ def result
19
+ @xml.xpath('//OperationResponse/Result').text
20
+ end
21
+
22
+ def message
23
+ @xml.xpath('//OperationResponse/Message').text
24
+ end
25
+
26
+ end
27
+
28
+ end
29
+ end
@@ -10,7 +10,11 @@ module BreadMachine
10
10
  class << self
11
11
 
12
12
  def open(*args, &block)
13
- TCPSocket.open(*args, &block)
13
+ begin
14
+ return TCPSocket.open(*args, &block)
15
+ rescue Errno::ECONNREFUSED
16
+ raise BreadMachine::GatewayConnectionError
17
+ end
14
18
  end
15
19
 
16
20
  end
@@ -7,6 +7,7 @@ module BreadMachine
7
7
 
8
8
  autoload :XPay, 'breadmachine/secure_trading/xpay'
9
9
  autoload :XPaySocket, 'breadmachine/secure_trading/xpay_socket'
10
+ autoload :XpayResponse, 'breadmachine/secure_trading/xpay_response'
10
11
 
11
12
  autoload :CardXml, 'breadmachine/secure_trading/card_xml'
12
13
 
@@ -21,9 +22,10 @@ module BreadMachine
21
22
  autoload :St3dAuthRequest, 'breadmachine/secure_trading/st_3d_auth_request'
22
23
  autoload :St3dAuthResponse, 'breadmachine/secure_trading/st_3d_auth_response'
23
24
 
24
- autoload :AuthReversalRequest, 'breadmachine/secure_trading/auth_reversal_request'
25
25
  autoload :AuthRequest, 'breadmachine/secure_trading/auth_request'
26
- # autoload :AuthResponse, 'breadmachine/secure_trading/st_3d_auth_response'
26
+
27
+ autoload :AuthReversalRequest, 'breadmachine/secure_trading/auth_reversal_request'
28
+ autoload :AuthReversalResponse, 'breadmachine/secure_trading/auth_reversal_response'
27
29
 
28
30
  extend BreadMachine::SecureTrading::Config::ClassMethods
29
31
 
data/lib/breadmachine.rb CHANGED
@@ -1,9 +1,9 @@
1
1
  require 'money'
2
2
  require 'nokogiri'
3
3
  require 'builder'
4
+ require 'activesupport'
4
5
 
5
6
  require 'breadmachine/extensions'
6
-
7
7
  require 'breadmachine/secure_trading'
8
8
 
9
9
  module BreadMachine
@@ -24,4 +24,9 @@ class Builder::XmlBase
24
24
  def <<(text)
25
25
  _text(text.indent(@level * @indent))
26
26
  end
27
- end
27
+ end
28
+
29
+ class BreadMachine::Exception < Exception; end;
30
+ class BreadMachine::GatewayConnectionError < BreadMachine::Exception; end;
31
+ class BreadMachine::MerchantConfigurationError < BreadMachine::Exception; end;
32
+ class BreadMachine::MerchantRequestError < BreadMachine::Exception; end;
@@ -2,16 +2,25 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
2
 
3
3
  describe BreadMachine::SecureTrading::AuthRequest do
4
4
 
5
- it "should validate input data when initialized"
6
-
5
+ it "should ensure amount is Money of correct currency" do
6
+ BreadMachine::SecureTrading.configuration.currency = 'USD'
7
+ amount = Money.new(200_00, 'GBP')
8
+
9
+ lambda {
10
+ @request = described_class.new(amount, @card, @customer_info, @order_info, @settlement_day)
11
+ }.should raise_error ArgumentError, "Currency mismatch"
12
+ end
13
+
7
14
  describe "XML generation" do
8
15
 
9
16
  before(:each) do
17
+ BreadMachine::SecureTrading.configuration.currency = 'GBP'
10
18
  @amount = Money.sterling(12_99)
11
19
  @card = BreadMachine::Card.make
12
20
  @customer_info = BreadMachine::CustomerInfo.make(:auth)
13
21
  @order_info = BreadMachine::OrderInfo.make
14
- @request = described_class.new(@amount, @card, @customer_info, @order_info)
22
+ @settlement_day = 1
23
+ @request = described_class.new(@amount, @card, @customer_info, @order_info, @settlement_day)
15
24
  end
16
25
 
17
26
  it "should set correct request type" do
@@ -35,10 +44,6 @@ describe BreadMachine::SecureTrading::AuthRequest do
35
44
  end
36
45
  end
37
46
 
38
- it "should ensure amount is Money of correct currency" do
39
- pending "Check that currency of amount matches currency specified in config"
40
- end
41
-
42
47
  it "should append CustomerInfo element" do
43
48
  request_xml.should have_tag("Request/CustomerInfo")
44
49
  end
@@ -1,54 +1,80 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
2
 
3
- class TestCard
4
- attr_accessor :issuer, :number, :expiry_date, :start_date, :issue, :security_code, :parent_transaction_reference
5
- include BreadMachine::SecureTrading::CardXml
6
- end
7
-
8
3
  describe BreadMachine::SecureTrading::CardXml do
9
4
 
10
- describe "xml representation generation" do
5
+ subject do
6
+ described_class.new(@card)
7
+ end
8
+
9
+ def xml
10
+ Nokogiri::XML::Document.parse(subject.to_xml)
11
+ end
12
+
13
+ describe "xml representation from card" do
11
14
 
12
15
  before(:each) do
13
- @card = TestCard.new
16
+ @card = BreadMachine::Card.new
14
17
  end
15
-
18
+
16
19
  it "should have CreditCard root element" do
17
- xml(@card).should have_tag('/CreditCard')
20
+ xml.should have_tag('/CreditCard')
18
21
  end
19
22
 
20
23
  it "should have correct Type element" do
21
24
  @card.issuer = 'Maestro'
22
- xml(@card).should have_tag("CreditCard/Type", 'Maestro')
25
+ xml.should have_tag("CreditCard/Type", 'Maestro')
23
26
  end
24
27
 
25
28
  it "should have correct Number element" do
26
29
  @card.number = 6759050000000005
27
- xml(@card).should have_tag("CreditCard/Number", '6759050000000005')
30
+ xml.should have_tag("CreditCard/Number", '6759050000000005')
28
31
  end
29
32
 
30
33
  it "should have correct ExpiryDate element" do
31
34
  @card.expiry_date = '07/11'
32
- xml(@card).should have_tag("CreditCard/ExpiryDate", '07/11')
35
+ xml.should have_tag("CreditCard/ExpiryDate", '07/11')
33
36
  end
34
37
 
35
38
  it "should have correct StartDate element" do
36
39
  @card.start_date = '03/08'
37
- xml(@card).should have_tag("CreditCard/StartDate", '03/08')
40
+ xml.should have_tag("CreditCard/StartDate", '03/08')
38
41
  end
39
42
 
40
43
  it "should have correct Issue element" do
41
44
  @card.issue = 2
42
- xml(@card).should have_tag("CreditCard/Issue", '2')
45
+ xml.should have_tag("CreditCard/Issue", '2')
43
46
  end
44
47
 
45
48
  it "should have correct SecurityCode element" do
46
49
  @card.security_code = 789
47
- xml(@card).should have_tag("CreditCard/SecurityCode", '789')
50
+ xml.should have_tag("CreditCard/SecurityCode", '789')
51
+ end
52
+
53
+ it "should have correct ParentTransactionReference element" do
54
+ @card.transaction_reference = '13-2-9875373'
55
+ xml.should have_tag("CreditCard/ParentTransactionReference", '13-2-9875373')
56
+ end
57
+
58
+ end
59
+
60
+ describe "xml representation from transaction" do
61
+
62
+ before(:each) do
63
+ @card = BreadMachine::Card.new
64
+ end
65
+
66
+ it "should have CreditCard root element" do
67
+ xml.should have_tag('/CreditCard')
68
+ end
69
+
70
+ it "should have correct TransactionVerifier element" do
71
+ @card.transaction_verifier = 'A_TRANSACTION_VERIFIER'
72
+ xml.should have_tag("CreditCard/TransactionVerifier", 'A_TRANSACTION_VERIFIER')
48
73
  end
49
74
 
50
- def xml(card)
51
- Nokogiri::XML::Document.parse(card.to_xml)
75
+ it "should have correct ParentTransactionReference element" do
76
+ @card.transaction_reference = 'A_TRANSACTION_REFERENCE'
77
+ xml.should have_tag("CreditCard/ParentTransactionReference", 'A_TRANSACTION_REFERENCE')
52
78
  end
53
79
 
54
80
  end
@@ -18,12 +18,12 @@ describe BreadMachine::SecureTrading::OrderInfoXml do
18
18
  generated_xml.should have_tag('/Order')
19
19
  end
20
20
 
21
- it "should have correct Phone" do
21
+ it "should have correct OrderReference" do
22
22
  @order_info.order_reference = 'Order 12345'
23
23
  generated_xml.should have_tag('Order/OrderReference', 'Order 12345')
24
24
  end
25
25
 
26
- it "should have correct Email" do
26
+ it "should have correct OrderInformation" do
27
27
  @order_info.order_information = '1 Bag of Assorted Widgets'
28
28
  generated_xml.should have_tag('Order/OrderInformation', '1 Bag of Assorted Widgets')
29
29
  end
@@ -2,17 +2,26 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
2
 
3
3
  describe BreadMachine::SecureTrading::St3dAuthRequest do
4
4
 
5
- it "should validate input data when initialized"
6
-
5
+ it "should ensure amount is Money of correct currency" do
6
+ BreadMachine::SecureTrading.configuration.currency = 'USD'
7
+ amount = Money.new(200_00, 'GBP')
8
+
9
+ lambda {
10
+ @request = described_class.new(amount, @card, @customer_info, @order_info, @three_d, @settlement_day)
11
+ }.should raise_error ArgumentError, "Currency mismatch"
12
+ end
13
+
7
14
  describe "XML generation" do
8
15
 
9
16
  before(:each) do
17
+ BreadMachine::SecureTrading.configuration.currency = 'GBP'
10
18
  @amount = Money.sterling(12_99)
11
19
  @card = BreadMachine::Card.make
12
20
  @customer_info = BreadMachine::CustomerInfo.make(:auth)
13
21
  @order_info = BreadMachine::OrderInfo.make
14
22
  @three_d = BreadMachine::ThreeDSecureCredentials.make
15
- @request = described_class.new(@amount, @card, @customer_info, @order_info, @three_d)
23
+ @settlement_day = 1
24
+ @request = described_class.new(@amount, @card, @customer_info, @order_info, @three_d, @settlement_day)
16
25
  end
17
26
 
18
27
  it "should set correct request type" do
@@ -36,10 +45,6 @@ describe BreadMachine::SecureTrading::St3dAuthRequest do
36
45
  end
37
46
  end
38
47
 
39
- it "should ensure amount is Money of correct currency" do
40
- pending "Check that currency of amount matches currency specified in config"
41
- end
42
-
43
48
  it "should append CustomerInfo element" do
44
49
  request_xml.should have_tag("Request/CustomerInfo")
45
50
  end
@@ -2,11 +2,19 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
2
 
3
3
  describe BreadMachine::SecureTrading::St3dCardQueryRequest do
4
4
 
5
- it "should validate input data when initialized"
5
+ it "should ensure amount is Money of correct currency" do
6
+ BreadMachine::SecureTrading.configuration.currency = 'USD'
7
+ amount = Money.new(200_00, 'GBP')
8
+
9
+ lambda {
10
+ @request = described_class.new(amount, @card, @customer_info, @order_info)
11
+ }.should raise_error ArgumentError, "Currency mismatch"
12
+ end
6
13
 
7
14
  context "XML generation" do
8
15
 
9
16
  before(:each) do
17
+ BreadMachine::SecureTrading.configuration.currency = 'GBP'
10
18
  @card = BreadMachine::Card.make
11
19
  @customer_info = BreadMachine::CustomerInfo.make(:card_query)
12
20
  @order_info = BreadMachine::OrderInfo.make
@@ -25,7 +33,7 @@ describe BreadMachine::SecureTrading::St3dCardQueryRequest do
25
33
  config.term_url = 'http://www.example.com'
26
34
  config.merchant_name = "Bob's Widgets Inc."
27
35
  end
28
- amount = Money.sterling(10_99)
36
+ amount = Money.us_dollar(10_99)
29
37
 
30
38
  @request = described_class.new(amount, @card, @customer_info, @order_info)
31
39
 
@@ -38,6 +46,15 @@ describe BreadMachine::SecureTrading::St3dCardQueryRequest do
38
46
  request_xml.should have_tag("Operation/MerchantName", "Bob's Widgets Inc.")
39
47
  end
40
48
 
49
+ it "should append to term_url if set in options" do
50
+ BreadMachine::SecureTrading.configuration.term_url = 'http://www.example.com'
51
+ options = {:term_url_append => '/some_value'}
52
+
53
+ @request = described_class.new(@amount, @card, @customer_info, @order_info, options)
54
+
55
+ request_xml.should have_tag("Operation/TermUrl", "http://www.example.com/some_value")
56
+ end
57
+
41
58
  it "should append CustomerInfo element" do
42
59
  request_xml.should have_tag("Request/CustomerInfo")
43
60
  end
@@ -45,13 +62,7 @@ describe BreadMachine::SecureTrading::St3dCardQueryRequest do
45
62
  it "should append PaymentMethod element" do
46
63
  request_xml.should have_tag("Request/PaymentMethod")
47
64
  end
48
-
49
- it "should ensure amount is Money of correct currency" do
50
- pending "Check that currency of amount matches currency specified in config"
51
- end
52
65
 
53
- it "should populate PaymentMethod element with correct data when querying from a previous ParentTransactionReference"
54
-
55
66
  it "should append Order element" do
56
67
  request_xml.should have_tag("Request/Order")
57
68
  end
@@ -2,52 +2,109 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
2
 
3
3
  describe BreadMachine::SecureTrading::St3dCardQueryResponse do
4
4
 
5
- it "should be successful when Success element is 1" do
6
- # TODO: this should probably be pushed up into a generic Response
7
- @response = described_class.new(successful_response)
8
- @response.should be_successful
5
+ describe "#successful?" do
6
+
7
+ it "should be successful when Result element is 1" do
8
+ response = described_class.new(successful_response(result = 1))
9
+ response.should be_successful
10
+ end
11
+
12
+ it "should be successful when Result element is 2" do
13
+ response = described_class.new(successful_response(result = 2))
14
+ response.should be_successful
15
+ end
16
+
17
+ it "should not be successful when Result element is 0" do
18
+ response = described_class.new(failed_response)
19
+ response.should_not be_successful
20
+ end
21
+
9
22
  end
10
23
 
11
- it "should not be successful when Success element is 0" do
12
- # TODO: this should probably be pushed up into a generic Response
13
- @response = described_class.new(failed_response)
14
- @response.should_not be_successful
24
+ describe "#error?" do
25
+
26
+ it "should be error when Result element is 0" do
27
+ response = described_class.new(failed_response)
28
+ response.should be_error
29
+ end
30
+
31
+ it "should not be error when Result element is 1" do
32
+ response = described_class.new(successful_response(result = 1))
33
+ response.should_not be_error
34
+ end
35
+
36
+ it "should not be error when Result element is 2" do
37
+ response = described_class.new(successful_response(result = 2))
38
+ response.should_not be_error
39
+ end
40
+
15
41
  end
16
42
 
17
- it "should select PaReq" do
18
- @response = described_class.new(successful_response)
19
- @response.pa_req.should == "EXAMPLE-PA-REQ"
20
- end
43
+ describe "accessors" do
21
44
 
22
- it "should select MD" do
23
- @response = described_class.new(successful_response)
24
- @response.md.should == "EXAMPLE-MD"
25
- end
45
+ it "should select PaReq" do
46
+ response = described_class.new(successful_response)
47
+ response.pa_req.should == "EXAMPLE-PA-REQ"
48
+ end
26
49
 
27
- it "should select AcsUrl" do
28
- @response = described_class.new(successful_response)
29
- @response.acs_url.should == "https://securetrading.net/secureweb/testacs0.cgi"
30
- end
50
+ it "should select MD" do
51
+ response = described_class.new(successful_response)
52
+ response.md.should == "EXAMPLE-MD"
53
+ end
54
+
55
+ it "should select AcsUrl" do
56
+ response = described_class.new(successful_response)
57
+ response.acs_url.should == "https://securetrading.net/secureweb/testacs0.cgi"
58
+ end
31
59
 
32
- it "should select TranscationReference" do
33
- @response = described_class.new(successful_response)
34
- @response.transaction_reference.should == "15-9-1266891"
60
+ it "should select TranscationReference" do
61
+ response = described_class.new(successful_response)
62
+ response.transaction_reference.should == "15-9-1266891"
63
+ end
64
+
65
+ it "should select Enrolled" do
66
+ response = described_class.new(successful_response)
67
+ response.enrolled.should == "Y"
68
+ end
69
+
35
70
  end
36
71
 
37
- def successful_response
38
- enrolled_response
72
+ describe "Auth type" do
73
+
74
+ it "should return s3 secure auth for auth type when card is enrolled" do
75
+ response = described_class.new(successful_response(result = 1, enrolled = 'Y'))
76
+ response.auth_type.should == BreadMachine::SecureTrading::St3dAuthRequest
77
+ end
78
+
79
+ it "should return s3 secure auth for auth type when card is not enrolled" do
80
+ response = described_class.new(successful_response(result = 1, enrolled = 'N'))
81
+ response.auth_type.should == BreadMachine::SecureTrading::St3dAuthRequest
82
+ end
83
+
84
+ it "should return standard auth for auth type when card provider is not part of scheme" do
85
+ response = described_class.new(successful_response(result = 2))
86
+ response.auth_type.should == BreadMachine::SecureTrading::AuthRequest
87
+ end
88
+
89
+ it "should return standard auth for auth type when response is error" do
90
+ response = described_class.new(successful_response(result = 0))
91
+ response.auth_type.should == BreadMachine::SecureTrading::AuthRequest
92
+ end
93
+
39
94
  end
95
+
96
+
40
97
 
41
- def enrolled_response
42
- <<-EOS
98
+ def successful_response(result = 1, enrolled = 'Y')
99
+ <<-XML
43
100
  <ResponseBlock Live="FALSE" Version="3.51">
44
101
  <Response Type="ST3DCARDQUERY">
45
102
  <OperationResponse>
46
103
  <TransactionReference>15-9-1266891</TransactionReference>
47
104
  <TransactionCompletedTimestamp>2009-09-24 14:50:41</TransactionCompletedTimestamp>
48
105
  <TransactionVerifier>AY4LBwreQ1qwbPpuH5PswO4eN7KD27qmNBLG03tCrhBSzLpRXKBXw+PwY7dcuzuGoQXAPVB7phZYZhcP8YcBy9LFXO8zRW02QaHhXXykY7+ekmsYdNGEYjeLE8wI2vUGpD9IrGySGgYQySq1zIFg1wtUg4LmyrlAlUyQUOvPof8c=</TransactionVerifier>
49
- <Result>1</Result>
50
- <Enrolled>Y</Enrolled>
106
+ <Result>#{result}</Result>
107
+ <Enrolled>#{enrolled}</Enrolled>
51
108
  <Html></Html>
52
109
  <MD>EXAMPLE-MD</MD>
53
110
  <PaReq>EXAMPLE-PA-REQ</PaReq>
@@ -60,7 +117,7 @@ describe BreadMachine::SecureTrading::St3dCardQueryResponse do
60
117
  </Order>
61
118
  </Response>
62
119
  </ResponseBlock>
63
- EOS
120
+ XML
64
121
  end
65
122
 
66
123
  def failed_response
@@ -0,0 +1,42 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe BreadMachine::SecureTrading::AuthReversalRequest do
4
+
5
+ before(:each) do
6
+ transaction = mock('transaction')
7
+ transaction.stub(:transaction_reference => 'A_TRANSACTION_REFERENCE')
8
+ transaction.stub(:transaction_verifier => 'A_TRANSACTION_VERIFIER')
9
+ @order_info = BreadMachine::OrderInfo.make
10
+ @request = described_class.new(transaction, @order_info)
11
+ end
12
+
13
+ describe "XML generation" do
14
+
15
+ def xml
16
+ Nokogiri::XML::Document.parse(@request.to_xml)
17
+ end
18
+
19
+ it "should set correct request type" do
20
+ xml.should have_tag("/Request[@Type='AUTHREVERSAL']")
21
+ end
22
+
23
+ it "should populate Operation element with correct data" do
24
+ BreadMachine::SecureTrading.configuration.site_reference = 'site12345'
25
+
26
+ xml.should have_tag("Request/Operation")
27
+ xml.should have_tag("Operation/SiteReference", "site12345")
28
+ end
29
+
30
+ it "should append CreditCard element" do
31
+ xml.should have_tag("Request/PaymentMethod/CreditCard")
32
+ end
33
+
34
+ it "should append Order element" do
35
+ xml.should have_tag("Request/Order")
36
+ end
37
+ end
38
+
39
+ it "should return correct response" do
40
+ @request.response('<xml>').should be_a(BreadMachine::SecureTrading::AuthReversalResponse)
41
+ end
42
+ end