stripe 5.31.0 → 5.35.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +18 -0
  3. data/VERSION +1 -1
  4. data/lib/stripe/api_operations/request.rb +35 -2
  5. data/lib/stripe/api_resource.rb +8 -0
  6. data/lib/stripe/connection_manager.rb +17 -2
  7. data/lib/stripe/object_types.rb +3 -0
  8. data/lib/stripe/resources.rb +3 -0
  9. data/lib/stripe/resources/identity/verification_report.rb +12 -0
  10. data/lib/stripe/resources/identity/verification_session.rb +35 -0
  11. data/lib/stripe/resources/tax_code.rb +10 -0
  12. data/lib/stripe/stripe_client.rb +120 -57
  13. data/lib/stripe/stripe_response.rb +80 -52
  14. data/lib/stripe/util.rb +3 -1
  15. data/lib/stripe/version.rb +1 -1
  16. data/stripe.gemspec +9 -2
  17. metadata +9 -198
  18. data/.editorconfig +0 -10
  19. data/.gitattributes +0 -4
  20. data/.github/ISSUE_TEMPLATE.md +0 -5
  21. data/.github/workflows/ci.yml +0 -34
  22. data/.gitignore +0 -8
  23. data/.rubocop.yml +0 -81
  24. data/.rubocop_todo.yml +0 -33
  25. data/.travis.yml +0 -38
  26. data/.vscode/extensions.json +0 -7
  27. data/.vscode/settings.json +0 -8
  28. data/test/openapi/README.md +0 -9
  29. data/test/stripe/account_link_test.rb +0 -18
  30. data/test/stripe/account_test.rb +0 -412
  31. data/test/stripe/alipay_account_test.rb +0 -37
  32. data/test/stripe/api_operations_test.rb +0 -80
  33. data/test/stripe/api_resource_test.rb +0 -646
  34. data/test/stripe/apple_pay_domain_test.rb +0 -46
  35. data/test/stripe/application_fee_refund_test.rb +0 -37
  36. data/test/stripe/application_fee_test.rb +0 -58
  37. data/test/stripe/balance_test.rb +0 -13
  38. data/test/stripe/balance_transaction_test.rb +0 -20
  39. data/test/stripe/bank_account_test.rb +0 -36
  40. data/test/stripe/billing_portal/configuration_test.rb +0 -37
  41. data/test/stripe/billing_portal/session_test.rb +0 -18
  42. data/test/stripe/capability_test.rb +0 -45
  43. data/test/stripe/charge_test.rb +0 -64
  44. data/test/stripe/checkout/session_test.rb +0 -53
  45. data/test/stripe/connection_manager_test.rb +0 -210
  46. data/test/stripe/country_spec_test.rb +0 -20
  47. data/test/stripe/coupon_test.rb +0 -61
  48. data/test/stripe/credit_note_test.rb +0 -90
  49. data/test/stripe/customer_balance_transaction_test.rb +0 -37
  50. data/test/stripe/customer_card_test.rb +0 -48
  51. data/test/stripe/customer_test.rb +0 -226
  52. data/test/stripe/dispute_test.rb +0 -51
  53. data/test/stripe/ephemeral_key_test.rb +0 -93
  54. data/test/stripe/errors_test.rb +0 -53
  55. data/test/stripe/exchange_rate_test.rb +0 -20
  56. data/test/stripe/file_link_test.rb +0 -41
  57. data/test/stripe/file_test.rb +0 -87
  58. data/test/stripe/instrumentation_test.rb +0 -74
  59. data/test/stripe/invoice_item_test.rb +0 -66
  60. data/test/stripe/invoice_line_item_test.rb +0 -8
  61. data/test/stripe/invoice_test.rb +0 -229
  62. data/test/stripe/issuing/authorization_test.rb +0 -72
  63. data/test/stripe/issuing/card_test.rb +0 -74
  64. data/test/stripe/issuing/cardholder_test.rb +0 -53
  65. data/test/stripe/issuing/dispute_test.rb +0 -54
  66. data/test/stripe/issuing/transaction_test.rb +0 -48
  67. data/test/stripe/list_object_test.rb +0 -202
  68. data/test/stripe/login_link_test.rb +0 -37
  69. data/test/stripe/mandate_test.rb +0 -14
  70. data/test/stripe/multipart_encoder_test.rb +0 -130
  71. data/test/stripe/oauth_test.rb +0 -149
  72. data/test/stripe/order_return_test.rb +0 -21
  73. data/test/stripe/order_test.rb +0 -82
  74. data/test/stripe/payment_intent_test.rb +0 -107
  75. data/test/stripe/payment_method_test.rb +0 -84
  76. data/test/stripe/payout_test.rb +0 -72
  77. data/test/stripe/person_test.rb +0 -46
  78. data/test/stripe/plan_test.rb +0 -98
  79. data/test/stripe/price_test.rb +0 -48
  80. data/test/stripe/product_test.rb +0 -58
  81. data/test/stripe/promotion_code_test.rb +0 -42
  82. data/test/stripe/radar/early_fraud_warning_test.rb +0 -22
  83. data/test/stripe/radar/value_list_item_test.rb +0 -48
  84. data/test/stripe/radar/value_list_test.rb +0 -61
  85. data/test/stripe/recipient_test.rb +0 -62
  86. data/test/stripe/refund_test.rb +0 -39
  87. data/test/stripe/reporting/report_run_test.rb +0 -33
  88. data/test/stripe/reporting/report_type_test.rb +0 -22
  89. data/test/stripe/reversal_test.rb +0 -43
  90. data/test/stripe/review_test.rb +0 -27
  91. data/test/stripe/setup_attempt_test.rb +0 -16
  92. data/test/stripe/setup_intent_test.rb +0 -84
  93. data/test/stripe/sigma/scheduled_query_run_test.rb +0 -22
  94. data/test/stripe/sku_test.rb +0 -60
  95. data/test/stripe/source_test.rb +0 -119
  96. data/test/stripe/stripe_client_test.rb +0 -1456
  97. data/test/stripe/stripe_configuration_test.rb +0 -159
  98. data/test/stripe/stripe_object_test.rb +0 -510
  99. data/test/stripe/stripe_response_test.rb +0 -95
  100. data/test/stripe/subscription_item_test.rb +0 -84
  101. data/test/stripe/subscription_schedule_test.rb +0 -82
  102. data/test/stripe/subscription_test.rb +0 -80
  103. data/test/stripe/tax_id_test.rb +0 -31
  104. data/test/stripe/tax_rate_test.rb +0 -43
  105. data/test/stripe/terminal/connection_token_test.rb +0 -16
  106. data/test/stripe/terminal/location_test.rb +0 -68
  107. data/test/stripe/terminal/reader_test.rb +0 -62
  108. data/test/stripe/three_d_secure_test.rb +0 -23
  109. data/test/stripe/topup_test.rb +0 -62
  110. data/test/stripe/transfer_test.rb +0 -88
  111. data/test/stripe/usage_record_summary_test.rb +0 -29
  112. data/test/stripe/util_test.rb +0 -402
  113. data/test/stripe/webhook_endpoint_test.rb +0 -59
  114. data/test/stripe/webhook_test.rb +0 -135
  115. data/test/stripe_mock.rb +0 -78
  116. data/test/stripe_test.rb +0 -137
  117. data/test/test_data.rb +0 -61
  118. data/test/test_helper.rb +0 -74
