fake_braintree 0.0.2 → 0.0.3

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.
@@ -1,11 +1,10 @@
1
+ require 'fileutils'
1
2
  require 'braintree'
2
3
  require 'sham_rack'
3
4
 
4
5
  require 'fake_braintree/sinatra_app'
5
6
  require 'fake_braintree/version'
6
7
 
7
- Braintree::Configuration.logger = Logger.new("tmp/log")
8
-
9
8
  module FakeBraintree
10
9
  class << self
11
10
  @customers = {}
@@ -26,12 +25,22 @@ module FakeBraintree
26
25
  ShamRack.mount(FakeBraintree::SinatraApp, "www.braintreegateway.com", 443)
27
26
  end
28
27
 
28
+ def self.log_file_path
29
+ 'tmp/log'
30
+ end
31
+
29
32
  def self.clear!
30
33
  self.customers = {}
31
34
  self.subscriptions = {}
32
35
  self.failures = {}
33
36
  self.transaction = {}
34
37
  self.decline_all_cards = false
38
+ clear_log!
39
+ end
40
+
41
+ def self.clear_log!
42
+ FileUtils.mkdir_p(File.dirname(log_file_path))
43
+ File.new(log_file_path, 'w').close
35
44
  end
36
45
 
37
46
  def self.failure?(card_number)
@@ -161,3 +170,4 @@ module FakeBraintree
161
170
  end
162
171
 
163
172
  FakeBraintree.activate!
173
+ Braintree::Configuration.logger = Logger.new(FakeBraintree.log_file_path)
@@ -18,20 +18,25 @@ module FakeBraintree
18
18
  def gzipped_response(status_code, uncompressed_content)
19
19
  [status_code, { "Content-Encoding" => "gzip" }, gzip(uncompressed_content)]
20
20
  end
21
+
22
+ def md5(content)
23
+ Digest::MD5.hexdigest(content)
24
+ end
21
25
  end
22
26
 
27
+ # Braintree::Customer.create
23
28
  post "/merchants/:merchant_id/customers" do
24
29
  customer = Hash.from_xml(request.body).delete("customer")
25
30
  if FakeBraintree.failure?(customer["credit_card"]["number"])
26
31
  gzipped_response(422, FakeBraintree.failure_response(customer["credit_card"]["number"]).to_xml(:root => 'api_error_response'))
27
32
  else
28
- customer["id"] ||= Digest::MD5.hexdigest("#{params[:merchant_id]}#{Time.now.to_f}")
33
+ customer["id"] ||= md5("#{params[:merchant_id]}#{Time.now.to_f}")
29
34
  customer["merchant-id"] = params[:merchant_id]
30
35
  if customer["credit_card"] && customer["credit_card"].is_a?(Hash)
31
36
  customer["credit_card"].delete("__content__")
32
37
  if !customer["credit_card"].empty?
33
38
  customer["credit_card"]["last_4"] = customer["credit_card"].delete("number")[-4..-1]
34
- customer["credit_card"]["token"] = Digest::MD5.hexdigest("#{customer['merchant_id']}#{customer['id']}#{Time.now.to_f}")
39
+ customer["credit_card"]["token"] = md5("#{customer['merchant_id']}#{customer['id']}#{Time.now.to_f}")
35
40
  expiration_date = customer["credit_card"].delete("expiration_date")
36
41
  customer["credit_card"]["expiration_month"] = expiration_date.split('/')[0]
37
42
  customer["credit_card"]["expiration_year"] = expiration_date.split('/')[1]
@@ -52,22 +57,22 @@ module FakeBraintree
52
57
 
53
58
  put "/merchants/:merchant_id/customers/:id" do
54
59
  customer = Hash.from_xml(request.body).delete("customer")
55
- if !FakeBraintree.failure?(customer["credit_card"]["number"])
56
- customer["id"] = params[:id]
60
+ if FakeBraintree.failure?(customer["credit_card"]["number"])
61
+ gzipped_response(422, FakeBraintree.failure_response(customer["credit_card"]["number"]).to_xml(:root => 'api_error_response'))
62
+ else
63
+ customer["id"] = params[:id]
57
64
  customer["merchant-id"] = params[:merchant_id]
58
65
  if customer["credit_card"] && customer["credit_card"].is_a?(Hash)
59
66
  customer["credit_card"].delete("__content__")
60
67
  if !customer["credit_card"].empty?
61
68
  customer["credit_card"]["last_4"] = customer["credit_card"].delete("number")[-4..-1]
