heartland_portico 3.2.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.document +5 -0
- data/.rspec +2 -0
- data/.ruby-version +1 -0
- data/Gemfile +33 -0
- data/Gemfile.lock +204 -0
- data/LICENSE.txt +20 -0
- data/Rakefile +66 -0
- data/VERSION +1 -0
- data/config/solano.yml +12 -0
- data/config/spec.yml +15 -0
- data/data/PosGateway.xsd +7186 -0
- data/lib/active_merchant/billing/gateways/heartland_portico.rb +165 -0
- data/lib/heartland_portico.rb +182 -0
- data/lib/heartland_portico/ach.rb +81 -0
- data/lib/wsdl.xml +43 -0
- data/spec/fixtures/check_sale_request_stub.xml +39 -0
- data/spec/fixtures/check_sale_response_success.xml +30 -0
- data/spec/fixtures/credit_account_verify_request_stub.xml +31 -0
- data/spec/fixtures/credit_account_verify_response_success.xml +29 -0
- data/spec/fixtures/credit_auth_request_stub.xml +27 -0
- data/spec/fixtures/credit_auth_response_approval.xml +29 -0
- data/spec/fixtures/credit_auth_response_decline.xml +29 -0
- data/spec/fixtures/response_authentication_error.xml +15 -0
- data/spec/heartland_portico/ach_spec.rb +108 -0
- data/spec/heartland_portico_spec.rb +108 -0
- data/spec/spec_helper.rb +25 -0
- data/test/comm_stub.rb +40 -0
- data/test/fixtures.yml +40 -0
- data/test/remote/gateways/certification_test.rb +172 -0
- data/test/remote/gateways/remote_heartland_portico_test.rb +126 -0
- data/test/test_helper.rb +259 -0
- data/test/unit/gateways/heartland_portico_test.rb +136 -0
- metadata +357 -0
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
require 'rspec'
|
4
|
+
require 'heartland_portico'
|
5
|
+
require 'heartland_portico/ach'
|
6
|
+
|
7
|
+
require 'pp'
|
8
|
+
|
9
|
+
# Requires supporting files with custom matchers and macros, etc,
|
10
|
+
# in ./support/ and its subdirectories.
|
11
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
12
|
+
|
13
|
+
module XmlFixtureHelpers
|
14
|
+
def xml_fixture(file)
|
15
|
+
File.read("spec/fixtures/#{file}.xml").tap { |xml|
|
16
|
+
xml.gsub!(/>\s+</, '><')
|
17
|
+
xml.gsub!(/<!--.*?-->/m, '')
|
18
|
+
xml.strip!
|
19
|
+
}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
RSpec.configure do |config|
|
24
|
+
config.include XmlFixtureHelpers
|
25
|
+
end
|
data/test/comm_stub.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
module CommStub
|
2
|
+
class Stub
|
3
|
+
def initialize(gateway, method_to_stub, action)
|
4
|
+
@gateway = gateway
|
5
|
+
@action = action
|
6
|
+
@complete = false
|
7
|
+
@method_to_stub = method_to_stub
|
8
|
+
end
|
9
|
+
|
10
|
+
def check_request(&block)
|
11
|
+
@check = block
|
12
|
+
self
|
13
|
+
end
|
14
|
+
|
15
|
+
def respond_with(*responses)
|
16
|
+
@complete = true
|
17
|
+
check = @check
|
18
|
+
(class << @gateway; self; end).send(:define_method, @method_to_stub) do |*args|
|
19
|
+
check.call(*args) if check
|
20
|
+
(responses.size == 1 ? responses.last : responses.shift)
|
21
|
+
end
|
22
|
+
@action.call
|
23
|
+
end
|
24
|
+
|
25
|
+
def complete?
|
26
|
+
@complete
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def stub_comms(gateway=@gateway, method_to_stub=:ssl_post, &action)
|
31
|
+
if @last_comm_stub
|
32
|
+
assert @last_comm_stub.complete?, "Tried to stub communications when there's a stub already in progress."
|
33
|
+
end
|
34
|
+
@last_comm_stub = Stub.new(gateway, method_to_stub, action)
|
35
|
+
end
|
36
|
+
|
37
|
+
def teardown
|
38
|
+
assert(@last_comm_stub.complete?) if @last_comm_stub
|
39
|
+
end
|
40
|
+
end
|
data/test/fixtures.yml
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# Override these with your own values in ~/.activemerchant/fixtures.yml
|
2
|
+
heartland_portico:
|
3
|
+
license_id: "12345"
|
4
|
+
site_id: "12345"
|
5
|
+
device_id: "1234567"
|
6
|
+
user_name: "123456789012"
|
7
|
+
password: "$Test1234"
|
8
|
+
#site_trace: ""
|
9
|
+
developer_i_d: "12345"
|
10
|
+
version_nbr: "1234"
|
11
|
+
#clerk_i_d: ""
|
12
|
+
#assignment: xxxx
|
13
|
+
#industry: eComm
|
14
|
+
|
15
|
+
heartland_portico_visa:
|
16
|
+
number: 4012002000060016
|
17
|
+
month: 12
|
18
|
+
year: 2025
|
19
|
+
brand: visa
|
20
|
+
heartland_portico_mastercard:
|
21
|
+
number: 5473500000000014
|
22
|
+
month: 12
|
23
|
+
year: 2025
|
24
|
+
brand: master
|
25
|
+
heartland_portico_discover:
|
26
|
+
number: 372700699251018
|
27
|
+
month: 12
|
28
|
+
year: 2025
|
29
|
+
brand: discover
|
30
|
+
heartland_portico_amex:
|
31
|
+
number: 6011000990156527
|
32
|
+
month: 12
|
33
|
+
year: 2025
|
34
|
+
brand: american_express
|
35
|
+
verification_value: 1234
|
36
|
+
heartland_portico_jcb:
|
37
|
+
number: 3566007770007321
|
38
|
+
month: 12
|
39
|
+
year: 2025
|
40
|
+
brand: jcb
|
@@ -0,0 +1,172 @@
|
|
1
|
+
# Run with:
|
2
|
+
# CERTIFY=true b ruby -Ilib:test test/remote/gateways/certification_test.rb
|
3
|
+
# ACH_CERTIFY=true b ruby -Ilib:test test/remote/gateways/certification_test.rb
|
4
|
+
require 'test_helper'
|
5
|
+
require 'active_merchant/billing/gateways/heartland_portico'
|
6
|
+
require 'heartland_portico'
|
7
|
+
require 'heartland_portico/ach'
|
8
|
+
|
9
|
+
class RemoteHeartlandPorticoCertificationTest < Test::Unit::TestCase
|
10
|
+
|
11
|
+
def options
|
12
|
+
$invoice_base ||= Time.now.strftime("%Y%m%d%H%M-")
|
13
|
+
$invoice_id ||= 0
|
14
|
+
$invoice_id += 1
|
15
|
+
{
|
16
|
+
:allow_dup => 'Y',
|
17
|
+
:invoice => $invoice_base+$invoice_id.to_s,
|
18
|
+
:invoice_ship_month => Date.today.month,
|
19
|
+
:invoice_ship_day => Date.today.day,
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_certification
|
24
|
+
return unless ENV['CERTIFY']
|
25
|
+
|
26
|
+
gateway = HeartlandPorticoGateway.new(fixtures(:heartland_portico))
|
27
|
+
|
28
|
+
visa = credit_card('', fixtures(:heartland_portico_visa))
|
29
|
+
mastercard = credit_card('', fixtures(:heartland_portico_mastercard))
|
30
|
+
discover = credit_card('', fixtures(:heartland_portico_discover))
|
31
|
+
amex = credit_card('', fixtures(:heartland_portico_amex))
|
32
|
+
jcb = credit_card('', fixtures(:heartland_portico_jcb))
|
33
|
+
|
34
|
+
zip_only = { :billing_address => {
|
35
|
+
:zip => "75024"
|
36
|
+
}}
|
37
|
+
street_zip = { :billing_address => {
|
38
|
+
:address1 => "6860 Dallas Pkwy",
|
39
|
+
:zip => "75024"
|
40
|
+
}}
|
41
|
+
street_zip9 = { :billing_address => {
|
42
|
+
:address1 => "6860 Dallas Pkwy",
|
43
|
+
:zip => "750241234"
|
44
|
+
}}
|
45
|
+
number_zip = { :billing_address => {
|
46
|
+
:address1 => "6860",
|
47
|
+
:zip => "75024"
|
48
|
+
}}
|
49
|
+
number_zip9 = { :billing_address => {
|
50
|
+
:address1 => "6860",
|
51
|
+
:zip => "750241234"
|
52
|
+
}}
|
53
|
+
|
54
|
+
# Card Verify (1-4)
|
55
|
+
assert_success gateway.verify(visa, options)
|
56
|
+
assert_success gateway.verify(mastercard, options)
|
57
|
+
assert_success gateway.verify(discover, options.merge(zip_only))
|
58
|
+
assert_success gateway.verify(amex, options.merge(zip_only))
|
59
|
+
|
60
|
+
# Sale (10-14)
|
61
|
+
assert_success r10 = gateway.purchase(1701, visa, options.merge(street_zip))
|
62
|
+
assert_success gateway.purchase(1702, mastercard, options.merge(number_zip))
|
63
|
+
assert_success gateway.purchase(1703, discover, options.merge(number_zip9))
|
64
|
+
assert_success gateway.purchase(1704, amex, options.merge(street_zip))
|
65
|
+
assert_success gateway.purchase(1705, jcb, options.merge(street_zip9))
|
66
|
+
|
67
|
+
# Authorize (15-17)
|
68
|
+
assert_success r15 = gateway.authorize(1706, visa, options.merge(street_zip))
|
69
|
+
assert_success r16 = gateway.authorize(1707, mastercard, options.merge(street_zip9))
|
70
|
+
assert_success r17 = gateway.authorize(1708, discover, options.merge(number_zip))
|
71
|
+
|
72
|
+
# Capture (15-17)
|
73
|
+
assert_success gateway.capture(1706, r15.authorization)
|
74
|
+
assert_success gateway.capture(1707, r16.authorization)
|
75
|
+
# Do not capture auth 17
|
76
|
+
|
77
|
+
# Not Yet Implemented: Level II Corporate Purchase Card (21-32)
|
78
|
+
|
79
|
+
# Return (34)
|
80
|
+
assert_success gateway.return(1515, mastercard, options)
|
81
|
+
|
82
|
+
# Void/Reversal (35)
|
83
|
+
assert_success gateway.void(r10.authorization)
|
84
|
+
end
|
85
|
+
|
86
|
+
def ach_options
|
87
|
+
{
|
88
|
+
:check_action => 'SALE', # OVERRIDE, RETURN
|
89
|
+
:data_entry_mode => 'MANUAL', # SWIPE
|
90
|
+
}
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_ach_certification
|
94
|
+
return unless ENV['ACH_CERTIFY']
|
95
|
+
|
96
|
+
consumer = {:sec_code => 'PPD'}
|
97
|
+
corporate = {:sec_code => 'CCD'}
|
98
|
+
web = {:sec_code => 'WEB'}
|
99
|
+
|
100
|
+
bank_account = {
|
101
|
+
:routing_number => '490000018',
|
102
|
+
:account_number => '24413815'
|
103
|
+
}
|
104
|
+
checking = {:account_type => 'CHECKING'}.merge(bank_account)
|
105
|
+
savings = {:account_type => 'SAVINGS'}.merge(bank_account)
|
106
|
+
|
107
|
+
personal = {:check_type => 'PERSONAL'}
|
108
|
+
business = {:check_type => 'BUSINESS'}
|
109
|
+
|
110
|
+
consumer_account_holder = {
|
111
|
+
:first_name => "Bob",
|
112
|
+
:last_name => "Smith",
|
113
|
+
:address => "123 Main St",
|
114
|
+
:city => "New York",
|
115
|
+
:state => "NY",
|
116
|
+
:zip => "10120",
|
117
|
+
:phone => "5555551234",
|
118
|
+
}
|
119
|
+
corporate_account_holder = {
|
120
|
+
:first_name => "Bob",
|
121
|
+
:last_name => "Smith",
|
122
|
+
:address => "123 Main St",
|
123
|
+
:city => "New York",
|
124
|
+
:state => "NY",
|
125
|
+
:zip => "10120",
|
126
|
+
:phone => "5555551234",
|
127
|
+
:memo => "Heartland Pays",
|
128
|
+
}
|
129
|
+
|
130
|
+
client = HeartlandPortico::ACH.new(fixtures(:heartland_portico), true)
|
131
|
+
|
132
|
+
# # ACH Debit - Consumer (1-4)
|
133
|
+
r1 = client.sale(1100, [ach_options, consumer, checking, personal, consumer_account_holder].inject(&:merge))
|
134
|
+
assert_equal "Transaction Approved", r1.message
|
135
|
+
r2 = client.sale(1200, [ach_options, consumer, checking, business, consumer_account_holder].inject(&:merge))
|
136
|
+
assert_equal "Transaction Approved", r2.message
|
137
|
+
r3 = client.sale(1300, [ach_options, consumer, savings, personal, consumer_account_holder].inject(&:merge))
|
138
|
+
assert_equal "Transaction Approved", r3.message
|
139
|
+
r4 = client.sale(1400, [ach_options, consumer, savings, business, consumer_account_holder].inject(&:merge))
|
140
|
+
assert_equal "Transaction Approved", r4.message
|
141
|
+
|
142
|
+
# # ACH Debit - Corporate (5-8)
|
143
|
+
r5 = client.sale(1500, [ach_options, corporate, checking, personal, corporate_account_holder].inject(&:merge))
|
144
|
+
assert_equal "Transaction Approved", r5.message
|
145
|
+
r6 = client.sale(1600, [ach_options, corporate, checking, business, corporate_account_holder].inject(&:merge))
|
146
|
+
assert_equal "Transaction Approved", r6.message
|
147
|
+
r7 = client.sale(1700, [ach_options, corporate, savings, personal, corporate_account_holder].inject(&:merge))
|
148
|
+
assert_equal "Transaction Approved", r7.message
|
149
|
+
r8 = client.sale(1800, [ach_options, corporate, savings, business, corporate_account_holder].inject(&:merge))
|
150
|
+
assert_equal "Transaction Approved", r8.message
|
151
|
+
|
152
|
+
# Checks-by-web (21-24)
|
153
|
+
r21 = client.sale(1900, [ach_options, web, checking, personal, corporate_account_holder].inject(&:merge))
|
154
|
+
assert_equal "Transaction Approved", r21.message
|
155
|
+
r22 = client.sale(2000, [ach_options, web, checking, business, corporate_account_holder].inject(&:merge))
|
156
|
+
assert_equal "Transaction Approved", r22.message
|
157
|
+
r23 = client.sale(2100, [ach_options, web, savings, personal, corporate_account_holder].inject(&:merge))
|
158
|
+
assert_equal "Transaction Approved", r23.message
|
159
|
+
r24 = client.sale(2200, [ach_options, web, savings, business, corporate_account_holder].inject(&:merge))
|
160
|
+
assert_equal "Transaction Approved", r24.message
|
161
|
+
|
162
|
+
# Void (25-29)
|
163
|
+
r25 = client.void(:gateway_txn_id => r1.authorization)
|
164
|
+
assert_equal "Transaction Approved", r25.message
|
165
|
+
r26 = client.void(:gateway_txn_id => r5.authorization)
|
166
|
+
assert_equal "Transaction Approved", r26.message
|
167
|
+
# 27: we do not run test 10
|
168
|
+
# 28: we do not run test 14
|
169
|
+
r29 = client.void(:gateway_txn_id => r23.authorization)
|
170
|
+
assert_equal "Transaction Approved", r29.message
|
171
|
+
end
|
172
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'active_merchant/billing/gateways/heartland_portico'
|
3
|
+
|
4
|
+
class RemoteHeartlandPorticoTest < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@gateway = HeartlandPorticoGateway.new(fixtures(:heartland_portico))
|
7
|
+
|
8
|
+
@amount = 100
|
9
|
+
@declined_amount = 1025
|
10
|
+
@credit_card = credit_card('', fixtures(:heartland_portico_mastercard))
|
11
|
+
|
12
|
+
@options = {
|
13
|
+
:order_id => '1',
|
14
|
+
:billing_address => {
|
15
|
+
:name => "Longbob Longsen",
|
16
|
+
:address1 => "6860 Dallas Pkwy",
|
17
|
+
:address2 => "",
|
18
|
+
:city => "Plano",
|
19
|
+
:state => "TX",
|
20
|
+
:zip => "75024",
|
21
|
+
:contry => "US",
|
22
|
+
:phone => "(555) 555-5555",
|
23
|
+
},
|
24
|
+
:invoice => "ABC123",
|
25
|
+
:invoice_ship_month => Date.today.month,
|
26
|
+
:invoice_ship_day => Date.today.day,
|
27
|
+
:description => 'Online Purchase',
|
28
|
+
:allow_dup => 'Y',
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_verify
|
33
|
+
assert response = @gateway.verify(@credit_card, @options)
|
34
|
+
assert_success response
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_successful_purchase
|
38
|
+
assert response = @gateway.purchase(@amount, @credit_card, @options)
|
39
|
+
assert_success response
|
40
|
+
assert_equal 'APPROVAL', response.message
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_unsuccessful_purchase
|
44
|
+
assert response = @gateway.purchase(@declined_amount, @credit_card, @options)
|
45
|
+
assert_failure response
|
46
|
+
assert_equal 'DECLINE', response.message
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_authorize_and_capture
|
50
|
+
amount = @amount
|
51
|
+
assert auth = @gateway.authorize(amount, @credit_card, @options)
|
52
|
+
assert_success auth
|
53
|
+
assert_equal 'APPROVAL', auth.message
|
54
|
+
assert auth.authorization
|
55
|
+
assert capture = @gateway.capture(amount, auth.authorization)
|
56
|
+
assert_success capture
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_failed_capture
|
60
|
+
assert response = @gateway.capture(@amount, '42')
|
61
|
+
assert_failure response
|
62
|
+
assert_equal 'ERROR', response.message
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_invalid_login
|
66
|
+
gateway = HeartlandPorticoGateway.new(
|
67
|
+
:user_name => '',
|
68
|
+
:password => '',
|
69
|
+
:developer_i_d => '',
|
70
|
+
:device_id => '',
|
71
|
+
:license_id => '',
|
72
|
+
:site_id => '',
|
73
|
+
:version_nbr => ''
|
74
|
+
)
|
75
|
+
assert response = gateway.purchase(@amount, @credit_card, @options)
|
76
|
+
assert_failure response
|
77
|
+
assert_equal 'ERROR', response.message
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_avs
|
81
|
+
# Magic amounts to generate AVS responses. See "HPS TEST Hardcode Values.xlsx"
|
82
|
+
assert response = @gateway.purchase(9008, @credit_card, @options)
|
83
|
+
assert_equal 'Y', response.avs_result['code']
|
84
|
+
# assert response.avs_address
|
85
|
+
# assert response.avs_zip
|
86
|
+
|
87
|
+
assert response = @gateway.purchase(9002, @credit_card, @options)
|
88
|
+
assert_equal 'N', response.avs_result['code']
|
89
|
+
# assert !response.avs_address
|
90
|
+
# assert !response.avs_zip
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_cvv
|
94
|
+
# Magic amounts to generate CVV responses. See "HPS TEST Hardcode Values.xlsx"
|
95
|
+
assert response = @gateway.purchase(9501, @credit_card, @options)
|
96
|
+
assert response.cvv_result['code'] == "M"
|
97
|
+
|
98
|
+
assert response = @gateway.purchase(9502, @credit_card, @options)
|
99
|
+
assert response.cvv_result['code'] == "N"
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_return
|
103
|
+
assert purchase = @gateway.purchase(@amount, @credit_card, @options)
|
104
|
+
assert_success purchase
|
105
|
+
|
106
|
+
assert response = @gateway.return(@amount, @credit_card)
|
107
|
+
assert_success response
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_reversal
|
111
|
+
assert purchase = @gateway.purchase(@amount, @credit_card, @options)
|
112
|
+
assert_success purchase
|
113
|
+
|
114
|
+
assert response = @gateway.reverse(@amount, purchase.authorization)
|
115
|
+
assert_success response
|
116
|
+
assert_equal "APPROVAL", response.message
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_void
|
120
|
+
assert purchase = @gateway.purchase(@amount, @credit_card, @options)
|
121
|
+
assert_success purchase
|
122
|
+
|
123
|
+
assert response = @gateway.void(purchase.authorization)
|
124
|
+
assert_success response
|
125
|
+
end
|
126
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,259 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$:.unshift File.expand_path('../../lib', __FILE__)
|
3
|
+
|
4
|
+
require 'pp'
|
5
|
+
require 'minitest'
|
6
|
+
|
7
|
+
begin
|
8
|
+
require 'rubygems'
|
9
|
+
require 'bundler'
|
10
|
+
Bundler.setup
|
11
|
+
rescue LoadError => e
|
12
|
+
puts "Error loading bundler (#{e.message}): \"gem install bundler\" for bundler support."
|
13
|
+
end
|
14
|
+
|
15
|
+
require 'test/unit'
|
16
|
+
require 'money'
|
17
|
+
require 'mocha/setup'
|
18
|
+
require 'yaml'
|
19
|
+
require 'json'
|
20
|
+
require 'active_merchant'
|
21
|
+
require 'comm_stub'
|
22
|
+
|
23
|
+
require 'active_support/core_ext/integer/time'
|
24
|
+
require 'active_support/core_ext/numeric/time'
|
25
|
+
require 'active_support/core_ext/hash/slice'
|
26
|
+
|
27
|
+
begin
|
28
|
+
require 'active_support/core_ext/time/acts_like'
|
29
|
+
rescue LoadError
|
30
|
+
end
|
31
|
+
|
32
|
+
begin
|
33
|
+
gem 'actionpack'
|
34
|
+
rescue LoadError
|
35
|
+
raise StandardError, "The view tests need ActionPack installed as gem to run"
|
36
|
+
end
|
37
|
+
|
38
|
+
#require 'action_controller'
|
39
|
+
#require "action_view/template"
|
40
|
+
begin
|
41
|
+
require 'active_support/core_ext/module/deprecation'
|
42
|
+
require 'action_dispatch/testing/test_process'
|
43
|
+
rescue LoadError
|
44
|
+
# require 'action_controller/test_process'
|
45
|
+
end
|
46
|
+
#require 'active_merchant/billing/integrations/action_view_helper'
|
47
|
+
|
48
|
+
ActiveMerchant::Billing::Base.mode = :test
|
49
|
+
|
50
|
+
if ENV['DEBUG_ACTIVE_MERCHANT'] == 'true'
|
51
|
+
require 'logger'
|
52
|
+
ActiveMerchant::Billing::Gateway.logger = Logger.new(STDOUT)
|
53
|
+
ActiveMerchant::Billing::Gateway.wiredump_device = STDOUT
|
54
|
+
end
|
55
|
+
|
56
|
+
# Test gateways
|
57
|
+
class SimpleTestGateway < ActiveMerchant::Billing::Gateway
|
58
|
+
end
|
59
|
+
|
60
|
+
class SubclassGateway < SimpleTestGateway
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
module ActiveMerchant
|
65
|
+
module Assertions
|
66
|
+
AssertionClass = RUBY_VERSION > '1.9' ? MiniTest::Assertion : Test::Unit::AssertionFailedError
|
67
|
+
|
68
|
+
def assert_field(field, value)
|
69
|
+
clean_backtrace do
|
70
|
+
assert_equal value, @helper.fields[field]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Allows the testing of you to check for negative assertions:
|
75
|
+
#
|
76
|
+
# # Instead of
|
77
|
+
# assert !something_that_is_false
|
78
|
+
#
|
79
|
+
# # Do this
|
80
|
+
# assert_false something_that_should_be_false
|
81
|
+
#
|
82
|
+
# An optional +msg+ parameter is available to help you debug.
|
83
|
+
def assert_false(boolean, message = nil)
|
84
|
+
message = build_message message, '<?> is not false or nil.', boolean
|
85
|
+
|
86
|
+
clean_backtrace do
|
87
|
+
assert_block message do
|
88
|
+
not boolean
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# A handy little assertion to check for a successful response:
|
94
|
+
#
|
95
|
+
# # Instead of
|
96
|
+
# assert_success response
|
97
|
+
#
|
98
|
+
# # DRY that up with
|
99
|
+
# assert_success response
|
100
|
+
#
|
101
|
+
# A message will automatically show the inspection of the response
|
102
|
+
# object if things go afoul.
|
103
|
+
def assert_success(response)
|
104
|
+
clean_backtrace do
|
105
|
+
assert response.success?, "Response failed: #{response.inspect}"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# The negative of +assert_success+
|
110
|
+
def assert_failure(response)
|
111
|
+
clean_backtrace do
|
112
|
+
assert_false response.success?, "Response expected to fail: #{response.inspect}"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def assert_valid(validateable)
|
117
|
+
clean_backtrace do
|
118
|
+
assert validateable.valid?, "Expected to be valid"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def assert_not_valid(validateable)
|
123
|
+
clean_backtrace do
|
124
|
+
assert_false validateable.valid?, "Expected to not be valid"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def assert_deprecation_warning(message, target)
|
129
|
+
target.expects(:deprecated).with(message)
|
130
|
+
yield
|
131
|
+
end
|
132
|
+
|
133
|
+
def assert_no_deprecation_warning(target)
|
134
|
+
target.expects(:deprecated).never
|
135
|
+
yield
|
136
|
+
end
|
137
|
+
|
138
|
+
private
|
139
|
+
def clean_backtrace(&block)
|
140
|
+
yield
|
141
|
+
rescue AssertionClass => e
|
142
|
+
path = File.expand_path(__FILE__)
|
143
|
+
raise AssertionClass, e.message, e.backtrace.reject { |line| File.expand_path(line) =~ /#{path}/ }
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
module Fixtures
|
148
|
+
HOME_DIR = RUBY_PLATFORM =~ /mswin32/ ? ENV['HOMEPATH'] : ENV['HOME'] unless defined?(HOME_DIR)
|
149
|
+
LOCAL_CREDENTIALS = File.join(HOME_DIR.to_s, '.active_merchant/fixtures.yml') unless defined?(LOCAL_CREDENTIALS)
|
150
|
+
DEFAULT_CREDENTIALS = File.join(File.dirname(__FILE__), 'fixtures.yml') unless defined?(DEFAULT_CREDENTIALS)
|
151
|
+
|
152
|
+
private
|
153
|
+
def credit_card(number = '4242424242424242', options = {})
|
154
|
+
defaults = {
|
155
|
+
:number => number,
|
156
|
+
:month => 9,
|
157
|
+
:year => Time.now.year + 1,
|
158
|
+
:first_name => 'Longbob',
|
159
|
+
:last_name => 'Longsen',
|
160
|
+
:verification_value => '123',
|
161
|
+
:brand => 'visa'
|
162
|
+
}.update(options)
|
163
|
+
|
164
|
+
Billing::CreditCard.new(defaults)
|
165
|
+
end
|
166
|
+
|
167
|
+
def check(options = {})
|
168
|
+
defaults = {
|
169
|
+
:name => 'Jim Smith',
|
170
|
+
:routing_number => '244183602',
|
171
|
+
:account_number => '15378535',
|
172
|
+
:account_holder_type => 'personal',
|
173
|
+
:account_type => 'checking',
|
174
|
+
:number => '1'
|
175
|
+
}.update(options)
|
176
|
+
|
177
|
+
Billing::Check.new(defaults)
|
178
|
+
end
|
179
|
+
|
180
|
+
def address(options = {})
|
181
|
+
{
|
182
|
+
:name => 'Jim Smith',
|
183
|
+
:address1 => '1234 My Street',
|
184
|
+
:address2 => 'Apt 1',
|
185
|
+
:company => 'Widgets Inc',
|
186
|
+
:city => 'Ottawa',
|
187
|
+
:state => 'ON',
|
188
|
+
:zip => 'K1C2N6',
|
189
|
+
:country => 'CA',
|
190
|
+
:phone => '(555)555-5555',
|
191
|
+
:fax => '(555)555-6666'
|
192
|
+
}.update(options)
|
193
|
+
end
|
194
|
+
|
195
|
+
def all_fixtures
|
196
|
+
@@fixtures ||= load_fixtures
|
197
|
+
end
|
198
|
+
|
199
|
+
def fixtures(key)
|
200
|
+
data = all_fixtures[key] || raise(StandardError, "No fixture data was found for '#{key}'")
|
201
|
+
|
202
|
+
data.dup
|
203
|
+
end
|
204
|
+
|
205
|
+
def load_fixtures
|
206
|
+
[DEFAULT_CREDENTIALS, LOCAL_CREDENTIALS].inject({}) do |credentials, file_name|
|
207
|
+
if File.exists?(file_name)
|
208
|
+
yaml_data = YAML.load(File.read(file_name))
|
209
|
+
credentials.merge!(symbolize_keys(yaml_data))
|
210
|
+
end
|
211
|
+
credentials
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
def symbolize_keys(hash)
|
216
|
+
return unless hash.is_a?(Hash)
|
217
|
+
|
218
|
+
hash.symbolize_keys!
|
219
|
+
hash.each{|k,v| symbolize_keys(v)}
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
Test::Unit::TestCase.class_eval do
|
225
|
+
include ActiveMerchant::Billing
|
226
|
+
include ActiveMerchant::Assertions
|
227
|
+
include ActiveMerchant::Utils
|
228
|
+
include ActiveMerchant::Fixtures
|
229
|
+
end
|
230
|
+
|
231
|
+
module ActionViewHelperTestHelper
|
232
|
+
|
233
|
+
def self.included(base)
|
234
|
+
base.send(:include, ActiveMerchant::Billing::Integrations::ActionViewHelper)
|
235
|
+
base.send(:include, ActionView::Helpers::FormHelper)
|
236
|
+
base.send(:include, ActionView::Helpers::FormTagHelper)
|
237
|
+
base.send(:include, ActionView::Helpers::UrlHelper)
|
238
|
+
base.send(:include, ActionView::Helpers::TagHelper)
|
239
|
+
base.send(:include, ActionView::Helpers::CaptureHelper)
|
240
|
+
base.send(:include, ActionView::Helpers::TextHelper)
|
241
|
+
base.send(:attr_accessor, :output_buffer)
|
242
|
+
end
|
243
|
+
|
244
|
+
def setup
|
245
|
+
@controller = Class.new do
|
246
|
+
attr_reader :url_for_options
|
247
|
+
def url_for(options, *parameters_for_method_reference)
|
248
|
+
@url_for_options = options
|
249
|
+
end
|
250
|
+
end
|
251
|
+
@controller = @controller.new
|
252
|
+
@output_buffer = ''
|
253
|
+
end
|
254
|
+
|
255
|
+
protected
|
256
|
+
def protect_against_forgery?
|
257
|
+
false
|
258
|
+
end
|
259
|
+
end
|