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 CHANGED
@@ -3,3 +3,4 @@
3
3
  Gemfile.lock
4
4
  pkg/*
5
5
  tmp/
6
+ tags
@@ -1,3 +1,6 @@
1
+ # 0.0.5
2
+ * Add support for Braintree::Customer.find
3
+
1
4
  # 0.0.4
2
5
  * Allow for very basic card verification
3
6
 
data/README.md CHANGED
@@ -1,7 +1,6 @@
1
1
  # fake\_braintree, a Braintree fake
2
2
 
3
- Currently in alpha. Needs complete test coverage, then more functionality can
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
- `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:
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.
@@ -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 'digest/md5'
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
- helpers do
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 = Hash.from_xml(request.body).delete("customer")
42
- if FakeBraintree.failure?(customer["credit_card"]["number"])
43
- gzipped_response(422, FakeBraintree.failure_response(customer["credit_card"]["number"]).to_xml(:root => 'api_error_response'))
14
+ customer = Customer.new(request, params[:merchant_id])
15
+ if customer.invalid?
16
+ customer.failure_response
44
17
  else
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
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
- gzipped_response(200, customer.to_xml(:root => 'customer'))
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
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<subscription>\n <plan-id type=\"integer\">2</plan-id>\n <payment-method-token>b22x</payment-method-token>\n</subscription>\n"
103
- subscription = Hash.from_xml(request.body).delete("subscription")
104
- subscription["id"] ||= md5("#{subscription["payment_method_token"]}#{Time.now.to_f}")[0,6]
105
- subscription["transactions"] = []
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
- put "/merchants/:merchant_id/subscriptions/:id" do
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
@@ -1,3 +1,3 @@
1
1
  module FakeBraintree
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  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
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-10-24 00:00:00.000000000Z
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: &70166836515360 !ruby/object:Gem::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: *70166836515360
24
+ version_requirements: *70312449445460
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: activesupport
27
- requirement: &70166836511340 !ruby/object:Gem::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: *70166836511340
35
+ version_requirements: *70312449445040
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: i18n
38
- requirement: &70166836500660 !ruby/object:Gem::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: *70166836500660
46
+ version_requirements: *70312449444620
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: sinatra
49
- requirement: &70166836498100 !ruby/object:Gem::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: *70166836498100
57
+ version_requirements: *70312460820820
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: braintree
60
- requirement: &70166836491540 !ruby/object:Gem::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: *70166836491540
68
+ version_requirements: *70312460820320
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec
71
- requirement: &70166836489720 !ruby/object:Gem::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: *70166836489720
79
+ version_requirements: *70312460819820
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: mocha
82
- requirement: &70166836488220 !ruby/object:Gem::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: *70166836488220
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/sinatra_app_spec.rb
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.11
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/sinatra_app_spec.rb
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