samurai 0.3.0 → 0.4.0
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.
- 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
|