rocketgate-ruby 0.0.1.pre

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ module RocketGate
2
+ VERSION = "0.0.1.pre"
3
+ end
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rocketgate/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "rocketgate-ruby"
8
+ spec.version = RocketGate::VERSION
9
+ spec.authors = ["Chris Cashwell"]
10
+ spec.email = ["ccashwell@gmail.com"]
11
+ spec.summary = %q{RocketGate Payment Gateway integration for Ruby}
12
+ spec.description = %q{rocketgate-ruby is a simple interface for communicating with RocketGate's Payment Gateway}
13
+ spec.homepage = "https://github.com/ccashwell/rocketgate-ruby"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.6"
22
+ spec.add_development_dependency "coveralls"
23
+ spec.add_development_dependency "guard-rspec"
24
+ spec.add_development_dependency "guard"
25
+ spec.add_development_dependency "pry-nav"
26
+ spec.add_development_dependency "pry-remote"
27
+ spec.add_development_dependency "pry"
28
+ spec.add_development_dependency "rake", "~> 10.0"
29
+ spec.add_development_dependency "rspec-nc"
30
+ spec.add_development_dependency "rspec"
31
+
32
+ spec.add_runtime_dependency "gyoku"
33
+ spec.add_runtime_dependency "nokogiri"
34
+ end
@@ -0,0 +1,87 @@
1
+ require 'spec_helper'
2
+
3
+ describe RocketGate::Authorization do
4
+ let(:authorization) { RocketGate::Authorization.new }
5
+
6
+ describe '#avs_ok?' do
7
+ subject { authorization.avs_ok? }
8
+
9
+ context 'when AVS verification is required' do
10
+ before { RocketGate.configuration.require_avs = true }
11
+
12
+ it 'returns true when the AVS check was successful' do
13
+ authorization.avs_response = :match
14
+ expect(subject).to be true
15
+ end
16
+
17
+ it 'returns false when the AVS check was unsuccessful' do
18
+ authorization.avs_response = :no_match
19
+ expect(subject).to be false
20
+ end
21
+ end
22
+
23
+ context 'when AVS verification is not required' do
24
+ before { RocketGate.configuration.require_avs = false }
25
+
26
+ it 'returns true' do
27
+ expect(subject).to be true
28
+ end
29
+ end
30
+ end
31
+
32
+ describe '#cvv_ok?' do
33
+ subject { authorization.cvv_ok? }
34
+
35
+ context 'when CVV verification is required' do
36
+ before { RocketGate.configuration.require_cvv = true }
37
+
38
+ it 'returns true when the CVV check was successful' do
39
+ authorization.cvv_response = :match
40
+ expect(subject).to be true
41
+ end
42
+
43
+ it 'returns false when the CVV check was unsuccessful' do
44
+ authorization.cvv_response = :no_match
45
+ expect(subject).to be false
46
+ end
47
+ end
48
+
49
+ context 'when CVV verification is not required' do
50
+ before { RocketGate.configuration.require_cvv = false }
51
+
52
+ it 'returns true' do
53
+ expect(subject).to be true
54
+ end
55
+ end
56
+ end
57
+
58
+ describe '#declined?' do
59
+ subject { authorization.declined? }
60
+
61
+ it 'returns true when successful' do
62
+ allow(authorization).to receive(:success?).and_return(true)
63
+ expect(subject).to be false
64
+ end
65
+
66
+ it 'returns false when unsuccessful' do
67
+ allow(authorization).to receive(:success?).and_return(false)
68
+ expect(subject).to be true
69
+ end
70
+ end
71
+
72
+ describe '#success?' do
73
+ subject { authorization.success? }
74
+
75
+ it 'returns true when everything is ok' do
76
+ allow(authorization).to receive(:avs_ok?).and_return(true)
77
+ allow(authorization).to receive(:cvv_ok?).and_return(true)
78
+ allow(authorization).to receive(:reason_code).and_return(:success)
79
+ expect(subject).to be true
80
+ end
81
+
82
+ it 'returns false when anything is not ok' do
83
+ allow(authorization).to receive(:avs_ok?).and_return(false)
84
+ expect(subject).to be false
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe RocketGate::Configuration do
4
+ describe '#initialize' do
5
+ let(:config) { RocketGate::Configuration.new }
6
+
7
+ it 'supplies a reasonable default config' do
8
+ expect(config.currency).to eq RocketGate::Configuration::DEFAULT_CURRENCY
9
+ expect(config.request_host).to eq RocketGate::Configuration::GATEWAY_LIVE_HOST
10
+ expect(config.request_path).to eq RocketGate::Configuration::GATEWAY_SERVLET
11
+ expect(config.request_port).to eq RocketGate::Configuration::GATEWAY_PORT
12
+ expect(config.request_timeout).to eq RocketGate::Configuration::DEFAULT_TIMEOUT
13
+ expect(config.request_version).to eq RocketGate::Configuration::GATEWAY_VERSION
14
+ expect(config.require_avs).to eq true
15
+ expect(config.require_cvv).to eq true
16
+ expect(config.require_scrub).to eq true
17
+ expect(config.require_ssl).to eq true
18
+ end
19
+ end
20
+
21
+ describe '#testing!' do
22
+ subject { config.testing! }
23
+
24
+ let(:config) { RocketGate::Configuration.new }
25
+
26
+ it 'sets up the default testing configuration' do
27
+ expect(subject).to eq config
28
+ expect(config.request_host).to eq RocketGate::Configuration::GATEWAY_TEST_HOST
29
+ expect(config.merchant_id).to eq '1'
30
+ expect(config.merchant_password).to eq 'testpassword'
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,65 @@
1
+ require 'spec_helper'
2
+
3
+ describe RocketGate::Connection do
4
+ before { allow(Net::HTTP).to receive(:new).and_return(client) }
5
+ let(:client) { Net::HTTP.new('insecure.com', 80) }
6
+
7
+ describe '.new' do
8
+ subject { RocketGate::Connection.new('example.com', 443, '/path') }
9
+
10
+ it 'instantiates a client' do
11
+ expect(Net::HTTP).to receive(:new).with('example.com', 443)
12
+ subject
13
+ end
14
+
15
+ it 'sets the request timeouts' do
16
+ expect(client).to receive(:open_timeout=).with(10)
17
+ expect(client).to receive(:read_timeout=).with(10)
18
+ subject
19
+ end
20
+
21
+ context 'when SSL is required' do
22
+ before { RocketGate.configuration.require_ssl = true }
23
+
24
+ it 'uses SSL, VERIFY_NONE mode' do
25
+ expect(client).to receive(:use_ssl=).with(true)
26
+ expect(client).to receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
27
+ subject
28
+ end
29
+ end
30
+
31
+ context 'when SSL is not required' do
32
+ before { RocketGate.configuration.require_ssl = false }
33
+
34
+ it 'uses SSL, VERIFY_NONE mode' do
35
+ expect(client).not_to receive(:use_ssl=)
36
+ expect(client).not_to receive(:verify_mode=)
37
+ subject
38
+ end
39
+ end
40
+ end
41
+
42
+ describe '#make_request!' do
43
+ subject { RocketGate::Connection.new('example.com', 443, '/path').make_request!('test') }
44
+ let(:request) { double(:post).as_null_object }
45
+ before do
46
+ allow(Net::HTTP::Post).to receive(:new).and_return(request)
47
+ allow(client).to receive(:request).with(request)
48
+ end
49
+
50
+ it 'builds a request' do
51
+ expect(Net::HTTP::Post).to receive(:new).with('/path', {
52
+ 'Accept' => 'text/xml',
53
+ 'Content-Type' => 'text/xml',
54
+ 'User-Agent' => 'rocketgate-ruby/0.0.1.pre'
55
+ }).and_return(request)
56
+ expect(request).to receive(:body=).with('test')
57
+ subject
58
+ end
59
+
60
+ it 'sends the request' do
61
+ expect(client).to receive(:request).with(request)
62
+ subject
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+
3
+ describe RocketGate::CreditCard do
4
+ describe '.new' do
5
+ it 'accepts an arbitrary set of arguments and assigns them to certain attributes' do
6
+ credit_card = RocketGate::CreditCard.new('4111111111111111', '01', '2015', '123')
7
+ expect(credit_card.number).to eq '4111111111111111'
8
+ expect(credit_card.exp_month).to eq '01'
9
+ expect(credit_card.exp_year).to eq '2015'
10
+ expect(credit_card.cvv).to eq '123'
11
+ end
12
+
13
+ it 'cleans the card number' do
14
+ expect(RocketGate::CreditCard.new('4111-2222-3333-4444').number).to eq '4111222233334444'
15
+ expect(RocketGate::CreditCard.new('4444 5555 6666 7777').number).to eq '4444555566667777'
16
+ end
17
+ end
18
+
19
+ describe '.from_card_hash' do
20
+ it 'instantiates a card with the hash' do
21
+ credit_card = RocketGate::CreditCard.from_card_hash('m77xlHZiPKVsF9p1/VdzTb+CUwaGBDpuSRxtcb7+j24=')
22
+ expect(credit_card.card_hash).to eq 'm77xlHZiPKVsF9p1/VdzTb+CUwaGBDpuSRxtcb7+j24='
23
+ end
24
+ end
25
+
26
+ describe '#to_hash' do
27
+ let(:credit_card) { RocketGate::CreditCard.new('4111111111111111', '01', '2015', '123') }
28
+
29
+ context 'when there is a card hash available' do
30
+ before { credit_card.card_hash = 'm77xlHZiPKVsF9p1/VdzTb+CUwaGBDpuSRxtcb7+j24=' }
31
+
32
+ it 'returns a hash which only includes the card hash' do
33
+ expect(credit_card.to_hash).to eq({ cardHash: 'm77xlHZiPKVsF9p1/VdzTb+CUwaGBDpuSRxtcb7+j24=' })
34
+ end
35
+ end
36
+
37
+ context 'when there is no card hash available' do
38
+ it 'returns a hash of the card attributes' do
39
+ expect(credit_card.to_hash).to eq({
40
+ cardNo: '4111111111111111',
41
+ expireMonth: '01',
42
+ expireYear: '2015',
43
+ cvv2: '123'
44
+ })
45
+ end
46
+ end
47
+ end
48
+
49
+ describe '#valid?' do
50
+ context 'when there is a card hash' do
51
+ let(:credit_card) { RocketGate::CreditCard.new.tap{|cc| cc.card_hash = 'abc' } }
52
+
53
+ it 'is true' do
54
+ expect(credit_card.valid?).to eq true
55
+ end
56
+ end
57
+
58
+ context 'when there is not a card hash' do
59
+ let(:credit_card) { RocketGate::CreditCard.new }
60
+
61
+ it 'validates the other attributes' do
62
+ expect(credit_card.valid?).to eq false
63
+
64
+ credit_card.number = '4111111111111111',
65
+ credit_card.exp_month = '01'
66
+ credit_card.exp_year = '2015'
67
+ credit_card.cvv = '123'
68
+
69
+ expect(credit_card.valid?).to eq true
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+
3
+ describe RocketGate::Customer do
4
+ describe '.new' do
5
+ it 'accepts an arbitrary set of arguments and assigns them to certain attributes' do
6
+ customer = RocketGate::Customer.new('Test', 'Person', '123 Fake Street', 'Beverly Hills', 'CA', '90210', 'US', 'test@example.com', 'tester', '127.0.0.1', '07f7b231-9b29-46d4-9c19-cd6790e712b5')
7
+ expect(customer.first_name).to eq 'Test'
8
+ expect(customer.last_name).to eq 'Person'
9
+ expect(customer.street_address).to eq '123 Fake Street'
10
+ expect(customer.city).to eq 'Beverly Hills'
11
+ expect(customer.state).to eq 'CA'
12
+ expect(customer.postal_code).to eq '90210'
13
+ expect(customer.country).to eq 'US'
14
+ expect(customer.email).to eq 'test@example.com'
15
+ expect(customer.username).to eq 'tester'
16
+ expect(customer.ip_address).to eq '127.0.0.1'
17
+ expect(customer.id).to eq '07f7b231-9b29-46d4-9c19-cd6790e712b5'
18
+ end
19
+ end
20
+
21
+ describe '#id' do
22
+ let(:customer) { RocketGate::Customer.new }
23
+
24
+ it 'returns the supplied ID when set' do
25
+ customer.id = 'abc123'
26
+ expect(customer.id).to eq 'abc123'
27
+ end
28
+
29
+ it 'generates a random UUID when not set' do
30
+ expect(SecureRandom).to receive(:uuid).and_return('07f7b231-9b29-46d4-9c19-cd6790e712b5')
31
+ expect(customer.id).to eq '07f7b231-9b29-46d4-9c19-cd6790e712b5'
32
+ end
33
+ end
34
+
35
+ describe '#to_hash' do
36
+ let(:customer) { RocketGate::Customer.new('Test', 'Person', '123 Fake Street', 'Beverly Hills', 'CA', '90210', 'US', 'test@example.com', 'tester', '127.0.0.1', '07f7b231-9b29-46d4-9c19-cd6790e712b5') }
37
+ let(:expected) do
38
+ {
39
+ merchantCustomerID: '07f7b231-9b29-46d4-9c19-cd6790e712b5',
40
+ customerFirstName: 'Test',
41
+ customerLastName: 'Person',
42
+ billingAddress: '123 Fake Street',
43
+ billingCity: 'Beverly Hills',
44
+ billingState: 'CA',
45
+ billingZipCode: '90210',
46
+ billingCountry: 'US',
47
+ email: 'test@example.com',
48
+ username: 'tester',
49
+ ipAddress: '127.0.0.1'
50
+ }
51
+ end
52
+
53
+ it 'returns a hash of the customer attributes' do
54
+ expect(customer.to_hash).to eq expected
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,85 @@
1
+ require 'spec_helper'
2
+
3
+ describe RocketGate::Hashable do
4
+ describe '.hashable' do
5
+ let(:test_class) { Class.new }
6
+
7
+ it 'records a hash of display names and their attribute mappings' do
8
+ expect(test_class).to receive(:hashable).with({:One => :one, "two" => :two})
9
+ test_class.class_eval do
10
+ include RocketGate::Hashable
11
+ attr_accessor :one, :two, :three
12
+ hashable({:One => :one, "two" => :two})
13
+ end
14
+ end
15
+
16
+ it 'records a list of mergable items appearing after the mappings' do
17
+ expect(test_class).to receive(:hashable).with({one: :one}, :two, :three)
18
+ test_class.class_eval do
19
+ include RocketGate::Hashable
20
+ attr_accessor :one, :two, :three
21
+ hashable({one: :one}, :two, :three)
22
+ end
23
+ end
24
+
25
+ it 'allows display names to be mapped to procs' do
26
+ expect(test_class).to receive(:hashable).with({one: an_instance_of(Proc)})
27
+ expect do
28
+ test_class.class_eval do
29
+ include RocketGate::Hashable
30
+ hashable({one: Proc.new { true } })
31
+ end
32
+ end.not_to raise_error
33
+ end
34
+
35
+ it 'allows mergable items to procs' do
36
+ expect(test_class).to receive(:hashable).with({one: :one}, an_instance_of(Proc))
37
+ expect do
38
+ test_class.class_eval do
39
+ include RocketGate::Hashable
40
+ attr_accessor :one
41
+ hashable({one: :one}, Proc.new { true })
42
+ end
43
+ end.not_to raise_error
44
+ end
45
+
46
+ it 'complains about display names mapped to attributes that are not real' do
47
+ expect do
48
+ test_class.class_eval do
49
+ include RocketGate::Hashable
50
+ attr_accessor :one, :two
51
+ hashable({:One => :one, "two" => :two, "3" => :three})
52
+ end
53
+ end.to raise_error(RocketGate::ValidationError, 'Invalid attribute: three')
54
+ end
55
+
56
+ it 'complains about mergable items which are not real' do
57
+ expect do
58
+ test_class.class_eval do
59
+ include RocketGate::Hashable
60
+ attr_accessor :one, :two
61
+ hashable({one: :one}, :two, :three)
62
+ end
63
+ end.to raise_error(RocketGate::ValidationError, 'Invalid attribute: three')
64
+ end
65
+ end
66
+
67
+ describe '#to_hash' do
68
+ let(:test_class) do
69
+ c = Class.new
70
+ c.class_eval do
71
+ include RocketGate::Hashable
72
+ attr_accessor :one, :two
73
+ define_method :three do
74
+ { "3" => 1+2 }
75
+ end
76
+ hashable({one: :one, 'Two' => :two}, :three, ->{ { four: 4 } })
77
+ end
78
+ c.new
79
+ end
80
+
81
+ it 'builds a hash using the mappings and mergables provided' do
82
+ expect(test_class.to_hash).to eq({one: nil, 'Two' => nil, '3' => 3, four: 4})
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,131 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'RocketGate Integration Certification Test Cases', integration: true do
4
+ before do
5
+ RocketGate.configuration.testing!
6
+ RocketGate.configuration.require_scrub = false
7
+ end
8
+
9
+ let(:request) { RocketGate::Request.new(transaction) }
10
+ let(:base_tx) do
11
+ RocketGate::Transaction.new.tap do |tx|
12
+ tx.id = 'b7bb0d51-ce1a-4dd2-b0f4-61e5ff5449db'
13
+ tx.amount = 1.00
14
+
15
+ tx.customer = RocketGate::Customer.new.tap do |cust|
16
+ cust.id = '17da86fd-7bac-4fa0-88c1-7396b3897ac2'
17
+ cust.first_name = 'John'
18
+ cust.last_name = 'Test'
19
+ cust.street_address = '1234 Main Street'
20
+ cust.city = 'Las Vegas'
21
+ cust.state = 'NV'
22
+ cust.postal_code = '89141'
23
+ cust.country = 'US'
24
+ cust.email = 'user@test.com'
25
+ cust.ip_address = '216.239.116.167'
26
+ end
27
+
28
+ tx.credit_card = RocketGate::CreditCard.new.tap do |cc|
29
+ cc.number = '4012 8888 8888 1881'
30
+ cc.exp_month = '08'
31
+ cc.exp_year = '2042'
32
+ cc.cvv = '1111'
33
+ end
34
+ end
35
+ end
36
+
37
+ describe 'Test Case #1 (auth-only, then ticket for authorization by ID)' do
38
+ let(:transaction) { base_tx.dup }
39
+ before { transaction.type = RocketGate::Transaction::TYPE[:auth] }
40
+
41
+ it 'successfully authorizes, confirms, and settles a transaction' do
42
+ auth_response = RocketGate.send_request!(RocketGate::Request.new(transaction))
43
+ expect(auth_response).to be_success
44
+ expect(auth_response.authorization).not_to be_declined
45
+
46
+ confirmation_response = auth_response.confirm!
47
+ expect(confirmation_response).to be_success
48
+
49
+ ticket_tx = RocketGate::Transaction.new.tap do |tx|
50
+ tx.reference_id = auth_response.authorization.reference_id
51
+ tx.type = RocketGate::Transaction::TYPE[:ticket]
52
+ end
53
+
54
+ ticket_response = RocketGate.send_request!(RocketGate::Request.new(ticket_tx))
55
+ expect(ticket_response).to be_success
56
+ expect(ticket_response).to be_authorized
57
+ expect(ticket_response.authorization).not_to be_declined
58
+ expect(ticket_response.authorization.approved_amount).to eq 1.0
59
+ expect(ticket_response.authorization.approved_currency).to eq 'USD'
60
+ expect(ticket_response.authorization.card_last_four).to eq '1881'
61
+ expect(ticket_response.authorization.card_expiration).to eq '0842'
62
+ expect(ticket_response.authorization.card_hash).to eq '3RPN+a+d07r0bOlq7NcWPKvzgcyyHmPxXw+hCxxmP6k='
63
+ expect(ticket_response.authorization.reference_id).not_to be_nil
64
+ end
65
+ end
66
+
67
+ describe 'Test Case #2 (make sale, then void sale by ID)' do
68
+ let(:transaction) { base_tx.dup }
69
+ before { transaction.type = RocketGate::Transaction::TYPE[:purchase] }
70
+
71
+ it 'successfully charges and voids a transaction' do
72
+ sale_response = RocketGate.send_request!(RocketGate::Request.new(transaction))
73
+ expect(sale_response).to be_success
74
+ expect(sale_response.authorization).not_to be_declined
75
+
76
+ confirmation_response = sale_response.confirm!
77
+ expect(confirmation_response).to be_success
78
+
79
+ void_tx = RocketGate::Transaction.new.tap do |tx|
80
+ tx.reference_id = sale_response.authorization.reference_id
81
+ tx.type = RocketGate::Transaction::TYPE[:void]
82
+ end
83
+ void_response = RocketGate.send_request!(RocketGate::Request.new(void_tx))
84
+
85
+ expect(void_response).to be_success
86
+ expect(void_response).to be_authorized
87
+ expect(void_response.authorization).not_to be_declined
88
+ expect(void_response.authorization.approved_amount).to eq 1.0
89
+ expect(void_response.authorization.approved_currency).to eq 'USD'
90
+ expect(void_response.authorization.card_last_four).to eq '1881'
91
+ expect(void_response.authorization.card_expiration).to eq '0842'
92
+ expect(void_response.authorization.card_hash).to eq '3RPN+a+d07r0bOlq7NcWPKvzgcyyHmPxXw+hCxxmP6k='
93
+ end
94
+ end
95
+
96
+ describe 'Test Case #3 (failed AVS check, response of N)' do
97
+ let(:transaction) { base_tx.dup }
98
+ before { transaction.customer.postal_code = '00008' }
99
+
100
+ it 'returns an unsuccessful response' do
101
+ response = RocketGate.send_request!(RocketGate::Request.new(transaction))
102
+ expect(response).not_to be_success
103
+ expect(response.authorization).to be_declined
104
+ expect(response.authorization.avs_ok?).to be false
105
+ end
106
+ end
107
+
108
+ describe 'Test Case #4 (failed CVV check, response of N)' do
109
+ let(:transaction) { base_tx.dup }
110
+ before { transaction.credit_card.cvv = '0001' }
111
+
112
+ it 'returns an unsuccessful response' do
113
+ response = RocketGate.send_request!(RocketGate::Request.new(transaction))
114
+ expect(response).not_to be_success
115
+ expect(response.authorization).to be_declined
116
+ expect(response.authorization.cvv_ok?).to be false
117
+ end
118
+ end
119
+
120
+ describe 'Test Case #5 (declined, card over limit)' do
121
+ let(:transaction) { base_tx.dup }
122
+ before { transaction.amount = 0.02 }
123
+
124
+ it 'returns an unsuccessful response' do
125
+ response = RocketGate.send_request!(RocketGate::Request.new(transaction))
126
+ expect(response).not_to be_success
127
+ expect(response.authorization).to be_declined
128
+ expect(response.authorization.reason_code).to eq :declined_over_limit
129
+ end
130
+ end
131
+ end