fake_braintree 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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