fake_braintree 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/Changelog.md ADDED
@@ -0,0 +1,9 @@
1
+ # 0.0.4
2
+ * Allow for very basic card verification
3
+
4
+ # 0.0.3
5
+ * Ensure FakeBraintree.log_file_path directory exists
6
+ * The FakeBraintree.log_file_path attribute can now be read (it could only be set before)
7
+ * Clear log when FakeBraintree.clear! is called
8
+ * Correctly handle nonexistent subscriptions when using
9
+ Braintree::Subscription.find
data/README.md CHANGED
@@ -3,4 +3,26 @@
3
3
  Currently in alpha. Needs complete test coverage, then more functionality can
4
4
  be added.
5
5
 
6
- Call FakeBraintree.activate! to make it go.
6
+ ## Quick start
7
+ Call `FakeBraintree.activate!` to make it go. `FakeBraintree.clear!` will clear
8
+ all data, which you probably want to do before each test.
9
+
10
+ Example, in spec\_helper.rb:
11
+
12
+ FakeBraintree.activate!
13
+
14
+ RSpec.configure do |c|
15
+ c.before do
16
+ FakeBraintree.clear!
17
+ end
18
+ end
19
+
20
+ ## Verifying credit cards
21
+
22
+ To verify every credit card you try to use, call
23
+ `FakeBraintree.verify\_all\_cards!`. This will stay "on" until you set
24
+ `FakeBraintree.verify_all_cards = false`. Calling FakeBraintree.clear! _will
25
+ not_ change it. It does very basic verification: it only matches the credit card
26
+ number against these:
27
+ http://www.braintreepayments.com/docs/ruby/reference/sandbox and rejects them if
28
+ they aren't one of the listed numbers.
@@ -3,6 +3,7 @@ require 'braintree'
3
3
  require 'sham_rack'
4
4
 
5
5
  require 'fake_braintree/sinatra_app'
6
+ require 'fake_braintree/valid_credit_cards'
6
7
  require 'fake_braintree/version'
7
8
 
8
9
  module FakeBraintree
@@ -13,7 +14,8 @@ module FakeBraintree
13
14
  @transaction = {}
14
15
 
15
16
  @decline_all_cards = false
16
- attr_accessor :customers, :subscriptions, :failures, :transaction, :decline_all_cards
17
+ @verify_all_cards = false
18
+ attr_accessor :customers, :subscriptions, :failures, :transaction, :decline_all_cards, :verify_all_cards
17
19
  end
18
20
 
19
21
  def self.activate!
@@ -48,7 +50,7 @@ module FakeBraintree
48
50
  end
49
51
 
50
52
  def self.failure_response(card_number)
51
- failure = self.failures[card_number]
53
+ failure = self.failures[card_number] || {}
52
54
  failure["errors"] ||= { "errors" => [] }
53
55
 
