fake_braintree 0.0.4 → 0.0.5
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/.gitignore +1 -0
- data/Changelog.md +3 -0
- data/README.md +11 -7
- data/lib/fake_braintree.rb +4 -81
- data/lib/fake_braintree/customer.rb +67 -0
- data/lib/fake_braintree/helpers.rb +19 -0
- data/lib/fake_braintree/sinatra_app.rb +17 -115
- data/lib/fake_braintree/subscription.rb +21 -0
- data/lib/fake_braintree/version.rb +1 -1
- data/spec/fake_braintree/credit_card_spec.rb +32 -0
- data/spec/fake_braintree/customer_spec.rb +92 -0
- data/spec/fake_braintree/subscription_spec.rb +56 -0
- metadata +26 -20
- data/spec/fake_braintree/sinatra_app_spec.rb +0 -126
- data/tags +0 -28
data/.gitignore
CHANGED
data/Changelog.md
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# fake\_braintree, a Braintree fake
|
2
2
|
|
3
|
-
Currently in alpha.
|
4
|
-
be added.
|
3
|
+
Currently in alpha.
|
5
4
|
|
6
5
|
## Quick start
|
7
6
|
Call `FakeBraintree.activate!` to make it go. `FakeBraintree.clear!` will clear
|
@@ -19,10 +18,15 @@ Example, in spec\_helper.rb:
|
|
19
18
|
|
20
19
|
## Verifying credit cards
|
21
20
|
|
22
|
-
To verify every credit card you try to use, call
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
21
|
+
To verify every credit card you try to use, call:
|
22
|
+
|
23
|
+
FakeBraintree.verify_all_cards!
|
24
|
+
|
25
|
+
This will stay "on" until you set
|
26
|
+
|
27
|
+
FakeBraintree.verify_all_cards = false
|
28
|
+
|
29
|
+
Calling FakeBraintree.clear! _will not_ change this setting. It does very basic
|
30
|
+
verification: it only matches the credit card number against these:
|
27
31
|
http://www.braintreepayments.com/docs/ruby/reference/sandbox and rejects them if
|
28
32
|
they aren't one of the listed numbers.
|
data/lib/fake_braintree.rb
CHANGED
@@ -2,6 +2,10 @@ require 'fileutils'
|
|
2
2
|
require 'braintree'
|
3
3
|
require 'sham_rack'
|
4
4
|
|
5
|
+
require 'fake_braintree/helpers'
|
6
|
+
require 'fake_braintree/customer'
|
7
|
+
require 'fake_braintree/subscription'
|
8
|
+
|
5
9
|
require 'fake_braintree/sinatra_app'
|
6
10
|
require 'fake_braintree/valid_credit_cards'
|
7
11
|
require 'fake_braintree/version'
|
@@ -92,87 +96,6 @@ module FakeBraintree
|
|
92
96
|
return card if card
|
93
97
|
end
|
94
98
|
end
|
95
|
-
|
96
|
-
def self.generated_transaction
|
97
|
-
{"status_history"=>[{"timestamp"=>Time.now,
|
98
|
-
"amount"=>FakeBraintree.transaction[:amount],
|
99
|
-
"transaction_source"=>"CP",
|
100
|
-
"user"=>"copycopter",
|
101
|
-
"status"=>"authorized"},
|
102
|
-
{"timestamp"=>Time.now,
|
103
|
-
"amount"=>FakeBraintree.transaction[:amount],
|
104
|
-
"transaction_source"=>"CP",
|
105
|
-
"user"=>"copycopter",
|
106
|
-
"status"=>FakeBraintree.transaction[:status]}],
|
107
|
-
"created_at"=>(FakeBraintree.transaction[:created_at] || Time.now),
|
108
|
-
"currency_iso_code"=>"USD",
|
109
|
-
"settlement_batch_id"=>nil,
|
110
|
-
"processor_authorization_code"=>"ZKB4VJ",
|
111
|
-
"avs_postal_code_response_code"=>"I",
|
112
|
-
"order_id"=>nil,
|
113
|
-
"updated_at"=>Time.now,
|
114
|
-
"refunded_transaction_id"=>nil,
|
115
|
-
"amount"=>FakeBraintree.transaction[:amount],
|
116
|
-
"credit_card"=>{"last_4"=>"1111",
|
117
|
-
"card_type"=>"Visa",
|
118
|
-
"token"=>"8yq7",
|
119
|
-
"customer_location"=>"US",
|
120
|
-
"expiration_year"=>"2013",
|
121
|
-
"expiration_month"=>"02",
|
122
|
-
"bin"=>"411111",
|
123
|
-
"cardholder_name"=>"Chad Lee Pytel"
|
124
|
-
},
|
125
|
-
"refund_id"=>nil,
|
126
|
-
"add_ons"=>[],
|
127
|
-
"shipping"=>{"region"=>nil,
|
128
|
-
"company"=>nil,
|
129
|
-
"country_name"=>nil,
|
130
|
-
"extended_address"=>nil,
|
131
|
-
"postal_code"=>nil,
|
132
|
-
"id"=>nil,
|
133
|
-
"street_address"=>nil,
|
134
|
-
"country_code_numeric"=>nil,
|
135
|
-
"last_name"=>nil,
|
136
|
-
"locality"=>nil,
|
137
|
-
"country_code_alpha2"=>nil,
|
138
|
-
"country_code_alpha3"=>nil,
|
139
|
-
"first_name"=>nil},
|
140
|
-
"id"=>"49sbx6",
|
141
|
-
"merchant_account_id"=>"Thoughtbot",
|
142
|
-
"type"=>"sale",
|
143
|
-
"cvv_response_code"=>"I",
|
144
|
-
"subscription_id"=>FakeBraintree.transaction[:subscription_id],
|
145
|
-
"custom_fields"=>"\n",
|
146
|
-
"discounts"=>[],
|
147
|
-
"billing"=>{"region"=>nil,
|
148
|
-
"company"=>nil,
|
149
|
-
"country_name"=>nil,
|
150
|
-
"extended_address"=>nil,
|
151
|
-
"postal_code"=>nil,
|
152
|
-
"id"=>nil,
|
153
|
-
"street_address"=>nil,
|
154
|
-
"country_code_numeric"=>nil,
|
155
|
-
"last_name"=>nil,
|
156
|
-
"locality"=>nil,
|
157
|
-
"country_code_alpha2"=>nil,
|
158
|
-
"country_code_alpha3"=>nil,
|
159
|
-
"first_name"=>nil},
|
160
|
-
"processor_response_code"=>"1000",
|
161
|
-
"refund_ids"=>[],
|
162
|
-
"customer"=>{"company"=>nil,
|
163
|
-
"id"=>"108427",
|
164
|
-
"last_name"=>nil,
|
165
|
-
"fax"=>nil,
|
166
|
-
"phone"=>nil,
|
167
|
-
"website"=>nil,
|
168
|
-
"first_name"=>nil,
|
169
|
-
"email"=>"cpytel@thoughtbot.com" },
|
170
|
-
"avs_error_response_code"=>nil,
|
171
|
-
"processor_response_text"=>"Approved",
|
172
|
-
"avs_street_address_response_code"=>"I",
|
173
|
-
"status"=>FakeBraintree.transaction[:status],
|
174
|
-
"gateway_rejection_reason"=>nil}
|
175
|
-
end
|
176
99
|
end
|
177
100
|
|
178
101
|
FakeBraintree.activate!
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module FakeBraintree
|
2
|
+
class Customer
|
3
|
+
include Helpers
|
4
|
+
|
5
|
+
def initialize(request, merchant_id)
|
6
|
+
@request_hash = Hash.from_xml(request.body).delete("customer")
|
7
|
+
@merchant_id = merchant_id
|
8
|
+
end
|
9
|
+
|
10
|
+
def invalid?
|
11
|
+
credit_card_is_failure? || invalid_credit_card?
|
12
|
+
end
|
13
|
+
|
14
|
+
def failure_response
|
15
|
+
gzipped_response(422, FakeBraintree.failure_response(@request_hash["credit_card"]["number"]).to_xml(:root => 'api_error_response'))
|
16
|
+
end
|
17
|
+
|
18
|
+
def customer_hash
|
19
|
+
hash = @request_hash.dup
|
20
|
+
hash["id"] ||= create_id
|
21
|
+
hash["merchant-id"] = @merchant_id
|
22
|
+
if hash["credit_card"] && hash["credit_card"].is_a?(Hash)
|
23
|
+
hash["credit_card"].delete("__content__")
|
24
|
+
if !hash["credit_card"].empty?
|
25
|
+
hash["credit_card"]["last_4"] = hash["credit_card"].delete("number")[-4..-1]
|
26
|
+
hash["credit_card"]["token"] = md5("#{hash['merchant_id']}#{hash['id']}")
|
27
|
+
expiration_date = hash["credit_card"].delete("expiration_date")
|
28
|
+
hash["credit_card"]["expiration_month"] = expiration_date.split('/')[0]
|
29
|
+
hash["credit_card"]["expiration_year"] = expiration_date.split('/')[1]
|
30
|
+
|
31
|
+
credit_card = hash.delete("credit_card")
|
32
|
+
hash["credit_cards"] = [credit_card]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
hash
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def create_id
|
42
|
+
md5("#{@merchant_id}#{Time.now.to_f}")
|
43
|
+
end
|
44
|
+
|
45
|
+
def credit_card_is_failure?
|
46
|
+
@request_hash.key?('credit_card') &&
|
47
|
+
FakeBraintree.failure?(@request_hash["credit_card"]["number"])
|
48
|
+
end
|
49
|
+
|
50
|
+
def invalid_credit_card?
|
51
|
+
verify_credit_card?(@request_hash) && has_invalid_credit_card?(@request_hash)
|
52
|
+
end
|
53
|
+
|
54
|
+
def verify_credit_card?(customer_hash)
|
55
|
+
return true if FakeBraintree.verify_all_cards
|
56
|
+
|
57
|
+
@request_hash.key?("credit_card") &&
|
58
|
+
@request_hash["credit_card"].key?("options") &&
|
59
|
+
@request_hash["credit_card"]["options"].is_a?(Hash) &&
|
60
|
+
@request_hash["credit_card"]["options"]["verify_card"] == true
|
61
|
+
end
|
62
|
+
|
63
|
+
def has_invalid_credit_card?(customer_hash)
|
64
|
+
! FakeBraintree::VALID_CREDIT_CARDS.include?(@request_hash["credit_card"]["number"])
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
require 'active_support'
|
3
|
+
require 'active_support/core_ext'
|
4
|
+
|
5
|
+
module FakeBraintree
|
6
|
+
module Helpers
|
7
|
+
def gzip(content)
|
8
|
+
ActiveSupport::Gzip.compress(content)
|
9
|
+
end
|
10
|
+
|
11
|
+
def gzipped_response(status_code, uncompressed_content)
|
12
|
+
[status_code, { "Content-Encoding" => "gzip" }, gzip(uncompressed_content)]
|
13
|
+
end
|
14
|
+
|
15
|
+
def md5(content)
|
16
|
+
Digest::MD5.hexdigest(content)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,7 +1,4 @@
|
|
1
|
-
require '
|
2
|
-
require 'sinatra'
|
3
|
-
require 'active_support'
|
4
|
-
require 'active_support/core_ext'
|
1
|
+
require 'sinatra/base'
|
5
2
|
|
6
3
|
module FakeBraintree
|
7
4
|
class SinatraApp < Sinatra::Base
|
@@ -10,105 +7,36 @@ module FakeBraintree
|
|
10
7
|
set :raise_errors, true
|
11
8
|
disable :logging
|
12
9
|
|
13
|
-
|
14
|
-
def gzip(content)
|
15
|
-
ActiveSupport::Gzip.compress(content)
|
16
|
-
end
|
17
|
-
|
18
|
-
def gzipped_response(status_code, uncompressed_content)
|
19
|
-
[status_code, { "Content-Encoding" => "gzip" }, gzip(uncompressed_content)]
|
20
|
-
end
|
21
|
-
|
22
|
-
def md5(content)
|
23
|
-
Digest::MD5.hexdigest(content)
|
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
|
37
|
-
end
|
10
|
+
include Helpers
|
38
11
|
|
39
12
|
# Braintree::Customer.create
|
40
13
|
post "/merchants/:merchant_id/customers" do
|
41
|
-
customer =
|
42
|
-
if
|
43
|
-
|
14
|
+
customer = Customer.new(request, params[:merchant_id])
|
15
|
+
if customer.invalid?
|
16
|
+
customer.failure_response
|
44
17
|
else
|
45
|
-
|
46
|
-
|
47
|
-
|
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
|
62
|
-
end
|
63
|
-
FakeBraintree.customers[customer["id"]] = customer
|
64
|
-
gzipped_response(201, customer.to_xml(:root => 'customer'))
|
65
|
-
end
|
18
|
+
customer_hash = customer.customer_hash
|
19
|
+
FakeBraintree.customers[customer_hash["id"]] = customer_hash
|
20
|
+
gzipped_response(201, customer_hash.to_xml(:root => 'customer'))
|
66
21
|
end
|
67
22
|
end
|
68
23
|
|
24
|
+
# Braintree::Customer.find
|
69
25
|
get "/merchants/:merchant_id/customers/:id" do
|
70
26
|
customer = FakeBraintree.customers[params[:id]]
|
71
|
-
|
72
|
-
end
|
73
|
-
|
74
|
-
put "/merchants/:merchant_id/customers/:id" do
|
75
|
-
customer = Hash.from_xml(request.body).delete("customer")
|
76
|
-
if FakeBraintree.failure?(customer["credit_card"]["number"])
|
77
|
-
gzipped_response(422, FakeBraintree.failure_response(customer["credit_card"]["number"]).to_xml(:root => 'api_error_response'))
|
78
|
-
else
|
79
|
-
customer["id"] = params[:id]
|
80
|
-
customer["merchant-id"] = params[:merchant_id]
|
81
|
-
if customer["credit_card"] && customer["credit_card"].is_a?(Hash)
|
82
|
-
customer["credit_card"].delete("__content__")
|
83
|
-
if !customer["credit_card"].empty?
|
84
|
-
customer["credit_card"]["last_4"] = customer["credit_card"].delete("number")[-4..-1]
|
85
|
-
customer["credit_card"]["token"] = md5("#{customer['merchant_id']}#{customer['id']}#{Time.now.to_f}")
|
86
|
-
credit_card = customer.delete("credit_card")
|
87
|
-
customer["credit_cards"] = [credit_card]
|
88
|
-
end
|
89
|
-
end
|
90
|
-
FakeBraintree.customers[params["id"]] = customer
|
27
|
+
if customer
|
91
28
|
gzipped_response(200, customer.to_xml(:root => 'customer'))
|
29
|
+
else
|
30
|
+
gzipped_response(404, {})
|
92
31
|
end
|
93
32
|
end
|
94
33
|
|
95
|
-
delete "/merchants/:merchant_id/customers/:id" do
|
96
|
-
FakeBraintree.customers[params["id"]] = nil
|
97
|
-
gzipped_response(200, "")
|
98
|
-
end
|
99
|
-
|
100
34
|
# Braintree::Subscription.create
|
101
35
|
post "/merchants/:merchant_id/subscriptions" do
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
subscription
|
106
|
-
subscription["add_ons"] = []
|
107
|
-
subscription["discounts"] = []
|
108
|
-
subscription["next_billing_date"] = 1.month.from_now
|
109
|
-
subscription["status"] = Braintree::Subscription::Status::Active
|
110
|
-
FakeBraintree.subscriptions[subscription["id"]] = subscription
|
111
|
-
gzipped_response(201, subscription.to_xml(:root => 'subscription'))
|
36
|
+
response_hash = Subscription.new(request).response_hash
|
37
|
+
|
38
|
+
FakeBraintree.subscriptions[response_hash["id"]] = response_hash
|
39
|
+
gzipped_response(201, response_hash.to_xml(:root => 'subscription'))
|
112
40
|
end
|
113
41
|
|
114
42
|
# Braintree::Subscription.find
|
@@ -121,33 +49,7 @@ module FakeBraintree
|
|
121
49
|
end
|
122
50
|
end
|
123
51
|
|
124
|
-
|
125
|
-
subscription = Hash.from_xml(request.body).delete("subscription")
|
126
|
-
subscription["transactions"] = []
|
127
|
-
subscription["add_ons"] = []
|
128
|
-
subscription["discounts"] = []
|
129
|
-
FakeBraintree.subscriptions[params["id"]] = subscription
|
130
|
-
gzipped_response(200, subscription.to_xml(:root => 'subscription'))
|
131
|
-
end
|
132
|
-
|
133
|
-
# Braintree::Transaction.search
|
134
|
-
post "/merchants/:merchant_id/transactions/advanced_search_ids" do
|
135
|
-
# "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<search>\n <created-at>\n <min type=\"datetime\">2011-01-10T14:14:26Z</min>\n </created-at>\n</search>\n"
|
136
|
-
gzipped_response(200,
|
137
|
-
['<search-results>',
|
138
|
-
' <page-size type="integer">50</page-size>',
|
139
|
-
' <ids type="array">',
|
140
|
-
' <item>49sbx6</item>',
|
141
|
-
' </ids>',
|
142
|
-
"</search-results>\n"].join("\n"))
|
143
|
-
end
|
144
|
-
|
145
|
-
# Braintree::Transaction.search
|
146
|
-
post "/merchants/:merchant_id/transactions/advanced_search" do
|
147
|
-
# "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<search>\n <ids type=\"array\">\n <item>49sbx6</item>\n </ids>\n <created-at>\n <min type=\"datetime\">2011-01-10T14:14:26Z</min>\n </created-at>\n</search>\n"
|
148
|
-
gzipped_response(200, FakeBraintree.generated_transaction.to_xml)
|
149
|
-
end
|
150
|
-
|
52
|
+
# Braintree::CreditCard.find
|
151
53
|
get "/merchants/:merchant_id/payment_methods/:credit_card_token" do
|
152
54
|
credit_card = FakeBraintree.credit_card_from_token(params[:credit_card_token])
|
153
55
|
gzipped_response(200, credit_card.to_xml(:root => "credit_card"))
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module FakeBraintree
|
2
|
+
class Subscription
|
3
|
+
include Helpers
|
4
|
+
|
5
|
+
def initialize(request)
|
6
|
+
@subscription_hash = Hash.from_xml(request.body).delete("subscription")
|
7
|
+
end
|
8
|
+
|
9
|
+
def response_hash
|
10
|
+
response_hash = {}
|
11
|
+
response_hash["id"] = md5("#{@subscription_hash["payment_method_token"]}#{Time.now.to_f}")[0,6]
|
12
|
+
response_hash["transactions"] = []
|
13
|
+
response_hash["add_ons"] = []
|
14
|
+
response_hash["discounts"] = []
|
15
|
+
response_hash["next_billing_date"] = 1.month.from_now
|
16
|
+
response_hash["status"] = Braintree::Subscription::Status::Active
|
17
|
+
|
18
|
+
response_hash
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe FakeBraintree::SinatraApp do
|
4
|
+
context "Braintree::CreditCard.find" do
|
5
|
+
let(:cc_number) { %w(4111 1111 1111 9876).join }
|
6
|
+
let(:expiration_date) { "04/2016" }
|
7
|
+
let(:token) { braintree_credit_card_token(cc_number, expiration_date) }
|
8
|
+
|
9
|
+
it "gets the correct credit card" do
|
10
|
+
credit_card = Braintree::CreditCard.find(token)
|
11
|
+
|
12
|
+
credit_card.last_4.should == "9876"
|
13
|
+
credit_card.expiration_year.should == "2016"
|
14
|
+
credit_card.expiration_month.should == "04"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context "Braintree::CreditCard.sale" do
|
19
|
+
let(:cc_number) { %w(4111 1111 1111 9876).join }
|
20
|
+
let(:expiration_date) { "04/2016" }
|
21
|
+
let(:token) { braintree_credit_card_token(cc_number, expiration_date) }
|
22
|
+
let(:amount) { 10.00 }
|
23
|
+
|
24
|
+
it "successfully creates a sale" do
|
25
|
+
result = Braintree::CreditCard.sale(token, amount: amount, options: {submit_for_settlement: true})
|
26
|
+
result.should be_success
|
27
|
+
|
28
|
+
Braintree::Transaction.find(result.transaction.id).should be
|
29
|
+
lambda { Braintree::Transaction.find("foo") }.should raise_error(Braintree::NotFoundError)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Braintree::Customer.create" do
|
4
|
+
let(:cc_number) { %w(4111 1111 1111 1111).join }
|
5
|
+
let(:expiration_date) { "04/2016" }
|
6
|
+
after { FakeBraintree.verify_all_cards = false }
|
7
|
+
|
8
|
+
def create_customer_with_credit_card(options)
|
9
|
+
Braintree::Customer.create(:credit_card => options)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "successfully creates a customer" do
|
13
|
+
result = create_customer_with_credit_card(:number => cc_number,
|
14
|
+
:expiration_date => expiration_date)
|
15
|
+
result.should be_success
|
16
|
+
end
|
17
|
+
|
18
|
+
it "records the billing address" do
|
19
|
+
result = create_customer_with_credit_card(
|
20
|
+
:number => cc_number,
|
21
|
+
:expiration_date => expiration_date,
|
22
|
+
:billing_address => {
|
23
|
+
:street_address => "1 E Main St",
|
24
|
+
:extended_address => "Suite 3",
|
25
|
+
:locality => "Chicago",
|
26
|
+
:region => "Illinois",
|
27
|
+
:postal_code => "60622",
|
28
|
+
:country_code_alpha2 => "US"
|
29
|
+
}
|
30
|
+
)
|
31
|
+
|
32
|
+
billing_address = result.customer.credit_cards[0].billing_address
|
33
|
+
|
34
|
+
billing_address.street_address.should == "1 E Main St"
|
35
|
+
billing_address.postal_code.should == "60622"
|
36
|
+
end
|
37
|
+
|
38
|
+
context "when passed :verify_card => true" do
|
39
|
+
it "accepts valid cards" do
|
40
|
+
create_customer_with_credit_card(
|
41
|
+
:number => cc_number,
|
42
|
+
:expiration_date => expiration_date,
|
43
|
+
:options => { :verify_card => true }
|
44
|
+
).should be_success
|
45
|
+
end
|
46
|
+
|
47
|
+
it "rejects invalid cards" do
|
48
|
+
create_customer_with_credit_card(
|
49
|
+
:number => '123456',
|
50
|
+
:expiration_date => expiration_date,
|
51
|
+
:options => { :verify_card => true }
|
52
|
+
).should_not be_success
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "when FakeBraintree.verify_all_cards == true" do
|
57
|
+
before { FakeBraintree.verify_all_cards! }
|
58
|
+
|
59
|
+
it "accepts valid cards" do
|
60
|
+
create_customer_with_credit_card(
|
61
|
+
:number => cc_number,
|
62
|
+
:expiration_date => expiration_date
|
63
|
+
).should be_success
|
64
|
+
end
|
65
|
+
|
66
|
+
it "rejects invalid cards" do
|
67
|
+
create_customer_with_credit_card(
|
68
|
+
:number => '123456',
|
69
|
+
:expiration_date => expiration_date
|
70
|
+
).should_not be_success
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "Braintree::Customer.find" do
|
76
|
+
let(:cc_number) { %w(4111 1111 1111 1111).join }
|
77
|
+
let(:expiration_date) { "04/2016" }
|
78
|
+
|
79
|
+
def create_customer(options)
|
80
|
+
Braintree::Customer.create(:credit_card => options)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "successfully finds a customer" do
|
84
|
+
result = Braintree::Customer.create(:first_name => "Bob", :last_name => "Smith")
|
85
|
+
|
86
|
+
Braintree::Customer.find(result.customer.id).first_name.should == "Bob"
|
87
|
+
end
|
88
|
+
|
89
|
+
it "raises an error for a nonexistent customer" do
|
90
|
+
lambda { Braintree::Customer.find("foo") }.should raise_error(Braintree::NotFoundError)
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe FakeBraintree::SinatraApp do
|
4
|
+
context "Braintree::Subscription.create" do
|
5
|
+
let(:plan_id) { 'plan-id-from-braintree-control-panel' }
|
6
|
+
let(:cc_number) { %w(4111 1111 1111 9876).join }
|
7
|
+
let(:expiration_date) { "04/2016" }
|
8
|
+
let(:payment_method_token) { braintree_credit_card_token(cc_number, expiration_date) }
|
9
|
+
let(:payment_method_token_2) { braintree_credit_card_token(cc_number.sub('1', '5'), expiration_date) }
|
10
|
+
|
11
|
+
it "successfully creates a subscription" do
|
12
|
+
result = Braintree::Subscription.create(:payment_method_token => payment_method_token,
|
13
|
+
:plan_id => plan_id)
|
14
|
+
result.should be_success
|
15
|
+
end
|
16
|
+
|
17
|
+
it "assigns a Braintree-esque ID to the subscription" do
|
18
|
+
result = Braintree::Subscription.create(:payment_method_token => payment_method_token,
|
19
|
+
:plan_id => plan_id)
|
20
|
+
|
21
|
+
result.subscription.id.should =~ /^[a-z0-9]{6}$/
|
22
|
+
end
|
23
|
+
|
24
|
+
it "assigns unique IDs to each subscription" do
|
25
|
+
first_result = Braintree::Subscription.create(:payment_method_token => payment_method_token,
|
26
|
+
:plan_id => plan_id)
|
27
|
+
second_result = Braintree::Subscription.create(:payment_method_token => payment_method_token_2,
|
28
|
+
:plan_id => plan_id)
|
29
|
+
|
30
|
+
first_result.subscription.id.should_not == second_result.subscription.id
|
31
|
+
end
|
32
|
+
|
33
|
+
it "sets the next billing date to 1 month from now in UTC" do
|
34
|
+
result = Braintree::Subscription.create(:payment_method_token => payment_method_token,
|
35
|
+
:plan_id => plan_id)
|
36
|
+
|
37
|
+
result.subscription.next_billing_date.to_i.should == 1.month.from_now.utc.to_i
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "Braintree::Subscription.find" do
|
42
|
+
let(:cc_number) { %w(4111 1111 1111 9876).join }
|
43
|
+
let(:expiration_date) { "04/2016" }
|
44
|
+
let(:payment_method_token) { braintree_credit_card_token(cc_number, expiration_date) }
|
45
|
+
let(:subscription_result) { Braintree::Subscription.create(:payment_method_token => payment_method_token,
|
46
|
+
:plan_id => 'my-plan-id') }
|
47
|
+
|
48
|
+
it "can find a created subscription" do
|
49
|
+
Braintree::Subscription.find(subscription_result.subscription.id).should be
|
50
|
+
end
|
51
|
+
|
52
|
+
it "raises a Braintree:NotFoundError when it cannot find a subscription" do
|
53
|
+
expect { Braintree::Subscription.find('abc123') }.to raise_error(Braintree::NotFoundError, /abc123/)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
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.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
12
|
+
date: 2011-11-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: sham_rack
|
16
|
-
requirement: &
|
16
|
+
requirement: &70312449445460 !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: *70312449445460
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: activesupport
|
27
|
-
requirement: &
|
27
|
+
requirement: &70312449445040 !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: *70312449445040
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: i18n
|
38
|
-
requirement: &
|
38
|
+
requirement: &70312449444620 !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: *70312449444620
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: sinatra
|
49
|
-
requirement: &
|
49
|
+
requirement: &70312460820820 !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: *70312460820820
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: braintree
|
60
|
-
requirement: &
|
60
|
+
requirement: &70312460820320 !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: *70312460820320
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rspec
|
71
|
-
requirement: &
|
71
|
+
requirement: &70312460819820 !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: *70312460819820
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: mocha
|
82
|
-
requirement: &
|
82
|
+
requirement: &70312460819360 !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: *70312460819360
|
91
91
|
description: A fake Braintree that you can run integration tests against
|
92
92
|
email:
|
93
93
|
- gabe@thoughtbot.com
|
@@ -103,14 +103,18 @@ files:
|
|
103
103
|
- Rakefile
|
104
104
|
- fake_braintree.gemspec
|
105
105
|
- lib/fake_braintree.rb
|
106
|
+
- lib/fake_braintree/customer.rb
|
107
|
+
- lib/fake_braintree/helpers.rb
|
106
108
|
- lib/fake_braintree/sinatra_app.rb
|
109
|
+
- lib/fake_braintree/subscription.rb
|
107
110
|
- lib/fake_braintree/valid_credit_cards.rb
|
108
111
|
- lib/fake_braintree/version.rb
|
109
|
-
- spec/fake_braintree/
|
112
|
+
- spec/fake_braintree/credit_card_spec.rb
|
113
|
+
- spec/fake_braintree/customer_spec.rb
|
114
|
+
- spec/fake_braintree/subscription_spec.rb
|
110
115
|
- spec/fake_braintree_spec.rb
|
111
116
|
- spec/spec_helper.rb
|
112
117
|
- spec/support/braintree_helpers.rb
|
113
|
-
- tags
|
114
118
|
homepage: ''
|
115
119
|
licenses: []
|
116
120
|
post_install_message:
|
@@ -131,12 +135,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
131
135
|
version: '0'
|
132
136
|
requirements: []
|
133
137
|
rubyforge_project:
|
134
|
-
rubygems_version: 1.8.
|
138
|
+
rubygems_version: 1.8.10
|
135
139
|
signing_key:
|
136
140
|
specification_version: 3
|
137
141
|
summary: A fake Braintree that you can run integration tests against
|
138
142
|
test_files:
|
139
|
-
- spec/fake_braintree/
|
143
|
+
- spec/fake_braintree/credit_card_spec.rb
|
144
|
+
- spec/fake_braintree/customer_spec.rb
|
145
|
+
- spec/fake_braintree/subscription_spec.rb
|
140
146
|
- spec/fake_braintree_spec.rb
|
141
147
|
- spec/spec_helper.rb
|
142
148
|
- spec/support/braintree_helpers.rb
|
@@ -1,126 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module FakeBraintree
|
4
|
-
describe SinatraApp, "Braintree::CreditCard.find" do
|
5
|
-
let(:cc_number) { %w(4111 1111 1111 9876).join }
|
6
|
-
let(:expiration_date) { "04/2016" }
|
7
|
-
let(:token) { braintree_credit_card_token(cc_number, expiration_date) }
|
8
|
-
|
9
|
-
it "gets the correct credit card" do
|
10
|
-
credit_card = Braintree::CreditCard.find(token)
|
11
|
-
|
12
|
-
credit_card.last_4.should == "9876"
|
13
|
-
credit_card.expiration_year.should == "2016"
|
14
|
-
credit_card.expiration_month.should == "04"
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
describe SinatraApp, "Braintree::CreditCard.sale" do
|
19
|
-
let(:cc_number) { %w(4111 1111 1111 9876).join }
|
20
|
-
let(:expiration_date) { "04/2016" }
|
21
|
-
let(:token) { braintree_credit_card_token(cc_number, expiration_date) }
|
22
|
-
let(:amount) { 10.00 }
|
23
|
-
|
24
|
-
it "successfully creates a sale" do
|
25
|
-
result = Braintree::CreditCard.sale(token, amount: amount, options: {submit_for_settlement: true})
|
26
|
-
result.should be_success
|
27
|
-
|
28
|
-
Braintree::Transaction.find(result.transaction.id).should be
|
29
|
-
lambda { Braintree::Transaction.find("foo") }.should raise_error(Braintree::NotFoundError)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
describe SinatraApp, "Braintree::Subscription.create" do
|
34
|
-
let(:plan_id) { 'plan-id-from-braintree-control-panel' }
|
35
|
-
let(:cc_number) { %w(4111 1111 1111 9876).join }
|
36
|
-
let(:expiration_date) { "04/2016" }
|
37
|
-
let(:payment_method_token) { braintree_credit_card_token(cc_number, expiration_date) }
|
38
|
-
let(:payment_method_token_2) { braintree_credit_card_token(cc_number.sub('1', '5'), expiration_date) }
|
39
|
-
|
40
|
-
it "successfully creates a subscription" do
|
41
|
-
result = Braintree::Subscription.create(:payment_method_token => payment_method_token,
|
42
|
-
:plan_id => plan_id)
|
43
|
-
result.should be_success
|
44
|
-
end
|
45
|
-
|
46
|
-
it "assigns a Braintree-esque ID to the subscription" do
|
47
|
-
result = Braintree::Subscription.create(:payment_method_token => payment_method_token,
|
48
|
-
:plan_id => plan_id)
|
49
|
-
|
50
|
-
result.subscription.id.should =~ /^[a-z0-9]{6}$/
|
51
|
-
end
|
52
|
-
|
53
|
-
it "assigns unique IDs to each subscription" do
|
54
|
-
first_result = Braintree::Subscription.create(:payment_method_token => payment_method_token,
|
55
|
-
:plan_id => plan_id)
|
56
|
-
second_result = Braintree::Subscription.create(:payment_method_token => payment_method_token_2,
|
57
|
-
:plan_id => plan_id)
|
58
|
-
|
59
|
-
first_result.subscription.id.should_not == second_result.subscription.id
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
describe SinatraApp, "Braintree::Subscription.find" do
|
64
|
-
let(:cc_number) { %w(4111 1111 1111 9876).join }
|
65
|
-
let(:expiration_date) { "04/2016" }
|
66
|
-
let(:payment_method_token) { braintree_credit_card_token(cc_number, expiration_date) }
|
67
|
-
let(:subscription_result) { Braintree::Subscription.create(:payment_method_token => payment_method_token,
|
68
|
-
:plan_id => 'my-plan-id') }
|
69
|
-
|
70
|
-
it "can find a created subscription" do
|
71
|
-
Braintree::Subscription.find(subscription_result.subscription.id).should be
|
72
|
-
end
|
73
|
-
|
74
|
-
it "raises a Braintree:NotFoundError when it cannot find a subscription" do
|
75
|
-
expect { Braintree::Subscription.find('abc123') }.to raise_error(Braintree::NotFoundError, /abc123/)
|
76
|
-
end
|
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
|
126
|
-
end
|
data/tags
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
|
2
|
-
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
|
3
|
-
!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/
|
4
|
-
!_TAG_PROGRAM_NAME Exuberant Ctags //
|
5
|
-
!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
|
6
|
-
!_TAG_PROGRAM_VERSION 5.8 //
|
7
|
-
BraintreeHelpers /Users/gabe/thoughtbot/fake_braintree/spec/support/braintree_helpers.rb /^module BraintreeHelpers$/;" m
|
8
|
-
FakeBraintree /Users/gabe/thoughtbot/fake_braintree/lib/fake_braintree.rb /^module FakeBraintree$/;" m
|
9
|
-
FakeBraintree /Users/gabe/thoughtbot/fake_braintree/lib/fake_braintree/sinatra_app.rb /^module FakeBraintree$/;" m
|
10
|
-
FakeBraintree /Users/gabe/thoughtbot/fake_braintree/lib/fake_braintree/version.rb /^module FakeBraintree$/;" m
|
11
|
-
FakeBraintree /Users/gabe/thoughtbot/fake_braintree/spec/fake_braintree/sinatra_app_spec.rb /^module FakeBraintree$/;" m
|
12
|
-
SinatraApp /Users/gabe/thoughtbot/fake_braintree/lib/fake_braintree/sinatra_app.rb /^ class SinatraApp < Sinatra::Base$/;" c class:FakeBraintree
|
13
|
-
activate /Users/gabe/thoughtbot/fake_braintree/lib/fake_braintree.rb /^ def self.activate!$/;" F
|
14
|
-
braintree_credit_card_token /Users/gabe/thoughtbot/fake_braintree/spec/support/braintree_helpers.rb /^ def braintree_credit_card_token(cc_number, expiration_date)$/;" f class:BraintreeHelpers
|
15
|
-
clear /Users/gabe/thoughtbot/fake_braintree/lib/fake_braintree.rb /^ def self.clear!$/;" F
|
16
|
-
clear_log /Users/gabe/thoughtbot/fake_braintree/lib/fake_braintree.rb /^ def self.clear_log!$/;" F
|
17
|
-
create_braintree_customer /Users/gabe/thoughtbot/fake_braintree/spec/support/braintree_helpers.rb /^ def create_braintree_customer(cc_number, expiration_date)$/;" f class:BraintreeHelpers
|
18
|
-
create_failure /Users/gabe/thoughtbot/fake_braintree/lib/fake_braintree.rb /^ def self.create_failure$/;" F
|
19
|
-
credit_card_from_token /Users/gabe/thoughtbot/fake_braintree/lib/fake_braintree.rb /^ def self.credit_card_from_token(token)$/;" F
|
20
|
-
decline_all_cards /Users/gabe/thoughtbot/fake_braintree/lib/fake_braintree.rb /^ def self.decline_all_cards!$/;" F
|
21
|
-
decline_all_cards /Users/gabe/thoughtbot/fake_braintree/lib/fake_braintree.rb /^ def self.decline_all_cards?$/;" F
|
22
|
-
failure /Users/gabe/thoughtbot/fake_braintree/lib/fake_braintree.rb /^ def self.failure?(card_number)$/;" F
|
23
|
-
failure_response /Users/gabe/thoughtbot/fake_braintree/lib/fake_braintree.rb /^ def self.failure_response(card_number)$/;" F
|
24
|
-
generated_transaction /Users/gabe/thoughtbot/fake_braintree/lib/fake_braintree.rb /^ def self.generated_transaction$/;" F
|
25
|
-
gzip /Users/gabe/thoughtbot/fake_braintree/lib/fake_braintree/sinatra_app.rb /^ def gzip(content)$/;" f class:FakeBraintree.SinatraApp
|
26
|
-
gzipped_response /Users/gabe/thoughtbot/fake_braintree/lib/fake_braintree/sinatra_app.rb /^ def gzipped_response(status_code, uncompressed_content)$/;" f class:FakeBraintree.SinatraApp
|
27
|
-
log_file_path /Users/gabe/thoughtbot/fake_braintree/lib/fake_braintree.rb /^ def self.log_file_path$/;" F
|
28
|
-
md5 /Users/gabe/thoughtbot/fake_braintree/lib/fake_braintree/sinatra_app.rb /^ def md5(content)$/;" f class:FakeBraintree.SinatraApp
|