rocketgate-ruby 0.0.1.pre

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.
@@ -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