stripe 4.21.2 → 5.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/.rubocop.yml +17 -4
- data/.rubocop_todo.yml +10 -9
- data/.travis.yml +2 -6
- data/CHANGELOG.md +40 -1
- data/Gemfile +2 -12
- data/README.md +10 -10
- data/Rakefile +8 -7
- data/VERSION +1 -1
- data/lib/stripe/api_operations/list.rb +0 -6
- data/lib/stripe/api_resource.rb +16 -0
- data/lib/stripe/connection_manager.rb +131 -0
- data/lib/stripe/error_object.rb +94 -0
- data/lib/stripe/errors.rb +15 -2
- data/lib/stripe/list_object.rb +2 -1
- data/lib/stripe/multipart_encoder.rb +131 -0
- data/lib/stripe/object_types.rb +0 -4
- data/lib/stripe/resources/account.rb +7 -7
- data/lib/stripe/resources/account_link.rb +1 -1
- data/lib/stripe/resources/alipay_account.rb +1 -1
- data/lib/stripe/resources/apple_pay_domain.rb +1 -1
- data/lib/stripe/resources/application_fee.rb +1 -12
- data/lib/stripe/resources/application_fee_refund.rb +1 -1
- data/lib/stripe/resources/balance.rb +1 -1
- data/lib/stripe/resources/balance_transaction.rb +1 -5
- data/lib/stripe/resources/bank_account.rb +1 -1
- data/lib/stripe/resources/bitcoin_receiver.rb +1 -1
- data/lib/stripe/resources/bitcoin_transaction.rb +1 -1
- data/lib/stripe/resources/capability.rb +1 -1
- data/lib/stripe/resources/card.rb +1 -1
- data/lib/stripe/resources/charge.rb +7 -69
- data/lib/stripe/resources/checkout/session.rb +1 -1
- data/lib/stripe/resources/country_spec.rb +1 -1
- data/lib/stripe/resources/coupon.rb +1 -1
- data/lib/stripe/resources/credit_note.rb +7 -3
- data/lib/stripe/resources/customer.rb +3 -63
- data/lib/stripe/resources/customer_balance_transaction.rb +1 -1
- data/lib/stripe/resources/discount.rb +1 -1
- data/lib/stripe/resources/dispute.rb +7 -9
- data/lib/stripe/resources/ephemeral_key.rb +1 -1
- data/lib/stripe/resources/event.rb +1 -1
- data/lib/stripe/resources/exchange_rate.rb +1 -1
- data/lib/stripe/resources/file.rb +3 -13
- data/lib/stripe/resources/file_link.rb +1 -1
- data/lib/stripe/resources/invoice.rb +36 -11
- data/lib/stripe/resources/invoice_item.rb +1 -1
- data/lib/stripe/resources/invoice_line_item.rb +1 -1
- data/lib/stripe/resources/issuing/authorization.rb +13 -5
- data/lib/stripe/resources/issuing/card.rb +7 -3
- data/lib/stripe/resources/issuing/card_details.rb +1 -1
- data/lib/stripe/resources/issuing/cardholder.rb +1 -1
- data/lib/stripe/resources/issuing/dispute.rb +1 -1
- data/lib/stripe/resources/issuing/transaction.rb +1 -1
- data/lib/stripe/resources/login_link.rb +1 -1
- data/lib/stripe/resources/order.rb +13 -13
- data/lib/stripe/resources/order_return.rb +1 -1
- data/lib/stripe/resources/payment_intent.rb +19 -7
- data/lib/stripe/resources/payment_method.rb +13 -5
- data/lib/stripe/resources/payout.rb +7 -9
- data/lib/stripe/resources/person.rb +1 -1
- data/lib/stripe/resources/plan.rb +1 -1
- data/lib/stripe/resources/product.rb +1 -1
- data/lib/stripe/resources/radar/early_fraud_warning.rb +1 -1
- data/lib/stripe/resources/radar/value_list.rb +1 -1
- data/lib/stripe/resources/radar/value_list_item.rb +1 -1
- data/lib/stripe/resources/recipient.rb +1 -5
- data/lib/stripe/resources/recipient_transfer.rb +1 -1
- data/lib/stripe/resources/refund.rb +1 -1
- data/lib/stripe/resources/reporting/report_run.rb +1 -1
- data/lib/stripe/resources/reporting/report_type.rb +1 -1
- data/lib/stripe/resources/reversal.rb +1 -1
- data/lib/stripe/resources/review.rb +7 -3
- data/lib/stripe/resources/setup_intent.rb +13 -5
- data/lib/stripe/resources/sigma/scheduled_query_run.rb +1 -1
- data/lib/stripe/resources/sku.rb +1 -1
- data/lib/stripe/resources/source.rb +7 -9
- data/lib/stripe/resources/source_transaction.rb +1 -1
- data/lib/stripe/resources/subscription.rb +9 -9
- data/lib/stripe/resources/subscription_item.rb +4 -1
- data/lib/stripe/resources/subscription_schedule.rb +13 -13
- data/lib/stripe/resources/tax_id.rb +1 -1
- data/lib/stripe/resources/tax_rate.rb +1 -1
- data/lib/stripe/resources/terminal/connection_token.rb +1 -1
- data/lib/stripe/resources/terminal/location.rb +1 -1
- data/lib/stripe/resources/terminal/reader.rb +1 -1
- data/lib/stripe/resources/three_d_secure.rb +1 -1
- data/lib/stripe/resources/token.rb +1 -1
- data/lib/stripe/resources/topup.rb +7 -3
- data/lib/stripe/resources/transfer.rb +7 -8
- data/lib/stripe/resources/usage_record.rb +1 -17
- data/lib/stripe/resources/usage_record_summary.rb +1 -1
- data/lib/stripe/resources/webhook_endpoint.rb +1 -1
- data/lib/stripe/resources.rb +0 -2
- data/lib/stripe/stripe_client.rb +281 -183
- data/lib/stripe/stripe_object.rb +4 -23
- data/lib/stripe/stripe_response.rb +53 -21
- data/lib/stripe/util.rb +14 -11
- data/lib/stripe/version.rb +1 -1
- data/lib/stripe/webhook.rb +1 -1
- data/lib/stripe.rb +56 -15
- data/stripe.gemspec +6 -9
- data/test/stripe/account_test.rb +0 -16
- data/test/stripe/api_operations_test.rb +2 -2
- data/test/stripe/api_resource_test.rb +98 -8
- data/test/stripe/balance_transaction_test.rb +20 -0
- data/test/stripe/charge_test.rb +0 -16
- data/test/stripe/connection_manager_test.rb +138 -0
- data/test/stripe/customer_test.rb +1 -44
- data/test/stripe/errors_test.rb +29 -8
- data/test/stripe/file_test.rb +0 -10
- data/test/stripe/invoice_test.rb +17 -1
- data/test/stripe/list_object_test.rb +0 -16
- data/test/stripe/login_link_test.rb +1 -1
- data/test/stripe/multipart_encoder_test.rb +130 -0
- data/test/stripe/payment_intent_test.rb +1 -1
- data/test/stripe/setup_intent_test.rb +1 -1
- data/test/stripe/source_test.rb +0 -18
- data/test/stripe/stripe_client_test.rb +214 -29
- data/test/stripe/stripe_object_test.rb +7 -35
- data/test/stripe/stripe_response_test.rb +70 -24
- data/test/stripe/subscription_item_test.rb +12 -0
- data/test/stripe/subscription_schedule_test.rb +0 -34
- data/test/stripe/subscription_test.rb +2 -2
- data/test/stripe/webhook_test.rb +2 -2
- data/test/stripe_mock.rb +4 -3
- data/test/stripe_test.rb +0 -13
- data/test/test_helper.rb +10 -5
- metadata +13 -42
- data/lib/stripe/resources/issuer_fraud_record.rb +0 -9
- data/lib/stripe/resources/subscription_schedule_revision.rb +0 -34
- data/test/stripe/file_upload_test.rb +0 -79
- data/test/stripe/issuer_fraud_record_test.rb +0 -20
- data/test/stripe/subscription_schedule_revision_test.rb +0 -37
- data/test/stripe/usage_record_test.rb +0 -28
|
@@ -17,6 +17,50 @@ module Stripe
|
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
+
context ".clear_all_connection_managers" do
|
|
21
|
+
should "clear connection managers across all threads" do
|
|
22
|
+
stub_request(:post, "#{Stripe.api_base}/path")
|
|
23
|
+
.to_return(body: JSON.generate(object: "account"))
|
|
24
|
+
|
|
25
|
+
num_threads = 3
|
|
26
|
+
|
|
27
|
+
# Poorly named class -- note this is actually a concurrent queue.
|
|
28
|
+
recv_queue = Queue.new
|
|
29
|
+
send_queue = Queue.new
|
|
30
|
+
|
|
31
|
+
threads = num_threads.times.map do |_|
|
|
32
|
+
Thread.start do
|
|
33
|
+
# Causes a connection manager to be created on this thread and a
|
|
34
|
+
# connection within that manager to be created for API access.
|
|
35
|
+
manager = StripeClient.default_connection_manager
|
|
36
|
+
manager.execute_request(:post, "#{Stripe.api_base}/path")
|
|
37
|
+
|
|
38
|
+
# Signal to the main thread we're ready.
|
|
39
|
+
recv_queue << true
|
|
40
|
+
|
|
41
|
+
# Wait for the main thread to signal continue.
|
|
42
|
+
send_queue.pop
|
|
43
|
+
|
|
44
|
+
# This check isn't great, but it's otherwise difficult to tell that
|
|
45
|
+
# anything happened with just the public-facing API.
|
|
46
|
+
assert_equal({}, manager.instance_variable_get(:@active_connections))
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Wait for threads to start up.
|
|
51
|
+
threads.each { recv_queue.pop }
|
|
52
|
+
|
|
53
|
+
# Do the clear (the method we're actually trying to test).
|
|
54
|
+
StripeClient.clear_all_connection_managers
|
|
55
|
+
|
|
56
|
+
# Tell threads to run their check.
|
|
57
|
+
threads.each { send_queue << true }
|
|
58
|
+
|
|
59
|
+
# And finally, give all threads time to perform their check.
|
|
60
|
+
threads.each(&:join)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
20
64
|
context ".default_client" do
|
|
21
65
|
should "be a StripeClient" do
|
|
22
66
|
assert_kind_of StripeClient, StripeClient.default_client
|
|
@@ -32,18 +76,19 @@ module Stripe
|
|
|
32
76
|
end
|
|
33
77
|
end
|
|
34
78
|
|
|
35
|
-
context ".
|
|
36
|
-
should "be a
|
|
37
|
-
assert_kind_of
|
|
79
|
+
context ".default_connection_manager" do
|
|
80
|
+
should "be a ConnectionManager" do
|
|
81
|
+
assert_kind_of ConnectionManager,
|
|
82
|
+
StripeClient.default_connection_manager
|
|
38
83
|
end
|
|
39
84
|
|
|
40
85
|
should "be a different connection on each thread" do
|
|
41
|
-
|
|
86
|
+
other_thread_manager = nil
|
|
42
87
|
thread = Thread.new do
|
|
43
|
-
|
|
88
|
+
other_thread_manager = StripeClient.default_connection_manager
|
|
44
89
|
end
|
|
45
90
|
thread.join
|
|
46
|
-
refute_equal StripeClient.
|
|
91
|
+
refute_equal StripeClient.default_connection_manager, other_thread_manager
|
|
47
92
|
end
|
|
48
93
|
end
|
|
49
94
|
|
|
@@ -52,26 +97,54 @@ module Stripe
|
|
|
52
97
|
Stripe.stubs(:max_network_retries).returns(2)
|
|
53
98
|
end
|
|
54
99
|
|
|
55
|
-
should "retry on
|
|
56
|
-
assert StripeClient.should_retry?(
|
|
100
|
+
should "retry on Errno::ECONNREFUSED" do
|
|
101
|
+
assert StripeClient.should_retry?(Errno::ECONNREFUSED.new,
|
|
102
|
+
method: :post, num_retries: 0)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
should "retry on Net::OpenTimeout" do
|
|
106
|
+
assert StripeClient.should_retry?(Net::OpenTimeout.new,
|
|
107
|
+
method: :post, num_retries: 0)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
should "retry on Net::ReadTimeout" do
|
|
111
|
+
assert StripeClient.should_retry?(Net::ReadTimeout.new,
|
|
112
|
+
method: :post, num_retries: 0)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
should "retry on SocketError" do
|
|
116
|
+
assert StripeClient.should_retry?(SocketError.new,
|
|
117
|
+
method: :post, num_retries: 0)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
should "retry on a 409 Conflict" do
|
|
121
|
+
assert StripeClient.should_retry?(Stripe::StripeError.new(http_status: 409),
|
|
122
|
+
method: :post, num_retries: 0)
|
|
57
123
|
end
|
|
58
124
|
|
|
59
|
-
should "retry on a
|
|
60
|
-
assert StripeClient.should_retry?(
|
|
125
|
+
should "retry on a 500 Internal Server Error when non-POST" do
|
|
126
|
+
assert StripeClient.should_retry?(Stripe::StripeError.new(http_status: 500),
|
|
127
|
+
method: :get, num_retries: 0)
|
|
61
128
|
end
|
|
62
129
|
|
|
63
|
-
should "retry on a
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
assert StripeClient.should_retry?(e, 0)
|
|
130
|
+
should "retry on a 503 Service Unavailable" do
|
|
131
|
+
assert StripeClient.should_retry?(Stripe::StripeError.new(http_status: 503),
|
|
132
|
+
method: :post, num_retries: 0)
|
|
67
133
|
end
|
|
68
134
|
|
|
69
135
|
should "not retry at maximum count" do
|
|
70
|
-
refute StripeClient.should_retry?(RuntimeError.new,
|
|
136
|
+
refute StripeClient.should_retry?(RuntimeError.new,
|
|
137
|
+
method: :post, num_retries: Stripe.max_network_retries)
|
|
71
138
|
end
|
|
72
139
|
|
|
73
140
|
should "not retry on a certificate validation error" do
|
|
74
|
-
refute StripeClient.should_retry?(
|
|
141
|
+
refute StripeClient.should_retry?(OpenSSL::SSL::SSLError.new,
|
|
142
|
+
method: :post, num_retries: 0)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
should "not retry on a 500 Internal Server Error when POST" do
|
|
146
|
+
refute StripeClient.should_retry?(Stripe::StripeError.new(http_status: 500),
|
|
147
|
+
method: :post, num_retries: 0)
|
|
75
148
|
end
|
|
76
149
|
end
|
|
77
150
|
|
|
@@ -115,15 +188,16 @@ module Stripe
|
|
|
115
188
|
end
|
|
116
189
|
|
|
117
190
|
context "#initialize" do
|
|
118
|
-
should "set Stripe.
|
|
191
|
+
should "set Stripe.default_connection_manager" do
|
|
119
192
|
client = StripeClient.new
|
|
120
|
-
assert_equal StripeClient.
|
|
193
|
+
assert_equal StripeClient.default_connection_manager,
|
|
194
|
+
client.connection_manager
|
|
121
195
|
end
|
|
122
196
|
|
|
123
197
|
should "set a different connection if one was specified" do
|
|
124
|
-
|
|
125
|
-
client = StripeClient.new(
|
|
126
|
-
assert_equal
|
|
198
|
+
connection_manager = ConnectionManager.new
|
|
199
|
+
client = StripeClient.new(connection_manager)
|
|
200
|
+
assert_equal connection_manager, client.connection_manager
|
|
127
201
|
end
|
|
128
202
|
end
|
|
129
203
|
|
|
@@ -178,7 +252,7 @@ module Stripe
|
|
|
178
252
|
Util.expects(:log_debug).with("Request details",
|
|
179
253
|
body: "",
|
|
180
254
|
idempotency_key: "abc",
|
|
181
|
-
|
|
255
|
+
query: nil)
|
|
182
256
|
|
|
183
257
|
Util.expects(:log_info).with("Response from Stripe API",
|
|
184
258
|
account: "acct_123",
|
|
@@ -403,6 +477,20 @@ module Stripe
|
|
|
403
477
|
assert_equal 'Invalid response object from API: "" (HTTP response code was 200)', e.message
|
|
404
478
|
end
|
|
405
479
|
|
|
480
|
+
should "handle low level error" do
|
|
481
|
+
stub_request(:post, "#{Stripe.api_base}/v1/charges")
|
|
482
|
+
.to_raise(Errno::ECONNREFUSED.new)
|
|
483
|
+
|
|
484
|
+
client = StripeClient.new
|
|
485
|
+
e = assert_raises Stripe::APIConnectionError do
|
|
486
|
+
client.execute_request(:post, "/v1/charges")
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
assert_equal StripeClient::ERROR_MESSAGE_CONNECTION % Stripe.api_base +
|
|
490
|
+
"\n\n(Network error: Connection refused)",
|
|
491
|
+
e.message
|
|
492
|
+
end
|
|
493
|
+
|
|
406
494
|
should "handle error response with unknown value" do
|
|
407
495
|
stub_request(:post, "#{Stripe.api_base}/v1/charges")
|
|
408
496
|
.to_return(body: JSON.generate(bar: "foo"), status: 500)
|
|
@@ -738,14 +826,106 @@ module Stripe
|
|
|
738
826
|
|
|
739
827
|
should "reset local thread state after a call" do
|
|
740
828
|
begin
|
|
741
|
-
|
|
829
|
+
StripeClient.current_thread_context.active_client = :stripe_client
|
|
742
830
|
|
|
743
831
|
client = StripeClient.new
|
|
744
832
|
client.request {}
|
|
745
833
|
|
|
746
|
-
assert_equal :stripe_client,
|
|
834
|
+
assert_equal :stripe_client,
|
|
835
|
+
StripeClient.current_thread_context.active_client
|
|
747
836
|
ensure
|
|
748
|
-
|
|
837
|
+
StripeClient.current_thread_context.active_client = nil
|
|
838
|
+
end
|
|
839
|
+
end
|
|
840
|
+
|
|
841
|
+
should "correctly return last responses despite multiple clients" do
|
|
842
|
+
charge_resp = { object: "charge" }
|
|
843
|
+
coupon_resp = { object: "coupon" }
|
|
844
|
+
|
|
845
|
+
stub_request(:post, "#{Stripe.api_base}/v1/charges")
|
|
846
|
+
.to_return(body: JSON.generate(charge_resp))
|
|
847
|
+
stub_request(:post, "#{Stripe.api_base}/v1/coupons")
|
|
848
|
+
.to_return(body: JSON.generate(coupon_resp))
|
|
849
|
+
|
|
850
|
+
client1 = StripeClient.new
|
|
851
|
+
client2 = StripeClient.new
|
|
852
|
+
|
|
853
|
+
client2_resp = nil
|
|
854
|
+
_charge, client1_resp = client1.request do
|
|
855
|
+
Charge.create
|
|
856
|
+
|
|
857
|
+
# This is contrived, but we run one client nested in the `request`
|
|
858
|
+
# block of another one just to ensure that the parent is still
|
|
859
|
+
# unwinding when this goes through. If the parent's last response
|
|
860
|
+
# were to be overridden by this client (through a bug), then it would
|
|
861
|
+
# happen here.
|
|
862
|
+
_coupon, client2_resp = client2.request do
|
|
863
|
+
Coupon.create
|
|
864
|
+
end
|
|
865
|
+
end
|
|
866
|
+
|
|
867
|
+
assert_equal charge_resp, client1_resp.data
|
|
868
|
+
assert_equal coupon_resp, client2_resp.data
|
|
869
|
+
end
|
|
870
|
+
|
|
871
|
+
should "correctly return last responses despite multiple threads" do
|
|
872
|
+
charge_resp = { object: "charge" }
|
|
873
|
+
coupon_resp = { object: "coupon" }
|
|
874
|
+
|
|
875
|
+
stub_request(:post, "#{Stripe.api_base}/v1/charges")
|
|
876
|
+
.to_return(body: JSON.generate(charge_resp))
|
|
877
|
+
stub_request(:post, "#{Stripe.api_base}/v1/coupons")
|
|
878
|
+
.to_return(body: JSON.generate(coupon_resp))
|
|
879
|
+
|
|
880
|
+
client = StripeClient.new
|
|
881
|
+
|
|
882
|
+
# Poorly named class -- note this is actually a concurrent queue.
|
|
883
|
+
recv_queue = Queue.new
|
|
884
|
+
send_queue = Queue.new
|
|
885
|
+
|
|
886
|
+
# Start a thread, make an API request, but then idle in the `request`
|
|
887
|
+
# block until the main thread has been able to make its own API request
|
|
888
|
+
# and signal that it's done. If this thread's last response were to be
|
|
889
|
+
# overridden by the main thread (through a bug), then this routine
|
|
890
|
+
# should suss it out.
|
|
891
|
+
resp1 = nil
|
|
892
|
+
thread = Thread.start do
|
|
893
|
+
_charge, resp1 = client.request do
|
|
894
|
+
Charge.create
|
|
895
|
+
|
|
896
|
+
# Idle in `request` block until main thread signals.
|
|
897
|
+
send_queue.pop
|
|
898
|
+
end
|
|
899
|
+
|
|
900
|
+
# Signal main thread that we're done and it can run its checks.
|
|
901
|
+
recv_queue << true
|
|
902
|
+
end
|
|
903
|
+
|
|
904
|
+
# Make an API request.
|
|
905
|
+
_coupon, resp2 = client.request do
|
|
906
|
+
Coupon.create
|
|
907
|
+
end
|
|
908
|
+
|
|
909
|
+
# Tell background thread to finish `request`, then wait for it to
|
|
910
|
+
# signal back to us that it's ready.
|
|
911
|
+
send_queue << true
|
|
912
|
+
recv_queue.pop
|
|
913
|
+
|
|
914
|
+
assert_equal charge_resp, resp1.data
|
|
915
|
+
assert_equal coupon_resp, resp2.data
|
|
916
|
+
|
|
917
|
+
# And for maximum hygiene, make sure that our thread rejoins.
|
|
918
|
+
thread.join
|
|
919
|
+
end
|
|
920
|
+
|
|
921
|
+
should "error if calls to #request are nested on the same thread" do
|
|
922
|
+
client = StripeClient.new
|
|
923
|
+
client.request do
|
|
924
|
+
e = assert_raises(RuntimeError) do
|
|
925
|
+
client.request {}
|
|
926
|
+
end
|
|
927
|
+
assert_equal "calls to StripeClient#request cannot be nested within a thread",
|
|
928
|
+
e.message
|
|
749
929
|
end
|
|
750
930
|
end
|
|
751
931
|
end
|
|
@@ -753,18 +933,23 @@ module Stripe
|
|
|
753
933
|
context "#proxy" do
|
|
754
934
|
should "run the request through the proxy" do
|
|
755
935
|
begin
|
|
756
|
-
|
|
936
|
+
StripeClient.current_thread_context.default_connection_manager = nil
|
|
757
937
|
|
|
758
|
-
Stripe.proxy = "http://localhost:8080"
|
|
938
|
+
Stripe.proxy = "http://user:pass@localhost:8080"
|
|
759
939
|
|
|
760
940
|
client = StripeClient.new
|
|
761
941
|
client.request {}
|
|
762
942
|
|
|
763
|
-
|
|
943
|
+
connection = Stripe::StripeClient.default_connection_manager.connection_for(Stripe.api_base)
|
|
944
|
+
|
|
945
|
+
assert_equal "localhost", connection.proxy_address
|
|
946
|
+
assert_equal 8080, connection.proxy_port
|
|
947
|
+
assert_equal "user", connection.proxy_user
|
|
948
|
+
assert_equal "pass", connection.proxy_pass
|
|
764
949
|
ensure
|
|
765
950
|
Stripe.proxy = nil
|
|
766
951
|
|
|
767
|
-
|
|
952
|
+
StripeClient.current_thread_context.default_connection_manager = nil
|
|
768
953
|
end
|
|
769
954
|
end
|
|
770
955
|
end
|
|
@@ -52,9 +52,9 @@ module Stripe
|
|
|
52
52
|
2,
|
|
53
53
|
],
|
|
54
54
|
map: {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
"0": StripeObject.construct_from({ id: "index0" }, opts),
|
|
56
|
+
"1": "index1",
|
|
57
|
+
"2": 2,
|
|
58
58
|
},
|
|
59
59
|
}
|
|
60
60
|
|
|
@@ -235,20 +235,6 @@ module Stripe
|
|
|
235
235
|
assert_equal true, obj.send(:metaclass).method_defined?(:foo)
|
|
236
236
|
end
|
|
237
237
|
|
|
238
|
-
should "warn that #refresh_from is deprecated" do
|
|
239
|
-
old_stderr = $stderr
|
|
240
|
-
$stderr = StringIO.new
|
|
241
|
-
begin
|
|
242
|
-
obj = Stripe::StripeObject.construct_from({})
|
|
243
|
-
obj.refresh_from({}, {})
|
|
244
|
-
message = "NOTE: Stripe::StripeObject#refresh_from is " \
|
|
245
|
-
"deprecated; use #update_attributes instead"
|
|
246
|
-
assert_match Regexp.new(message), $stderr.string
|
|
247
|
-
ensure
|
|
248
|
-
$stderr = old_stderr
|
|
249
|
-
end
|
|
250
|
-
end
|
|
251
|
-
|
|
252
238
|
should "pass opts down to children when initializing" do
|
|
253
239
|
opts = { custom: "opts" }
|
|
254
240
|
|
|
@@ -302,14 +288,14 @@ module Stripe
|
|
|
302
288
|
end
|
|
303
289
|
|
|
304
290
|
should "#serialize_params on an array that shortens" do
|
|
305
|
-
obj = Stripe::StripeObject.construct_from(foo: [
|
|
291
|
+
obj = Stripe::StripeObject.construct_from(foo: %w[0-index 1-index 2-index])
|
|
306
292
|
obj.foo = ["new-value"]
|
|
307
293
|
assert_equal({ foo: ["new-value"] },
|
|
308
294
|
obj.serialize_params)
|
|
309
295
|
end
|
|
310
296
|
|
|
311
297
|
should "#serialize_params on an array that lengthens" do
|
|
312
|
-
obj = Stripe::StripeObject.construct_from(foo: [
|
|
298
|
+
obj = Stripe::StripeObject.construct_from(foo: %w[0-index 1-index 2-index])
|
|
313
299
|
obj.foo = ["new-value"] * 4
|
|
314
300
|
assert_equal({ foo: ["new-value"] * 4 },
|
|
315
301
|
obj.serialize_params)
|
|
@@ -331,8 +317,8 @@ module Stripe
|
|
|
331
317
|
end
|
|
332
318
|
|
|
333
319
|
should "#serialize_params on an array that is unchanged" do
|
|
334
|
-
obj = Stripe::StripeObject.construct_from(foo: [
|
|
335
|
-
obj.foo = [
|
|
320
|
+
obj = Stripe::StripeObject.construct_from(foo: %w[0-index 1-index 2-index])
|
|
321
|
+
obj.foo = %w[0-index 1-index 2-index]
|
|
336
322
|
assert_equal({}, obj.serialize_params)
|
|
337
323
|
end
|
|
338
324
|
|
|
@@ -475,20 +461,6 @@ module Stripe
|
|
|
475
461
|
assert_equal(expected, obj.to_s)
|
|
476
462
|
end
|
|
477
463
|
|
|
478
|
-
should "warn that .serialize_params is deprecated" do
|
|
479
|
-
old_stderr = $stderr
|
|
480
|
-
$stderr = StringIO.new
|
|
481
|
-
begin
|
|
482
|
-
obj = Stripe::StripeObject.construct_from({})
|
|
483
|
-
Stripe::StripeObject.serialize_params(obj)
|
|
484
|
-
message = "NOTE: Stripe::StripeObject.serialize_params is " \
|
|
485
|
-
"deprecated; use #serialize_params instead"
|
|
486
|
-
assert_match Regexp.new(message), $stderr.string
|
|
487
|
-
ensure
|
|
488
|
-
$stderr = old_stderr
|
|
489
|
-
end
|
|
490
|
-
end
|
|
491
|
-
|
|
492
464
|
should "error on setting a property to an empty string" do
|
|
493
465
|
obj = Stripe::StripeObject.construct_from(foo: "bar")
|
|
494
466
|
e = assert_raises ArgumentError do
|
|
@@ -4,46 +4,92 @@ require ::File.expand_path("../test_helper", __dir__)
|
|
|
4
4
|
|
|
5
5
|
module Stripe
|
|
6
6
|
class StripeResponseTest < Test::Unit::TestCase
|
|
7
|
-
context "
|
|
8
|
-
should "
|
|
9
|
-
body = '{"foo": "bar"}'
|
|
7
|
+
context "Headers" do
|
|
8
|
+
should "allow case-insensitive header access" do
|
|
10
9
|
headers = { "Request-Id" => "request-id" }
|
|
10
|
+
http_resp = create_net_http_resp(200, "", headers)
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
body: body,
|
|
14
|
-
headers: headers,
|
|
15
|
-
status: 200,
|
|
16
|
-
}
|
|
12
|
+
headers = StripeResponse::Headers.from_net_http(http_resp)
|
|
17
13
|
|
|
18
|
-
|
|
14
|
+
assert_equal "request-id", headers["request-id"]
|
|
15
|
+
assert_equal "request-id", headers["Request-Id"]
|
|
16
|
+
assert_equal "request-id", headers["Request-ID"]
|
|
17
|
+
end
|
|
19
18
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
should "initialize without error" do
|
|
20
|
+
StripeResponse::Headers.new({})
|
|
21
|
+
StripeResponse::Headers.new("Request-Id" => [])
|
|
22
|
+
StripeResponse::Headers.new("Request-Id" => ["request-id"])
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
should "initialize with error on a malformed hash" do
|
|
26
|
+
assert_raises(ArgumentError) do
|
|
27
|
+
StripeResponse::Headers.new(nil)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
assert_raises(ArgumentError) do
|
|
31
|
+
StripeResponse::Headers.new(1 => [])
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
assert_raises(ArgumentError) do
|
|
35
|
+
StripeResponse::Headers.new("Request-Id" => 1)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
assert_raises(ArgumentError) do
|
|
39
|
+
StripeResponse::Headers.new("Request-Id" => [1])
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
should "warn on duplicate header values" do
|
|
44
|
+
old_stderr = $stderr
|
|
45
|
+
$stderr = StringIO.new
|
|
46
|
+
begin
|
|
47
|
+
headers = StripeResponse::Headers.new("Duplicated" => %w[a b])
|
|
48
|
+
assert_equal "a", headers["Duplicated"]
|
|
49
|
+
assert_equal "Duplicate header values for `Duplicated`; returning only first",
|
|
50
|
+
$stderr.string.rstrip
|
|
51
|
+
ensure
|
|
52
|
+
$stderr = old_stderr
|
|
53
|
+
end
|
|
25
54
|
end
|
|
26
55
|
end
|
|
27
56
|
|
|
28
|
-
context ".
|
|
57
|
+
context ".from_net_http" do
|
|
29
58
|
should "converts to StripeResponse" do
|
|
59
|
+
code = 200
|
|
30
60
|
body = '{"foo": "bar"}'
|
|
31
61
|
headers = { "Request-Id" => "request-id" }
|
|
62
|
+
http_resp = create_net_http_resp(code, body, headers)
|
|
32
63
|
|
|
33
|
-
|
|
34
|
-
status: 200, body: body,
|
|
35
|
-
response_headers: headers
|
|
36
|
-
)
|
|
37
|
-
http_resp = Faraday::Response.new(env)
|
|
38
|
-
|
|
39
|
-
resp = StripeResponse.from_faraday_response(http_resp)
|
|
64
|
+
resp = StripeResponse.from_net_http(http_resp)
|
|
40
65
|
|
|
41
66
|
assert_equal JSON.parse(body, symbolize_names: true), resp.data
|
|
42
67
|
assert_equal body, resp.http_body
|
|
43
|
-
assert_equal
|
|
44
|
-
assert_equal
|
|
68
|
+
assert_equal "request-id", resp.http_headers["Request-ID"]
|
|
69
|
+
assert_equal code, resp.http_status
|
|
45
70
|
assert_equal "request-id", resp.request_id
|
|
46
71
|
end
|
|
47
72
|
end
|
|
73
|
+
|
|
74
|
+
# Synthesizes a `Net::HTTPResponse` object for testing purposes.
|
|
75
|
+
private def create_net_http_resp(code, body, headers)
|
|
76
|
+
# The "1.1" is HTTP version.
|
|
77
|
+
http_resp = Net::HTTPResponse.new("1.1", code.to_s, nil)
|
|
78
|
+
http_resp.body = body
|
|
79
|
+
|
|
80
|
+
# This is obviously super sketchy, but the Ruby team has done everything
|
|
81
|
+
# in their power to make these objects as difficult to test with as
|
|
82
|
+
# possible. Even if you specify a body, accessing `#body` the first time
|
|
83
|
+
# will attempt to read from a non-existent socket which will subsequently
|
|
84
|
+
# blow up. Setting this internal variable skips that read and allows the
|
|
85
|
+
# object to use the body that we specified above.
|
|
86
|
+
http_resp.instance_variable_set(:@read, true)
|
|
87
|
+
|
|
88
|
+
headers.each do |name, value|
|
|
89
|
+
http_resp[name] = value
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
http_resp
|
|
93
|
+
end
|
|
48
94
|
end
|
|
49
95
|
end
|
|
@@ -59,5 +59,17 @@ module Stripe
|
|
|
59
59
|
assert item.is_a?(Stripe::SubscriptionItem)
|
|
60
60
|
end
|
|
61
61
|
end
|
|
62
|
+
|
|
63
|
+
context "#create_usage_record" do
|
|
64
|
+
should "create a usage record" do
|
|
65
|
+
Stripe::SubscriptionItem.create_usage_record(
|
|
66
|
+
"si_123",
|
|
67
|
+
quantity: 5000,
|
|
68
|
+
timestamp: Time.now.to_i,
|
|
69
|
+
action: "increment"
|
|
70
|
+
)
|
|
71
|
+
assert_requested :post, "#{Stripe.api_base}/v1/subscription_items/si_123/usage_records"
|
|
72
|
+
end
|
|
73
|
+
end
|
|
62
74
|
end
|
|
63
75
|
end
|
|
@@ -78,39 +78,5 @@ module Stripe
|
|
|
78
78
|
assert schedule.is_a?(Stripe::SubscriptionSchedule)
|
|
79
79
|
end
|
|
80
80
|
end
|
|
81
|
-
|
|
82
|
-
context "#revisions" do
|
|
83
|
-
should "retrieve the subscription schedule's revisions" do
|
|
84
|
-
schedule = Stripe::SubscriptionSchedule.retrieve("sub_sched_123")
|
|
85
|
-
revisions = schedule.revisions
|
|
86
|
-
assert_requested :get,
|
|
87
|
-
"#{Stripe.api_base}/v1/subscription_schedules/sub_sched_123/revisions"
|
|
88
|
-
assert revisions.data.is_a?(Array)
|
|
89
|
-
assert revisions.data[0].is_a?(Stripe::SubscriptionScheduleRevision)
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
context "#retrieve_revision" do
|
|
94
|
-
should "retrieve a subscription schedule revision" do
|
|
95
|
-
revision = Stripe::SubscriptionSchedule.retrieve_revision(
|
|
96
|
-
"sub_sched_123",
|
|
97
|
-
"sub_sched_rev_123"
|
|
98
|
-
)
|
|
99
|
-
assert_requested :get, "#{Stripe.api_base}/v1/subscription_schedules/sub_sched_123/revisions/sub_sched_rev_123"
|
|
100
|
-
assert revision.is_a?(Stripe::SubscriptionScheduleRevision)
|
|
101
|
-
end
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
context "#list_revisions" do
|
|
105
|
-
should "list a subscription schedule's revisions" do
|
|
106
|
-
revisions = Stripe::SubscriptionSchedule.list_revisions(
|
|
107
|
-
"sub_sched_123"
|
|
108
|
-
)
|
|
109
|
-
assert_requested :get, "#{Stripe.api_base}/v1/subscription_schedules/sub_sched_123/revisions"
|
|
110
|
-
assert revisions.is_a?(Stripe::ListObject)
|
|
111
|
-
assert revisions.data.is_a?(Array)
|
|
112
|
-
assert revisions.data[0].is_a?(Stripe::SubscriptionScheduleRevision)
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
81
|
end
|
|
116
82
|
end
|
|
@@ -63,9 +63,9 @@ module Stripe
|
|
|
63
63
|
context "#delete_discount" do
|
|
64
64
|
should "be able to delete a subscriptions's discount" do
|
|
65
65
|
subscription = Stripe::Subscription.retrieve("sub_123")
|
|
66
|
-
|
|
66
|
+
discount = subscription.delete_discount
|
|
67
67
|
assert_requested :delete, "#{Stripe.api_base}/v1/subscriptions/sub_123/discount"
|
|
68
|
-
assert
|
|
68
|
+
assert discount.is_a?(Stripe::Discount)
|
|
69
69
|
end
|
|
70
70
|
end
|
|
71
71
|
|
data/test/stripe/webhook_test.rb
CHANGED
|
@@ -4,13 +4,13 @@ require ::File.expand_path("../test_helper", __dir__)
|
|
|
4
4
|
|
|
5
5
|
module Stripe
|
|
6
6
|
class WebhookTest < Test::Unit::TestCase
|
|
7
|
-
EVENT_PAYLOAD =
|
|
7
|
+
EVENT_PAYLOAD = <<~PAYLOAD
|
|
8
8
|
{
|
|
9
9
|
"id": "evt_test_webhook",
|
|
10
10
|
"object": "event"
|
|
11
11
|
}
|
|
12
12
|
PAYLOAD
|
|
13
|
-
SECRET = "whsec_test_secret"
|
|
13
|
+
SECRET = "whsec_test_secret"
|
|
14
14
|
|
|
15
15
|
def generate_header(opts = {})
|
|
16
16
|
opts[:timestamp] ||= Time.now.to_i
|
data/test/stripe_mock.rb
CHANGED
|
@@ -4,8 +4,8 @@ module Stripe
|
|
|
4
4
|
class StripeMock
|
|
5
5
|
include Singleton
|
|
6
6
|
|
|
7
|
-
PATH_SPEC = "#{::File.dirname(__FILE__)}/openapi/spec3.json"
|
|
8
|
-
PATH_FIXTURES = "#{::File.dirname(__FILE__)}/openapi/fixtures3.json"
|
|
7
|
+
PATH_SPEC = "#{::File.dirname(__FILE__)}/openapi/spec3.json"
|
|
8
|
+
PATH_FIXTURES = "#{::File.dirname(__FILE__)}/openapi/fixtures3.json"
|
|
9
9
|
|
|
10
10
|
@pid = nil
|
|
11
11
|
@port = -1
|
|
@@ -29,7 +29,7 @@ module Stripe
|
|
|
29
29
|
@stderr, @child_stderr = ::IO.pipe
|
|
30
30
|
|
|
31
31
|
@pid = ::Process.spawn(
|
|
32
|
-
[
|
|
32
|
+
%w[stripe-mock stripe-mock],
|
|
33
33
|
"-http-port",
|
|
34
34
|
"0", # have stripe-mock select a port
|
|
35
35
|
"-spec",
|
|
@@ -66,6 +66,7 @@ module Stripe
|
|
|
66
66
|
# Stops stripe-mock, if necessary.
|
|
67
67
|
def self.stop
|
|
68
68
|
return if @pid.nil?
|
|
69
|
+
|
|
69
70
|
puts("Stopping stripe-mock...")
|
|
70
71
|
::Process.kill(:SIGTERM, @pid)
|
|
71
72
|
::Process.waitpid2(@pid)
|
data/test/stripe_test.rb
CHANGED
|
@@ -3,19 +3,6 @@
|
|
|
3
3
|
require ::File.expand_path("test_helper", __dir__)
|
|
4
4
|
|
|
5
5
|
class StripeTest < Test::Unit::TestCase
|
|
6
|
-
should "warn that #refresh_from is deprecated" do
|
|
7
|
-
old_stderr = $stderr
|
|
8
|
-
$stderr = StringIO.new
|
|
9
|
-
begin
|
|
10
|
-
Stripe.uri_encode({})
|
|
11
|
-
message = "NOTE: Stripe.uri_encode is deprecated; use " \
|
|
12
|
-
"Stripe::Util#encode_parameters instead"
|
|
13
|
-
assert_match Regexp.new(message), $stderr.string
|
|
14
|
-
ensure
|
|
15
|
-
$stderr = old_stderr
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
|
|
19
6
|
should "allow app_info to be configured" do
|
|
20
7
|
begin
|
|
21
8
|
old = Stripe.app_info
|