54
56
  { "message" => failure["message"],
@@ -78,6 +80,10 @@ module FakeBraintree
78
80
  self.decline_all_cards
79
81
  end
80
82
 
83
+ def self.verify_all_cards!
84
+ self.verify_all_cards = true
85
+ end
86
+
81
87
  def self.credit_card_from_token(token)
82
88
  self.customers.values.detect do |customer|
83
89
  next unless customer.key?("credit_cards")
@@ -22,6 +22,18 @@ module FakeBraintree
22
22
  def md5(content)
23
23
  Digest::MD5.hexdigest(content)
24
24
  end
25
+
26
+ def verify_credit_card?(customer_hash)
27
+ return true if FakeBraintree.verify_all_cards
28
+
29
+ customer_hash["credit_card"].key?("options") &&
30
+ customer_hash["credit_card"]["options"].is_a?(Hash) &&
31
+ customer_hash["credit_card"]["options"]["verify_card"] == true
32
+ end
33
+
34
+ def has_invalid_credit_card?(customer_hash)
35
+ ! FakeBraintree::VALID_CREDIT_CARDS.include?(customer_hash["credit_card"]["number"])
36
+ end
25
37
  end
26
38
 
27
39
  # Braintree::Customer.create
@@ -30,23 +42,27 @@ module FakeBraintree
30
42
  if FakeBraintree.failure?(customer["credit_card"]["number"])
31
43
  gzipped_response(422, FakeBraintree.failure_response(customer["credit_card"]["number"]).to_xml(:root => 'api_error_response'))
32
44
  else
33
- customer["id"] ||= md5("#{params[:merchant_id]}#{Time.now.to_f}")
34
- customer["merchant-id"] = params[:merchant_id]
35
- if customer["credit_card"] && customer["credit_card"].is_a?(Hash)
36
- customer["credit_card"].delete("__content__")
37
- if !customer["credit_card"].empty?
38
- customer["credit_card"]["last_4"] = customer["credit_card"].delete("number")[-4..-1]
39
- customer["credit_card"]["token"] = md5("#{customer['merchant_id']}#{customer['id']}#{Time.now.to_f}")
40
- expiration_date = customer["credit_card"].delete("expiration_date")
41
- customer["credit_card"]["expiration_month"] = expiration_date.split('/')[0]
42
- customer["credit_card"]["expiration_year"] = expiration_date.split('/')[1]
43
-
44
- credit_card = customer.delete("credit_card")
45
- customer["credit_cards"] = [credit_card]
45
+ if verify_credit_card?(customer) && has_invalid_credit_card?(customer)
46
+ gzipped_response(422, FakeBraintree.failure_response(customer["credit_card"]["number"]).to_xml(:root => 'api_error_response'))
47
+ else
48
+ customer["id"] ||= md5("#{params[:merchant_id]}#{Time.now.to_f}")
49
+ customer["merchant-id"] = params[:merchant_id]
50
+ if customer["credit_card"] && customer["credit_card"].is_a?(Hash)
51
+ customer["credit_card"].delete("__content__")
52
+ if !customer["credit_card"].empty?
53
+ customer["credit_card"]["last_4"] = customer["credit_card"].delete("number")[-4..-1]
54
+ customer["credit_card"]["token"] = md5("#{customer['merchant_id']}#{customer['id']}#{Time.now.to_f}")
55
+ expiration_date = customer["credit_card"].delete("expiration_date")
56
+ customer["credit_card"]["expiration_month"] = expiration_date.split('/')[0]
57
+ customer["credit_card"]["expiration_year"] = expiration_date.split('/')[1]
58
+
59
+ credit_card = customer.delete("credit_card")
60
+ customer["credit_cards"] = [credit_card]
61
+ end
46
62
  end
63
+ FakeBraintree.customers[customer["id"]] = customer
64
+ gzipped_response(201, customer.to_xml(:root => 'customer'))
47
65
  end
48
- FakeBraintree.customers[customer["id"]] = customer
49
- gzipped_response(201, customer.to_xml(:root => 'customer'))
50
66
  end
51
67
  end
52
68
 
@@ -0,0 +1,9 @@
1
+ module FakeBraintree
2
+ VALID_CREDIT_CARDS = %w(4111111111111111 4005519200000004
3
+ 4009348888881881 4012000033330026
4
+ 4012000077777777 4012888888881881
5
+ 4217651111111119 4500600000000061
6
+ 5555555555554444 378282246310005
7
+ 371449635398431 6011111111111117
8
+ 3530111333300000)
9
+ end
@@ -1,3 +1,3 @@
1
1
  module FakeBraintree
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -65,7 +65,7 @@ module FakeBraintree
65
65
  let(:expiration_date) { "04/2016" }
66
66
  let(:payment_method_token) { braintree_credit_card_token(cc_number, expiration_date) }
67
67
  let(:subscription_result) { Braintree::Subscription.create(:payment_method_token => payment_method_token,
68
- :plan_id => plan_id) }
68
+ :plan_id => 'my-plan-id') }
69
69
 
70
70
  it "can find a created subscription" do
71
71
  Braintree::Subscription.find(subscription_result.subscription.id).should be
@@ -75,4 +75,52 @@ module FakeBraintree
75
75
  expect { Braintree::Subscription.find('abc123') }.to raise_error(Braintree::NotFoundError, /abc123/)
76
76
  end
77
77
  end
