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