62
- customer["credit_card"]["token"] = Digest::MD5.hexdigest("#{customer['merchant_id']}#{customer['id']}#{Time.now.to_f}")
69
+ customer["credit_card"]["token"] = md5("#{customer['merchant_id']}#{customer['id']}#{Time.now.to_f}")
63
70
  credit_card = customer.delete("credit_card")
64
71
  customer["credit_cards"] = [credit_card]
65
72
  end
66
73
  end
67
74
  FakeBraintree.customers[params["id"]] = customer
68
75
  gzipped_response(200, customer.to_xml(:root => 'customer'))
69
- else
70
- gzipped_response(422, FakeBraintree.failure_response(customer["credit_card"]["number"]).to_xml(:root => 'api_error_response'))
71
76
  end
72
77
  end
73
78
 
@@ -76,29 +81,35 @@ module FakeBraintree
76
81
  gzipped_response(200, "")
77
82
  end
78
83
 
84
+ # Braintree::Subscription.create
79
85
  post "/merchants/:merchant_id/subscriptions" do
80
86
  "<?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"
81
87
  subscription = Hash.from_xml(request.body).delete("subscription")
82
- subscription["id"] ||= Digest::MD5.hexdigest("#{subscription["payment_method_token"]}#{Time.now.to_f}")
83
- subscription["transactions"] = []
84
- subscription["add_ons"] = []
85
- subscription["discounts"] = []
88
+ subscription["id"] ||= md5("#{subscription["payment_method_token"]}#{Time.now.to_f}")[0,6]
89
+ subscription["transactions"] = []
90
+ subscription["add_ons"] = []
91
+ subscription["discounts"] = []
86
92
  subscription["next_billing_date"] = 1.month.from_now
87
- subscription["status"] = Braintree::Subscription::Status::Active
93
+ subscription["status"] = Braintree::Subscription::Status::Active
88
94
  FakeBraintree.subscriptions[subscription["id"]] = subscription
89
95
  gzipped_response(201, subscription.to_xml(:root => 'subscription'))
90
96
  end
91
97
 
98
+ # Braintree::Subscription.find
92
99
  get "/merchants/:merchant_id/subscriptions/:id" do
93
100
  subscription = FakeBraintree.subscriptions[params[:id]]
94
- gzipped_response(200, subscription.to_xml(:root => 'subscription'))
101
+ if subscription
102
+ gzipped_response(200, subscription.to_xml(:root => 'subscription'))
103
+ else
104
+ gzipped_response(404, {})
105
+ end
95
106
  end
96
107
 
97
108
  put "/merchants/:merchant_id/subscriptions/:id" do
98
109
  subscription = Hash.from_xml(request.body).delete("subscription")
99
110
  subscription["transactions"] = []
100
- subscription["add_ons"] = []
101
- subscription["discounts"] = []
111
+ subscription["add_ons"] = []
112
+ subscription["discounts"] = []
102
113
  FakeBraintree.subscriptions[params["id"]] = subscription
103
114
  gzipped_response(200, subscription.to_xml(:root => 'subscription'))
104
115
  end
@@ -106,7 +117,13 @@ module FakeBraintree
106
117
  # Braintree::Transaction.search
107
118
  post "/merchants/:merchant_id/transactions/advanced_search_ids" do
108
119
  # "<?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"
109
- gzipped_response(200, "<search-results>\n <page-size type=\"integer\">50</page-size>\n <ids type=\"array\">\n <item>49sbx6</item>\n </ids>\n</search-results>\n")
120
+ gzipped_response(200,
121
+ ['<search-results>',
122
+ ' <page-size type="integer">50</page-size>',
123
+ ' <ids type="array">',
124
+ ' <item>49sbx6</item>',
125
+ ' </ids>',
126
+ "</search-results>\n"].join("\n"))
110
127
  end
111
128
 
112
129
  # Braintree::Transaction.search
@@ -123,13 +140,12 @@ module FakeBraintree
123
140
  # Braintree::Transaction.sale
124
141
  # Braintree::CreditCard.sale
125
142
  post "/merchants/:merchant_id/transactions" do
126
- transaction = Hash.from_xml(request.body)["transaction"]
127
- transaction_id = Digest::MD5.hexdigest("#{params[:merchant_id]}#{Time.now.to_f}")
128
- transaction_response = {"id" => transaction_id, "amount" => transaction["amount"]}
129
-
130
143
  if FakeBraintree.decline_all_cards?
131
144
  gzipped_response(422, FakeBraintree.create_failure.to_xml(:root => 'api_error_response'))
132
145
  else