78
+
79
+ describe SinatraApp, "Braintree::Customer.create" do
80
+ let(:cc_number) { %w(4111 1111 1111 1111).join }
81
+ let(:expiration_date) { "04/2016" }
82
+ after { FakeBraintree.verify_all_cards = false }
83
+
84
+ it "successfully creates a customer" do
85
+ result = Braintree::Customer.create(
86
+ :credit_card => {
87
+ :number => cc_number,
88
+ :expiration_date => expiration_date
89
+ })
90
+
91
+ result.should be_success
92
+ end
93
+
94
+ it "verifies the card number when passed :verify_card => true" do
95
+ Braintree::Customer.create(
96
+ :credit_card => {
97
+ :number => cc_number,
98
+ :expiration_date => expiration_date,
99
+ :options => { :verify_card => true }
100
+ }).should be_success
101
+
102
+ Braintree::Customer.create(
103
+ :credit_card => {
104
+ :number => '123456',
105
+ :expiration_date => expiration_date,
106
+ :options => { :verify_card => true }
107
+ }).should_not be_success
108
+ end
109
+
110
+ it "verifies the card number when FakeBraintree.verify_all_cards == true" do
111
+ FakeBraintree.verify_all_cards!
112
+
113
+ Braintree::Customer.create(
114
+ :credit_card => {
115
+ :number => cc_number,
116
+ :expiration_date => expiration_date
117
+ }).should be_success
118
+
119
+ Braintree::Customer.create(
120
+ :credit_card => {
121
+ :number => '123456',
122
+ :expiration_date => expiration_date
123
+ }).should_not be_success
124
+ end
125
+ end
78
126
  end
@@ -84,3 +84,20 @@ describe FakeBraintree, ".clear_log!" do
84
84
  FakeBraintree.clear!
85
85
  end
86
86
  end
87
+
88
+ describe FakeBraintree, "VALID_CREDIT_CARDS" do
89
+ let(:valid_credit_cards) do
90
+ %w(4111111111111111 4005519200000004
91
+ 4009348888881881 4012000033330026
92
+ 4012000077777777 4012888888881881
93
+ 4217651111111119 4500600000000061
94
+ 5555555555554444 378282246310005
95
+ 371449635398431 6011111111111117
96
+ 3530111333300000
97
+ )
98
+ end
99
+
100
+ it "includes only credit cards that are valid in production" do
101
+ FakeBraintree::VALID_CREDIT_CARDS.sort.should == valid_credit_cards.sort
102
+ end
103
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fake_braintree
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2011-10-24 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sham_rack
16
- requirement: &70234757701580 !ruby/object:Gem::Requirement
16
+ requirement: &70166836515360 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70234757701580
24
+ version_requirements: *70166836515360
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: activesupport
27
- requirement: &70234757700380 !ruby/object:Gem::Requirement
27
+ requirement: &70166836511340 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70234757700380
35
+ version_requirements: *70166836511340
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: i18n
38
- requirement: &70234757699160 !ruby/object:Gem::Requirement
38
+ requirement: &70166836500660 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70234757699160
46
+ version_requirements: *70166836500660
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: sinatra
49
- requirement: &70234757698720 !ruby/object:Gem::Requirement
49
+ requirement: &70166836498100 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70234757698720
57
+ version_requirements: *70166836498100
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: braintree
60
- requirement: &70234757698120 !ruby/object:Gem::Requirement
60
+ requirement: &70166836491540 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '2.5'
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *70234757698120
68
+ version_requirements: *70166836491540
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec
71
- requirement: &70234757697400 !ruby/object:Gem::Requirement
71
+ requirement: &70166836489720 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ~>
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: 2.6.0
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70234757697400
79
+ version_requirements: *70166836489720
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: mocha
82
- requirement: &70234757696880 !ruby/object:Gem::Requirement
82
+ requirement: &70166836488220 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ~>
@@ -87,7 +87,7 @@ dependencies:
87
87
  version: 0.9.12
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *70234757696880
90
+ version_requirements: *70166836488220
91
91
  description: A fake Braintree that you can run integration tests against
92
92
  email:
93
93
  - gabe@thoughtbot.com
@@ -97,12 +97,14 @@ extensions: []
97
97
  extra_rdoc_files: []
98
98
  files:
99
99
  - .gitignore
100
+ - Changelog.md
100
101
  - Gemfile
101
102
  - README.md
102
103
  - Rakefile
103
104
  - fake_braintree.gemspec
104
105
  - lib/fake_braintree.rb
105
106
  - lib/fake_braintree/sinatra_app.rb
107
+ - lib/fake_braintree/valid_credit_cards.rb
106
108
  - lib/fake_braintree/version.rb
107
109
  - spec/fake_braintree/sinatra_app_spec.rb
108
110
  - spec/fake_braintree_spec.rb