breadmachine 0.0.0 → 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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