stripe 1.30.3 → 2.0.0
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.
- checksums.yaml +4 -4
- data/.gitattributes +4 -0
- data/.github/ISSUE_TEMPLATE.md +5 -0
- data/.travis.yml +3 -14
- data/Gemfile +28 -4
- data/History.txt +180 -0
- data/README.md +147 -0
- data/Rakefile +10 -0
- data/VERSION +1 -1
- data/bin/stripe-console +12 -5
- data/lib/data/ca-certificates.crt +3868 -5114
- data/lib/stripe/account.rb +43 -23
- data/lib/stripe/alipay_account.rb +20 -0
- data/lib/stripe/api_operations/create.rb +2 -2
- data/lib/stripe/api_operations/delete.rb +2 -2
- data/lib/stripe/api_operations/list.rb +2 -3
- data/lib/stripe/api_operations/request.rb +9 -3
- data/lib/stripe/api_operations/save.rb +85 -0
- data/lib/stripe/api_resource.rb +38 -5
- data/lib/stripe/apple_pay_domain.rb +12 -0
- data/lib/stripe/application_fee.rb +8 -8
- data/lib/stripe/application_fee_refund.rb +7 -3
- data/lib/stripe/balance_transaction.rb +1 -1
- data/lib/stripe/bank_account.rb +13 -4
- data/lib/stripe/bitcoin_receiver.rb +6 -6
- data/lib/stripe/bitcoin_transaction.rb +1 -1
- data/lib/stripe/card.rb +9 -5
- data/lib/stripe/charge.rb +38 -20
- data/lib/stripe/country_spec.rb +9 -0
- data/lib/stripe/coupon.rb +1 -1
- data/lib/stripe/customer.rb +12 -10
- data/lib/stripe/dispute.rb +4 -5
- data/lib/stripe/errors.rb +92 -0
- data/lib/stripe/file_upload.rb +1 -1
- data/lib/stripe/invoice.rb +7 -7
- data/lib/stripe/invoice_item.rb +1 -1
- data/lib/stripe/list_object.rb +8 -7
- data/lib/stripe/order.rb +12 -4
- data/lib/stripe/order_return.rb +9 -0
- data/lib/stripe/plan.rb +1 -1
- data/lib/stripe/product.rb +2 -10
- data/lib/stripe/recipient.rb +1 -1
- data/lib/stripe/refund.rb +1 -1
- data/lib/stripe/reversal.rb +7 -3
- data/lib/stripe/singleton_api_resource.rb +3 -3
- data/lib/stripe/sku.rb +2 -2
- data/lib/stripe/source.rb +11 -0
- data/lib/stripe/stripe_client.rb +396 -0
- data/lib/stripe/stripe_object.rb +167 -91
- data/lib/stripe/stripe_response.rb +48 -0
- data/lib/stripe/subscription.rb +15 -9
- data/lib/stripe/subscription_item.rb +12 -0
- data/lib/stripe/three_d_secure.rb +9 -0
- data/lib/stripe/transfer.rb +4 -5
- data/lib/stripe/util.rb +105 -33
- data/lib/stripe/version.rb +1 -1
- data/lib/stripe.rb +69 -266
- data/spec/fixtures.json +1409 -0
- data/spec/fixtures.yaml +1153 -0
- data/spec/spec.json +19949 -0
- data/spec/spec.yaml +15504 -0
- data/stripe.gemspec +5 -18
- data/test/api_fixtures.rb +29 -0
- data/test/api_stub_helpers.rb +125 -0
- data/test/stripe/account_test.rb +163 -211
- data/test/stripe/alipay_account_test.rb +19 -0
- data/test/stripe/api_operations_test.rb +31 -0
- data/test/stripe/api_resource_test.rb +174 -340
- data/test/stripe/apple_pay_domain_test.rb +33 -0
- data/test/stripe/application_fee_refund_test.rb +22 -31
- data/test/stripe/application_fee_test.rb +6 -14
- data/test/stripe/balance_test.rb +3 -3
- data/test/stripe/bank_account_test.rb +41 -0
- data/test/stripe/bitcoin_receiver_test.rb +51 -42
- data/test/stripe/bitcoin_transaction_test.rb +11 -19
- data/test/stripe/charge_test.rb +39 -98
- data/test/stripe/country_spec_test.rb +20 -0
- data/test/stripe/coupon_test.rb +35 -11
- data/test/stripe/customer_card_test.rb +25 -46
- data/test/stripe/customer_test.rb +89 -61
- data/test/stripe/dispute_test.rb +28 -31
- data/test/stripe/errors_test.rb +18 -0
- data/test/stripe/file_upload_test.rb +32 -24
- data/test/stripe/invoice_item_test.rb +55 -0
- data/test/stripe/invoice_test.rb +50 -24
- data/test/stripe/list_object_test.rb +57 -45
- data/test/stripe/order_return_test.rb +21 -0
- data/test/stripe/order_test.rb +41 -34
- data/test/stripe/plan_test.rb +52 -0
- data/test/stripe/product_test.rb +31 -25
- data/test/stripe/recipient_card_test.rb +23 -40
- data/test/stripe/recipient_test.rb +50 -0
- data/test/stripe/refund_test.rb +20 -36
- data/test/stripe/reversal_test.rb +27 -31
- data/test/stripe/sku_test.rb +39 -13
- data/test/stripe/source_test.rb +43 -0
- data/test/stripe/stripe_client_test.rb +428 -0
- data/test/stripe/stripe_object_test.rb +186 -13
- data/test/stripe/stripe_response_test.rb +46 -0
- data/test/stripe/subscription_item_test.rb +54 -0
- data/test/stripe/subscription_test.rb +40 -52
- data/test/stripe/three_d_secure_test.rb +23 -0
- data/test/stripe/transfer_test.rb +38 -13
- data/test/stripe/util_test.rb +48 -16
- data/test/stripe_test.rb +25 -0
- data/test/test_data.rb +5 -621
- data/test/test_helper.rb +24 -24
- metadata +60 -139
- data/README.rdoc +0 -68
- data/gemfiles/default-with-activesupport.gemfile +0 -10
- data/gemfiles/json.gemfile +0 -12
- data/gemfiles/yajl.gemfile +0 -12
- data/lib/stripe/api_operations/update.rb +0 -58
- data/lib/stripe/errors/api_connection_error.rb +0 -4
- data/lib/stripe/errors/api_error.rb +0 -4
- data/lib/stripe/errors/authentication_error.rb +0 -4
- data/lib/stripe/errors/card_error.rb +0 -12
- data/lib/stripe/errors/invalid_request_error.rb +0 -11
- data/lib/stripe/errors/rate_limit_error.rb +0 -4
- data/lib/stripe/errors/stripe_error.rb +0 -26
- data/test/stripe/charge_refund_test.rb +0 -55
- data/test/stripe/metadata_test.rb +0 -129
@@ -2,46 +2,42 @@ require File.expand_path('../../test_helper', __FILE__)
|
|
2
2
|
|
3
3
|
module Stripe
|
4
4
|
class ReversalTest < Test::Unit::TestCase
|
5
|
-
|
6
|
-
@mock.expects(:get).once.returns(make_response(make_transfer))
|
5
|
+
FIXTURE = API_FIXTURES.fetch(:transfer_reversal)
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
assert transfer.reversals.first.kind_of?(Stripe::Reversal)
|
7
|
+
setup do
|
8
|
+
@transfer = Stripe::Transfer.retrieve(API_FIXTURES.fetch(:transfer)[:id])
|
11
9
|
end
|
12
10
|
|
13
|
-
should "
|
14
|
-
@
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
assert_equal 'refreshed_reversal', reversal.id
|
11
|
+
should "be listable" do
|
12
|
+
reversals = @transfer.reversals.list
|
13
|
+
assert_requested :get,
|
14
|
+
"#{Stripe.api_base}/v1/transfers/#{@transfer.id}/reversals"
|
15
|
+
assert reversals.data.kind_of?(Array)
|
16
|
+
assert reversals.data[0].kind_of?(Stripe::Reversal)
|
21
17
|
end
|
22
18
|
|
23
|
-
should "
|
24
|
-
@
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
19
|
+
should "be retrievable" do
|
20
|
+
reversal = @transfer.reversals.retrieve(FIXTURE[:id])
|
21
|
+
assert_requested :get,
|
22
|
+
"#{Stripe.api_base}/v1/transfers/#{@transfer.id}/reversals/#{FIXTURE[:id]}"
|
23
|
+
assert reversal.kind_of?(Stripe::Reversal)
|
24
|
+
end
|
29
25
|
|
30
|
-
|
26
|
+
should "be creatable" do
|
27
|
+
reversal = @transfer.reversals.create(
|
28
|
+
amount: 100
|
29
|
+
)
|
30
|
+
assert_requested :post,
|
31
|
+
"#{Stripe.api_base}/v1/transfers/#{@transfer.id}/reversals"
|
32
|
+
assert reversal.kind_of?(Stripe::Reversal)
|
33
|
+
end
|
31
34
|
|
35
|
+
should "be saveable" do
|
36
|
+
reversal = @transfer.reversals.retrieve(FIXTURE[:id])
|
32
37
|
reversal.metadata['key'] = 'value'
|
33
38
|
reversal.save
|
34
|
-
|
35
|
-
|
36
|
-
end
|
37
|
-
|
38
|
-
should "create should return a new reversal" do
|
39
|
-
@mock.expects(:get).once.returns(make_response(make_transfer))
|
40
|
-
@mock.expects(:post).once.returns(make_response(make_reversal(:id => 'test_new_reversal')))
|
41
|
-
|
42
|
-
transfer = Stripe::Transfer.retrieve('test_transfer')
|
43
|
-
reversals = transfer.reversals.create(:amount => 20)
|
44
|
-
assert_equal 'test_new_reversal', reversals.id
|
39
|
+
assert_requested :post,
|
40
|
+
"#{Stripe.api_base}/v1/transfers/#{@transfer.id}/reversals/#{FIXTURE[:id]}"
|
45
41
|
end
|
46
42
|
end
|
47
43
|
end
|
data/test/stripe/sku_test.rb
CHANGED
@@ -2,23 +2,49 @@ require File.expand_path('../../test_helper', __FILE__)
|
|
2
2
|
|
3
3
|
module Stripe
|
4
4
|
class SKUTest < Test::Unit::TestCase
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
FIXTURE = API_FIXTURES.fetch(:sku)
|
6
|
+
|
7
|
+
should "be listable" do
|
8
8
|
skus = Stripe::SKU.list
|
9
|
-
|
10
|
-
skus.
|
11
|
-
|
12
|
-
|
9
|
+
assert_requested :get, "#{Stripe.api_base}/v1/skus"
|
10
|
+
assert skus.data.kind_of?(Array)
|
11
|
+
assert skus.data[0].kind_of?(Stripe::SKU)
|
12
|
+
end
|
13
|
+
|
14
|
+
should "be retrievable" do
|
15
|
+
sku = Stripe::SKU.retrieve(FIXTURE[:id])
|
16
|
+
assert_requested :get, "#{Stripe.api_base}/v1/skus/#{FIXTURE[:id]}"
|
17
|
+
assert sku.kind_of?(Stripe::SKU)
|
18
|
+
end
|
19
|
+
|
20
|
+
should "be creatable" do
|
21
|
+
_ = Stripe::SKU.create(
|
22
|
+
currency: "USD",
|
23
|
+
inventory: { type: "finite", quantity: 500 },
|
24
|
+
price: 100,
|
25
|
+
product: API_FIXTURES.fetch(:product)[:id]
|
26
|
+
)
|
27
|
+
assert_requested :post, "#{Stripe.api_base}/v1/skus"
|
28
|
+
end
|
29
|
+
|
30
|
+
should "be saveable" do
|
31
|
+
sku = Stripe::SKU.retrieve(FIXTURE[:id])
|
32
|
+
sku.metadata['key'] = 'value'
|
33
|
+
sku.save
|
34
|
+
assert_requested :post, "#{Stripe.api_base}/v1/skus/#{FIXTURE[:id]}"
|
13
35
|
end
|
14
36
|
|
15
|
-
should "
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
p.delete
|
20
|
-
end
|
37
|
+
should "be updateable" do
|
38
|
+
sku = Stripe::SKU.update(FIXTURE[:id], metadata: {foo: 'bar'})
|
39
|
+
assert_requested :post, "#{Stripe.api_base}/v1/skus/#{FIXTURE[:id]}"
|
40
|
+
assert sku.kind_of?(Stripe::SKU)
|
21
41
|
end
|
22
42
|
|
43
|
+
should "be deletable" do
|
44
|
+
sku = Stripe::SKU.retrieve(FIXTURE[:id])
|
45
|
+
sku = sku.delete
|
46
|
+
assert_requested :delete, "#{Stripe.api_base}/v1/skus/#{FIXTURE[:id]}"
|
47
|
+
assert sku.kind_of?(Stripe::SKU)
|
48
|
+
end
|
23
49
|
end
|
24
50
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require File.expand_path('../../test_helper', __FILE__)
|
2
|
+
|
3
|
+
module Stripe
|
4
|
+
class SourceTest < Test::Unit::TestCase
|
5
|
+
FIXTURE = API_FIXTURES.fetch(:source)
|
6
|
+
|
7
|
+
should "be retrievable" do
|
8
|
+
source = Stripe::Source.retrieve(FIXTURE[:id])
|
9
|
+
assert_requested :get, "#{Stripe.api_base}/v1/sources/#{FIXTURE[:id]}"
|
10
|
+
assert source.kind_of?(Stripe::Source)
|
11
|
+
end
|
12
|
+
|
13
|
+
should "be creatable" do
|
14
|
+
source = Stripe::Source.create(
|
15
|
+
type: 'card',
|
16
|
+
token: API_FIXTURES.fetch(:token)[:id]
|
17
|
+
)
|
18
|
+
assert_requested :post, "#{Stripe.api_base}/v1/sources"
|
19
|
+
assert source.kind_of?(Stripe::Card)
|
20
|
+
end
|
21
|
+
|
22
|
+
should "be saveable" do
|
23
|
+
source = Stripe::Source.retrieve(FIXTURE[:id])
|
24
|
+
source.metadata['key'] = 'value'
|
25
|
+
source.save
|
26
|
+
assert_requested :post, "#{Stripe.api_base}/v1/sources/#{FIXTURE[:id]}"
|
27
|
+
end
|
28
|
+
|
29
|
+
should "be updateable" do
|
30
|
+
source = Stripe::Source.update(FIXTURE[:id], metadata: {foo: 'bar'})
|
31
|
+
assert_requested :post, "#{Stripe.api_base}/v1/sources/#{FIXTURE[:id]}"
|
32
|
+
assert source.kind_of?(Stripe::Card)
|
33
|
+
end
|
34
|
+
|
35
|
+
context "#verify" do
|
36
|
+
should "verify the source" do
|
37
|
+
source = Stripe::Source.retrieve(FIXTURE[:id])
|
38
|
+
source = source.verify(:values => [1,2])
|
39
|
+
assert source.kind_of?(Stripe::Source)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,428 @@
|
|
1
|
+
require File.expand_path('../../test_helper', __FILE__)
|
2
|
+
|
3
|
+
module Stripe
|
4
|
+
class StripeClientTest < Test::Unit::TestCase
|
5
|
+
context ".active_client" do
|
6
|
+
should "be .default_client outside of #request" do
|
7
|
+
assert_equal StripeClient.default_client, StripeClient.active_client
|
8
|
+
end
|
9
|
+
|
10
|
+
should "be active client inside of #request" do
|
11
|
+
client = StripeClient.new
|
12
|
+
client.request do
|
13
|
+
assert_equal client, StripeClient.active_client
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context ".default_client" do
|
19
|
+
should "be a StripeClient" do
|
20
|
+
assert_kind_of StripeClient, StripeClient.default_client
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context ".default_conn" do
|
25
|
+
should "be a Faraday::Connection" do
|
26
|
+
assert_kind_of Faraday::Connection, StripeClient.default_conn
|
27
|
+
end
|
28
|
+
|
29
|
+
should "be a different connection on each thread" do
|
30
|
+
other_thread_conn = nil
|
31
|
+
thread = Thread.new do
|
32
|
+
other_thread_conn = StripeClient.default_conn
|
33
|
+
end
|
34
|
+
thread.join
|
35
|
+
refute_equal StripeClient.default_conn, other_thread_conn
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context ".should_retry?" do
|
40
|
+
setup do
|
41
|
+
Stripe.stubs(:max_network_retries).returns(2)
|
42
|
+
end
|
43
|
+
|
44
|
+
should 'retry on timeout' do
|
45
|
+
assert StripeClient.should_retry?(Faraday::TimeoutError.new(""), 0)
|
46
|
+
end
|
47
|
+
|
48
|
+
should 'retry on a failed connection' do
|
49
|
+
assert StripeClient.should_retry?(Faraday::ConnectionFailed.new(""), 0)
|
50
|
+
end
|
51
|
+
|
52
|
+
should 'retry on a conflict' do
|
53
|
+
error = make_rate_limit_error
|
54
|
+
e = Faraday::ClientError.new(error[:error][:message], { status: 409 })
|
55
|
+
assert StripeClient.should_retry?(e, 0)
|
56
|
+
end
|
57
|
+
|
58
|
+
should 'not retry at maximum count' do
|
59
|
+
refute StripeClient.should_retry?(RuntimeError.new, Stripe.max_network_retries)
|
60
|
+
end
|
61
|
+
|
62
|
+
should 'not retry on a certificate validation error' do
|
63
|
+
refute StripeClient.should_retry?(Faraday::SSLError.new(""), 0)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context ".sleep_time" do
|
68
|
+
should "should grow exponentially" do
|
69
|
+
StripeClient.stubs(:rand).returns(1)
|
70
|
+
Stripe.stubs(:max_network_retry_delay).returns(999)
|
71
|
+
assert_equal(Stripe.initial_network_retry_delay, StripeClient.sleep_time(1))
|
72
|
+
assert_equal(Stripe.initial_network_retry_delay * 2, StripeClient.sleep_time(2))
|
73
|
+
assert_equal(Stripe.initial_network_retry_delay * 4, StripeClient.sleep_time(3))
|
74
|
+
assert_equal(Stripe.initial_network_retry_delay * 8, StripeClient.sleep_time(4))
|
75
|
+
end
|
76
|
+
|
77
|
+
should "enforce the max_network_retry_delay" do
|
78
|
+
StripeClient.stubs(:rand).returns(1)
|
79
|
+
Stripe.stubs(:initial_network_retry_delay).returns(1)
|
80
|
+
Stripe.stubs(:max_network_retry_delay).returns(2)
|
81
|
+
assert_equal(1, StripeClient.sleep_time(1))
|
82
|
+
assert_equal(2, StripeClient.sleep_time(2))
|
83
|
+
assert_equal(2, StripeClient.sleep_time(3))
|
84
|
+
assert_equal(2, StripeClient.sleep_time(4))
|
85
|
+
end
|
86
|
+
|
87
|
+
should "add some randomness" do
|
88
|
+
random_value = 0.8
|
89
|
+
StripeClient.stubs(:rand).returns(random_value)
|
90
|
+
Stripe.stubs(:initial_network_retry_delay).returns(1)
|
91
|
+
Stripe.stubs(:max_network_retry_delay).returns(8)
|
92
|
+
|
93
|
+
base_value = Stripe.initial_network_retry_delay * (0.5 * (1 + random_value))
|
94
|
+
|
95
|
+
# the initial value cannot be smaller than the base,
|
96
|
+
# so the randomness is ignored
|
97
|
+
assert_equal(Stripe.initial_network_retry_delay, StripeClient.sleep_time(1))
|
98
|
+
|
99
|
+
# after the first one, the randomness is applied
|
100
|
+
assert_equal(base_value * 2, StripeClient.sleep_time(2))
|
101
|
+
assert_equal(base_value * 4, StripeClient.sleep_time(3))
|
102
|
+
assert_equal(base_value * 8, StripeClient.sleep_time(4))
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context "#initialize" do
|
107
|
+
should "set Stripe.default_conn" do
|
108
|
+
client = StripeClient.new
|
109
|
+
assert_equal StripeClient.default_conn, client.conn
|
110
|
+
end
|
111
|
+
|
112
|
+
should "set a different connection if one was specified" do
|
113
|
+
conn = Faraday.new
|
114
|
+
client = StripeClient.new(conn)
|
115
|
+
assert_equal conn, client.conn
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context "#execute_request" do
|
120
|
+
context "headers" do
|
121
|
+
should "support literal headers" do
|
122
|
+
stub_request(:post, "#{Stripe.api_base}/v1/account").
|
123
|
+
with(headers: { "Stripe-Account" => "bar" }).
|
124
|
+
to_return(body: JSON.generate(API_FIXTURES.fetch(:account)))
|
125
|
+
|
126
|
+
client = StripeClient.new
|
127
|
+
client.execute_request(:post, '/v1/account',
|
128
|
+
headers: { "Stripe-Account" => "bar" }
|
129
|
+
)
|
130
|
+
end
|
131
|
+
|
132
|
+
should "support RestClient-style header keys" do
|
133
|
+
stub_request(:post, "#{Stripe.api_base}/v1/account").
|
134
|
+
with(headers: { "Stripe-Account" => "bar" }).
|
135
|
+
to_return(body: JSON.generate(API_FIXTURES.fetch(:account)))
|
136
|
+
|
137
|
+
client = StripeClient.new
|
138
|
+
client.execute_request(:post, '/v1/account',
|
139
|
+
headers: { :stripe_account => "bar" }
|
140
|
+
)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
context "Stripe-Account header" do
|
145
|
+
should "use a globally set header" do
|
146
|
+
Stripe.stripe_account = 'acct_1234'
|
147
|
+
|
148
|
+
stub_request(:post, "#{Stripe.api_base}/v1/account").
|
149
|
+
with(headers: {"Stripe-Account" => Stripe.stripe_account}).
|
150
|
+
to_return(body: JSON.generate(API_FIXTURES.fetch(:account)))
|
151
|
+
|
152
|
+
client = StripeClient.new
|
153
|
+
client.execute_request(:post, '/v1/account')
|
154
|
+
end
|
155
|
+
|
156
|
+
should "use a locally set header" do
|
157
|
+
stripe_account = "acct_0000"
|
158
|
+
stub_request(:post, "#{Stripe.api_base}/v1/account").
|
159
|
+
with(headers: {"Stripe-Account" => stripe_account}).
|
160
|
+
to_return(body: JSON.generate(API_FIXTURES.fetch(:account)))
|
161
|
+
|
162
|
+
client = StripeClient.new
|
163
|
+
client.execute_request(:post, '/v1/account',
|
164
|
+
headers: { :stripe_account => stripe_account }
|
165
|
+
)
|
166
|
+
end
|
167
|
+
|
168
|
+
should "not send it otherwise" do
|
169
|
+
stub_request(:post, "#{Stripe.api_base}/v1/account").
|
170
|
+
with { |req|
|
171
|
+
req.headers["Stripe-Account"].nil?
|
172
|
+
}.to_return(body: JSON.generate(API_FIXTURES.fetch(:account)))
|
173
|
+
|
174
|
+
client = StripeClient.new
|
175
|
+
client.execute_request(:post, '/v1/account')
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
context "error handling" do
|
180
|
+
should "handle error response with empty body" do
|
181
|
+
stub_request(:post, "#{Stripe.api_base}/v1/charges").
|
182
|
+
to_return(body: '', status: 500)
|
183
|
+
|
184
|
+
client = StripeClient.new
|
185
|
+
e = assert_raises Stripe::APIError do
|
186
|
+
client.execute_request(:post, '/v1/charges')
|
187
|
+
end
|
188
|
+
|
189
|
+
assert_equal 'Invalid response object from API: "" (HTTP response code was 500)', e.message
|
190
|
+
end
|
191
|
+
|
192
|
+
should "handle error response with non-object error value" do
|
193
|
+
stub_request(:post, "#{Stripe.api_base}/v1/charges").
|
194
|
+
to_return(body: JSON.generate({ error: "foo" }), status: 500)
|
195
|
+
|
196
|
+
client = StripeClient.new
|
197
|
+
e = assert_raises Stripe::APIError do
|
198
|
+
client.execute_request(:post, '/v1/charges')
|
199
|
+
end
|
200
|
+
|
201
|
+
assert_equal 'Invalid response object from API: "{\"error\":\"foo\"}" (HTTP response code was 500)', e.message
|
202
|
+
end
|
203
|
+
|
204
|
+
should "raise InvalidRequestError on 400" do
|
205
|
+
stub_request(:post, "#{Stripe.api_base}/v1/charges").
|
206
|
+
to_return(body: JSON.generate(make_missing_id_error), status: 400)
|
207
|
+
client = StripeClient.new
|
208
|
+
begin
|
209
|
+
client.execute_request(:post, '/v1/charges')
|
210
|
+
rescue Stripe::InvalidRequestError => e
|
211
|
+
assert_equal(400, e.http_status)
|
212
|
+
assert_equal(true, !!e.http_body)
|
213
|
+
assert_equal(true, e.json_body.kind_of?(Hash))
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
should "raise AuthenticationError on 401" do
|
218
|
+
stub_request(:post, "#{Stripe.api_base}/v1/charges").
|
219
|
+
to_return(body: JSON.generate(make_missing_id_error), status: 401)
|
220
|
+
client = StripeClient.new
|
221
|
+
begin
|
222
|
+
client.execute_request(:post, '/v1/charges')
|
223
|
+
rescue Stripe::AuthenticationError => e
|
224
|
+
assert_equal(401, e.http_status)
|
225
|
+
assert_equal(true, !!e.http_body)
|
226
|
+
assert_equal(true, e.json_body.kind_of?(Hash))
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
should "raise CardError on 402" do
|
231
|
+
stub_request(:post, "#{Stripe.api_base}/v1/charges").
|
232
|
+
to_return(body: JSON.generate(make_missing_id_error), status: 402)
|
233
|
+
client = StripeClient.new
|
234
|
+
begin
|
235
|
+
client.execute_request(:post, '/v1/charges')
|
236
|
+
rescue Stripe::CardError => e
|
237
|
+
assert_equal(402, e.http_status)
|
238
|
+
assert_equal(true, !!e.http_body)
|
239
|
+
assert_equal(true, e.json_body.kind_of?(Hash))
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
should "raise PermissionError on 403" do
|
244
|
+
stub_request(:post, "#{Stripe.api_base}/v1/charges").
|
245
|
+
to_return(body: JSON.generate(make_missing_id_error), status: 403)
|
246
|
+
client = StripeClient.new
|
247
|
+
begin
|
248
|
+
client.execute_request(:post, '/v1/charges')
|
249
|
+
rescue Stripe::PermissionError => e
|
250
|
+
assert_equal(403, e.http_status)
|
251
|
+
assert_equal(true, !!e.http_body)
|
252
|
+
assert_equal(true, e.json_body.kind_of?(Hash))
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
should "raise InvalidRequestError on 404" do
|
257
|
+
stub_request(:post, "#{Stripe.api_base}/v1/charges").
|
258
|
+
to_return(body: JSON.generate(make_missing_id_error), status: 404)
|
259
|
+
client = StripeClient.new
|
260
|
+
begin
|
261
|
+
client.execute_request(:post, '/v1/charges')
|
262
|
+
rescue Stripe::InvalidRequestError => e
|
263
|
+
assert_equal(404, e.http_status)
|
264
|
+
assert_equal(true, !!e.http_body)
|
265
|
+
assert_equal(true, e.json_body.kind_of?(Hash))
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
should "raise RateLimitError on 429" do
|
270
|
+
stub_request(:post, "#{Stripe.api_base}/v1/charges").
|
271
|
+
to_return(body: JSON.generate(make_rate_limit_error), status: 429)
|
272
|
+
client = StripeClient.new
|
273
|
+
begin
|
274
|
+
client.execute_request(:post, '/v1/charges')
|
275
|
+
rescue Stripe::RateLimitError => e
|
276
|
+
assert_equal(429, e.http_status)
|
277
|
+
assert_equal(true, !!e.http_body)
|
278
|
+
assert_equal(true, e.json_body.kind_of?(Hash))
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
context "idempotency keys" do
|
284
|
+
setup do
|
285
|
+
Stripe.stubs(:max_network_retries).returns(2)
|
286
|
+
end
|
287
|
+
|
288
|
+
should 'not add an idempotency key to GET requests' do
|
289
|
+
SecureRandom.expects(:uuid).times(0)
|
290
|
+
stub_request(:get, "#{Stripe.api_base}/v1/charges/#{API_FIXTURES.fetch(:charge)[:id]}").
|
291
|
+
with { |req|
|
292
|
+
req.headers['Idempotency-Key'].nil?
|
293
|
+
}.to_return(body: JSON.generate(API_FIXTURES.fetch(:charge)))
|
294
|
+
client = StripeClient.new
|
295
|
+
client.execute_request(:get, "/v1/charges/#{API_FIXTURES.fetch(:charge)[:id]}")
|
296
|
+
end
|
297
|
+
|
298
|
+
should 'ensure there is always an idempotency_key on POST requests' do
|
299
|
+
SecureRandom.expects(:uuid).at_least_once.returns("random_key")
|
300
|
+
stub_request(:post, "#{Stripe.api_base}/v1/charges").
|
301
|
+
with(headers: {"Idempotency-Key" => "random_key"}).
|
302
|
+
to_return(body: JSON.generate(API_FIXTURES.fetch(:charge)))
|
303
|
+
client = StripeClient.new
|
304
|
+
client.execute_request(:post, "/v1/charges")
|
305
|
+
end
|
306
|
+
|
307
|
+
should 'ensure there is always an idempotency_key on DELETE requests' do
|
308
|
+
SecureRandom.expects(:uuid).at_least_once.returns("random_key")
|
309
|
+
stub_request(:delete, "#{Stripe.api_base}/v1/charges/#{API_FIXTURES.fetch(:charge)[:id]}").
|
310
|
+
with(headers: {"Idempotency-Key" => "random_key"}).
|
311
|
+
to_return(body: JSON.generate(API_FIXTURES.fetch(:charge)))
|
312
|
+
client = StripeClient.new
|
313
|
+
client.execute_request(:delete, "/v1/charges/#{API_FIXTURES.fetch(:charge)[:id]}")
|
314
|
+
end
|
315
|
+
|
316
|
+
should 'not override a provided idempotency_key' do
|
317
|
+
# Note that this expectation looks like `:idempotency_key` instead of
|
318
|
+
# the header `Idempotency-Key` because it's user provided as seen
|
319
|
+
# below. The ones injected by the library itself look like headers
|
320
|
+
# (`Idempotency-Key`), but rest-client does allow this symbol
|
321
|
+
# formatting and will properly override the system generated one as
|
322
|
+
# expected.
|
323
|
+
stub_request(:post, "#{Stripe.api_base}/v1/charges").
|
324
|
+
with(headers: {"Idempotency-Key" => "provided_key"}).
|
325
|
+
to_return(body: JSON.generate(API_FIXTURES.fetch(:charge)))
|
326
|
+
|
327
|
+
client = StripeClient.new
|
328
|
+
client.execute_request(:post, "/v1/charges",
|
329
|
+
headers: {:idempotency_key => 'provided_key'})
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
context "retry logic" do
|
334
|
+
setup do
|
335
|
+
Stripe.stubs(:max_network_retries).returns(2)
|
336
|
+
end
|
337
|
+
|
338
|
+
should 'retry failed requests and raise if error persists' do
|
339
|
+
StripeClient.expects(:sleep_time).at_least_once.returns(0)
|
340
|
+
stub_request(:post, "#{Stripe.api_base}/v1/charges").
|
341
|
+
to_raise(Errno::ECONNREFUSED.new)
|
342
|
+
|
343
|
+
client = StripeClient.new
|
344
|
+
err = assert_raises Stripe::APIConnectionError do
|
345
|
+
client.execute_request(:post, '/v1/charges')
|
346
|
+
end
|
347
|
+
assert_match(/Request was retried 2 times/, err.message)
|
348
|
+
end
|
349
|
+
|
350
|
+
should 'retry failed requests and return successful response' do
|
351
|
+
StripeClient.expects(:sleep_time).at_least_once.returns(0)
|
352
|
+
|
353
|
+
i = 0
|
354
|
+
stub_request(:post, "#{Stripe.api_base}/v1/charges").
|
355
|
+
to_return { |_|
|
356
|
+
if i < 2
|
357
|
+
i += 1
|
358
|
+
raise Errno::ECONNREFUSED.new
|
359
|
+
else
|
360
|
+
{ body: JSON.generate({"id" => "myid"}) }
|
361
|
+
end
|
362
|
+
}
|
363
|
+
|
364
|
+
client = StripeClient.new
|
365
|
+
client.execute_request(:post, '/v1/charges')
|
366
|
+
end
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
370
|
+
context "#request" do
|
371
|
+
should "return a result and response object" do
|
372
|
+
stub_request(:post, "#{Stripe.api_base}/v1/charges").
|
373
|
+
to_return(body: JSON.generate(API_FIXTURES.fetch(:charge)))
|
374
|
+
|
375
|
+
client = StripeClient.new
|
376
|
+
charge, resp = client.request { Charge.create }
|
377
|
+
|
378
|
+
assert charge.is_a?(Charge)
|
379
|
+
assert resp.is_a?(StripeResponse)
|
380
|
+
assert_equal 200, resp.http_status
|
381
|
+
end
|
382
|
+
|
383
|
+
should "return the value of given block" do
|
384
|
+
client = StripeClient.new
|
385
|
+
ret, _ = client.request { 7 }
|
386
|
+
assert_equal 7, ret
|
387
|
+
end
|
388
|
+
|
389
|
+
should "reset local thread state after a call" do
|
390
|
+
begin
|
391
|
+
Thread.current[:stripe_client] = :stripe_client
|
392
|
+
|
393
|
+
client = StripeClient.new
|
394
|
+
client.request {}
|
395
|
+
|
396
|
+
assert_equal :stripe_client, Thread.current[:stripe_client]
|
397
|
+
ensure
|
398
|
+
Thread.current[:stripe_client] = nil
|
399
|
+
end
|
400
|
+
end
|
401
|
+
end
|
402
|
+
end
|
403
|
+
|
404
|
+
class SystemProfilerTest < Test::Unit::TestCase
|
405
|
+
context "#get_uname" do
|
406
|
+
should "run without failure" do
|
407
|
+
# Don't actually check the result because we try a variety of different
|
408
|
+
# strategies that will have different results depending on where this
|
409
|
+
# test and running. We're mostly making sure that no exception is thrown.
|
410
|
+
_ = StripeClient::SystemProfiler.get_uname
|
411
|
+
end
|
412
|
+
end
|
413
|
+
|
414
|
+
context "#get_uname_from_system" do
|
415
|
+
should "run without failure" do
|
416
|
+
# as above, just verify that an exception is not thrown
|
417
|
+
_ = StripeClient::SystemProfiler.get_uname_from_system
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
421
|
+
context "#get_uname_from_system_ver" do
|
422
|
+
should "run without failure" do
|
423
|
+
# as above, just verify that an exception is not thrown
|
424
|
+
_ = StripeClient::SystemProfiler.get_uname_from_system_ver
|
425
|
+
end
|
426
|
+
end
|
427
|
+
end
|
428
|
+
end
|