fake_braintree 0.0.3 → 0.0.4
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/Changelog.md +9 -0
- data/README.md +23 -1
- data/lib/fake_braintree.rb +8 -2
- data/lib/fake_braintree/sinatra_app.rb +31 -15
- data/lib/fake_braintree/valid_credit_cards.rb +9 -0
- data/lib/fake_braintree/version.rb +1 -1
- data/spec/fake_braintree/sinatra_app_spec.rb +49 -1
- data/spec/fake_braintree_spec.rb +17 -0
- metadata +17 -15
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
|
-
|
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.
|
data/lib/fake_braintree.rb
CHANGED
@@ -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
|
-
|
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
|
34
|
-
|
35
|
-
|
36
|
-
customer["
|
37
|
-
|
38
|
-
|
39
|
-
customer["credit_card"]
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
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
|
@@ -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 =>
|
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
|
data/spec/fake_braintree_spec.rb
CHANGED
@@ -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.
|
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: &
|
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: *
|
24
|
+
version_requirements: *70166836515360
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: activesupport
|
27
|
-
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: *
|
35
|
+
version_requirements: *70166836511340
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: i18n
|
38
|
-
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: *
|
46
|
+
version_requirements: *70166836500660
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: sinatra
|
49
|
-
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: *
|
57
|
+
version_requirements: *70166836498100
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: braintree
|
60
|
-
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: *
|
68
|
+
version_requirements: *70166836491540
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rspec
|
71
|
-
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: *
|
79
|
+
version_requirements: *70166836489720
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: mocha
|
82
|
-
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: *
|
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
|