samurai 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +2 -1
- data/Gemfile.lock +10 -8
- data/lib/samurai.rb +2 -1
- data/lib/samurai/active_resource_support.rb +30 -0
- data/lib/samurai/payment_method.rb +6 -16
- data/lib/samurai/processor.rb +1 -1
- data/lib/samurai/transaction.rb +2 -14
- data/lib/samurai/version.rb +1 -1
- data/samurai.gemspec +4 -3
- data/spec/lib/payment_method_spec.rb +77 -21
- data/spec/lib/processor_spec.rb +10 -4
- data/spec/lib/transaction_spec.rb +5 -5
- data/spec/support/custom_matchers.rb +16 -0
- data/spec/support/transparent_redirect_helper.rb +5 -0
- metadata +16 -12
data/Gemfile
CHANGED
@@ -3,4 +3,5 @@ source :gemcutter
|
|
3
3
|
# Specify your gem's dependencies in samurai.gemspec
|
4
4
|
gemspec
|
5
5
|
|
6
|
-
gem 'rspec_junit_formatter', :git=>'git://github.com/jkrall/rspec_junit_formatter.git'
|
6
|
+
gem 'rspec_junit_formatter', :git=>'git://github.com/jkrall/rspec_junit_formatter.git'
|
7
|
+
gem 'rake'
|
data/Gemfile.lock
CHANGED
@@ -9,20 +9,20 @@ GIT
|
|
9
9
|
PATH
|
10
10
|
remote: .
|
11
11
|
specs:
|
12
|
-
samurai (0.
|
12
|
+
samurai (0.4.0)
|
13
13
|
activeresource (>= 2.2.2)
|
14
14
|
|
15
15
|
GEM
|
16
16
|
remote: http://rubygems.org/
|
17
17
|
specs:
|
18
|
-
activemodel (3.
|
19
|
-
activesupport (= 3.
|
18
|
+
activemodel (3.2.1)
|
19
|
+
activesupport (= 3.2.1)
|
20
20
|
builder (~> 3.0.0)
|
21
|
+
activeresource (3.2.1)
|
22
|
+
activemodel (= 3.2.1)
|
23
|
+
activesupport (= 3.2.1)
|
24
|
+
activesupport (3.2.1)
|
21
25
|
i18n (~> 0.6)
|
22
|
-
activeresource (3.1.1)
|
23
|
-
activemodel (= 3.1.1)
|
24
|
-
activesupport (= 3.1.1)
|
25
|
-
activesupport (3.1.1)
|
26
26
|
multi_json (~> 1.0)
|
27
27
|
archive-tar-minitar (0.5.2)
|
28
28
|
builder (3.0.0)
|
@@ -32,7 +32,8 @@ GEM
|
|
32
32
|
i18n (0.6.0)
|
33
33
|
linecache19 (0.5.12)
|
34
34
|
ruby_core_source (>= 0.1.4)
|
35
|
-
multi_json (1.0.
|
35
|
+
multi_json (1.0.4)
|
36
|
+
rake (0.9.2)
|
36
37
|
rspec (2.6.0)
|
37
38
|
rspec-core (~> 2.6.0)
|
38
39
|
rspec-expectations (~> 2.6.0)
|
@@ -58,6 +59,7 @@ PLATFORMS
|
|
58
59
|
DEPENDENCIES
|
59
60
|
bundler (>= 1.0.0)
|
60
61
|
fakeweb
|
62
|
+
rake
|
61
63
|
rspec (>= 2.6.0)
|
62
64
|
rspec_junit_formatter!
|
63
65
|
ruby-debug19
|
data/lib/samurai.rb
CHANGED
@@ -47,6 +47,7 @@ module Samurai
|
|
47
47
|
end
|
48
48
|
|
49
49
|
# Require each of the samurai components
|
50
|
+
require 'samurai/active_resource_support'
|
50
51
|
require 'samurai/cacheable_by_token'
|
51
52
|
require 'samurai/base'
|
52
53
|
require 'samurai/processor'
|
@@ -78,4 +79,4 @@ module ActiveResource
|
|
78
79
|
end
|
79
80
|
end
|
80
81
|
end
|
81
|
-
end
|
82
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Samurai
|
2
|
+
module ActiveResourceSupport
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
if [ActiveResource::VERSION::MAJOR, ActiveResource::VERSION::MINOR].compact.join('.').to_f < 3.0
|
6
|
+
# If we're using ActiveResource pre-3.1, there's no schema class method, so we resort to some tricks...
|
7
|
+
# Initialize the known attributes from the schema as empty strings, so that they can be accessed via method-missing
|
8
|
+
base.const_set 'EMPTY_ATTRIBUTES', base.const_get('KNOWN_ATTRIBUTES').inject(HashWithIndifferentAccess.new) {|h, k| h[k] = ''; h}
|
9
|
+
|
10
|
+
base.class_eval do
|
11
|
+
# Modify the constructor to emulate the schema behavior
|
12
|
+
def initialize(attrs={})
|
13
|
+
_empty_attributes = self.class.const_get('EMPTY_ATTRIBUTES')
|
14
|
+
super(_empty_attributes.merge(attrs))
|
15
|
+
end
|
16
|
+
|
17
|
+
# Add missing #update_attributes
|
18
|
+
def update_attributes(attributes)
|
19
|
+
load(attributes) && save
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
else
|
24
|
+
# Post AR 3.1, we can use the schema method to define our attributes
|
25
|
+
base.schema { string *base.const_get('KNOWN_ATTRIBUTES') }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -20,12 +20,14 @@ class Samurai::PaymentMethod < Samurai::Base
|
|
20
20
|
# Retains the payment method on `api.samurai.feefighters.com`. Retain a payment method if
|
21
21
|
# it will not be used immediately.
|
22
22
|
def retain
|
23
|
-
self.post(:retain)
|
23
|
+
resp = self.post(:retain, {}, '<payment_method></payment_method>')
|
24
|
+
self.load_attributes_from_response(resp)
|
24
25
|
end
|
25
26
|
|
26
27
|
# Redacts sensitive information from the payment method, rendering it unusable.
|
27
28
|
def redact
|
28
|
-
self.post(:redact)
|
29
|
+
resp = self.post(:redact, {}, '<payment_method></payment_method>')
|
30
|
+
self.load_attributes_from_response(resp)
|
29
31
|
end
|
30
32
|
|
31
33
|
# Retrieves JSON formatted custom data that is encoded in the custom_data attribute
|
@@ -51,19 +53,7 @@ class Samurai::PaymentMethod < Samurai::Base
|
|
51
53
|
:first_name, :last_name, :address_1, :address_2, :city, :state, :zip,
|
52
54
|
:card_number, :cvv, :expiry_month, :expiry_year, :sandbox, :custom
|
53
55
|
]
|
54
|
-
|
55
|
-
# If we're using ActiveResource pre-3.1, there's no schema class method, so we resort to some tricks...
|
56
|
-
# Initialize the known attributes from the schema as empty strings, so that they can be accessed via method-missing
|
57
|
-
EMPTY_ATTRIBUTES = KNOWN_ATTRIBUTES.inject(HashWithIndifferentAccess.new) {|h, k| h[k] = ''; h}
|
58
|
-
def initialize(attrs={})
|
59
|
-
super(EMPTY_ATTRIBUTES.merge(attrs))
|
60
|
-
end
|
61
|
-
else
|
62
|
-
# Post AR 3.1, we can use the schema method to define our attributes
|
63
|
-
schema do
|
64
|
-
string *KNOWN_ATTRIBUTES
|
65
|
-
end
|
66
|
-
end
|
56
|
+
include Samurai::ActiveResourceSupport
|
67
57
|
|
68
58
|
# Convenience method for preparing a new PaymentMethod for use with a transparent redirect form
|
69
59
|
def self.for_transparent_redirect(params)
|
@@ -73,7 +63,7 @@ class Samurai::PaymentMethod < Samurai::Base
|
|
73
63
|
Samurai::PaymentMethod.find(params[:payment_method_token]).tap do |pm|
|
74
64
|
pm.card_number = "************#{pm.last_four_digits}"
|
75
65
|
pm.cvv = "***"
|
76
|
-
pm.errors
|
66
|
+
pm.errors.add :base, 'The card number or CVV are not valid.' if !pm.is_sensitive_data_valid
|
77
67
|
end
|
78
68
|
end
|
79
69
|
end
|
data/lib/samurai/processor.rb
CHANGED
@@ -78,7 +78,7 @@ class Samurai::Processor < Samurai::Base
|
|
78
78
|
transaction.payment_method = Samurai::PaymentMethod.find options[:payment_method_token]
|
79
79
|
transaction.created_at = Time.now
|
80
80
|
transaction.processor_response = nil
|
81
|
-
transaction.errors
|
81
|
+
transaction.errors.add :base, "Invalid request."
|
82
82
|
end
|
83
83
|
end
|
84
84
|
end
|
data/lib/samurai/transaction.rb
CHANGED
@@ -58,7 +58,7 @@ class Samurai::Transaction < Samurai::Base
|
|
58
58
|
Samurai::Transaction.new(options.merge(:transaction_type=>action.to_s)).tap do |transaction|
|
59
59
|
transaction.created_at = Time.now
|
60
60
|
transaction.processor_response = nil
|
61
|
-
transaction.errors
|
61
|
+
transaction.errors.add :base, "Invalid request."
|
62
62
|
end
|
63
63
|
end
|
64
64
|
end
|
@@ -101,18 +101,6 @@ class Samurai::Transaction < Samurai::Base
|
|
101
101
|
:description, :custom, :customer_reference, :billing_reference, :processor_response,
|
102
102
|
:descriptor_name, :descriptor_phone
|
103
103
|
]
|
104
|
-
|
105
|
-
# If we're using ActiveResource pre-3.1, there's no schema class method, so we resort to some tricks...
|
106
|
-
# Initialize the known attributes from the schema as empty strings, so that they can be accessed via method-missing
|
107
|
-
EMPTY_ATTRIBUTES = KNOWN_ATTRIBUTES.inject(HashWithIndifferentAccess.new) {|h, k| h[k] = ''; h}
|
108
|
-
def initialize(attrs={})
|
109
|
-
super(EMPTY_ATTRIBUTES.merge(attrs))
|
110
|
-
end
|
111
|
-
else
|
112
|
-
# Post AR 3.1, we can use the schema method to define our attributes
|
113
|
-
schema do
|
114
|
-
string *KNOWN_ATTRIBUTES
|
115
|
-
end
|
116
|
-
end
|
104
|
+
include Samurai::ActiveResourceSupport
|
117
105
|
|
118
106
|
end
|
data/lib/samurai/version.rb
CHANGED
data/samurai.gemspec
CHANGED
@@ -5,8 +5,8 @@ Gem::Specification.new do |s|
|
|
5
5
|
s.name = "samurai"
|
6
6
|
s.version = Samurai::VERSION.dup
|
7
7
|
s.platform = Gem::Platform::RUBY
|
8
|
-
s.authors = ["Graeme Rouse", "Derek Zak"]
|
9
|
-
s.email = ["graeme@ubergateway.com", "derek@ubergateway.com"]
|
8
|
+
s.authors = ["Joshua Krall", "Graeme Rouse", "Derek Zak"]
|
9
|
+
s.email = ["josh@feefighters.com", "graeme@ubergateway.com", "derek@ubergateway.com"]
|
10
10
|
s.homepage = "http://rubygems.org/gems/samurai"
|
11
11
|
s.summary = "Integration gem for samurai.feefighters.com"
|
12
12
|
s.description = "If you are an online merchant and using samurai.feefighters.com, this gem will make your life easy. Integrate with the samurai.feefighters.com portal and process transaction."
|
@@ -14,6 +14,7 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.required_rubygems_version = ">= 1.3.5"
|
15
15
|
# s.rubyforge_project = "samurai"
|
16
16
|
|
17
|
+
#s.add_dependency "activeresource", "~> 2.3" # use this line to test with activeresource 2.3.x
|
17
18
|
s.add_dependency "activeresource", ">= 2.2.2"
|
18
19
|
|
19
20
|
s.add_development_dependency "bundler", ">= 1.0.0"
|
@@ -28,4 +29,4 @@ Gem::Specification.new do |s|
|
|
28
29
|
s.files = `git ls-files`.split("\n")
|
29
30
|
s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
|
30
31
|
s.require_path = 'lib'
|
31
|
-
end
|
32
|
+
end
|
@@ -39,39 +39,39 @@ describe "PaymentMethod" do
|
|
39
39
|
it 'should return is_blank' do
|
40
40
|
pm = Samurai::PaymentMethod.create @params.merge(:card_number => '')
|
41
41
|
pm.is_sensitive_data_valid.should be_false
|
42
|
-
pm.
|
42
|
+
pm.should have_the_error('input.card_number', 'The card number was blank.')
|
43
43
|
end
|
44
44
|
it 'should return too_short' do
|
45
45
|
pm = Samurai::PaymentMethod.create @params.merge(:card_number => '4111-1')
|
46
46
|
pm.is_sensitive_data_valid.should be_false
|
47
|
-
pm.
|
47
|
+
pm.should have_the_error('input.card_number', 'The card number was too short.')
|
48
48
|
end
|
49
49
|
it 'should return too_long' do
|
50
50
|
pm = Samurai::PaymentMethod.create @params.merge(:card_number => '4111-1111-1111-1111-11')
|
51
51
|
pm.is_sensitive_data_valid.should be_false
|
52
|
-
pm.
|
52
|
+
pm.should have_the_error('input.card_number', 'The card number was too long.')
|
53
53
|
end
|
54
54
|
it 'should return failed_checksum' do
|
55
55
|
pm = Samurai::PaymentMethod.create @params.merge(:card_number => '4111-1111-1111-1234')
|
56
56
|
pm.is_sensitive_data_valid.should be_false
|
57
|
-
pm.
|
57
|
+
pm.should have_the_error('input.card_number', 'The card number was invalid.')
|
58
58
|
end
|
59
59
|
end
|
60
60
|
describe 'fail on input.cvv' do
|
61
61
|
it 'should return too_short' do
|
62
62
|
pm = Samurai::PaymentMethod.create @params.merge(:cvv => '1')
|
63
63
|
pm.is_sensitive_data_valid.should be_false
|
64
|
-
pm.
|
64
|
+
pm.should have_the_error('input.cvv', 'The CVV was too short.')
|
65
65
|
end
|
66
66
|
it 'should return too_long' do
|
67
67
|
pm = Samurai::PaymentMethod.create @params.merge(:cvv => '111111')
|
68
68
|
pm.is_sensitive_data_valid.should be_false
|
69
|
-
pm.
|
69
|
+
pm.should have_the_error('input.cvv', 'The CVV was too long.')
|
70
70
|
end
|
71
71
|
it 'should return not_numeric' do
|
72
72
|
pm = Samurai::PaymentMethod.create @params.merge(:cvv => 'abcd1')
|
73
73
|
pm.is_sensitive_data_valid.should be_false
|
74
|
-
pm.
|
74
|
+
pm.should have_the_error('input.cvv', 'The CVV was invalid.')
|
75
75
|
end
|
76
76
|
end
|
77
77
|
describe 'fail on input.expiry_month' do
|
@@ -79,13 +79,13 @@ describe "PaymentMethod" do
|
|
79
79
|
pm = Samurai::PaymentMethod.create @params.merge(:expiry_month => '')
|
80
80
|
pm.is_sensitive_data_valid.should be_true
|
81
81
|
pm.is_expiration_valid.should be_false
|
82
|
-
pm.
|
82
|
+
pm.should have_the_error('input.expiry_month', 'The expiration month was blank.')
|
83
83
|
end
|
84
84
|
it 'should return is_invalid' do
|
85
85
|
pm = Samurai::PaymentMethod.create @params.merge(:expiry_month => 'abcd')
|
86
86
|
pm.is_sensitive_data_valid.should be_true
|
87
87
|
pm.is_expiration_valid.should be_false
|
88
|
-
pm.
|
88
|
+
pm.should have_the_error('input.expiry_month', 'The expiration month was invalid.')
|
89
89
|
end
|
90
90
|
end
|
91
91
|
describe 'fail on input.expiry_year' do
|
@@ -93,13 +93,13 @@ describe "PaymentMethod" do
|
|
93
93
|
pm = Samurai::PaymentMethod.create @params.merge(:expiry_year => '')
|
94
94
|
pm.is_sensitive_data_valid.should be_true
|
95
95
|
pm.is_expiration_valid.should be_false
|
96
|
-
pm.
|
96
|
+
pm.should have_the_error('input.expiry_year', 'The expiration year was blank.')
|
97
97
|
end
|
98
98
|
it 'should return is_invalid' do
|
99
99
|
pm = Samurai::PaymentMethod.create @params.merge(:expiry_year => 'abcd')
|
100
100
|
pm.is_sensitive_data_valid.should be_true
|
101
101
|
pm.is_expiration_valid.should be_false
|
102
|
-
pm.
|
102
|
+
pm.should have_the_error('input.expiry_year', 'The expiration year was invalid.')
|
103
103
|
end
|
104
104
|
end
|
105
105
|
end
|
@@ -140,7 +140,7 @@ describe "PaymentMethod" do
|
|
140
140
|
end
|
141
141
|
it 'should be successful preserving sensitive data' do
|
142
142
|
_params = @params.merge({
|
143
|
-
:card_number => '
|
143
|
+
:card_number => '****-****-****-5454',
|
144
144
|
:cvv => '***',
|
145
145
|
})
|
146
146
|
@pm.update_attributes _params
|
@@ -163,29 +163,29 @@ describe "PaymentMethod" do
|
|
163
163
|
it 'should return too_short' do
|
164
164
|
@pm.update_attributes @params.merge(:card_number => '4111-1')
|
165
165
|
@pm.is_sensitive_data_valid.should be_false
|
166
|
-
@pm.
|
166
|
+
@pm.should have_the_error('input.card_number', 'The card number was too short.')
|
167
167
|
end
|
168
168
|
it 'should return too_long' do
|
169
169
|
@pm.update_attributes @params.merge(:card_number => '4111-1111-1111-1111-11')
|
170
170
|
@pm.is_sensitive_data_valid.should be_false
|
171
|
-
@pm.
|
171
|
+
@pm.should have_the_error('input.card_number', 'The card number was too long.')
|
172
172
|
end
|
173
173
|
it 'should return failed_checksum' do
|
174
174
|
@pm.update_attributes @params.merge(:card_number => '4111-1111-1111-1234')
|
175
175
|
@pm.is_sensitive_data_valid.should be_false
|
176
|
-
@pm.
|
176
|
+
@pm.should have_the_error('input.card_number', 'The card number was invalid.')
|
177
177
|
end
|
178
178
|
end
|
179
179
|
describe 'fail on input.cvv' do
|
180
180
|
it 'should return too_short' do
|
181
181
|
@pm.update_attributes @params.merge(:cvv => '1')
|
182
182
|
@pm.is_sensitive_data_valid.should be_false
|
183
|
-
@pm.
|
183
|
+
@pm.should have_the_error('input.cvv', 'The CVV was too short.')
|
184
184
|
end
|
185
185
|
it 'should return too_long' do
|
186
186
|
@pm.update_attributes @params.merge(:cvv => '111111')
|
187
187
|
@pm.is_sensitive_data_valid.should be_false
|
188
|
-
@pm.
|
188
|
+
@pm.should have_the_error('input.cvv', 'The CVV was too long.')
|
189
189
|
end
|
190
190
|
end
|
191
191
|
describe 'fail on input.expiry_month' do
|
@@ -193,13 +193,13 @@ describe "PaymentMethod" do
|
|
193
193
|
@pm.update_attributes @params.merge(:expiry_month => '')
|
194
194
|
@pm.is_sensitive_data_valid.should be_true
|
195
195
|
@pm.is_expiration_valid.should be_false
|
196
|
-
@pm.
|
196
|
+
@pm.should have_the_error('input.expiry_month', 'The expiration month was blank.')
|
197
197
|
end
|
198
198
|
it 'should return is_invalid' do
|
199
199
|
@pm.update_attributes @params.merge(:expiry_month => 'abcd')
|
200
200
|
@pm.is_sensitive_data_valid.should be_true
|
201
201
|
@pm.is_expiration_valid.should be_false
|
202
|
-
@pm.
|
202
|
+
@pm.should have_the_error('input.expiry_month', 'The expiration month was invalid.')
|
203
203
|
end
|
204
204
|
end
|
205
205
|
describe 'fail on input.expiry_year' do
|
@@ -207,13 +207,13 @@ describe "PaymentMethod" do
|
|
207
207
|
@pm.update_attributes @params.merge(:expiry_year => '')
|
208
208
|
@pm.is_sensitive_data_valid.should be_true
|
209
209
|
@pm.is_expiration_valid.should be_false
|
210
|
-
@pm.
|
210
|
+
@pm.should have_the_error('input.expiry_year', 'The expiration year was blank.')
|
211
211
|
end
|
212
212
|
it 'should return is_invalid' do
|
213
213
|
@pm.update_attributes @params.merge(:expiry_year => 'abcd')
|
214
214
|
@pm.is_sensitive_data_valid.should be_true
|
215
215
|
@pm.is_expiration_valid.should be_false
|
216
|
-
@pm.
|
216
|
+
@pm.should have_the_error('input.expiry_year', 'The expiration year was invalid.')
|
217
217
|
end
|
218
218
|
end
|
219
219
|
end
|
@@ -245,4 +245,60 @@ describe "PaymentMethod" do
|
|
245
245
|
end
|
246
246
|
end
|
247
247
|
|
248
|
+
describe '#redact' do
|
249
|
+
before do
|
250
|
+
@pm = Samurai::PaymentMethod.create(@params)
|
251
|
+
end
|
252
|
+
it 'should be successful' do
|
253
|
+
@pm.is_redacted.should be_false
|
254
|
+
@pm.redact
|
255
|
+
@pm.tap do |pm|
|
256
|
+
pm.is_redacted.should be_true
|
257
|
+
pm.is_sensitive_data_valid.should be_true
|
258
|
+
pm.is_expiration_valid.should be_true
|
259
|
+
pm.first_name.should == @params[:first_name]
|
260
|
+
pm.last_name.should == @params[:last_name]
|
261
|
+
pm.address_1.should == @params[:address_1]
|
262
|
+
pm.address_2.should == @params[:address_2]
|
263
|
+
pm.city.should == @params[:city]
|
264
|
+
pm.state.should == @params[:state]
|
265
|
+
pm.zip.should == @params[:zip]
|
266
|
+
pm.last_four_digits.should == @params[:card_number][-4, 4]
|
267
|
+
pm.expiry_month.should == @params[:expiry_month].to_i
|
268
|
+
pm.expiry_year.should == @params[:expiry_year].to_i
|
269
|
+
end
|
270
|
+
end
|
271
|
+
#it 'should not allow an authorize' do
|
272
|
+
# lambda do
|
273
|
+
# @pm.redact
|
274
|
+
# @authorize = Samurai::Processor.authorize(@pm.token, 100.0)
|
275
|
+
# end.should raise_error(ActiveResource::ResourceNotFound)
|
276
|
+
#end
|
277
|
+
end
|
278
|
+
|
279
|
+
describe '#retain' do
|
280
|
+
before do
|
281
|
+
@pm = Samurai::PaymentMethod.create(@params)
|
282
|
+
end
|
283
|
+
it 'should be successful' do
|
284
|
+
@pm.is_retained.should be_false
|
285
|
+
@pm.retain
|
286
|
+
@pm.tap do |pm|
|
287
|
+
pm.is_retained.should be_true
|
288
|
+
pm.is_sensitive_data_valid.should be_true
|
289
|
+
pm.is_expiration_valid.should be_true
|
290
|
+
pm.first_name.should == @params[:first_name]
|
291
|
+
pm.last_name.should == @params[:last_name]
|
292
|
+
pm.address_1.should == @params[:address_1]
|
293
|
+
pm.address_2.should == @params[:address_2]
|
294
|
+
pm.city.should == @params[:city]
|
295
|
+
pm.state.should == @params[:state]
|
296
|
+
pm.zip.should == @params[:zip]
|
297
|
+
pm.last_four_digits.should == @params[:card_number][-4, 4]
|
298
|
+
pm.expiry_month.should == @params[:expiry_month].to_i
|
299
|
+
pm.expiry_year.should == @params[:expiry_year].to_i
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
248
304
|
end
|
data/spec/lib/processor_spec.rb
CHANGED
@@ -44,12 +44,18 @@ describe "Processor" do
|
|
44
44
|
it 'should return processor.transaction - declined' do
|
45
45
|
purchase = Samurai::Processor.purchase(@payment_method_token, 1.02, :billing_reference=>rand(1000))
|
46
46
|
purchase.success.should be_false
|
47
|
-
purchase.
|
47
|
+
purchase.should have_the_error('processor.transaction', 'The card was declined.')
|
48
48
|
end
|
49
49
|
it 'should return input.amount - invalid' do
|
50
50
|
purchase = Samurai::Processor.purchase(@payment_method_token, 1.10, :billing_reference=>rand(1000))
|
51
51
|
purchase.success.should be_false
|
52
|
-
purchase.
|
52
|
+
purchase.should have_the_error('input.amount', 'The transaction amount was invalid.')
|
53
|
+
end
|
54
|
+
it 'should return invalid sandbox request' do
|
55
|
+
payment_method_token = create_payment_method(default_payment_method_params.merge('credit_card[card_number]'=>'4065054005873709'))[:payment_method_token]
|
56
|
+
purchase = Samurai::Processor.purchase(payment_method_token, 1.00, :billing_reference=>rand(1000))
|
57
|
+
purchase.success.should be_false
|
58
|
+
purchase.should have_the_error('base', 'Invalid request.')
|
53
59
|
end
|
54
60
|
end
|
55
61
|
describe 'cvv responses' do
|
@@ -128,12 +134,12 @@ describe "Processor" do
|
|
128
134
|
it 'should return processor.transaction - declined' do
|
129
135
|
authorize = Samurai::Processor.authorize(@payment_method_token, 1.02, :billing_reference=>rand(1000))
|
130
136
|
authorize.success.should be_false
|
131
|
-
authorize.
|
137
|
+
authorize.should have_the_error('processor.transaction', 'The card was declined.')
|
132
138
|
end
|
133
139
|
it 'should return input.amount - invalid' do
|
134
140
|
authorize = Samurai::Processor.authorize(@payment_method_token, 1.10, :billing_reference=>rand(1000))
|
135
141
|
authorize.success.should be_false
|
136
|
-
authorize.
|
142
|
+
authorize.should have_the_error('input.amount', 'The transaction amount was invalid.')
|
137
143
|
end
|
138
144
|
end
|
139
145
|
describe 'cvv responses' do
|
@@ -29,19 +29,19 @@ describe "Transaction" do
|
|
29
29
|
auth = Samurai::Processor.authorize(@payment_method_token, 100.02) # declined auth
|
30
30
|
capture = auth.capture
|
31
31
|
capture.success.should be_false
|
32
|
-
capture.
|
32
|
+
capture.should have_the_error('processor.transaction', 'This transaction type is not allowed.')
|
33
33
|
end
|
34
34
|
it 'should return processor.transaction - declined' do
|
35
35
|
auth = Samurai::Processor.authorize(@payment_method_token, 100.00)
|
36
36
|
capture = auth.capture(100.02)
|
37
37
|
capture.success.should be_false
|
38
|
-
capture.
|
38
|
+
capture.should have_the_error('processor.transaction', 'The card was declined.')
|
39
39
|
end
|
40
40
|
it 'should return input.amount - invalid' do
|
41
41
|
auth = Samurai::Processor.authorize(@payment_method_token, 100.00)
|
42
42
|
capture = auth.capture(100.10)
|
43
43
|
capture.success.should be_false
|
44
|
-
capture.
|
44
|
+
capture.should have_the_error('input.amount', 'The transaction amount was invalid.')
|
45
45
|
end
|
46
46
|
end
|
47
47
|
end
|
@@ -78,7 +78,7 @@ describe "Transaction" do
|
|
78
78
|
purchase = Samurai::Processor.purchase(@payment_method_token, 100.00)
|
79
79
|
reverse = purchase.reverse(100.10)
|
80
80
|
reverse.success.should be_false
|
81
|
-
reverse.
|
81
|
+
reverse.should have_the_error('input.amount', 'The transaction amount was invalid.')
|
82
82
|
end
|
83
83
|
end
|
84
84
|
end
|
@@ -115,7 +115,7 @@ describe "Transaction" do
|
|
115
115
|
purchase = Samurai::Processor.purchase(@payment_method_token, 100.00)
|
116
116
|
credit = purchase.credit(100.10)
|
117
117
|
credit.success.should be_false
|
118
|
-
credit.
|
118
|
+
credit.should have_the_error('input.amount', 'The transaction amount was invalid.')
|
119
119
|
end
|
120
120
|
end
|
121
121
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
RSpec::Matchers.define :have_the_error do |key, expected|
|
2
|
+
match do |actual|
|
3
|
+
[actual.errors[key]].flatten.include?(expected)
|
4
|
+
end
|
5
|
+
failure_message_for_should do |actual|
|
6
|
+
"expected that #{actual.errors[key].inspect} would have the error #{expected.inspect}"
|
7
|
+
end
|
8
|
+
|
9
|
+
failure_message_for_should_not do |actual|
|
10
|
+
"expected that #{actual.errors[key].inspect} would not have the error '#{expected.inspect}'"
|
11
|
+
end
|
12
|
+
|
13
|
+
description do
|
14
|
+
"have the error #{key.inspect} - #{expected.inspect}"
|
15
|
+
end
|
16
|
+
end
|
@@ -15,6 +15,11 @@ module TransparentRedirectHelper
|
|
15
15
|
res = Net::HTTP.new(uri.host, uri.port)
|
16
16
|
res.use_ssl = true
|
17
17
|
|
18
|
+
puts "---------------------------------------"
|
19
|
+
puts "-- #{uri.inspect} "
|
20
|
+
puts "-- Body:\n#{req.body}"
|
21
|
+
puts "--------"
|
22
|
+
|
18
23
|
response = res.start {|http| http.request(req) }
|
19
24
|
{
|
20
25
|
:payment_method_token => response['Location'] && response['Location'].sub(%r{#{Regexp.escape params['redirect_url']}\?payment_method_token=}, ''),
|
metadata
CHANGED
@@ -1,20 +1,21 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: samurai
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
|
+
- Joshua Krall
|
8
9
|
- Graeme Rouse
|
9
10
|
- Derek Zak
|
10
11
|
autorequire:
|
11
12
|
bindir: bin
|
12
13
|
cert_chain: []
|
13
|
-
date:
|
14
|
+
date: 2012-02-06 00:00:00.000000000Z
|
14
15
|
dependencies:
|
15
16
|
- !ruby/object:Gem::Dependency
|
16
17
|
name: activeresource
|
17
|
-
requirement: &
|
18
|
+
requirement: &70338889701400 !ruby/object:Gem::Requirement
|
18
19
|
none: false
|
19
20
|
requirements:
|
20
21
|
- - ! '>='
|
@@ -22,10 +23,10 @@ dependencies:
|
|
22
23
|
version: 2.2.2
|
23
24
|
type: :runtime
|
24
25
|
prerelease: false
|
25
|
-
version_requirements: *
|
26
|
+
version_requirements: *70338889701400
|
26
27
|
- !ruby/object:Gem::Dependency
|
27
28
|
name: bundler
|
28
|
-
requirement: &
|
29
|
+
requirement: &70338889700940 !ruby/object:Gem::Requirement
|
29
30
|
none: false
|
30
31
|
requirements:
|
31
32
|
- - ! '>='
|
@@ -33,10 +34,10 @@ dependencies:
|
|
33
34
|
version: 1.0.0
|
34
35
|
type: :development
|
35
36
|
prerelease: false
|
36
|
-
version_requirements: *
|
37
|
+
version_requirements: *70338889700940
|
37
38
|
- !ruby/object:Gem::Dependency
|
38
39
|
name: rspec
|
39
|
-
requirement: &
|
40
|
+
requirement: &70338889700480 !ruby/object:Gem::Requirement
|
40
41
|
none: false
|
41
42
|
requirements:
|
42
43
|
- - ! '>='
|
@@ -44,10 +45,10 @@ dependencies:
|
|
44
45
|
version: 2.6.0
|
45
46
|
type: :development
|
46
47
|
prerelease: false
|
47
|
-
version_requirements: *
|
48
|
+
version_requirements: *70338889700480
|
48
49
|
- !ruby/object:Gem::Dependency
|
49
50
|
name: fakeweb
|
50
|
-
requirement: &
|
51
|
+
requirement: &70338889700080 !ruby/object:Gem::Requirement
|
51
52
|
none: false
|
52
53
|
requirements:
|
53
54
|
- - ! '>='
|
@@ -55,10 +56,10 @@ dependencies:
|
|
55
56
|
version: '0'
|
56
57
|
type: :development
|
57
58
|
prerelease: false
|
58
|
-
version_requirements: *
|
59
|
+
version_requirements: *70338889700080
|
59
60
|
- !ruby/object:Gem::Dependency
|
60
61
|
name: ruby-debug19
|
61
|
-
requirement: &
|
62
|
+
requirement: &70338889699580 !ruby/object:Gem::Requirement
|
62
63
|
none: false
|
63
64
|
requirements:
|
64
65
|
- - ! '>='
|
@@ -66,11 +67,12 @@ dependencies:
|
|
66
67
|
version: '0'
|
67
68
|
type: :development
|
68
69
|
prerelease: false
|
69
|
-
version_requirements: *
|
70
|
+
version_requirements: *70338889699580
|
70
71
|
description: If you are an online merchant and using samurai.feefighters.com, this
|
71
72
|
gem will make your life easy. Integrate with the samurai.feefighters.com portal
|
72
73
|
and process transaction.
|
73
74
|
email:
|
75
|
+
- josh@feefighters.com
|
74
76
|
- graeme@ubergateway.com
|
75
77
|
- derek@ubergateway.com
|
76
78
|
executables: []
|
@@ -88,6 +90,7 @@ files:
|
|
88
90
|
- app/views/application/_payment_form.html.erb
|
89
91
|
- app/views/application/_transaction.html.erb
|
90
92
|
- lib/samurai.rb
|
93
|
+
- lib/samurai/active_resource_support.rb
|
91
94
|
- lib/samurai/base.rb
|
92
95
|
- lib/samurai/cacheable_by_token.rb
|
93
96
|
- lib/samurai/message.rb
|
@@ -105,6 +108,7 @@ files:
|
|
105
108
|
- spec/lib/processor_spec.rb
|
106
109
|
- spec/lib/transaction_spec.rb
|
107
110
|
- spec/spec_helper.rb
|
111
|
+
- spec/support/custom_matchers.rb
|
108
112
|
- spec/support/transaction_seed.rb
|
109
113
|
- spec/support/transparent_redirect_helper.rb
|
110
114
|
homepage: http://rubygems.org/gems/samurai
|