146
+ transaction = Hash.from_xml(request.body)["transaction"]
147
+ transaction_id = md5("#{params[:merchant_id]}#{Time.now.to_f}")
148
+ transaction_response = {"id" => transaction_id, "amount" => transaction["amount"]}
133
149
  FakeBraintree.transaction.replace(transaction_response)
134
150
  gzipped_response(200, transaction_response.to_xml(:root => "transaction"))
135
151
  end
@@ -1,3 +1,3 @@
1
1
  module FakeBraintree
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -29,4 +29,50 @@ module FakeBraintree
29
29
  lambda { Braintree::Transaction.find("foo") }.should raise_error(Braintree::NotFoundError)
30
30
  end
31
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 => 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
32
78
  end
@@ -43,6 +43,12 @@ describe FakeBraintree, ".decline_all_cards!" do
43
43
  end
44
44
  end
45
45
 
46
+ describe FakeBraintree, ".log_file_path" do
47
+ it "is tmp/log" do
48
+ FakeBraintree.log_file_path.should == 'tmp/log'
49
+ end
50
+ end
51
+
46
52
  describe "configuration variables" do
47
53
  subject { Braintree::Configuration }
48
54
 
@@ -56,10 +62,25 @@ describe "configuration variables" do
56
62
  subject.private_key.should == "xxx"
57
63
  end
58
64
 
59
- its(:logger) { should be_a Logger }
65
+ it "creates a log file" do
66
+ File.exist?(FakeBraintree.log_file_path).should == true
67
+ end
60
68
 
61
- it "does not log to STDOUT" do
62
- STDOUT.expects(:write).with("Logger test\n").never
69
+ it "logs to the correct path" do
63
70
  subject.logger.info('Logger test')
71
+ File.readlines(FakeBraintree.log_file_path).last.should == "Logger test\n"
72
+ end
73
+ end
74
+
75
+ describe FakeBraintree, ".clear_log!" do
76
+ it "clears the log file" do
77
+ %w(one two).each { |string| Braintree::Configuration.logger.info(string) }
78
+ subject.clear_log!
79
+ File.read(FakeBraintree.log_file_path).should == ""
80
+ end
81
+
82
+ it "is called by clear!" do
83
+ FakeBraintree.expects(:clear_log!)
84
+ FakeBraintree.clear!
64
85
  end
65
86
  end
data/tags ADDED
@@ -0,0 +1,28 @@
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
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.2
4
+ version: 0.0.3
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-09-08 00:00:00.000000000Z
12
+ date: 2011-10-24 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sham_rack
16
- requirement: &2162481680 !ruby/object:Gem::Requirement
16
+ requirement: &70234757701580 !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: *2162481680
24
+ version_requirements: *70234757701580
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: activesupport
27
- requirement: &2162481240 !ruby/object:Gem::Requirement
27
+ requirement: &70234757700380 !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: *2162481240
35
+ version_requirements: *70234757700380
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: i18n
38
- requirement: &2162480820 !ruby/object:Gem::Requirement
38
+ requirement: &70234757699160 !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: *2162480820
46
+ version_requirements: *70234757699160
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: sinatra
49
- requirement: &2162480400 !ruby/object:Gem::Requirement
49
+ requirement: &70234757698720 !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: *2162480400
57
+ version_requirements: *70234757698720
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: braintree
60
- requirement: &2162479900 !ruby/object:Gem::Requirement
60
+ requirement: &70234757698120 !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: *2162479900
68
+ version_requirements: *70234757698120
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec
71
- requirement: &2162479400 !ruby/object:Gem::Requirement
71
+ requirement: &70234757697400 !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: *2162479400
79
+ version_requirements: *70234757697400
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: mocha
82
- requirement: &2162478940 !ruby/object:Gem::Requirement
82
+ requirement: &70234757696880 !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: *2162478940
90
+ version_requirements: *70234757696880
91
91
  description: A fake Braintree that you can run integration tests against
92
92
  email:
93
93
  - gabe@thoughtbot.com
@@ -108,6 +108,7 @@ files:
108
108
  - spec/fake_braintree_spec.rb
109
109
  - spec/spec_helper.rb
110
110
  - spec/support/braintree_helpers.rb
111
+ - tags
111
112
  homepage: ''
112
113
  licenses: []
113
114
  post_install_message:
@@ -128,7 +129,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
128
129
  version: '0'
129
130
  requirements: []
130
131
  rubyforge_project:
131
- rubygems_version: 1.8.8
132
+ rubygems_version: 1.8.11
132
133
  signing_key:
133
134
  specification_version: 3
134
135
  summary: A fake Braintree that you can run integration tests against