@@ -1,43 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require ::File.expand_path("../test_helper", __dir__)
4
-
5
- module Stripe
6
- class ReversalTest < Test::Unit::TestCase
7
- setup do
8
- @transfer = Stripe::Transfer.retrieve("tr_123")
9
- end
10
-
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.is_a?(Array)
16
- assert reversals.data[0].is_a?(Stripe::Reversal)
17
- end
18
-
19
- should "be retrievable" do
20
- reversal = @transfer.reversals.retrieve("trr_123")
21
- assert_requested :get,
22
- "#{Stripe.api_base}/v1/transfers/#{@transfer.id}/reversals/trr_123"
23
- assert reversal.is_a?(Stripe::Reversal)
24
- end
25
-
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.is_a?(Stripe::Reversal)
33
- end
34
-
35
- should "be saveable" do
36
- reversal = @transfer.reversals.retrieve("trr_123")
37
- reversal.metadata["key"] = "value"
38
- reversal.save
39
- assert_requested :post,
40
- "#{Stripe.api_base}/v1/transfers/#{reversal.transfer}/reversals/#{reversal.id}"
41
- end
42
- end
43
- end
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require ::File.expand_path("../test_helper", __dir__)
4
-
5
- module Stripe
6
- class ReviewTest < Test::Unit::TestCase
7
- should "be listable" do
8
- reviews = Stripe::Review.list
9
- assert_requested :get, "#{Stripe.api_base}/v1/reviews"
10
- assert reviews.data.is_a?(Array)
11
- assert reviews.first.is_a?(Stripe::Review)
12
- end
13
-
14
- should "be retrievable" do
15
- review = Stripe::Review.retrieve("prv_123")
16
- assert_requested :get, "#{Stripe.api_base}/v1/reviews/prv_123"
17
- assert review.is_a?(Stripe::Review)
18
- end
19
-
20
- should "be approvable" do
21
- review = Stripe::Review.retrieve("prv_123")
22
- review.approve
23
- assert_requested :post, "#{Stripe.api_base}/v1/reviews/prv_123/approve"
24
- assert review.is_a?(Stripe::Review)
25
- end
26
- end
27
- end
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require ::File.expand_path("../test_helper", __dir__)
4
-
5
- module Stripe
6
- class SetupAttemptTest < Test::Unit::TestCase
7
- should "be listable" do
8
- setup_attempts = Stripe::SetupAttempt.list({
9
- setup_intent: "seti_123",
10
- })
11
- assert_requested :get, "#{Stripe.api_base}/v1/setup_attempts?setup_intent=seti_123"
12
- assert setup_attempts.data.is_a?(Array)
13
- assert setup_attempts.data[0].is_a?(Stripe::SetupAttempt)
14
- end
15
- end
16
- end
@@ -1,84 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require ::File.expand_path("../test_helper", __dir__)
4
-
5
- module Stripe
6
- class SetupIntentTest < Test::Unit::TestCase
7
- TEST_RESOURCE_ID = "seti_123"
8
-
9
- should "be listable" do
10
- setup_intents = Stripe::SetupIntent.list
11
- assert_requested :get, "#{Stripe.api_base}/v1/setup_intents"
12
- assert setup_intents.data.is_a?(Array)
13
- assert setup_intents.data[0].is_a?(Stripe::SetupIntent)
14
- end
15
-
16
- should "be retrievable" do
17
- setup_intent = Stripe::SetupIntent.retrieve("seti_123")
18
- assert_requested :get, "#{Stripe.api_base}/v1/setup_intents/seti_123"
19
- assert setup_intent.is_a?(Stripe::SetupIntent)
20
- end
21
-
22
- should "be creatable" do
23
- setup_intent = Stripe::SetupIntent.create(
24
- payment_method_types: ["card"]
25
- )
26
- assert_requested :post, "#{Stripe.api_base}/v1/setup_intents"
27
- assert setup_intent.is_a?(Stripe::SetupIntent)
28
- end
29
-
30
- should "be saveable" do
31
- setup_intent = Stripe::SetupIntent.construct_from(id: "seti_123", object: "setup_intent", metadata: {})
32
- setup_intent.metadata["key"] = "value"
33
- setup_intent.save
34
- assert_requested :post, "#{Stripe.api_base}/v1/setup_intents/#{setup_intent.id}"
35
- end
36
-
37
- should "be updateable" do
38
- setup_intent = Stripe::SetupIntent.update("seti_123", metadata: { foo: "bar" })
39
-
40
- assert_requested :post, "#{Stripe.api_base}/v1/setup_intents/seti_123"
41
- assert setup_intent.is_a?(Stripe::SetupIntent)
42
- end
43
-
44
- context "#cancel" do
45
- should "cancel a setup_intent" do
46
- setup_intent = Stripe::SetupIntent.construct_from(id: "seti_123", object: "setup_intent")
47
- setup_intent = setup_intent.cancel
48
-
49
- assert_requested :post, "#{Stripe.api_base}/v1/setup_intents/seti_123/cancel"
50
- assert setup_intent.is_a?(Stripe::SetupIntent)
51
- end
52
- end
53
-
54
- context ".cancel" do
55
- should "cancel a setup_intent" do
56
- setup_intent = Stripe::SetupIntent.cancel("seti_123")
57
-
58
- assert_requested :post, "#{Stripe.api_base}/v1/setup_intents/seti_123/cancel"
59
- assert setup_intent.is_a?(Stripe::SetupIntent)
60
- end
61
- end
62
-
63
- context "#confirm" do
64
- should "confirm a setup_intent" do
65
- setup_intent = Stripe::SetupIntent.construct_from(id: "seti_123", object: "setup_intent")
66
- setup_intent = setup_intent.confirm(
67
- payment_method: "pm_123"
68
- )
69
-
70
- assert_requested :post, "#{Stripe.api_base}/v1/setup_intents/seti_123/confirm"
71
- assert setup_intent.is_a?(Stripe::SetupIntent)
72
- end
73
- end
74
-
75
- context ".confirm" do
76
- should "confirm a setup_intent" do
77
- setup_intent = Stripe::SetupIntent.confirm("seti_123", payment_method: "pm_123")
78
-
79
- assert_requested :post, "#{Stripe.api_base}/v1/setup_intents/seti_123/confirm"
80
- assert setup_intent.is_a?(Stripe::SetupIntent)
81
- end
82
- end
83
- end
84
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require ::File.expand_path("../../test_helper", __dir__)
4
-
5
- module Stripe
6
- module Issuing
7
- class ScheduledQueryRunTest < Test::Unit::TestCase
8
- should "be listable" do
9
- runs = Stripe::Sigma::ScheduledQueryRun.list
10
- assert_requested :get, "#{Stripe.api_base}/v1/sigma/scheduled_query_runs"
11
- assert runs.data.is_a?(Array)
12
- assert runs.data[0].is_a?(Stripe::Sigma::ScheduledQueryRun)
13
- end
14
-
15
- should "be retrievable" do
16
- run = Stripe::Sigma::ScheduledQueryRun.retrieve("sqr_123")
17
- assert_requested :get, "#{Stripe.api_base}/v1/sigma/scheduled_query_runs/sqr_123"
18
- assert run.is_a?(Stripe::Sigma::ScheduledQueryRun)
19
- end
20
- end
21
- end
22
- end
@@ -1,60 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require ::File.expand_path("../test_helper", __dir__)
4
-
5
- module Stripe
6
- class SKUTest < Test::Unit::TestCase
7
- should "be listable" do
8
- skus = Stripe::SKU.list
9
- assert_requested :get, "#{Stripe.api_base}/v1/skus"
10
- assert skus.data.is_a?(Array)
11
- assert skus.data[0].is_a?(Stripe::SKU)
12
- end
13
-
14
- should "be retrievable" do
15
- sku = Stripe::SKU.retrieve("sku_123")
16
- assert_requested :get, "#{Stripe.api_base}/v1/skus/sku_123"
17
- assert sku.is_a?(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: "prod_123"
26
- )
27
- assert_requested :post, "#{Stripe.api_base}/v1/skus"
28
- end
29
-
30
- should "be saveable" do
31
- sku = Stripe::SKU.retrieve("sku_123")
32
- sku.metadata["key"] = "value"
33
- sku.save
34
- assert_requested :post, "#{Stripe.api_base}/v1/skus/#{sku.id}"
35
- end
36
-
37
- should "be updateable" do
38
- sku = Stripe::SKU.update("sku_123", metadata: { foo: "bar" })
39
- assert_requested :post, "#{Stripe.api_base}/v1/skus/sku_123"
40
- assert sku.is_a?(Stripe::SKU)
41
- end
42
-
43
- context "#delete" do
44
- should "be deletable" do
45
- sku = Stripe::SKU.retrieve("sku_123")
46
- sku = sku.delete
47
- assert_requested :delete, "#{Stripe.api_base}/v1/skus/#{sku.id}"
48
- assert sku.is_a?(Stripe::SKU)
49
- end
50
- end
51
-
52
- context ".delete" do
53
- should "be deletable" do
54
- sku = Stripe::SKU.delete("sku_123")
55
- assert_requested :delete, "#{Stripe.api_base}/v1/skus/sku_123"
56
- assert sku.is_a?(Stripe::SKU)
57
- end
58
- end
59
- end
60
- end
@@ -1,119 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require ::File.expand_path("../test_helper", __dir__)
4
-
5
- module Stripe
6
- class SourceTest < Test::Unit::TestCase
7
- should "be retrievable" do
8
- source = Stripe::Source.retrieve("src_123")
9
- assert_requested :get, "#{Stripe.api_base}/v1/sources/src_123"
10
- assert source.is_a?(Stripe::Source)
11
- end
12
-
13
- should "be creatable" do
14
- source = Stripe::Source.create(
15
- type: "card",
16
- token: "tok_123"
17
- )
18
- assert_requested :post, "#{Stripe.api_base}/v1/sources"
19
- assert source.is_a?(Stripe::Source)
20
- end
21
-
22
- should "be saveable" do
23
- source = Stripe::Source.retrieve("src_123")
24
- source.metadata["key"] = "value"
25
- source.save
26
- assert_requested :post, "#{Stripe.api_base}/v1/sources/#{source.id}"
27
- end
28
-
29
- should "be updateable" do
30
- source = Stripe::Source.update("src_123", metadata: { foo: "bar" })
31
- assert_requested :post, "#{Stripe.api_base}/v1/sources/src_123"
32
- assert source.is_a?(Stripe::Source)
33
- end
34
-
35
- context "#detach" do
36
- should "not be deletable when unattached" do
37
- source = Stripe::Source.retrieve("src_123")
38
-
39
- assert_raises NotImplementedError do
40
- source.detach
41
- end
42
- end
43
-
44
- should "be deletable when attached to a customer" do
45
- source = Stripe::Source.construct_from(customer: "cus_123",
46
- id: "src_123",
47
- object: "source")
48
- source = source.detach
49
- assert_requested :delete, "#{Stripe.api_base}/v1/customers/cus_123/sources/src_123"
50
- assert source.is_a?(Stripe::Source)
51
- end
52
- end
53
-
54
- should "not be listable" do
55
- assert_raises NoMethodError do
56
- Stripe::Source.list
57
- end
58
- end
59
-
60
- context "#verify" do
61
- should "verify the source" do
62
- source = Stripe::Source.retrieve("src_123")
63
- source = source.verify(values: [1, 2])
64
- assert_requested :post,
65
- "#{Stripe.api_base}/v1/sources/#{source.id}/verify",
66
- body: { values: [1, 2] }
67
- assert source.is_a?(Stripe::Source)
68
- end
69
- end
70
-
71
- context ".verify" do
72
- should "verify the source" do
73
- source = Stripe::Source.verify("src_123", values: [1, 2])
74
- assert_requested :post,
75
- "#{Stripe.api_base}/v1/sources/src_123/verify",
76
- body: { values: [1, 2] }
77
- assert source.is_a?(Stripe::Source)
78
- end
79
- end
80
-
81
- context ".retrieve_source_transaction" do
82
- should "retrieve a source transaction" do
83
- Stripe::Source.retrieve_source_transaction(
84
- "src_123",
85
- "srctxn_123"
86
- )
87
- assert_requested :get, "#{Stripe.api_base}/v1/sources/src_123/source_transactions/srctxn_123"
88
- end
89
- end
90
-
91
- context ".list_source_transactions" do
92
- should "list source transactions" do
93
- Stripe::Source.list_source_transactions(
94
- "src_123"
95
- )
96
- assert_requested :get, "#{Stripe.api_base}/v1/sources/src_123/source_transactions"
97
- end
98
- end
99
-
100
- context "#source_transactions" do
101
- should "list source transactions" do
102
- old_stderr = $stderr
103
- $stderr = StringIO.new
104
-
105
- begin
106
- source = Stripe::Source.construct_from(id: "src_123",
107
- object: "source")
108
- source.source_transactions
109
- assert_requested :get, "#{Stripe.api_base}/v1/sources/src_123/source_transactions"
110
-
111
- assert_include $stderr.string,
112
- "use Source.list_source_transactions instead"
113
- ensure
114
- $stderr = old_stderr
115
- end
116
- end
117
- end
118
- end
119
- end
@@ -1,1456 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require ::File.expand_path("../test_helper", __dir__)
4
-
5
- module Stripe
6
- class StripeClientTest < Test::Unit::TestCase
7
- context "initializing a StripeClient" do
8
- should "allow a String to be passed in order to set the api key" do
9
- assert_equal StripeClient.new("test_123").config.api_key, "test_123"
10
- end
11
-
12
- should "allow for overrides via a Hash" do
13
- config = { api_key: "test_123", open_timeout: 100 }
14
- client = StripeClient.new(config)
15
-
16
- assert_equal client.config.api_key, "test_123"
17
- assert_equal client.config.open_timeout, 100
18
- end
19
-
20
- should "support deprecated ConnectionManager objects" do
21
- assert StripeClient.new(Stripe::ConnectionManager.new).config.is_a?(Stripe::StripeConfiguration)
22
- end
23
-
24
- should "support passing a full configuration object" do
25
- config = Stripe.config.reverse_duplicate_merge({ api_key: "test_123", open_timeout: 100 })
26
- client = StripeClient.new(config)
27
- assert_equal config, client.config
28
- end
29
- end
30
-
31
- context ".active_client" do
32
- should "be .default_client outside of #request" do
33
- assert_equal StripeClient.default_client, StripeClient.active_client
34
- end
35
-
36
- should "be active client inside of #request" do
37
- client = StripeClient.new
38
- client.request do
39
- assert_equal client, StripeClient.active_client
40
- end
41
- end
42
- end
43
-
44
- context ".maybe_gc_connection_managers" do
45
- should "garbage collect old connection managers when appropriate" do
46
- stub_request(:post, "#{Stripe.api_base}/v1/path")
47
- .to_return(body: JSON.generate(object: "account"))
48
-
49
- # Make sure we start with a blank slate (state may have been left in
50
- # place by other tests).
51
- StripeClient.clear_all_connection_managers
52
-
53
- # Establish a base time.
54
- t = 0.0
55
-
56
- # And pretend that `StripeClient` was just initialized for the first
57
- # time. (Don't access instance variables like this, but it's tricky to
58
- # test properly otherwise.)
59
- StripeClient.instance_variable_set(:@last_connection_manager_gc, t)
60
-
61
- #
62
- # t
63
- #
64
- Util.stubs(:monotonic_time).returns(t)
65
-
66
- # Execute an initial request to ensure that a connection manager was
67
- # created.
68
- client = StripeClient.new
69
- client.execute_request(:post, "/v1/path")
70
-
71
- # The GC shouldn't run yet (a `nil` return indicates that GC didn't run).
72
- assert_equal nil, StripeClient.maybe_gc_connection_managers
73
-
74
- #
75
- # t + StripeClient::CONNECTION_MANAGER_GC_PERIOD - 1
76
- #
77
- # Move time to just *before* garbage collection is eligible to run.
78
- # Nothing should happen.
79
- #
80
- Util.stubs(:monotonic_time).returns(t + StripeClient::CONNECTION_MANAGER_GC_PERIOD - 1)
81
-
82
- assert_equal nil, StripeClient.maybe_gc_connection_managers
83
-
84
- #
85
- # t + StripeClient::CONNECTION_MANAGER_GC_PERIOD + 1
86
- #
87
- # Move time to just *after* garbage collection is eligible to run.
88
- # Garbage collection will run, but because the connection manager is
89
- # not passed its expiry age, it will not be collected. Zero is returned
90
- # to indicate so.
91
- #
92
- Util.stubs(:monotonic_time).returns(t + StripeClient::CONNECTION_MANAGER_GC_PERIOD + 1)
93
-
94
- assert_equal 0, StripeClient.maybe_gc_connection_managers
95
-
96
- #
97
- # t + StripeClient::CONNECTION_MANAGER_GC_LAST_USED_EXPIRY + 1
98
- #
99
- # Move us far enough into the future that we're passed the horizons for
100
- # both a GC run as well as well as the expiry age of a connection
101
- # manager. That means the GC will run and collect the connection
102
- # manager that we created above.
103
- #
104
- Util.stubs(:monotonic_time).returns(t + StripeClient::CONNECTION_MANAGER_GC_LAST_USED_EXPIRY + 1)
105
-
106
- assert_equal 1, StripeClient.maybe_gc_connection_managers
107
-
108
- # And as an additional check, the connection manager of the current
109
- # thread context should have been removed as it was GCed.
110
- assert_equal({}, StripeClient.current_thread_context.default_connection_managers)
111
- end
112
-
113
- should "only garbage collect when all connection managers for a thread are expired" do
114
- stub_request(:post, "#{Stripe.api_base}/v1/path")
115
- .to_return(body: JSON.generate(object: "account"))
116
-
117
- # Make sure we start with a blank slate (state may have been left in
118
- # place by other tests).
119
- StripeClient.clear_all_connection_managers
120
-
121
- # Establish a base time.
122
- t = 0.0
123
-
124
- # And pretend that `StripeClient` was just initialized for the first
125
- # time. (Don't access instance variables like this, but it's tricky to
126
- # test properly otherwise.)
127
- StripeClient.instance_variable_set(:@last_connection_manager_gc, t)
128
-
129
- #
130
- # t
131
- #
132
- Util.stubs(:monotonic_time).returns(t)
133
-
134
- # Execute an initial request to ensure that a connection manager was
135
- # created.
136
- client = StripeClient.new
137
- client.execute_request(:post, "/v1/path")
138
-
139
- # Create a new client with a unique config to make sure the thread has two
140
- # connection managers
141
- active_client = StripeClient.new(max_network_retries: 10)
142
- active_client.execute_request(:post, "/v1/path")
143
-
144
- assert_equal 2, StripeClient.current_thread_context.default_connection_managers.keys.count
145
- assert_equal nil, StripeClient.maybe_gc_connection_managers
146
-
147
- # t + StripeClient::CONNECTION_MANAGER_GC_LAST_USED_EXPIRY + 1
148
- #
149
- # Move us far enough into the future that we're passed the horizons for
150
- # both a GC run as well as well as the expiry age of a connection
151
- # manager. That means the GC will run and collect the connection
152
- # manager that we created above.
153
- #
154
- Util.stubs(:monotonic_time).returns(t + StripeClient::CONNECTION_MANAGER_GC_LAST_USED_EXPIRY + 1)
155
-
156
- # Manually set the active_client's last_used time into the future to prevent GC.
157
- StripeClient.default_connection_manager(active_client.config)
158
- .instance_variable_set(:@last_used, Util.monotonic_time + 1)
159
-
160
- assert_equal 0, StripeClient.maybe_gc_connection_managers
161
-
162
- # Move time into the future past the last GC round
163
- current_time = Util.monotonic_time
164
- Util.stubs(:monotonic_time).returns(current_time * 2)
165
-
166
- assert_equal 1, StripeClient.maybe_gc_connection_managers
167
- end
168
- end
169
-
170
- context ".clear_all_connection_managers" do
171
- should "clear connection managers across all threads" do
172
- stub_request(:post, "#{Stripe.api_base}/path")
173
- .to_return(body: JSON.generate(object: "account"))
174
-
175
- num_threads = 3
176
-
177
- # Poorly named class -- note this is actually a concurrent queue.
178
- recv_queue = Queue.new
179
- send_queue = Queue.new
180
-
181
- threads = num_threads.times.map do |_|
182
- Thread.start do
183
- # Causes a connection manager to be created on this thread and a
184
- # connection within that manager to be created for API access.
185
- manager = StripeClient.default_connection_manager
186
- manager.execute_request(:post, "#{Stripe.api_base}/path")
187
-
188
- # Signal to the main thread we're ready.
189
- recv_queue << true
190
-
191
- # Wait for the main thread to signal continue.
192
- send_queue.pop
193
-
194
- # This check isn't great, but it's otherwise difficult to tell that
195
- # anything happened with just the public-facing API.
196
- assert_equal({}, manager.instance_variable_get(:@active_connections))
197
- end
198
- end
199
-
200
- # Wait for threads to start up.
201
- threads.each { recv_queue.pop }
202
-
203
- # Do the clear (the method we're actually trying to test).
204
- StripeClient.clear_all_connection_managers
205
-
206
- # Tell threads to run their check.
207
- threads.each { send_queue << true }
208
-
209
- # And finally, give all threads time to perform their check.
210
- threads.each(&:join)
211
- end
212
-
213
- should "clear only connection managers with a given configuration" do
214
- StripeClient.clear_all_connection_managers
215
-
216
- client1 = StripeClient.new(read_timeout: 5.0)
217
- StripeClient.default_connection_manager(client1.config)
218
- client2 = StripeClient.new(read_timeout: 2.0)
219
- StripeClient.default_connection_manager(client2.config)
220
-
221
- thread_contexts = StripeClient.instance_variable_get(:@thread_contexts_with_connection_managers)
222
- assert_equal 1, thread_contexts.count
223
- thread_context = thread_contexts.first
224
-
225
- refute_nil thread_context.default_connection_managers[client1.config.key]
226
- refute_nil thread_context.default_connection_managers[client2.config.key]
227
-
228
- StripeClient.clear_all_connection_managers(config: client1.config)
229
-
230
- assert_nil thread_context.default_connection_managers[client1.config.key]
231
- refute_nil thread_context.default_connection_managers[client2.config.key]
232
- end
233
- end
234
-
235
- context ".default_client" do
236
- should "be a StripeClient" do
237
- assert_kind_of StripeClient, StripeClient.default_client
238
- end
239
-
240
- should "be a different client on each thread" do
241
- other_thread_client = nil
242
- thread = Thread.new do
243
- other_thread_client = StripeClient.default_client
244
- end
245
- thread.join
246
- refute_equal StripeClient.default_client, other_thread_client
247
- end
248
- end
249
-
250
- context ".default_connection_manager" do
251
- should "be a ConnectionManager" do
252
- assert_kind_of ConnectionManager,
253
- StripeClient.default_connection_manager
254
- end
255
-
256
- should "be a different connection on each thread" do
257
- other_thread_manager = nil
258
- thread = Thread.new do
259
- other_thread_manager = StripeClient.default_connection_manager
260
- end
261
- thread.join
262
- refute_equal StripeClient.default_connection_manager, other_thread_manager
263
- end
264
-
265
- should "create a separate connection manager per configuration" do
266
- config = Stripe::StripeConfiguration.setup { |c| c.open_timeout = 100 }
267
- connection_manager_one = StripeClient.default_connection_manager
268
- connection_manager_two = StripeClient.default_connection_manager(config)
269
-
270
- assert_equal connection_manager_one.config.open_timeout, 30
271
- assert_equal connection_manager_two.config.open_timeout, 100
272
- end
273
-
274
- should "create a single connection manager for identical configurations" do
275
- StripeClient.clear_all_connection_managers
276
-
277
- 2.times { StripeClient.default_connection_manager(Stripe::StripeConfiguration.setup) }
278
-
279
- assert_equal 1, StripeClient.instance_variable_get(:@thread_contexts_with_connection_managers).first.default_connection_managers.size
280
- end
281
- end
282
-
283
- context ".should_retry?" do
284
- setup do
285
- Stripe::StripeConfiguration.any_instance.stubs(:max_network_retries).returns(2)
286
- end
287
-
288
- should "retry on Errno::ECONNREFUSED" do
289
- assert StripeClient.should_retry?(Errno::ECONNREFUSED.new,
290
- method: :post, num_retries: 0)
291
- end
292
-
293
- should "retry on EOFError" do
294
- assert StripeClient.should_retry?(EOFError.new,
295
- method: :post, num_retries: 0)
296
- end
297
-
298
- should "retry on Errno::ECONNRESET" do
299
- assert StripeClient.should_retry?(Errno::ECONNRESET.new,
300
- method: :post, num_retries: 0)
301
- end
302
-
303
- should "retry on Errno::ETIMEDOUT" do
304
- assert StripeClient.should_retry?(Errno::ETIMEDOUT.new,
305
- method: :post, num_retries: 0)
306
- end
307
-
308
- should "retry on Errno::EHOSTUNREACH" do
309
- assert StripeClient.should_retry?(Errno::EHOSTUNREACH.new,
310
- method: :post, num_retries: 0)
311
- end
312
-
313
- should "retry on Net::OpenTimeout" do
314
- assert StripeClient.should_retry?(Net::OpenTimeout.new,
315
- method: :post, num_retries: 0)
316
- end
317
-
318
- should "retry on Net::ReadTimeout" do
319
- assert StripeClient.should_retry?(Net::ReadTimeout.new,
320
- method: :post, num_retries: 0)
321
- end
322
-
323
- should "retry on SocketError" do
324
- assert StripeClient.should_retry?(SocketError.new,
325
- method: :post, num_retries: 0)
326
- end
327
-
328
- should "retry when the `Stripe-Should-Retry` header is `true`" do
329
- headers = StripeResponse::Headers.new(
330
- "Stripe-Should-Retry" => ["true"]
331
- )
332
-
333
- # Note we send status 400 here, which would normally not be retried.
334
- assert StripeClient.should_retry?(Stripe::StripeError.new(http_headers: headers,
335
- http_status: 400),
336
- method: :post, num_retries: 0)
337
- end
338
-
339
- should "not retry when the `Stripe-Should-Retry` header is `false`" do
340
- headers = StripeResponse::Headers.new(
341
- "Stripe-Should-Retry" => ["false"]
342
- )
343
-
344
- # Note we send status 409 here, which would normally be retried.
345
- refute StripeClient.should_retry?(Stripe::StripeError.new(http_headers: headers,
346
- http_status: 409),
347
- method: :post, num_retries: 0)
348
- end
349
-
350
- should "retry on a 409 Conflict" do
351
- assert StripeClient.should_retry?(Stripe::StripeError.new(http_status: 409),
352
- method: :post, num_retries: 0)
353
- end
354
-
355
- should "retry on a 429 Too Many Requests when lock timeout" do
356
- assert StripeClient.should_retry?(Stripe::StripeError.new(http_status: 429,
357
- code: "lock_timeout"),
358
- method: :post, num_retries: 0)
359
- end
360
-
361
- should "retry on a 500 Internal Server Error when non-POST" do
362
- assert StripeClient.should_retry?(Stripe::StripeError.new(http_status: 500),
363
- method: :get, num_retries: 0)
364
- end
365
-
366
- should "retry on a 503 Service Unavailable" do
367
- assert StripeClient.should_retry?(Stripe::StripeError.new(http_status: 503),
368
- method: :post, num_retries: 0)
369
- end
370
-
371
- should "not retry at maximum count" do
372
- refute StripeClient.should_retry?(RuntimeError.new,
373
- method: :post, num_retries: Stripe.max_network_retries)
374
- end
375
-
376
- should "not retry on a certificate validation error" do
377
- refute StripeClient.should_retry?(OpenSSL::SSL::SSLError.new,
378
- method: :post, num_retries: 0)
379
- end
380
-
381
- should "not retry on a 429 Too Many Requests when not lock timeout" do
382
- refute StripeClient.should_retry?(Stripe::StripeError.new(http_status: 429,
383
- code: "rate_limited"),
384
- method: :post, num_retries: 0)
385
- end
386
-
387
- should "not retry on a 500 Internal Server Error when POST" do
388
- refute StripeClient.should_retry?(Stripe::StripeError.new(http_status: 500),
389
- method: :post, num_retries: 0)
390
- end
391
- end
392
-
393
- context ".sleep_time" do
394
- should "should grow exponentially" do
395
- StripeClient.stubs(:rand).returns(1)
396
- Stripe.config.stubs(:max_network_retry_delay).returns(999)
397
- assert_equal(Stripe.initial_network_retry_delay, StripeClient.sleep_time(1))
398
- assert_equal(Stripe.initial_network_retry_delay * 2, StripeClient.sleep_time(2))
399
- assert_equal(Stripe.initial_network_retry_delay * 4, StripeClient.sleep_time(3))
400
- assert_equal(Stripe.initial_network_retry_delay * 8, StripeClient.sleep_time(4))
401
- end
402
-
403
- should "enforce the max_network_retry_delay" do
404
- StripeClient.stubs(:rand).returns(1)
405
- Stripe.config.stubs(:initial_network_retry_delay).returns(1)
406
- Stripe.config.stubs(:max_network_retry_delay).returns(2)
407
- assert_equal(1, StripeClient.sleep_time(1))
408
- assert_equal(2, StripeClient.sleep_time(2))
409
- assert_equal(2, StripeClient.sleep_time(3))
410
- assert_equal(2, StripeClient.sleep_time(4))
411
- end
412
-
413
- should "add some randomness" do
414
- random_value = 0.8
415
- StripeClient.stubs(:rand).returns(random_value)
416
- Stripe.config.stubs(:initial_network_retry_delay).returns(1)
417
- Stripe.config.stubs(:max_network_retry_delay).returns(8)
418
-
419
- base_value = Stripe.initial_network_retry_delay * (0.5 * (1 + random_value))
420
-
421
- # the initial value cannot be smaller than the base,
422
- # so the randomness is ignored
423
- assert_equal(Stripe.initial_network_retry_delay, StripeClient.sleep_time(1))
424
-
425
- # after the first one, the randomness is applied
426
- assert_equal(base_value * 2, StripeClient.sleep_time(2))
427
- assert_equal(base_value * 4, StripeClient.sleep_time(3))
428
- assert_equal(base_value * 8, StripeClient.sleep_time(4))
429
- end
430
-
431
- should "permit passing in a configuration object" do
432
- StripeClient.stubs(:rand).returns(1)
433
- config = Stripe::StripeConfiguration.setup do |c|
434
- c.initial_network_retry_delay = 1
435
- c.max_network_retry_delay = 2
436
- end
437
-
438
- # Set the global configuration to be different than the client
439
- Stripe.config.stubs(:initial_network_retry_delay).returns(100)
440
- Stripe.config.stubs(:max_network_retry_delay).returns(200)
441
-
442
- assert_equal(1, StripeClient.sleep_time(1, config: config))
443
- assert_equal(2, StripeClient.sleep_time(2, config: config))
444
- assert_equal(2, StripeClient.sleep_time(3, config: config))
445
- assert_equal(2, StripeClient.sleep_time(4, config: config))
446
- end
447
- end
448
-
449
- context "#execute_request" do
450
- context "headers" do
451
- should "support literal headers" do
452
- stub_request(:post, "#{Stripe.api_base}/v1/account")
453
- .with(headers: { "Stripe-Account" => "bar" })
454
- .to_return(body: JSON.generate(object: "account"))
455
-
456
- client = StripeClient.new
457
- client.execute_request(:post, "/v1/account",
458
- headers: { "Stripe-Account" => "bar" })
459
- end
460
-
461
- should "support RestClient-style header keys" do
462
- stub_request(:post, "#{Stripe.api_base}/v1/account")
463
- .with(headers: { "Stripe-Account" => "bar" })
464
- .to_return(body: JSON.generate(object: "account"))
465
-
466
- client = StripeClient.new
467
- client.execute_request(:post, "/v1/account",
468
- headers: { stripe_account: "bar" })
469
- end
470
- end
471
-
472
- context "logging" do
473
- setup do
474
- # Freeze time for the purposes of the `elapsed` parameter that we
475
- # emit for responses. Mocha's `anything` parameter can't match inside
476
- # of a hash and is therefore not useful for this purpose. If we
477
- # switch over to rspec-mocks at some point, we can probably remove
478
- # this.
479
- Util.stubs(:monotonic_time).returns(0.0)
480
-
481
- # Stub the Stripe.config so that mocha matchers will succeed. Currently,
482
- # mocha does not support using param matchers within hashes.
483
- StripeClient.any_instance.stubs(:config).returns(Stripe.config)
484
- end
485
-
486
- should "produce appropriate logging" do
487
- body = JSON.generate(object: "account")
488
-
489
- Util.expects(:log_info).with("Request to Stripe API",
490
- account: "acct_123",
491
- api_version: "2010-11-12",
492
- idempotency_key: "abc",
493
- method: :post,
494
- num_retries: 0,
495
- path: "/v1/account",
496
- config: Stripe.config)
497
- Util.expects(:log_debug).with("Request details",
498
- body: "",
499
- idempotency_key: "abc",
500
- query: nil,
501
- config: Stripe.config)
502
-
503
- Util.expects(:log_info).with("Response from Stripe API",
504
- account: "acct_123",
505
- api_version: "2010-11-12",
506
- elapsed: 0.0,
507
- idempotency_key: "abc",
508
- method: :post,
509
- path: "/v1/account",
510
- request_id: "req_123",
511
- status: 200,
512
- config: Stripe.config)
513
- Util.expects(:log_debug).with("Response details",
514
- body: body,
515
- idempotency_key: "abc",
516
- request_id: "req_123",
517
- config: Stripe.config)
518
- Util.expects(:log_debug).with("Dashboard link for request",
519
- idempotency_key: "abc",
520
- request_id: "req_123",
521
- url: Util.request_id_dashboard_url("req_123", Stripe.api_key),
522
- config: Stripe.config)
523
-
524
- stub_request(:post, "#{Stripe.api_base}/v1/account")
525
- .to_return(
526
- body: body,
527
- headers: {
528
- "Idempotency-Key" => "abc",
529
- "Request-Id" => "req_123",
530
- "Stripe-Account" => "acct_123",
531
- "Stripe-Version" => "2010-11-12",
532
- }
533
- )
534
-
535
- client = StripeClient.new
536
- client.execute_request(:post, "/v1/account",
537
- headers: {
538
- "Idempotency-Key" => "abc",
539
- "Stripe-Account" => "acct_123",
540
- "Stripe-Version" => "2010-11-12",
541
- })
542
- end
543
-
544
- should "produce logging on API error" do
545
- Util.expects(:log_info).with("Request to Stripe API",
546
- account: nil,
547
- api_version: nil,
548
- idempotency_key: nil,
549
- method: :post,
550
- num_retries: 0,
551
- path: "/v1/account",
552
- config: Stripe.config)
553
- Util.expects(:log_info).with("Response from Stripe API",
554
- account: nil,
555
- api_version: nil,
556
- elapsed: 0.0,
557
- idempotency_key: nil,
558
- method: :post,
559
- path: "/v1/account",
560
- request_id: nil,
561
- status: 500,
562
- config: Stripe.config)
563
-
564
- error = {
565
- code: "code",
566
- message: "message",
567
- param: "param",
568
- type: "type",
569
- }
570
- Util.expects(:log_error).with("Stripe API error",
571
- status: 500,
572
- error_code: error[:code],
573
- error_message: error[:message],
574
- error_param: error[:param],
575
- error_type: error[:type],
576
- idempotency_key: nil,
577
- request_id: nil,
578
- config: Stripe.config)
579
-
580
- stub_request(:post, "#{Stripe.api_base}/v1/account")
581
- .to_return(
582
- body: JSON.generate(error: error),
583
- status: 500
584
- )
585
-
586
- client = StripeClient.new
587
- assert_raises Stripe::APIError do
588
- client.execute_request(:post, "/v1/account")
589
- end
590
- end
591
-
592
- should "produce logging on OAuth error" do
593
- Util.expects(:log_info).with("Request to Stripe API",
594
- account: nil,
595
- api_version: nil,
596
- idempotency_key: nil,
597
- method: :post,
598
- num_retries: 0,
599
- path: "/oauth/token",
600
- config: Stripe.config)
601
- Util.expects(:log_info).with("Response from Stripe API",
602
- account: nil,
603
- api_version: nil,
604
- elapsed: 0.0,
605
- idempotency_key: nil,
606
- method: :post,
607
- path: "/oauth/token",
608
- request_id: nil,
609
- status: 400,
610
- config: Stripe.config)
611
-
612
- Util.expects(:log_error).with("Stripe OAuth error",
613
- status: 400,
614
- error_code: "invalid_request",
615
- error_description: "No grant type specified",
616
- idempotency_key: nil,
617
- request_id: nil,
618
- config: Stripe.config)
619
-
620
- stub_request(:post, "#{Stripe.connect_base}/oauth/token")
621
- .to_return(body: JSON.generate(error: "invalid_request",
622
- error_description: "No grant type specified"), status: 400)
623
-
624
- client = StripeClient.new
625
- opts = { api_base: Stripe.connect_base }
626
- assert_raises Stripe::OAuth::InvalidRequestError do
627
- client.execute_request(:post, "/oauth/token", **opts)
628
- end
629
- end
630
- end
631
-
632
- context "Stripe-Account header" do
633
- should "use a globally set header" do
634
- begin
635
- old = Stripe.stripe_account
636
- Stripe.stripe_account = "acct_1234"
637
-
638
- stub_request(:post, "#{Stripe.api_base}/v1/account")
639
- .with(headers: { "Stripe-Account" => Stripe.stripe_account })
640
- .to_return(body: JSON.generate(object: "account"))
641
-
642
- client = StripeClient.new
643
- client.execute_request(:post, "/v1/account")
644
- ensure
645
- Stripe.stripe_account = old
646
- end
647
- end
648
-
649
- should "use a locally set header" do
650
- stripe_account = "acct_0000"
651
- stub_request(:post, "#{Stripe.api_base}/v1/account")
652
- .with(headers: { "Stripe-Account" => stripe_account })
653
- .to_return(body: JSON.generate(object: "account"))
654
-
655
- client = StripeClient.new
656
- client.execute_request(:post, "/v1/account",
657
- headers: { stripe_account: stripe_account })
658
- end
659
-
660
- should "not send it otherwise" do
661
- stub_request(:post, "#{Stripe.api_base}/v1/account")
662
- .with do |req|
663
- req.headers["Stripe-Account"].nil?
664
- end.to_return(body: JSON.generate(object: "account"))
665
-
666
- client = StripeClient.new
667
- client.execute_request(:post, "/v1/account")
668
- end
669
- end
670
-
671
- context "app_info" do
672
- should "send app_info if set" do
673
- begin
674
- old = Stripe.app_info
675
- Stripe.set_app_info(
676
- "MyAwesomePlugin",
677
- partner_id: "partner_1234",
678
- url: "https://myawesomeplugin.info",
679
- version: "1.2.34"
680
- )
681
-
682
- stub_request(:post, "#{Stripe.api_base}/v1/account")
683
- .with do |req|
684
- assert_equal \
685
- "Stripe/v1 RubyBindings/#{Stripe::VERSION} " \
686
- "MyAwesomePlugin/1.2.34 (https://myawesomeplugin.info)",
687
- req.headers["User-Agent"]
688
-
689
- data = JSON.parse(req.headers["X-Stripe-Client-User-Agent"],
690
- symbolize_names: true)
691
-
692
- assert_equal({
693
- name: "MyAwesomePlugin",
694
- partner_id: "partner_1234",
695
- url: "https://myawesomeplugin.info",
696
- version: "1.2.34",
697
- }, data[:application])
698
-
699
- true
700
- end.to_return(body: JSON.generate(object: "account"))
701
-
702
- client = StripeClient.new
703
- client.execute_request(:post, "/v1/account")
704
- ensure
705
- Stripe.app_info = old
706
- end
707
- end
708
- end
709
-
710
- context "error handling" do
711
- should "handle error response with empty body" do
712
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
713
- .to_return(body: "", status: 500)
714
-
715
- client = StripeClient.new
716
-
717
- e = assert_raises Stripe::APIError do
718
- client.execute_request(:post, "/v1/charges")
719
- end
720
- assert_equal 'Invalid response object from API: "" (HTTP response code was 500)', e.message
721
- end
722
-
723
- should "handle success response with empty body" do
724
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
725
- .to_return(body: "", status: 200)
726
-
727
- client = StripeClient.new
728
-
729
- e = assert_raises Stripe::APIError do
730
- client.execute_request(:post, "/v1/charges")
731
- end
732
- assert_equal 'Invalid response object from API: "" (HTTP response code was 200)', e.message
733
- end
734
-
735
- should "feed a request ID through to the error object" do
736
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
737
- .to_return(body: JSON.generate(make_missing_id_error),
738
- headers: { "Request-ID": "req_123" },
739
- status: 400)
740
-
741
- client = StripeClient.new
742
-
743
- e = assert_raises Stripe::InvalidRequestError do
744
- client.execute_request(:post, "/v1/charges")
745
- end
746
- assert_equal("req_123", e.request_id)
747
- end
748
-
749
- should "handle low level error" do
750
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
751
- .to_raise(Errno::ECONNREFUSED.new)
752
-
753
- client = StripeClient.new
754
-
755
- e = assert_raises Stripe::APIConnectionError do
756
- client.execute_request(:post, "/v1/charges")
757
- end
758
- assert_equal StripeClient::ERROR_MESSAGE_CONNECTION % Stripe.api_base +
759
- "\n\n(Network error: Connection refused)",
760
- e.message
761
- end
762
-
763
- should "handle error response with unknown value" do
764
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
765
- .to_return(body: JSON.generate(bar: "foo"), status: 500)
766
-
767
- client = StripeClient.new
768
-
769
- e = assert_raises Stripe::APIError do
770
- client.execute_request(:post, "/v1/charges")
771
- end
772
- assert_equal 'Invalid response object from API: "{\"bar\":\"foo\"}" (HTTP response code was 500)', e.message
773
- end
774
-
775
- should "raise IdempotencyError on 400 of type idempotency_error" do
776
- data = make_missing_id_error
777
- data[:error][:type] = "idempotency_error"
778
-
779
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
780
- .to_return(body: JSON.generate(data), status: 400)
781
-
782
- client = StripeClient.new
783
-
784
- e = assert_raises Stripe::IdempotencyError do
785
- client.execute_request(:post, "/v1/charges")
786
- end
787
- assert_equal(400, e.http_status)
788
- assert_equal(true, e.json_body.is_a?(Hash))
789
- end
790
-
791
- should "raise InvalidRequestError on other 400s" do
792
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
793
- .to_return(body: JSON.generate(make_missing_id_error), status: 400)
794
-
795
- client = StripeClient.new
796
-
797
- e = assert_raises Stripe::InvalidRequestError do
798
- client.execute_request(:post, "/v1/charges")
799
- end
800
- assert_equal(400, e.http_status)
801
- assert_equal(true, e.json_body.is_a?(Hash))
802
- end
803
-
804
- should "raise AuthenticationError on 401" do
805
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
806
- .to_return(body: JSON.generate(make_missing_id_error), status: 401)
807
-
808
- client = StripeClient.new
809
-
810
- e = assert_raises Stripe::AuthenticationError do
811
- client.execute_request(:post, "/v1/charges")
812
- end
813
- assert_equal(401, e.http_status)
814
- assert_equal(true, e.json_body.is_a?(Hash))
815
- end
816
-
817
- should "raise CardError on 402" do
818
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
819
- .to_return(body: JSON.generate(make_invalid_exp_year_error), status: 402)
820
-
821
- client = StripeClient.new
822
-
823
- e = assert_raises Stripe::CardError do
824
- client.execute_request(:post, "/v1/charges")
825
- end
826
- assert_equal(402, e.http_status)
827
- assert_equal(true, e.json_body.is_a?(Hash))
828
- assert_equal("invalid_expiry_year", e.code)
829
- assert_equal("exp_year", e.param)
830
- end
831
-
832
- should "raise PermissionError on 403" do
833
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
834
- .to_return(body: JSON.generate(make_missing_id_error), status: 403)
835
-
836
- client = StripeClient.new
837
-
838
- e = assert_raises Stripe::PermissionError do
839
- client.execute_request(:post, "/v1/charges")
840
- end
841
- assert_equal(403, e.http_status)
842
- assert_equal(true, e.json_body.is_a?(Hash))
843
- end
844
-
845
- should "raise InvalidRequestError on 404" do
846
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
847
- .to_return(body: JSON.generate(make_missing_id_error), status: 404)
848
-
849
- client = StripeClient.new
850
-
851
- e = assert_raises Stripe::InvalidRequestError do
852
- client.execute_request(:post, "/v1/charges")
853
- end
854
- assert_equal(404, e.http_status)
855
- assert_equal(true, e.json_body.is_a?(Hash))
856
- end
857
-
858
- should "raise RateLimitError on 429" do
859
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
860
- .to_return(body: JSON.generate(make_rate_limit_error), status: 429)
861
-
862
- client = StripeClient.new
863
-
864
- e = assert_raises Stripe::RateLimitError do
865
- client.execute_request(:post, "/v1/charges")
866
- end
867
- assert_equal(429, e.http_status)
868
- assert_equal(true, e.json_body.is_a?(Hash))
869
- end
870
-
871
- should "raise OAuth::InvalidRequestError when error is a string with value 'invalid_request'" do
872
- stub_request(:post, "#{Stripe.connect_base}/oauth/token")
873
- .to_return(body: JSON.generate(error: "invalid_request",
874
- error_description: "No grant type specified"), status: 400)
875
-
876
- client = StripeClient.new
877
-
878
- opts = { api_base: Stripe.connect_base }
879
- e = assert_raises Stripe::OAuth::InvalidRequestError do
880
- client.execute_request(:post, "/oauth/token", **opts)
881
- end
882
-
883
- assert_equal(400, e.http_status)
884
- assert_equal("No grant type specified", e.message)
885
- end
886
-
887
- should "raise OAuth::InvalidGrantError when error is a string with value 'invalid_grant'" do
888
- stub_request(:post, "#{Stripe.connect_base}/oauth/token")
889
- .to_return(body: JSON.generate(error: "invalid_grant",
890
- error_description: "This authorization code has already been used. All tokens issued with this code have been revoked."), status: 400)
891
-
892
- client = StripeClient.new
893
-
894
- opts = { api_base: Stripe.connect_base }
895
- e = assert_raises Stripe::OAuth::InvalidGrantError do
896
- client.execute_request(:post, "/oauth/token", **opts)
897
- end
898
-
899
- assert_equal(400, e.http_status)
900
- assert_equal("invalid_grant", e.code)
901
- assert_equal("This authorization code has already been used. All tokens issued with this code have been revoked.", e.message)
902
- end
903
-
904
- should "raise OAuth::InvalidClientError when error is a string with value 'invalid_client'" do
905
- stub_request(:post, "#{Stripe.connect_base}/oauth/deauthorize")
906
- .to_return(body: JSON.generate(error: "invalid_client",
907
- error_description: "This application is not connected to stripe account acct_19tLK7DSlTMT26Mk, or that account does not exist."), status: 401)
908
-
909
- client = StripeClient.new
910
-
911
- opts = { api_base: Stripe.connect_base }
912
- e = assert_raises Stripe::OAuth::InvalidClientError do
913
- client.execute_request(:post, "/oauth/deauthorize", **opts)
914
- end
915
-
916
- assert_equal(401, e.http_status)
917
- assert_equal("invalid_client", e.code)
918
- assert_equal("This application is not connected to stripe account acct_19tLK7DSlTMT26Mk, or that account does not exist.", e.message)
919
- end
920
-
921
- should "raise Stripe::OAuthError on indeterminate OAuth error" do
922
- stub_request(:post, "#{Stripe.connect_base}/oauth/deauthorize")
923
- .to_return(body: JSON.generate(error: "new_code_not_recognized",
924
- error_description: "Something."), status: 401)
925
-
926
- client = StripeClient.new
927
-
928
- opts = { api_base: Stripe.connect_base }
929
- e = assert_raises Stripe::OAuth::OAuthError do
930
- client.execute_request(:post, "/oauth/deauthorize", **opts)
931
- end
932
-
933
- assert_equal(401, e.http_status)
934
- assert_equal("new_code_not_recognized", e.code)
935
- assert_equal("Something.", e.message)
936
- end
937
- end
938
-
939
- context "idempotency keys" do
940
- setup do
941
- Stripe::StripeConfiguration.any_instance.stubs(:max_network_retries).returns(2)
942
- end
943
-
944
- should "not add an idempotency key to GET requests" do
945
- SecureRandom.expects(:uuid).times(0)
946
- stub_request(:get, "#{Stripe.api_base}/v1/charges/ch_123")
947
- .with do |req|
948
- req.headers["Idempotency-Key"].nil?
949
- end.to_return(body: JSON.generate(object: "charge"))
950
- client = StripeClient.new
951
- client.execute_request(:get, "/v1/charges/ch_123")
952
- end
953
-
954
- should "ensure there is always an idempotency_key on POST requests" do
955
- SecureRandom.expects(:uuid).at_least_once.returns("random_key")
956
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
957
- .with(headers: { "Idempotency-Key" => "random_key" })
958
- .to_return(body: JSON.generate(object: "charge"))
959
- client = StripeClient.new
960
- client.execute_request(:post, "/v1/charges")
961
- end
962
-
963
- should "ensure there is always an idempotency_key on DELETE requests" do
964
- SecureRandom.expects(:uuid).at_least_once.returns("random_key")
965
- stub_request(:delete, "#{Stripe.api_base}/v1/charges/ch_123")
966
- .with(headers: { "Idempotency-Key" => "random_key" })
967
- .to_return(body: JSON.generate(object: "charge"))
968
- client = StripeClient.new
969
- client.execute_request(:delete, "/v1/charges/ch_123")
970
- end
971
-
972
- should "not override a provided idempotency_key" do
973
- # Note that this expectation looks like `:idempotency_key` instead of
974
- # the header `Idempotency-Key` because it's user provided as seen
975
- # below. The ones injected by the library itself look like headers
976
- # (`Idempotency-Key`), but rest-client does allow this symbol
977
- # formatting and will properly override the system generated one as
978
- # expected.
979
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
980
- .with(headers: { "Idempotency-Key" => "provided_key" })
981
- .to_return(body: JSON.generate(object: "charge"))
982
-
983
- client = StripeClient.new
984
- client.execute_request(:post, "/v1/charges",
985
- headers: { idempotency_key: "provided_key" })
986
- end
987
- end
988
-
989
- context "retry logic" do
990
- setup do
991
- Stripe::StripeConfiguration.any_instance.stubs(:max_network_retries).returns(2)
992
- end
993
-
994
- should "retry failed requests and raise if error persists" do
995
- StripeClient.expects(:sleep_time).at_least_once.returns(0)
996
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
997
- .to_raise(Errno::ECONNREFUSED.new)
998
-
999
- client = StripeClient.new
1000
- err = assert_raises Stripe::APIConnectionError do
1001
- client.execute_request(:post, "/v1/charges")
1002
- end
1003
- assert_match(/Request was retried 2 times/, err.message)
1004
- end
1005
-
1006
- should "retry failed requests and return successful response" do
1007
- StripeClient.expects(:sleep_time).at_least_once.returns(0)
1008
-
1009
- i = 0
1010
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
1011
- .to_return do |_|
1012
- if i < 2
1013
- i += 1
1014
- raise Errno::ECONNREFUSED
1015
- else
1016
- { body: JSON.generate("id" => "myid") }
1017
- end
1018
- end
1019
-
1020
- client = StripeClient.new
1021
- client.execute_request(:post, "/v1/charges")
1022
- end
1023
-
1024
- should "pass the client configuration when retrying" do
1025
- StripeClient.expects(:sleep_time)
1026
- .with(any_of(1, 2),
1027
- has_entry(:config, kind_of(Stripe::StripeConfiguration)))
1028
- .at_least_once.returns(0)
1029
-
1030
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
1031
- .to_raise(Errno::ECONNREFUSED.new)
1032
-
1033
- client = StripeClient.new
1034
- assert_raises Stripe::APIConnectionError do
1035
- client.execute_request(:post, "/v1/charges")
1036
- end
1037
- end
1038
- end
1039
-
1040
- context "params serialization" do
1041
- should "allows empty strings in params" do
1042
- client = StripeClient.new
1043
- client.execute_request(:get, "/v1/invoices/upcoming", params: {
1044
- customer: "cus_123",
1045
- coupon: "",
1046
- })
1047
- assert_requested(
1048
- :get,
1049
- "#{Stripe.api_base}/v1/invoices/upcoming?",
1050
- query: {
1051
- customer: "cus_123",
1052
- coupon: "",
1053
- }
1054
- )
1055
- end
1056
-
1057
- should "filter nils in params" do
1058
- client = StripeClient.new
1059
- client.execute_request(:get, "/v1/invoices/upcoming", params: {
1060
- customer: "cus_123",
1061
- coupon: nil,
1062
- })
1063
- assert_requested(
1064
- :get,
1065
- "#{Stripe.api_base}/v1/invoices/upcoming?",
1066
- query: {
1067
- customer: "cus_123",
1068
- }
1069
- )
1070
- end
1071
-
1072
- should "merge query parameters in URL and params" do
1073
- client = StripeClient.new
1074
- client.execute_request(:get, "/v1/invoices/upcoming?coupon=25OFF", params: {
1075
- customer: "cus_123",
1076
- })
1077
- assert_requested(
1078
- :get,
1079
- "#{Stripe.api_base}/v1/invoices/upcoming?",
1080
- query: {
1081
- coupon: "25OFF",
1082
- customer: "cus_123",
1083
- }
1084
- )
1085
- end
1086
-
1087
- should "prefer query parameters in params when specified in URL as well" do
1088
- client = StripeClient.new
1089
- client.execute_request(:get, "/v1/invoices/upcoming?customer=cus_query", params: {
1090
- customer: "cus_param",
1091
- })
1092
- assert_requested(
1093
- :get,
1094
- "#{Stripe.api_base}/v1/invoices/upcoming?",
1095
- query: {
1096
- customer: "cus_param",
1097
- }
1098
- )
1099
- end
1100
- end
1101
- end
1102
-
1103
- context "#connection_manager" do
1104
- should "warn that #connection_manager is deprecated" do
1105
- old_stderr = $stderr
1106
- $stderr = StringIO.new
1107
- begin
1108
- client = StripeClient.new
1109
- client.connection_manager
1110
- message = "NOTE: Stripe::StripeClient#connection_manager is " \
1111
- "deprecated"
1112
- assert_match Regexp.new(message), $stderr.string
1113
- ensure
1114
- $stderr = old_stderr
1115
- end
1116
- end
1117
- end
1118
-
1119
- context "#request" do
1120
- should "return a result and response object" do
1121
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
1122
- .to_return(body: JSON.generate(object: "charge"))
1123
-
1124
- client = StripeClient.new
1125
- charge, resp = client.request { Charge.create }
1126
-
1127
- assert charge.is_a?(Charge)
1128
- assert resp.is_a?(StripeResponse)
1129
- assert_equal 200, resp.http_status
1130
- end
1131
-
1132
- should "return the value of given block" do
1133
- client = StripeClient.new
1134
- ret, = client.request { 7 }
1135
- assert_equal 7, ret
1136
- end
1137
-
1138
- should "reset local thread state after a call" do
1139
- begin
1140
- StripeClient.current_thread_context.active_client = :stripe_client
1141
-
1142
- client = StripeClient.new
1143
- client.request {}
1144
-
1145
- assert_equal :stripe_client,
1146
- StripeClient.current_thread_context.active_client
1147
- ensure
1148
- StripeClient.current_thread_context.active_client = nil
1149
- end
1150
- end
1151
-
1152
- should "correctly return last responses despite multiple clients" do
1153
- charge_resp = { object: "charge" }
1154
- coupon_resp = { object: "coupon" }
1155
-
1156
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
1157
- .to_return(body: JSON.generate(charge_resp))
1158
- stub_request(:post, "#{Stripe.api_base}/v1/coupons")
1159
- .to_return(body: JSON.generate(coupon_resp))
1160
-
1161
- client1 = StripeClient.new
1162
- client2 = StripeClient.new
1163
-
1164
- client2_resp = nil
1165
- _charge, client1_resp = client1.request do
1166
- Charge.create
1167
-
1168
- # This is contrived, but we run one client nested in the `request`
1169
- # block of another one just to ensure that the parent is still
1170
- # unwinding when this goes through. If the parent's last response
1171
- # were to be overridden by this client (through a bug), then it would
1172
- # happen here.
1173
- _coupon, client2_resp = client2.request do
1174
- Coupon.create
1175
- end
1176
- end
1177
-
1178
- assert_equal charge_resp, client1_resp.data
1179
- assert_equal coupon_resp, client2_resp.data
1180
- end
1181
-
1182
- should "correctly return last responses despite multiple threads" do
1183
- charge_resp = { object: "charge" }
1184
- coupon_resp = { object: "coupon" }
1185
-
1186
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
1187
- .to_return(body: JSON.generate(charge_resp))
1188
- stub_request(:post, "#{Stripe.api_base}/v1/coupons")
1189
- .to_return(body: JSON.generate(coupon_resp))
1190
-
1191
- client = StripeClient.new
1192
-
1193
- # Poorly named class -- note this is actually a concurrent queue.
1194
- recv_queue = Queue.new
1195
- send_queue = Queue.new
1196
-
1197
- # Start a thread, make an API request, but then idle in the `request`
1198
- # block until the main thread has been able to make its own API request
1199
- # and signal that it's done. If this thread's last response were to be
1200
- # overridden by the main thread (through a bug), then this routine
1201
- # should suss it out.
1202
- resp1 = nil
1203
- thread = Thread.start do
1204
- _charge, resp1 = client.request do
1205
- Charge.create
1206
-
1207
- # Idle in `request` block until main thread signals.
1208
- send_queue.pop
1209
- end
1210
-
1211
- # Signal main thread that we're done and it can run its checks.
1212
- recv_queue << true
1213
- end
1214
-
1215
- # Make an API request.
1216
- _coupon, resp2 = client.request do
1217
- Coupon.create
1218
- end
1219
-
1220
- # Tell background thread to finish `request`, then wait for it to
1221
- # signal back to us that it's ready.
1222
- send_queue << true
1223
- recv_queue.pop
1224
-
1225
- assert_equal charge_resp, resp1.data
1226
- assert_equal coupon_resp, resp2.data
1227
-
1228
- # And for maximum hygiene, make sure that our thread rejoins.
1229
- thread.join
1230
- end
1231
-
1232
- should "error if calls to #request are nested on the same thread" do
1233
- client = StripeClient.new
1234
- client.request do
1235
- e = assert_raises(RuntimeError) do
1236
- client.request {}
1237
- end
1238
- assert_equal "calls to StripeClient#request cannot be nested within a thread",
1239
- e.message
1240
- end
1241
- end
1242
- end
1243
-
1244
- context "#proxy" do
1245
- should "run the request through the proxy" do
1246
- begin
1247
- StripeClient.clear_all_connection_managers
1248
-
1249
- Stripe.proxy = "http://user:pass@localhost:8080"
1250
-
1251
- client = StripeClient.new
1252
- client.request {}
1253
-
1254
- connection = Stripe::StripeClient.default_connection_manager.connection_for(Stripe.api_base)
1255
-
1256
- assert_equal "localhost", connection.proxy_address
1257
- assert_equal 8080, connection.proxy_port
1258
- assert_equal "user", connection.proxy_user
1259
- assert_equal "pass", connection.proxy_pass
1260
- ensure
1261
- Stripe.proxy = nil
1262
-
1263
- StripeClient.clear_all_connection_managers
1264
- end
1265
- end
1266
- end
1267
-
1268
- context "#telemetry" do
1269
- teardown do
1270
- # make sure to always set telemetry back to false
1271
- # to not mutate global state
1272
- Stripe.enable_telemetry = false
1273
- end
1274
-
1275
- should "not send metrics if enable trace flag is not set" do
1276
- Stripe.enable_telemetry = false
1277
-
1278
- trace_metrics_header = nil
1279
- stub_request(:get, "#{Stripe.api_base}/v1/charges")
1280
- .with do |req|
1281
- trace_metrics_header = req.headers["X-Stripe-Client-Telemetry"]
1282
- false
1283
- end.to_return(body: JSON.generate(object: "charge"))
1284
-
1285
- Stripe::Charge.list
1286
- assert(trace_metrics_header.nil?)
1287
-
1288
- Stripe::Charge.list
1289
- assert(trace_metrics_header.nil?)
1290
- end
1291
-
1292
- should "send metrics if enabled telemetry is true" do
1293
- Stripe.enable_telemetry = true
1294
-
1295
- trace_metrics_header = nil
1296
- stub_request(:get, "#{Stripe.api_base}/v1/charges")
1297
- .with do |req|
1298
- trace_metrics_header = req.headers["X-Stripe-Client-Telemetry"]
1299
- false
1300
- end.to_return(body: JSON.generate(object: "charge"))
1301
-
1302
- Stripe::Charge.list
1303
- Stripe::Charge.list
1304
-
1305
- assert(!trace_metrics_header.nil?)
1306
-
1307
- trace_payload = JSON.parse(trace_metrics_header)
1308
- assert(trace_payload["last_request_metrics"]["request_id"] == "req_123")
1309
- assert(!trace_payload["last_request_metrics"]["request_duration_ms"].nil?)
1310
- end
1311
- end
1312
-
1313
- context "instrumentation" do
1314
- teardown do
1315
- Stripe::Instrumentation.unsubscribe(:request, :test)
1316
- end
1317
-
1318
- should "notify a subscribe on HTTP request start" do
1319
- events = []
1320
- Stripe::Instrumentation.subscribe(:request_end, :test) { |event| events << event }
1321
-
1322
- stub_request(:get, "#{Stripe.api_base}/v1/charges")
1323
- .to_return(body: JSON.generate(object: "charge"))
1324
- Stripe::Charge.list
1325
-
1326
- assert_equal(1, events.size)
1327
- event = events.first
1328
- assert_equal(:get, event.method)
1329
- assert_equal("/v1/charges", event.path)
1330
- end
1331
-
1332
- should "notify a subscriber of a successful HTTP request" do
1333
- events = []
1334
- Stripe::Instrumentation.subscribe(:request_end, :test) { |event| events << event }
1335
-
1336
- stub_request(:get, "#{Stripe.api_base}/v1/charges")
1337
- .to_return(body: JSON.generate(object: "charge"))
1338
- Stripe::Charge.list
1339
-
1340
- assert_equal(1, events.size)
1341
- event = events.first
1342
- assert_equal(:get, event.method)
1343
- assert_equal("/v1/charges", event.path)
1344
- assert_equal(200, event.http_status)
1345
- assert(event.duration.positive?)
1346
- assert_equal(0, event.num_retries)
1347
- end
1348
-
1349
- should "notify a subscriber of a StripeError" do
1350
- events = []
1351
- Stripe::Instrumentation.subscribe(:request_end, :test) { |event| events << event }
1352
-
1353
- error = {
1354
- code: "code",
1355
- message: "message",
1356
- param: "param",
1357
- type: "type",
1358
- }
1359
- stub_request(:get, "#{Stripe.api_base}/v1/charges")
1360
- .to_return(
1361
- body: JSON.generate(error: error),
1362
- status: 500
1363
- )
1364
- assert_raises(Stripe::APIError) do
1365
- Stripe::Charge.list
1366
- end
1367
-
1368
- assert_equal(1, events.size)
1369
- event = events.first
1370
- assert_equal(:get, event.method)
1371
- assert_equal("/v1/charges", event.path)
1372
- assert_equal(500, event.http_status)
1373
- assert(event.duration.positive?)
1374
- assert_equal(0, event.num_retries)
1375
- end
1376
-
1377
- should "notify a subscriber of a network error" do
1378
- events = []
1379
- Stripe::Instrumentation.subscribe(:request_end, :test) { |event| events << event }
1380
-
1381
- stub_request(:get, "#{Stripe.api_base}/v1/charges")
1382
- .to_raise(Net::OpenTimeout)
1383
- assert_raises(Stripe::APIConnectionError) do
1384
- Stripe::Charge.list
1385
- end
1386
-
1387
- assert_equal(1, events.size)
1388
- event = events.first
1389
- assert_equal(:get, event.method)
1390
- assert_equal("/v1/charges", event.path)
1391
- assert_nil(event.http_status)
1392
- assert(event.duration.positive?)
1393
- assert_equal(0, event.num_retries)
1394
- end
1395
-
1396
- should "pass `user_data` from `request_begin` to `request_end`" do
1397
- actual_user_data = nil
1398
-
1399
- Stripe::Instrumentation.subscribe(:request_begin) do |event|
1400
- event.user_data[:foo] = :bar
1401
- end
1402
- Stripe::Instrumentation.subscribe(:request_end) do |event|
1403
- actual_user_data = event.user_data
1404
- end
1405
-
1406
- stub_request(:get, "#{Stripe.api_base}/v1/charges")
1407
- .to_return(body: JSON.generate(object: "charge"))
1408
- Stripe::Charge.list
1409
-
1410
- assert_equal({ foo: :bar }, actual_user_data)
1411
- end
1412
-
1413
- should "provide backward compatibility on `request` topic" do
1414
- events = []
1415
- Stripe::Instrumentation.subscribe(:request, :test) { |event| events << event }
1416
-
1417
- stub_request(:get, "#{Stripe.api_base}/v1/charges")
1418
- .to_return(body: JSON.generate(object: "charge"))
1419
- Stripe::Charge.list
1420
-
1421
- assert_equal(1, events.size)
1422
- event = events.first
1423
- assert_equal(:get, event.method)
1424
- assert_equal("/v1/charges", event.path)
1425
- assert_equal(200, event.http_status)
1426
- assert(event.duration.positive?)
1427
- assert_equal(0, event.num_retries)
1428
- end
1429
- end
1430
- end
1431
-
1432
- class SystemProfilerTest < Test::Unit::TestCase
1433
- context "#uname" do
1434
- should "run without failure" do
1435
- # Don't actually check the result because we try a variety of different
1436
- # strategies that will have different results depending on where this
1437
- # test and running. We're mostly making sure that no exception is thrown.
1438
- _ = StripeClient::SystemProfiler.uname
1439
- end
1440
- end
1441
-
1442
- context "#uname_from_system" do
1443
- should "run without failure" do
1444
- # as above, just verify that an exception is not thrown
1445
- _ = StripeClient::SystemProfiler.uname_from_system
1446
- end
1447
- end
1448
-
1449
- context "#uname_from_system_ver" do
1450
- should "run without failure" do
1451
- # as above, just verify that an exception is not thrown
1452
- _ = StripeClient::SystemProfiler.uname_from_system_ver
1453
- end
1454
- end
1455
- end
1456
- end