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 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'
@@ -9,20 +9,20 @@ GIT
9
9
  PATH
10
10
  remote: .
11
11
  specs:
12
- samurai (0.2.29)
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.1.1)
19
- activesupport (= 3.1.1)
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.3)
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
@@ -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
- if [ActiveResource::VERSION::MAJOR, ActiveResource::VERSION::MINOR].compact.join('.').to_f < 3.1
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[:base] << 'The card number or CVV are not valid.' if !pm.is_sensitive_data_valid
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
@@ -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[:base] << "Invalid request."
81
+ transaction.errors.add :base, "Invalid request."
82
82
  end
83
83
  end
84
84
  end
@@ -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[:base] << "Invalid request."
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
- if [ActiveResource::VERSION::MAJOR, ActiveResource::VERSION::MINOR].compact.join('.').to_f < 3.1
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
@@ -1,3 +1,3 @@
1
1
  module Samurai
2
- VERSION = "0.3.0".freeze
2
+ VERSION = "0.4.0".freeze
3
3
  end
@@ -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.errors['input.card_number'].should == [ 'The card number was blank.' ]
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.errors['input.card_number'].should == [ 'The card number was too short.' ]
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.errors['input.card_number'].should == [ 'The card number was too long.' ]
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.errors['input.card_number'].should == [ 'The card number was invalid.' ]
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.errors['input.cvv'].should == [ 'The CVV was too short.' ]
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.errors['input.cvv'].should == [ 'The CVV was too long.' ]
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.errors['input.cvv'].should == [ 'The CVV was invalid.' ]
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.errors['input.expiry_month'].should == [ 'The expiration month was blank.' ]
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.errors['input.expiry_month'].should == [ 'The expiration month was invalid.' ]
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.errors['input.expiry_year'].should == [ 'The expiration year was blank.' ]
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.errors['input.expiry_year'].should == [ 'The expiration year was invalid.' ]
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.errors['input.card_number'].should == [ 'The card number was too short.' ]
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.errors['input.card_number'].should == [ 'The card number was too long.' ]
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.errors['input.card_number'].should == [ 'The card number was invalid.' ]
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.errors['input.cvv'].should == [ 'The CVV was too short.' ]
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.errors['input.cvv'].should == [ 'The CVV was too long.' ]
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.errors['input.expiry_month'].should == [ 'The expiration month was blank.' ]
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.errors['input.expiry_month'].should == [ 'The expiration month was invalid.' ]
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.errors['input.expiry_year'].should == [ 'The expiration year was blank.' ]
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.errors['input.expiry_year'].should == [ 'The expiration year was invalid.' ]
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
@@ -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.errors['processor.transaction'].should == [ 'The card was declined.' ]
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.errors['input.amount'].should == [ 'The transaction amount was invalid.' ]
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.errors['processor.transaction'].should == [ 'The card was declined.' ]
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.errors['input.amount'].should == [ 'The transaction amount was invalid.' ]
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.errors['processor.transaction'].should == [ 'This transaction type is not allowed.' ]
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.errors['processor.transaction'].should == [ 'The card was declined.' ]
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.errors['input.amount'].should == [ 'The transaction amount was invalid.' ]
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.errors['input.amount'].should == [ 'The transaction amount was invalid.' ]
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.errors['input.amount'].should == [ 'The transaction amount was invalid.' ]
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.3.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: 2011-12-22 00:00:00.000000000Z
14
+ date: 2012-02-06 00:00:00.000000000Z
14
15
  dependencies:
15
16
  - !ruby/object:Gem::Dependency
16
17
  name: activeresource
17
- requirement: &70265074098340 !ruby/object:Gem::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: *70265074098340
26
+ version_requirements: *70338889701400
26
27
  - !ruby/object:Gem::Dependency
27
28
  name: bundler
28
- requirement: &70265074097660 !ruby/object:Gem::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: *70265074097660
37
+ version_requirements: *70338889700940
37
38
  - !ruby/object:Gem::Dependency
38
39
  name: rspec
39
- requirement: &70265074096960 !ruby/object:Gem::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: *70265074096960
48
+ version_requirements: *70338889700480
48
49
  - !ruby/object:Gem::Dependency
49
50
  name: fakeweb
50
- requirement: &70265074096580 !ruby/object:Gem::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: *70265074096580
59
+ version_requirements: *70338889700080
59
60
  - !ruby/object:Gem::Dependency
60
61
  name: ruby-debug19
61
- requirement: &70265074095780 !ruby/object:Gem::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: *70265074095780
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