stripe 4.24.0 → 5.36.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (216) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +169 -0
  3. data/CODE_OF_CONDUCT.md +77 -0
  4. data/Gemfile +10 -16
  5. data/README.md +111 -44
  6. data/Rakefile +8 -7
  7. data/VERSION +1 -1
  8. data/lib/stripe.rb +39 -130
  9. data/lib/stripe/api_operations/create.rb +1 -1
  10. data/lib/stripe/api_operations/delete.rb +7 -3
  11. data/lib/stripe/api_operations/list.rb +1 -12
  12. data/lib/stripe/api_operations/nested_resource.rb +29 -26
  13. data/lib/stripe/api_operations/request.rb +82 -6
  14. data/lib/stripe/api_operations/save.rb +7 -4
  15. data/lib/stripe/api_resource.rb +12 -3
  16. data/lib/stripe/connection_manager.rb +179 -0
  17. data/lib/stripe/error_object.rb +94 -0
  18. data/lib/stripe/errors.rb +24 -3
  19. data/lib/stripe/instrumentation.rb +82 -0
  20. data/lib/stripe/list_object.rb +34 -5
  21. data/lib/stripe/multipart_encoder.rb +131 -0
  22. data/lib/stripe/oauth.rb +8 -6
  23. data/lib/stripe/object_types.rb +12 -1
  24. data/lib/stripe/resources.rb +12 -1
  25. data/lib/stripe/resources/account.rb +6 -14
  26. data/lib/stripe/resources/account_link.rb +2 -1
  27. data/lib/stripe/resources/alipay_account.rb +1 -1
  28. data/lib/stripe/resources/apple_pay_domain.rb +2 -1
  29. data/lib/stripe/resources/application_fee.rb +2 -12
  30. data/lib/stripe/resources/application_fee_refund.rb +1 -1
  31. data/lib/stripe/resources/balance.rb +2 -1
  32. data/lib/stripe/resources/balance_transaction.rb +2 -1
  33. data/lib/stripe/resources/bank_account.rb +3 -2
  34. data/lib/stripe/resources/billing_portal/configuration.rb +14 -0
  35. data/lib/stripe/resources/billing_portal/session.rb +12 -0
  36. data/lib/stripe/resources/bitcoin_receiver.rb +2 -1
  37. data/lib/stripe/resources/bitcoin_transaction.rb +1 -1
  38. data/lib/stripe/resources/capability.rb +1 -1
  39. data/lib/stripe/resources/card.rb +2 -1
  40. data/lib/stripe/resources/charge.rb +8 -69
  41. data/lib/stripe/resources/checkout/session.rb +6 -1
  42. data/lib/stripe/resources/country_spec.rb +2 -1
  43. data/lib/stripe/resources/coupon.rb +2 -1
  44. data/lib/stripe/resources/credit_note.rb +12 -1
  45. data/lib/stripe/resources/credit_note_line_item.rb +7 -0
  46. data/lib/stripe/resources/customer.rb +9 -63
  47. data/lib/stripe/resources/customer_balance_transaction.rb +1 -1
  48. data/lib/stripe/resources/discount.rb +1 -1
  49. data/lib/stripe/resources/dispute.rb +2 -7
  50. data/lib/stripe/resources/ephemeral_key.rb +2 -1
  51. data/lib/stripe/resources/event.rb +2 -1
  52. data/lib/stripe/resources/exchange_rate.rb +2 -1
  53. data/lib/stripe/resources/file.rb +6 -14
  54. data/lib/stripe/resources/file_link.rb +2 -1
  55. data/lib/stripe/resources/identity/verification_report.rb +12 -0
  56. data/lib/stripe/resources/identity/verification_session.rb +35 -0
  57. data/lib/stripe/resources/invoice.rb +8 -2
  58. data/lib/stripe/resources/invoice_item.rb +2 -1
  59. data/lib/stripe/resources/invoice_line_item.rb +1 -1
  60. data/lib/stripe/resources/issuing/authorization.rb +2 -1
  61. data/lib/stripe/resources/issuing/card.rb +2 -1
  62. data/lib/stripe/resources/issuing/card_details.rb +1 -1
  63. data/lib/stripe/resources/issuing/cardholder.rb +2 -1
  64. data/lib/stripe/resources/issuing/dispute.rb +13 -1
  65. data/lib/stripe/resources/issuing/transaction.rb +2 -1
  66. data/lib/stripe/resources/line_item.rb +7 -0
  67. data/lib/stripe/resources/login_link.rb +1 -1
  68. data/lib/stripe/resources/mandate.rb +8 -0
  69. data/lib/stripe/resources/order.rb +2 -9
  70. data/lib/stripe/resources/order_return.rb +2 -1
  71. data/lib/stripe/resources/payment_intent.rb +2 -1
  72. data/lib/stripe/resources/payment_method.rb +2 -1
  73. data/lib/stripe/resources/payout.rb +10 -5
  74. data/lib/stripe/resources/person.rb +1 -1
  75. data/lib/stripe/resources/plan.rb +2 -1
  76. data/lib/stripe/resources/price.rb +12 -0
  77. data/lib/stripe/resources/product.rb +2 -1
  78. data/lib/stripe/resources/promotion_code.rb +12 -0
  79. data/lib/stripe/resources/quote.rb +95 -0
  80. data/lib/stripe/resources/radar/early_fraud_warning.rb +2 -1
  81. data/lib/stripe/resources/radar/value_list.rb +2 -1
  82. data/lib/stripe/resources/radar/value_list_item.rb +2 -1
  83. data/lib/stripe/resources/recipient.rb +2 -5
  84. data/lib/stripe/resources/recipient_transfer.rb +1 -1
  85. data/lib/stripe/resources/refund.rb +2 -1
  86. data/lib/stripe/resources/reporting/report_run.rb +2 -1
  87. data/lib/stripe/resources/reporting/report_type.rb +2 -1
  88. data/lib/stripe/resources/reversal.rb +1 -1
  89. data/lib/stripe/resources/review.rb +2 -1
  90. data/lib/stripe/resources/setup_attempt.rb +10 -0
  91. data/lib/stripe/resources/setup_intent.rb +2 -1
  92. data/lib/stripe/resources/sigma/scheduled_query_run.rb +2 -1
  93. data/lib/stripe/resources/sku.rb +2 -1
  94. data/lib/stripe/resources/source.rb +11 -10
  95. data/lib/stripe/resources/source_transaction.rb +1 -1
  96. data/lib/stripe/resources/subscription.rb +10 -9
  97. data/lib/stripe/resources/subscription_item.rb +8 -2
  98. data/lib/stripe/resources/subscription_schedule.rb +2 -1
  99. data/lib/stripe/resources/tax_code.rb +10 -0
  100. data/lib/stripe/resources/tax_id.rb +1 -1
  101. data/lib/stripe/resources/tax_rate.rb +2 -1
  102. data/lib/stripe/resources/terminal/connection_token.rb +2 -1
  103. data/lib/stripe/resources/terminal/location.rb +2 -1
  104. data/lib/stripe/resources/terminal/reader.rb +2 -1
  105. data/lib/stripe/resources/three_d_secure.rb +2 -1
  106. data/lib/stripe/resources/token.rb +2 -1
  107. data/lib/stripe/resources/topup.rb +2 -1
  108. data/lib/stripe/resources/transfer.rb +2 -6
  109. data/lib/stripe/resources/usage_record.rb +1 -17
  110. data/lib/stripe/resources/usage_record_summary.rb +1 -1
  111. data/lib/stripe/resources/webhook_endpoint.rb +2 -1
  112. data/lib/stripe/stripe_client.rb +608 -242
  113. data/lib/stripe/stripe_configuration.rb +194 -0
  114. data/lib/stripe/stripe_object.rb +30 -25
  115. data/lib/stripe/stripe_response.rb +87 -27
  116. data/lib/stripe/util.rb +37 -18
  117. data/lib/stripe/version.rb +1 -1
  118. data/lib/stripe/webhook.rb +39 -8
  119. data/stripe.gemspec +15 -11
  120. metadata +24 -216
  121. data/.editorconfig +0 -10
  122. data/.gitattributes +0 -4
  123. data/.github/ISSUE_TEMPLATE.md +0 -5
  124. data/.gitignore +0 -8
  125. data/.rubocop.yml +0 -43
  126. data/.rubocop_todo.yml +0 -38
  127. data/.travis.yml +0 -43
  128. data/.vscode/extensions.json +0 -7
  129. data/.vscode/settings.json +0 -8
  130. data/lib/stripe/resources/issuer_fraud_record.rb +0 -9
  131. data/test/api_stub_helpers.rb +0 -1
  132. data/test/openapi/README.md +0 -9
  133. data/test/stripe/account_link_test.rb +0 -18
  134. data/test/stripe/account_test.rb +0 -428
  135. data/test/stripe/alipay_account_test.rb +0 -37
  136. data/test/stripe/api_operations_test.rb +0 -80
  137. data/test/stripe/api_resource_test.rb +0 -621
  138. data/test/stripe/apple_pay_domain_test.rb +0 -46
  139. data/test/stripe/application_fee_refund_test.rb +0 -37
  140. data/test/stripe/application_fee_test.rb +0 -58
  141. data/test/stripe/balance_test.rb +0 -13
  142. data/test/stripe/balance_transaction_test.rb +0 -20
  143. data/test/stripe/bank_account_test.rb +0 -36
  144. data/test/stripe/capability_test.rb +0 -45
  145. data/test/stripe/charge_test.rb +0 -80
  146. data/test/stripe/checkout/session_test.rb +0 -41
  147. data/test/stripe/country_spec_test.rb +0 -20
  148. data/test/stripe/coupon_test.rb +0 -61
  149. data/test/stripe/credit_note_test.rb +0 -61
  150. data/test/stripe/customer_balance_transaction_test.rb +0 -37
  151. data/test/stripe/customer_card_test.rb +0 -42
  152. data/test/stripe/customer_test.rb +0 -269
  153. data/test/stripe/dispute_test.rb +0 -51
  154. data/test/stripe/ephemeral_key_test.rb +0 -93
  155. data/test/stripe/errors_test.rb +0 -20
  156. data/test/stripe/exchange_rate_test.rb +0 -20
  157. data/test/stripe/file_link_test.rb +0 -41
  158. data/test/stripe/file_test.rb +0 -97
  159. data/test/stripe/file_upload_test.rb +0 -79
  160. data/test/stripe/invoice_item_test.rb +0 -66
  161. data/test/stripe/invoice_line_item_test.rb +0 -8
  162. data/test/stripe/invoice_test.rb +0 -213
  163. data/test/stripe/issuer_fraud_record_test.rb +0 -20
  164. data/test/stripe/issuing/authorization_test.rb +0 -72
  165. data/test/stripe/issuing/card_test.rb +0 -62
  166. data/test/stripe/issuing/cardholder_test.rb +0 -53
  167. data/test/stripe/issuing/dispute_test.rb +0 -45
  168. data/test/stripe/issuing/transaction_test.rb +0 -48
  169. data/test/stripe/list_object_test.rb +0 -156
  170. data/test/stripe/login_link_test.rb +0 -37
  171. data/test/stripe/oauth_test.rb +0 -88
  172. data/test/stripe/order_return_test.rb +0 -21
  173. data/test/stripe/order_test.rb +0 -82
  174. data/test/stripe/payment_intent_test.rb +0 -107
  175. data/test/stripe/payment_method_test.rb +0 -84
  176. data/test/stripe/payout_test.rb +0 -57
  177. data/test/stripe/person_test.rb +0 -46
  178. data/test/stripe/plan_test.rb +0 -98
  179. data/test/stripe/product_test.rb +0 -59
  180. data/test/stripe/radar/early_fraud_warning_test.rb +0 -22
  181. data/test/stripe/radar/value_list_item_test.rb +0 -48
  182. data/test/stripe/radar/value_list_test.rb +0 -61
  183. data/test/stripe/recipient_test.rb +0 -62
  184. data/test/stripe/refund_test.rb +0 -39
  185. data/test/stripe/reporting/report_run_test.rb +0 -33
  186. data/test/stripe/reporting/report_type_test.rb +0 -22
  187. data/test/stripe/reversal_test.rb +0 -43
  188. data/test/stripe/review_test.rb +0 -27
  189. data/test/stripe/setup_intent_test.rb +0 -84
  190. data/test/stripe/sigma/scheduled_query_run_test.rb +0 -22
  191. data/test/stripe/sku_test.rb +0 -60
  192. data/test/stripe/source_test.rb +0 -99
  193. data/test/stripe/source_transaction_test.rb +0 -19
  194. data/test/stripe/stripe_client_test.rb +0 -842
  195. data/test/stripe/stripe_object_test.rb +0 -525
  196. data/test/stripe/stripe_response_test.rb +0 -49
  197. data/test/stripe/subscription_item_test.rb +0 -75
  198. data/test/stripe/subscription_schedule_test.rb +0 -82
  199. data/test/stripe/subscription_test.rb +0 -80
  200. data/test/stripe/tax_id_test.rb +0 -31
  201. data/test/stripe/tax_rate_test.rb +0 -43
  202. data/test/stripe/terminal/connection_token_test.rb +0 -16
  203. data/test/stripe/terminal/location_test.rb +0 -68
  204. data/test/stripe/terminal/reader_test.rb +0 -62
  205. data/test/stripe/three_d_secure_test.rb +0 -23
  206. data/test/stripe/topup_test.rb +0 -62
  207. data/test/stripe/transfer_test.rb +0 -88
  208. data/test/stripe/usage_record_summary_test.rb +0 -19
  209. data/test/stripe/usage_record_test.rb +0 -28
  210. data/test/stripe/util_test.rb +0 -402
  211. data/test/stripe/webhook_endpoint_test.rb +0 -59
  212. data/test/stripe/webhook_test.rb +0 -96
  213. data/test/stripe_mock.rb +0 -77
  214. data/test/stripe_test.rb +0 -63
  215. data/test/test_data.rb +0 -61
  216. data/test/test_helper.rb +0 -71
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require ::File.expand_path("../../test_helper", __dir__)
4
-
5
- module Stripe
6
- module Reporting
7
- class ReportRunTest < Test::Unit::TestCase
8
- should "be creatable" do
9
- report_run = Stripe::Reporting::ReportRun.create(
10
- parameters: {
11
- connected_account: "acct_123",
12
- },
13
- report_type: "activity.summary.1"
14
- )
15
- assert_requested :post, "#{Stripe.api_base}/v1/reporting/report_runs"
16
- assert report_run.is_a?(Stripe::Reporting::ReportRun)
17
- end
18
-
19
- should "be listable" do
20
- report_runs = Stripe::Reporting::ReportRun.list
21
- assert_requested :get, "#{Stripe.api_base}/v1/reporting/report_runs"
22
- assert report_runs.data.is_a?(Array)
23
- assert report_runs.data[0].is_a?(Stripe::Reporting::ReportRun)
24
- end
25
-
26
- should "be retrievable" do
27
- report_run = Stripe::Reporting::ReportRun.retrieve("frr_123")
28
- assert_requested :get, "#{Stripe.api_base}/v1/reporting/report_runs/frr_123"
29
- assert report_run.is_a?(Stripe::Reporting::ReportRun)
30
- end
31
- end
32
- end
33
- 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 Reporting
7
- class ReportTypeTest < Test::Unit::TestCase
8
- should "be listable" do
9
- report_types = Stripe::Reporting::ReportType.list
10
- assert_requested :get, "#{Stripe.api_base}/v1/reporting/report_types"
11
- assert report_types.data.is_a?(Array)
12
- assert report_types.data[0].is_a?(Stripe::Reporting::ReportType)
13
- end
14
-
15
- should "be retrievable" do
16
- report_type = Stripe::Reporting::ReportType.retrieve("activity.summary.1")
17
- assert_requested :get, "#{Stripe.api_base}/v1/reporting/report_types/activity.summary.1"
18
- assert report_type.is_a?(Stripe::Reporting::ReportType)
19
- end
20
- end
21
- end
22
- end
@@ -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,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".freeze
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,99 +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
- context "#delete" do
55
- should "warn that #delete is deprecated" do
56
- old_stderr = $stderr
57
- $stderr = StringIO.new
58
- begin
59
- source = Stripe::Source.construct_from(customer: "cus_123",
60
- id: "src_123",
61
- object: "source")
62
- source.delete
63
- message = "NOTE: Stripe::Source#delete is " \
64
- "deprecated; use #detach instead"
65
- assert_match Regexp.new(message), $stderr.string
66
- ensure
67
- $stderr = old_stderr
68
- end
69
- end
70
- end
71
-
72
- should "not be listable" do
73
- assert_raises NoMethodError do
74
- Stripe::Source.list
75
- end
76
- end
77
-
78
- context "#verify" do
79
- should "verify the source" do
80
- source = Stripe::Source.retrieve("src_123")
81
- source = source.verify(values: [1, 2])
82
- assert_requested :post,
83
- "#{Stripe.api_base}/v1/sources/#{source.id}/verify",
84
- body: { values: [1, 2] }
85
- assert source.is_a?(Stripe::Source)
86
- end
87
- end
88
-
89
- context ".verify" do
90
- should "verify the source" do
91
- source = Stripe::Source.verify("src_123", values: [1, 2])
92
- assert_requested :post,
93
- "#{Stripe.api_base}/v1/sources/src_123/verify",
94
- body: { values: [1, 2] }
95
- assert source.is_a?(Stripe::Source)
96
- end
97
- end
98
- end
99
- end
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require ::File.expand_path("../test_helper", __dir__)
4
-
5
- module Stripe
6
- class SourceTransactionTest < Test::Unit::TestCase
7
- setup do
8
- @source = Stripe::Source.retrieve("src_123")
9
- end
10
-
11
- should "be listable" do
12
- transactions = @source.source_transactions
13
-
14
- assert_requested :get, "#{Stripe.api_base}/v1/sources/#{@source.id}/source_transactions"
15
- assert transactions.data.is_a?(Array)
16
- assert transactions.first.is_a?(Stripe::SourceTransaction)
17
- end
18
- end
19
- end
@@ -1,842 +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 ".active_client" do
8
- should "be .default_client outside of #request" do
9
- assert_equal StripeClient.default_client, StripeClient.active_client
10
- end
11
-
12
- should "be active client inside of #request" do
13
- client = StripeClient.new
14
- client.request do
15
- assert_equal client, StripeClient.active_client
16
- end
17
- end
18
- end
19
-
20
- context ".default_client" do
21
- should "be a StripeClient" do
22
- assert_kind_of StripeClient, StripeClient.default_client
23
- end
24
-
25
- should "be a different client on each thread" do
26
- other_thread_client = nil
27
- thread = Thread.new do
28
- other_thread_client = StripeClient.default_client
29
- end
30
- thread.join
31
- refute_equal StripeClient.default_client, other_thread_client
32
- end
33
- end
34
-
35
- context ".default_conn" do
36
- should "be a Faraday::Connection" do
37
- assert_kind_of Faraday::Connection, StripeClient.default_conn
38
- end
39
-
40
- should "be a different connection on each thread" do
41
- other_thread_conn = nil
42
- thread = Thread.new do
43
- other_thread_conn = StripeClient.default_conn
44
- end
45
- thread.join
46
- refute_equal StripeClient.default_conn, other_thread_conn
47
- end
48
- end
49
-
50
- context ".should_retry?" do
51
- setup do
52
- Stripe.stubs(:max_network_retries).returns(2)
53
- end
54
-
55
- should "retry on timeout" do
56
- assert StripeClient.should_retry?(Faraday::TimeoutError.new(""), 0)
57
- end
58
-
59
- should "retry on a failed connection" do
60
- assert StripeClient.should_retry?(Faraday::ConnectionFailed.new(""), 0)
61
- end
62
-
63
- should "retry on a conflict" do
64
- error = make_rate_limit_error
65
- e = Faraday::ClientError.new(error[:error][:message], status: 409)
66
- assert StripeClient.should_retry?(e, 0)
67
- end
68
-
69
- should "not retry at maximum count" do
70
- refute StripeClient.should_retry?(RuntimeError.new, Stripe.max_network_retries)
71
- end
72
-
73
- should "not retry on a certificate validation error" do
74
- refute StripeClient.should_retry?(Faraday::SSLError.new(""), 0)
75
- end
76
- end
77
-
78
- context ".sleep_time" do
79
- should "should grow exponentially" do
80
- StripeClient.stubs(:rand).returns(1)
81
- Stripe.stubs(:max_network_retry_delay).returns(999)
82
- assert_equal(Stripe.initial_network_retry_delay, StripeClient.sleep_time(1))
83
- assert_equal(Stripe.initial_network_retry_delay * 2, StripeClient.sleep_time(2))
84
- assert_equal(Stripe.initial_network_retry_delay * 4, StripeClient.sleep_time(3))
85
- assert_equal(Stripe.initial_network_retry_delay * 8, StripeClient.sleep_time(4))
86
- end
87
-
88
- should "enforce the max_network_retry_delay" do
89
- StripeClient.stubs(:rand).returns(1)
90
- Stripe.stubs(:initial_network_retry_delay).returns(1)
91
- Stripe.stubs(:max_network_retry_delay).returns(2)
92
- assert_equal(1, StripeClient.sleep_time(1))
93
- assert_equal(2, StripeClient.sleep_time(2))
94
- assert_equal(2, StripeClient.sleep_time(3))
95
- assert_equal(2, StripeClient.sleep_time(4))
96
- end
97
-
98
- should "add some randomness" do
99
- random_value = 0.8
100
- StripeClient.stubs(:rand).returns(random_value)
101
- Stripe.stubs(:initial_network_retry_delay).returns(1)
102
- Stripe.stubs(:max_network_retry_delay).returns(8)
103
-
104
- base_value = Stripe.initial_network_retry_delay * (0.5 * (1 + random_value))
105
-
106
- # the initial value cannot be smaller than the base,
107
- # so the randomness is ignored
108
- assert_equal(Stripe.initial_network_retry_delay, StripeClient.sleep_time(1))
109
-
110
- # after the first one, the randomness is applied
111
- assert_equal(base_value * 2, StripeClient.sleep_time(2))
112
- assert_equal(base_value * 4, StripeClient.sleep_time(3))
113
- assert_equal(base_value * 8, StripeClient.sleep_time(4))
114
- end
115
- end
116
-
117
- context "#initialize" do
118
- should "set Stripe.default_conn" do
119
- client = StripeClient.new
120
- assert_equal StripeClient.default_conn, client.conn
121
- end
122
-
123
- should "set a different connection if one was specified" do
124
- conn = Faraday.new
125
- client = StripeClient.new(conn)
126
- assert_equal conn, client.conn
127
- end
128
- end
129
-
130
- context "#execute_request" do
131
- context "headers" do
132
- should "support literal headers" do
133
- stub_request(:post, "#{Stripe.api_base}/v1/account")
134
- .with(headers: { "Stripe-Account" => "bar" })
135
- .to_return(body: JSON.generate(object: "account"))
136
-
137
- client = StripeClient.new
138
- client.execute_request(:post, "/v1/account",
139
- headers: { "Stripe-Account" => "bar" })
140
- end
141
-
142
- should "support RestClient-style header keys" do
143
- stub_request(:post, "#{Stripe.api_base}/v1/account")
144
- .with(headers: { "Stripe-Account" => "bar" })
145
- .to_return(body: JSON.generate(object: "account"))
146
-
147
- client = StripeClient.new
148
- client.execute_request(:post, "/v1/account",
149
- headers: { stripe_account: "bar" })
150
- end
151
- end
152
-
153
- context "logging" do
154
- setup do
155
- # Freeze time for the purposes of the `elapsed` parameter that we
156
- # emit for responses. I didn't want to bring in a new dependency for
157
- # this, but Mocha's `anything` parameter can't match inside of a hash
158
- # and is therefore not useful for this purpose. If we switch over to
159
- # rspec-mocks at some point, we can probably remove Timecop from the
160
- # project.
161
- Timecop.freeze(Time.local(1990))
162
- end
163
-
164
- teardown do
165
- Timecop.return
166
- end
167
-
168
- should "produce appropriate logging" do
169
- body = JSON.generate(object: "account")
170
-
171
- Util.expects(:log_info).with("Request to Stripe API",
172
- account: "acct_123",
173
- api_version: "2010-11-12",
174
- idempotency_key: "abc",
175
- method: :post,
176
- num_retries: 0,
177
- path: "/v1/account")
178
- Util.expects(:log_debug).with("Request details",
179
- body: "",
180
- idempotency_key: "abc",
181
- query_params: nil)
182
-
183
- Util.expects(:log_info).with("Response from Stripe API",
184
- account: "acct_123",
185
- api_version: "2010-11-12",
186
- elapsed: 0.0,
187
- idempotency_key: "abc",
188
- method: :post,
189
- path: "/v1/account",
190
- request_id: "req_123",
191
- status: 200)
192
- Util.expects(:log_debug).with("Response details",
193
- body: body,
194
- idempotency_key: "abc",
195
- request_id: "req_123")
196
- Util.expects(:log_debug).with("Dashboard link for request",
197
- idempotency_key: "abc",
198
- request_id: "req_123",
199
- url: Util.request_id_dashboard_url("req_123", Stripe.api_key))
200
-
201
- stub_request(:post, "#{Stripe.api_base}/v1/account")
202
- .to_return(
203
- body: body,
204
- headers: {
205
- "Idempotency-Key" => "abc",
206
- "Request-Id" => "req_123",
207
- "Stripe-Account" => "acct_123",
208
- "Stripe-Version" => "2010-11-12",
209
- }
210
- )
211
-
212
- client = StripeClient.new
213
- client.execute_request(:post, "/v1/account",
214
- headers: {
215
- "Idempotency-Key" => "abc",
216
- "Stripe-Account" => "acct_123",
217
- "Stripe-Version" => "2010-11-12",
218
- })
219
- end
220
-
221
- should "produce logging on API error" do
222
- Util.expects(:log_info).with("Request to Stripe API",
223
- account: nil,
224
- api_version: nil,
225
- idempotency_key: nil,
226
- method: :post,
227
- num_retries: 0,
228
- path: "/v1/account")
229
- Util.expects(:log_info).with("Response from Stripe API",
230
- account: nil,
231
- api_version: nil,
232
- elapsed: 0.0,
233
- idempotency_key: nil,
234
- method: :post,
235
- path: "/v1/account",
236
- request_id: nil,
237
- status: 500)
238
-
239
- error = {
240
- code: "code",
241
- message: "message",
242
- param: "param",
243
- type: "type",
244
- }
245
- Util.expects(:log_error).with("Stripe API error",
246
- status: 500,
247
- error_code: error[:code],
248
- error_message: error[:message],
249
- error_param: error[:param],
250
- error_type: error[:type],
251
- idempotency_key: nil,
252
- request_id: nil)
253
-
254
- stub_request(:post, "#{Stripe.api_base}/v1/account")
255
- .to_return(
256
- body: JSON.generate(error: error),
257
- status: 500
258
- )
259
-
260
- client = StripeClient.new
261
- assert_raises Stripe::APIError do
262
- client.execute_request(:post, "/v1/account")
263
- end
264
- end
265
-
266
- should "produce logging on OAuth error" do
267
- Util.expects(:log_info).with("Request to Stripe API",
268
- account: nil,
269
- api_version: nil,
270
- idempotency_key: nil,
271
- method: :post,
272
- num_retries: 0,
273
- path: "/oauth/token")
274
- Util.expects(:log_info).with("Response from Stripe API",
275
- account: nil,
276
- api_version: nil,
277
- elapsed: 0.0,
278
- idempotency_key: nil,
279
- method: :post,
280
- path: "/oauth/token",
281
- request_id: nil,
282
- status: 400)
283
-
284
- Util.expects(:log_error).with("Stripe OAuth error",
285
- status: 400,
286
- error_code: "invalid_request",
287
- error_description: "No grant type specified",
288
- idempotency_key: nil,
289
- request_id: nil)
290
-
291
- stub_request(:post, "#{Stripe.connect_base}/oauth/token")
292
- .to_return(body: JSON.generate(error: "invalid_request",
293
- error_description: "No grant type specified"), status: 400)
294
-
295
- client = StripeClient.new
296
- opts = { api_base: Stripe.connect_base }
297
- assert_raises Stripe::OAuth::InvalidRequestError do
298
- client.execute_request(:post, "/oauth/token", opts)
299
- end
300
- end
301
- end
302
-
303
- context "Stripe-Account header" do
304
- should "use a globally set header" do
305
- begin
306
- old = Stripe.stripe_account
307
- Stripe.stripe_account = "acct_1234"
308
-
309
- stub_request(:post, "#{Stripe.api_base}/v1/account")
310
- .with(headers: { "Stripe-Account" => Stripe.stripe_account })
311
- .to_return(body: JSON.generate(object: "account"))
312
-
313
- client = StripeClient.new
314
- client.execute_request(:post, "/v1/account")
315
- ensure
316
- Stripe.stripe_account = old
317
- end
318
- end
319
-
320
- should "use a locally set header" do
321
- stripe_account = "acct_0000"
322
- stub_request(:post, "#{Stripe.api_base}/v1/account")
323
- .with(headers: { "Stripe-Account" => stripe_account })
324
- .to_return(body: JSON.generate(object: "account"))
325
-
326
- client = StripeClient.new
327
- client.execute_request(:post, "/v1/account",
328
- headers: { stripe_account: stripe_account })
329
- end
330
-
331
- should "not send it otherwise" do
332
- stub_request(:post, "#{Stripe.api_base}/v1/account")
333
- .with do |req|
334
- req.headers["Stripe-Account"].nil?
335
- end.to_return(body: JSON.generate(object: "account"))
336
-
337
- client = StripeClient.new
338
- client.execute_request(:post, "/v1/account")
339
- end
340
- end
341
-
342
- context "app_info" do
343
- should "send app_info if set" do
344
- begin
345
- old = Stripe.app_info
346
- Stripe.set_app_info(
347
- "MyAwesomePlugin",
348
- partner_id: "partner_1234",
349
- url: "https://myawesomeplugin.info",
350
- version: "1.2.34"
351
- )
352
-
353
- stub_request(:post, "#{Stripe.api_base}/v1/account")
354
- .with do |req|
355
- assert_equal \
356
- "Stripe/v1 RubyBindings/#{Stripe::VERSION} " \
357
- "MyAwesomePlugin/1.2.34 (https://myawesomeplugin.info)",
358
- req.headers["User-Agent"]
359
-
360
- data = JSON.parse(req.headers["X-Stripe-Client-User-Agent"],
361
- symbolize_names: true)
362
-
363
- assert_equal({
364
- name: "MyAwesomePlugin",
365
- partner_id: "partner_1234",
366
- url: "https://myawesomeplugin.info",
367
- version: "1.2.34",
368
- }, data[:application])
369
-
370
- true
371
- end.to_return(body: JSON.generate(object: "account"))
372
-
373
- client = StripeClient.new
374
- client.execute_request(:post, "/v1/account")
375
- ensure
376
- Stripe.app_info = old
377
- end
378
- end
379
- end
380
-
381
- context "error handling" do
382
- should "handle error response with empty body" do
383
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
384
- .to_return(body: "", status: 500)
385
-
386
- client = StripeClient.new
387
- e = assert_raises Stripe::APIError do
388
- client.execute_request(:post, "/v1/charges")
389
- end
390
-
391
- assert_equal 'Invalid response object from API: "" (HTTP response code was 500)', e.message
392
- end
393
-
394
- should "handle success response with empty body" do
395
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
396
- .to_return(body: "", status: 200)
397
-
398
- client = StripeClient.new
399
- e = assert_raises Stripe::APIError do
400
- client.execute_request(:post, "/v1/charges")
401
- end
402
-
403
- assert_equal 'Invalid response object from API: "" (HTTP response code was 200)', e.message
404
- end
405
-
406
- should "handle error response with unknown value" do
407
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
408
- .to_return(body: JSON.generate(bar: "foo"), status: 500)
409
-
410
- client = StripeClient.new
411
- e = assert_raises Stripe::APIError do
412
- client.execute_request(:post, "/v1/charges")
413
- end
414
-
415
- assert_equal 'Invalid response object from API: "{\"bar\":\"foo\"}" (HTTP response code was 500)', e.message
416
- end
417
-
418
- should "raise IdempotencyError on 400 of type idempotency_error" do
419
- data = make_missing_id_error
420
- data[:error][:type] = "idempotency_error"
421
-
422
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
423
- .to_return(body: JSON.generate(data), status: 400)
424
- client = StripeClient.new
425
-
426
- e = assert_raises Stripe::IdempotencyError do
427
- client.execute_request(:post, "/v1/charges")
428
- end
429
- assert_equal(400, e.http_status)
430
- assert_equal(true, e.json_body.is_a?(Hash))
431
- end
432
-
433
- should "raise InvalidRequestError on other 400s" do
434
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
435
- .to_return(body: JSON.generate(make_missing_id_error), status: 400)
436
- client = StripeClient.new
437
- begin
438
- client.execute_request(:post, "/v1/charges")
439
- rescue Stripe::InvalidRequestError => e
440
- assert_equal(400, e.http_status)
441
- assert_equal(true, e.json_body.is_a?(Hash))
442
- end
443
- end
444
-
445
- should "raise AuthenticationError on 401" do
446
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
447
- .to_return(body: JSON.generate(make_missing_id_error), status: 401)
448
- client = StripeClient.new
449
- begin
450
- client.execute_request(:post, "/v1/charges")
451
- rescue Stripe::AuthenticationError => e
452
- assert_equal(401, e.http_status)
453
- assert_equal(true, e.json_body.is_a?(Hash))
454
- end
455
- end
456
-
457
- should "raise CardError on 402" do
458
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
459
- .to_return(body: JSON.generate(make_invalid_exp_year_error), status: 402)
460
- client = StripeClient.new
461
- begin
462
- client.execute_request(:post, "/v1/charges")
463
- rescue Stripe::CardError => e
464
- assert_equal(402, e.http_status)
465
- assert_equal(true, e.json_body.is_a?(Hash))
466
- assert_equal("invalid_expiry_year", e.code)
467
- assert_equal("exp_year", e.param)
468
- end
469
- end
470
-
471
- should "raise PermissionError on 403" do
472
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
473
- .to_return(body: JSON.generate(make_missing_id_error), status: 403)
474
- client = StripeClient.new
475
- begin
476
- client.execute_request(:post, "/v1/charges")
477
- rescue Stripe::PermissionError => e
478
- assert_equal(403, e.http_status)
479
- assert_equal(true, e.json_body.is_a?(Hash))
480
- end
481
- end
482
-
483
- should "raise InvalidRequestError on 404" do
484
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
485
- .to_return(body: JSON.generate(make_missing_id_error), status: 404)
486
- client = StripeClient.new
487
- begin
488
- client.execute_request(:post, "/v1/charges")
489
- rescue Stripe::InvalidRequestError => e
490
- assert_equal(404, e.http_status)
491
- assert_equal(true, e.json_body.is_a?(Hash))
492
- end
493
- end
494
-
495
- should "raise RateLimitError on 429" do
496
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
497
- .to_return(body: JSON.generate(make_rate_limit_error), status: 429)
498
- client = StripeClient.new
499
- begin
500
- client.execute_request(:post, "/v1/charges")
501
- rescue Stripe::RateLimitError => e
502
- assert_equal(429, e.http_status)
503
- assert_equal(true, e.json_body.is_a?(Hash))
504
- end
505
- end
506
-
507
- should "raise OAuth::InvalidRequestError when error is a string with value 'invalid_request'" do
508
- stub_request(:post, "#{Stripe.connect_base}/oauth/token")
509
- .to_return(body: JSON.generate(error: "invalid_request",
510
- error_description: "No grant type specified"), status: 400)
511
-
512
- client = StripeClient.new
513
- opts = { api_base: Stripe.connect_base }
514
- e = assert_raises Stripe::OAuth::InvalidRequestError do
515
- client.execute_request(:post, "/oauth/token", opts)
516
- end
517
-
518
- assert_equal(400, e.http_status)
519
- assert_equal("No grant type specified", e.message)
520
- end
521
-
522
- should "raise OAuth::InvalidGrantError when error is a string with value 'invalid_grant'" do
523
- stub_request(:post, "#{Stripe.connect_base}/oauth/token")
524
- .to_return(body: JSON.generate(error: "invalid_grant",
525
- error_description: "This authorization code has already been used. All tokens issued with this code have been revoked."), status: 400)
526
-
527
- client = StripeClient.new
528
- opts = { api_base: Stripe.connect_base }
529
- e = assert_raises Stripe::OAuth::InvalidGrantError do
530
- client.execute_request(:post, "/oauth/token", opts)
531
- end
532
-
533
- assert_equal(400, e.http_status)
534
- assert_equal("invalid_grant", e.code)
535
- assert_equal("This authorization code has already been used. All tokens issued with this code have been revoked.", e.message)
536
- end
537
-
538
- should "raise OAuth::InvalidClientError when error is a string with value 'invalid_client'" do
539
- stub_request(:post, "#{Stripe.connect_base}/oauth/deauthorize")
540
- .to_return(body: JSON.generate(error: "invalid_client",
541
- error_description: "This application is not connected to stripe account acct_19tLK7DSlTMT26Mk, or that account does not exist."), status: 401)
542
-
543
- client = StripeClient.new
544
- opts = { api_base: Stripe.connect_base }
545
- e = assert_raises Stripe::OAuth::InvalidClientError do
546
- client.execute_request(:post, "/oauth/deauthorize", opts)
547
- end
548
-
549
- assert_equal(401, e.http_status)
550
- assert_equal("invalid_client", e.code)
551
- assert_equal("This application is not connected to stripe account acct_19tLK7DSlTMT26Mk, or that account does not exist.", e.message)
552
- end
553
-
554
- should "raise Stripe::OAuthError on indeterminate OAuth error" do
555
- stub_request(:post, "#{Stripe.connect_base}/oauth/deauthorize")
556
- .to_return(body: JSON.generate(error: "new_code_not_recognized",
557
- error_description: "Something."), status: 401)
558
-
559
- client = StripeClient.new
560
- opts = { api_base: Stripe.connect_base }
561
- e = assert_raises Stripe::OAuth::OAuthError do
562
- client.execute_request(:post, "/oauth/deauthorize", opts)
563
- end
564
-
565
- assert_equal(401, e.http_status)
566
- assert_equal("new_code_not_recognized", e.code)
567
- assert_equal("Something.", e.message)
568
- end
569
- end
570
-
571
- context "idempotency keys" do
572
- setup do
573
- Stripe.stubs(:max_network_retries).returns(2)
574
- end
575
-
576
- should "not add an idempotency key to GET requests" do
577
- SecureRandom.expects(:uuid).times(0)
578
- stub_request(:get, "#{Stripe.api_base}/v1/charges/ch_123")
579
- .with do |req|
580
- req.headers["Idempotency-Key"].nil?
581
- end.to_return(body: JSON.generate(object: "charge"))
582
- client = StripeClient.new
583
- client.execute_request(:get, "/v1/charges/ch_123")
584
- end
585
-
586
- should "ensure there is always an idempotency_key on POST requests" do
587
- SecureRandom.expects(:uuid).at_least_once.returns("random_key")
588
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
589
- .with(headers: { "Idempotency-Key" => "random_key" })
590
- .to_return(body: JSON.generate(object: "charge"))
591
- client = StripeClient.new
592
- client.execute_request(:post, "/v1/charges")
593
- end
594
-
595
- should "ensure there is always an idempotency_key on DELETE requests" do
596
- SecureRandom.expects(:uuid).at_least_once.returns("random_key")
597
- stub_request(:delete, "#{Stripe.api_base}/v1/charges/ch_123")
598
- .with(headers: { "Idempotency-Key" => "random_key" })
599
- .to_return(body: JSON.generate(object: "charge"))
600
- client = StripeClient.new
601
- client.execute_request(:delete, "/v1/charges/ch_123")
602
- end
603
-
604
- should "not override a provided idempotency_key" do
605
- # Note that this expectation looks like `:idempotency_key` instead of
606
- # the header `Idempotency-Key` because it's user provided as seen
607
- # below. The ones injected by the library itself look like headers
608
- # (`Idempotency-Key`), but rest-client does allow this symbol
609
- # formatting and will properly override the system generated one as
610
- # expected.
611
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
612
- .with(headers: { "Idempotency-Key" => "provided_key" })
613
- .to_return(body: JSON.generate(object: "charge"))
614
-
615
- client = StripeClient.new
616
- client.execute_request(:post, "/v1/charges",
617
- headers: { idempotency_key: "provided_key" })
618
- end
619
- end
620
-
621
- context "retry logic" do
622
- setup do
623
- Stripe.stubs(:max_network_retries).returns(2)
624
- end
625
-
626
- should "retry failed requests and raise if error persists" do
627
- StripeClient.expects(:sleep_time).at_least_once.returns(0)
628
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
629
- .to_raise(Errno::ECONNREFUSED.new)
630
-
631
- client = StripeClient.new
632
- err = assert_raises Stripe::APIConnectionError do
633
- client.execute_request(:post, "/v1/charges")
634
- end
635
- assert_match(/Request was retried 2 times/, err.message)
636
- end
637
-
638
- should "retry failed requests and return successful response" do
639
- StripeClient.expects(:sleep_time).at_least_once.returns(0)
640
-
641
- i = 0
642
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
643
- .to_return do |_|
644
- if i < 2
645
- i += 1
646
- raise Errno::ECONNREFUSED
647
- else
648
- { body: JSON.generate("id" => "myid") }
649
- end
650
- end
651
-
652
- client = StripeClient.new
653
- client.execute_request(:post, "/v1/charges")
654
- end
655
- end
656
-
657
- context "params serialization" do
658
- should "allows empty strings in params" do
659
- client = StripeClient.new
660
- client.execute_request(:get, "/v1/invoices/upcoming", params: {
661
- customer: "cus_123",
662
- coupon: "",
663
- })
664
- assert_requested(
665
- :get,
666
- "#{Stripe.api_base}/v1/invoices/upcoming?",
667
- query: {
668
- customer: "cus_123",
669
- coupon: "",
670
- }
671
- )
672
- end
673
-
674
- should "filter nils in params" do
675
- client = StripeClient.new
676
- client.execute_request(:get, "/v1/invoices/upcoming", params: {
677
- customer: "cus_123",
678
- coupon: nil,
679
- })
680
- assert_requested(
681
- :get,
682
- "#{Stripe.api_base}/v1/invoices/upcoming?",
683
- query: {
684
- customer: "cus_123",
685
- }
686
- )
687
- end
688
-
689
- should "merge query parameters in URL and params" do
690
- client = StripeClient.new
691
- client.execute_request(:get, "/v1/invoices/upcoming?coupon=25OFF", params: {
692
- customer: "cus_123",
693
- })
694
- assert_requested(
695
- :get,
696
- "#{Stripe.api_base}/v1/invoices/upcoming?",
697
- query: {
698
- coupon: "25OFF",
699
- customer: "cus_123",
700
- }
701
- )
702
- end
703
-
704
- should "prefer query parameters in params when specified in URL as well" do
705
- client = StripeClient.new
706
- client.execute_request(:get, "/v1/invoices/upcoming?customer=cus_query", params: {
707
- customer: "cus_param",
708
- })
709
- assert_requested(
710
- :get,
711
- "#{Stripe.api_base}/v1/invoices/upcoming?",
712
- query: {
713
- customer: "cus_param",
714
- }
715
- )
716
- end
717
- end
718
- end
719
-
720
- context "#request" do
721
- should "return a result and response object" do
722
- stub_request(:post, "#{Stripe.api_base}/v1/charges")
723
- .to_return(body: JSON.generate(object: "charge"))
724
-
725
- client = StripeClient.new
726
- charge, resp = client.request { Charge.create }
727
-
728
- assert charge.is_a?(Charge)
729
- assert resp.is_a?(StripeResponse)
730
- assert_equal 200, resp.http_status
731
- end
732
-
733
- should "return the value of given block" do
734
- client = StripeClient.new
735
- ret, = client.request { 7 }
736
- assert_equal 7, ret
737
- end
738
-
739
- should "reset local thread state after a call" do
740
- begin
741
- Thread.current[:stripe_client] = :stripe_client
742
-
743
- client = StripeClient.new
744
- client.request {}
745
-
746
- assert_equal :stripe_client, Thread.current[:stripe_client]
747
- ensure
748
- Thread.current[:stripe_client] = nil
749
- end
750
- end
751
- end
752
-
753
- context "#proxy" do
754
- should "run the request through the proxy" do
755
- begin
756
- Thread.current[:stripe_client_default_conn] = nil
757
-
758
- Stripe.proxy = "http://localhost:8080"
759
-
760
- client = StripeClient.new
761
- client.request {}
762
-
763
- assert_equal "http://localhost:8080", Stripe::StripeClient.default_conn.proxy.uri.to_s
764
- ensure
765
- Stripe.proxy = nil
766
-
767
- Thread.current[:stripe_client_default_conn] = nil
768
- end
769
- end
770
- end
771
-
772
- context "#telemetry" do
773
- teardown do
774
- # make sure to always set telemetry back to false
775
- # to not mutate global state
776
- Stripe.enable_telemetry = false
777
- end
778
-
779
- should "not send metrics if enable trace flag is not set" do
780
- Stripe.enable_telemetry = false
781
-
782
- trace_metrics_header = nil
783
- stub_request(:get, "#{Stripe.api_base}/v1/charges")
784
- .with do |req|
785
- trace_metrics_header = req.headers["X-Stripe-Client-Telemetry"]
786
- false
787
- end.to_return(body: JSON.generate(object: "charge"))
788
-
789
- Stripe::Charge.list
790
- assert(trace_metrics_header.nil?)
791
-
792
- Stripe::Charge.list
793
- assert(trace_metrics_header.nil?)
794
- end
795
-
796
- should "send metrics if enabled telemetry is true" do
797
- Stripe.enable_telemetry = true
798
-
799
- trace_metrics_header = nil
800
- stub_request(:get, "#{Stripe.api_base}/v1/charges")
801
- .with do |req|
802
- trace_metrics_header = req.headers["X-Stripe-Client-Telemetry"]
803
- false
804
- end.to_return(body: JSON.generate(object: "charge"))
805
-
806
- Stripe::Charge.list
807
- Stripe::Charge.list
808
-
809
- assert(!trace_metrics_header.nil?)
810
-
811
- trace_payload = JSON.parse(trace_metrics_header)
812
- assert(trace_payload["last_request_metrics"]["request_id"] == "req_123")
813
- assert(!trace_payload["last_request_metrics"]["request_duration_ms"].nil?)
814
- end
815
- end
816
- end
817
-
818
- class SystemProfilerTest < Test::Unit::TestCase
819
- context "#uname" do
820
- should "run without failure" do
821
- # Don't actually check the result because we try a variety of different
822
- # strategies that will have different results depending on where this
823
- # test and running. We're mostly making sure that no exception is thrown.
824
- _ = StripeClient::SystemProfiler.uname
825
- end
826
- end
827
-
828
- context "#uname_from_system" do
829
- should "run without failure" do
830
- # as above, just verify that an exception is not thrown
831
- _ = StripeClient::SystemProfiler.uname_from_system
832
- end
833
- end
834
-
835
- context "#uname_from_system_ver" do
836
- should "run without failure" do
837
- # as above, just verify that an exception is not thrown
838
- _ = StripeClient::SystemProfiler.uname_from_system_ver
839
- end
840
- end
841
- end
842
- end