stripe 4.9.0 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (224) hide show
  1. checksums.yaml +4 -4
  2. data/.editorconfig +10 -0
  3. data/.rubocop.yml +28 -4
  4. data/.rubocop_todo.yml +11 -22
  5. data/.travis.yml +3 -6
  6. data/.vscode/extensions.json +7 -0
  7. data/.vscode/settings.json +8 -0
  8. data/CHANGELOG.md +102 -2
  9. data/Gemfile +2 -10
  10. data/README.md +96 -40
  11. data/Rakefile +8 -7
  12. data/VERSION +1 -1
  13. data/lib/stripe.rb +64 -85
  14. data/lib/stripe/api_operations/delete.rb +23 -1
  15. data/lib/stripe/api_operations/list.rb +0 -6
  16. data/lib/stripe/api_operations/nested_resource.rb +14 -7
  17. data/lib/stripe/api_operations/request.rb +3 -7
  18. data/lib/stripe/api_operations/save.rb +1 -3
  19. data/lib/stripe/api_resource.rb +50 -2
  20. data/lib/stripe/connection_manager.rb +141 -0
  21. data/lib/stripe/error_object.rb +94 -0
  22. data/lib/stripe/errors.rb +22 -9
  23. data/lib/stripe/list_object.rb +11 -5
  24. data/lib/stripe/multipart_encoder.rb +131 -0
  25. data/lib/stripe/object_types.rb +94 -0
  26. data/lib/stripe/resources.rb +77 -0
  27. data/lib/stripe/{account.rb → resources/account.rb} +49 -27
  28. data/lib/stripe/{account_link.rb → resources/account_link.rb} +1 -1
  29. data/lib/stripe/resources/alipay_account.rb +34 -0
  30. data/lib/stripe/{apple_pay_domain.rb → resources/apple_pay_domain.rb} +1 -1
  31. data/lib/stripe/resources/application_fee.rb +13 -0
  32. data/lib/stripe/resources/application_fee_refund.rb +30 -0
  33. data/lib/stripe/{balance.rb → resources/balance.rb} +1 -1
  34. data/lib/stripe/{balance_transaction.rb → resources/balance_transaction.rb} +1 -5
  35. data/lib/stripe/{bank_account.rb → resources/bank_account.rb} +14 -4
  36. data/lib/stripe/{bitcoin_receiver.rb → resources/bitcoin_receiver.rb} +3 -3
  37. data/lib/stripe/{bitcoin_transaction.rb → resources/bitcoin_transaction.rb} +1 -1
  38. data/lib/stripe/resources/capability.rb +33 -0
  39. data/lib/stripe/{card.rb → resources/card.rb} +12 -4
  40. data/lib/stripe/resources/charge.rb +22 -0
  41. data/lib/stripe/{checkout → resources/checkout}/session.rb +2 -2
  42. data/lib/stripe/{country_spec.rb → resources/country_spec.rb} +1 -1
  43. data/lib/stripe/{coupon.rb → resources/coupon.rb} +2 -2
  44. data/lib/stripe/resources/credit_note.rb +22 -0
  45. data/lib/stripe/resources/customer.rb +35 -0
  46. data/lib/stripe/resources/customer_balance_transaction.rb +30 -0
  47. data/lib/stripe/resources/discount.rb +7 -0
  48. data/lib/stripe/{dispute.rb → resources/dispute.rb} +9 -7
  49. data/lib/stripe/{ephemeral_key.rb → resources/ephemeral_key.rb} +5 -2
  50. data/lib/stripe/{event.rb → resources/event.rb} +1 -1
  51. data/lib/stripe/{exchange_rate.rb → resources/exchange_rate.rb} +1 -1
  52. data/lib/stripe/{file.rb → resources/file.rb} +8 -11
  53. data/lib/stripe/{file_link.rb → resources/file_link.rb} +2 -2
  54. data/lib/stripe/resources/invoice.rb +73 -0
  55. data/lib/stripe/{invoice_item.rb → resources/invoice_item.rb} +2 -2
  56. data/lib/stripe/{invoice_line_item.rb → resources/invoice_line_item.rb} +1 -1
  57. data/lib/stripe/resources/issuing/authorization.rb +33 -0
  58. data/lib/stripe/resources/issuing/card.rb +24 -0
  59. data/lib/stripe/{issuing → resources/issuing}/card_details.rb +1 -1
  60. data/lib/stripe/{issuing → resources/issuing}/cardholder.rb +2 -2
  61. data/lib/stripe/{issuing → resources/issuing}/dispute.rb +2 -2
  62. data/lib/stripe/{issuing → resources/issuing}/transaction.rb +2 -2
  63. data/lib/stripe/resources/login_link.rb +14 -0
  64. data/lib/stripe/resources/order.rb +32 -0
  65. data/lib/stripe/{order_return.rb → resources/order_return.rb} +1 -1
  66. data/lib/stripe/resources/payment_intent.rb +42 -0
  67. data/lib/stripe/resources/payment_method.rb +32 -0
  68. data/lib/stripe/resources/payout.rb +22 -0
  69. data/lib/stripe/{person.rb → resources/person.rb} +8 -3
  70. data/lib/stripe/{plan.rb → resources/plan.rb} +1 -1
  71. data/lib/stripe/{product.rb → resources/product.rb} +3 -3
  72. data/lib/stripe/resources/radar/early_fraud_warning.rb +11 -0
  73. data/lib/stripe/{radar → resources/radar}/value_list.rb +2 -2
  74. data/lib/stripe/{radar → resources/radar}/value_list_item.rb +2 -2
  75. data/lib/stripe/{recipient.rb → resources/recipient.rb} +2 -6
  76. data/lib/stripe/{recipient_transfer.rb → resources/recipient_transfer.rb} +1 -1
  77. data/lib/stripe/{refund.rb → resources/refund.rb} +1 -1
  78. data/lib/stripe/{reporting → resources/reporting}/report_run.rb +2 -2
  79. data/lib/stripe/{reporting → resources/reporting}/report_type.rb +2 -2
  80. data/lib/stripe/resources/reversal.rb +29 -0
  81. data/lib/stripe/resources/review.rb +20 -0
  82. data/lib/stripe/resources/setup_intent.rb +32 -0
  83. data/lib/stripe/{sigma → resources/sigma}/scheduled_query_run.rb +2 -2
  84. data/lib/stripe/{sku.rb → resources/sku.rb} +3 -3
  85. data/lib/stripe/{source.rb → resources/source.rb} +17 -15
  86. data/lib/stripe/{source_transaction.rb → resources/source_transaction.rb} +1 -1
  87. data/lib/stripe/resources/subscription.rb +25 -0
  88. data/lib/stripe/{subscription_item.rb → resources/subscription_item.rb} +5 -2
  89. data/lib/stripe/resources/subscription_schedule.rb +32 -0
  90. data/lib/stripe/resources/tax_id.rb +26 -0
  91. data/lib/stripe/resources/tax_rate.rb +11 -0
  92. data/lib/stripe/{terminal → resources/terminal}/connection_token.rb +2 -2
  93. data/lib/stripe/{terminal → resources/terminal}/location.rb +3 -2
  94. data/lib/stripe/{terminal → resources/terminal}/reader.rb +3 -2
  95. data/lib/stripe/{three_d_secure.rb → resources/three_d_secure.rb} +1 -1
  96. data/lib/stripe/{token.rb → resources/token.rb} +1 -1
  97. data/lib/stripe/resources/topup.rb +22 -0
  98. data/lib/stripe/resources/transfer.rb +26 -0
  99. data/lib/stripe/resources/usage_record.rb +7 -0
  100. data/lib/stripe/{usage_record_summary.rb → resources/usage_record_summary.rb} +1 -1
  101. data/lib/stripe/{webhook_endpoint.rb → resources/webhook_endpoint.rb} +2 -2
  102. data/lib/stripe/singleton_api_resource.rb +3 -1
  103. data/lib/stripe/stripe_client.rb +347 -218
  104. data/lib/stripe/stripe_object.rb +72 -59
  105. data/lib/stripe/stripe_response.rb +53 -21
  106. data/lib/stripe/util.rb +54 -109
  107. data/lib/stripe/version.rb +1 -1
  108. data/lib/stripe/webhook.rb +5 -3
  109. data/stripe.gemspec +14 -5
  110. data/test/stripe/account_link_test.rb +1 -1
  111. data/test/stripe/account_test.rb +193 -32
  112. data/test/stripe/alipay_account_test.rb +1 -1
  113. data/test/stripe/api_operations_test.rb +3 -4
  114. data/test/stripe/api_resource_test.rb +119 -30
  115. data/test/stripe/apple_pay_domain_test.rb +18 -5
  116. data/test/stripe/application_fee_refund_test.rb +1 -1
  117. data/test/stripe/application_fee_test.rb +45 -1
  118. data/test/stripe/balance_test.rb +1 -1
  119. data/test/stripe/balance_transaction_test.rb +20 -0
  120. data/test/stripe/bank_account_test.rb +1 -1
  121. data/test/stripe/capability_test.rb +45 -0
  122. data/test/stripe/charge_test.rb +13 -8
  123. data/test/stripe/checkout/session_test.rb +7 -1
  124. data/test/stripe/connection_manager_test.rb +138 -0
  125. data/test/stripe/country_spec_test.rb +1 -1
  126. data/test/stripe/coupon_test.rb +16 -6
  127. data/test/stripe/credit_note_test.rb +61 -0
  128. data/test/stripe/customer_balance_transaction_test.rb +37 -0
  129. data/test/stripe/customer_card_test.rb +1 -1
  130. data/test/stripe/customer_test.rb +151 -40
  131. data/test/stripe/dispute_test.rb +10 -1
  132. data/test/stripe/ephemeral_key_test.rb +8 -1
  133. data/test/stripe/errors_test.rb +30 -9
  134. data/test/stripe/exchange_rate_test.rb +1 -1
  135. data/test/stripe/file_link_test.rb +1 -1
  136. data/test/stripe/file_test.rb +19 -5
  137. data/test/stripe/invoice_item_test.rb +18 -7
  138. data/test/stripe/invoice_line_item_test.rb +1 -1
  139. data/test/stripe/invoice_test.rb +77 -9
  140. data/test/stripe/issuing/authorization_test.rb +33 -11
  141. data/test/stripe/issuing/card_test.rb +15 -6
  142. data/test/stripe/issuing/cardholder_test.rb +1 -1
  143. data/test/stripe/issuing/dispute_test.rb +1 -1
  144. data/test/stripe/issuing/transaction_test.rb +1 -1
  145. data/test/stripe/list_object_test.rb +1 -17
  146. data/test/stripe/login_link_test.rb +2 -2
  147. data/test/stripe/multipart_encoder_test.rb +130 -0
  148. data/test/stripe/oauth_test.rb +1 -1
  149. data/test/stripe/order_return_test.rb +1 -1
  150. data/test/stripe/order_test.rb +28 -3
  151. data/test/stripe/payment_intent_test.rb +31 -4
  152. data/test/stripe/payment_method_test.rb +84 -0
  153. data/test/stripe/payout_test.rb +8 -1
  154. data/test/stripe/person_test.rb +1 -1
  155. data/test/stripe/plan_test.rb +26 -20
  156. data/test/stripe/product_test.rb +16 -6
  157. data/test/stripe/radar/early_fraud_warning_test.rb +22 -0
  158. data/test/stripe/radar/value_list_item_test.rb +16 -6
  159. data/test/stripe/radar/value_list_test.rb +16 -6
  160. data/test/stripe/recipient_test.rb +18 -5
  161. data/test/stripe/refund_test.rb +1 -1
  162. data/test/stripe/reporting/report_run_test.rb +1 -1
  163. data/test/stripe/reporting/report_type_test.rb +1 -1
  164. data/test/stripe/reversal_test.rb +1 -1
  165. data/test/stripe/review_test.rb +1 -1
  166. data/test/stripe/setup_intent_test.rb +84 -0
  167. data/test/stripe/sigma/scheduled_query_run_test.rb +1 -1
  168. data/test/stripe/sku_test.rb +16 -6
  169. data/test/stripe/source_test.rb +14 -19
  170. data/test/stripe/source_transaction_test.rb +1 -1
  171. data/test/stripe/stripe_client_test.rb +242 -26
  172. data/test/stripe/stripe_object_test.rb +8 -36
  173. data/test/stripe/stripe_response_test.rb +71 -25
  174. data/test/stripe/subscription_item_test.rb +28 -6
  175. data/test/stripe/subscription_schedule_test.rb +19 -1
  176. data/test/stripe/subscription_test.rb +29 -9
  177. data/test/stripe/tax_id_test.rb +31 -0
  178. data/test/stripe/tax_rate_test.rb +43 -0
  179. data/test/stripe/terminal/connection_token_test.rb +1 -1
  180. data/test/stripe/terminal/location_test.rb +18 -1
  181. data/test/stripe/terminal/reader_test.rb +18 -1
  182. data/test/stripe/three_d_secure_test.rb +1 -1
  183. data/test/stripe/topup_test.rb +9 -1
  184. data/test/stripe/transfer_test.rb +46 -1
  185. data/test/stripe/usage_record_summary_test.rb +1 -1
  186. data/test/stripe/util_test.rb +1 -1
  187. data/test/stripe/webhook_endpoint_test.rb +18 -1
  188. data/test/stripe/webhook_test.rb +4 -4
  189. data/test/stripe_mock.rb +4 -3
  190. data/test/stripe_test.rb +1 -14
  191. data/test/test_helper.rb +14 -11
  192. metadata +117 -125
  193. data/lib/stripe/alipay_account.rb +0 -27
  194. data/lib/stripe/application_fee.rb +0 -23
  195. data/lib/stripe/application_fee_refund.rb +0 -22
  196. data/lib/stripe/charge.rb +0 -84
  197. data/lib/stripe/customer.rb +0 -90
  198. data/lib/stripe/invoice.rb +0 -48
  199. data/lib/stripe/issuer_fraud_record.rb +0 -9
  200. data/lib/stripe/issuing/authorization.rb +0 -22
  201. data/lib/stripe/issuing/card.rb +0 -18
  202. data/lib/stripe/login_link.rb +0 -11
  203. data/lib/stripe/order.rb +0 -31
  204. data/lib/stripe/payment_intent.rb +0 -26
  205. data/lib/stripe/payout.rb +0 -20
  206. data/lib/stripe/reversal.rb +0 -22
  207. data/lib/stripe/review.rb +0 -14
  208. data/lib/stripe/subscription.rb +0 -25
  209. data/lib/stripe/subscription_schedule.rb +0 -32
  210. data/lib/stripe/subscription_schedule_revision.rb +0 -25
  211. data/lib/stripe/topup.rb +0 -16
  212. data/lib/stripe/transfer.rb +0 -23
  213. data/lib/stripe/usage_record.rb +0 -14
  214. data/test/stripe/account_external_accounts_operations_test.rb +0 -69
  215. data/test/stripe/account_login_links_operations_test.rb +0 -21
  216. data/test/stripe/account_persons_operations_test.rb +0 -70
  217. data/test/stripe/application_fee_refunds_operations_test.rb +0 -56
  218. data/test/stripe/customer_sources_operations_test.rb +0 -64
  219. data/test/stripe/file_upload_test.rb +0 -76
  220. data/test/stripe/issuer_fraud_record_test.rb +0 -20
  221. data/test/stripe/subscription_schedule_revision_test.rb +0 -37
  222. data/test/stripe/subscription_schedule_revisions_operations_test.rb +0 -35
  223. data/test/stripe/transfer_reversals_operations_test.rb +0 -57
  224. data/test/stripe/usage_record_test.rb +0 -28
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Stripe
4
- VERSION = "4.9.0".freeze
4
+ VERSION = "5.1.0"
5
5
  end
@@ -8,7 +8,8 @@ module Stripe
8
8
  #
9
9
  # This may raise JSON::ParserError if the payload is not valid JSON, or
10
10
  # SignatureVerificationError if the signature verification fails.
11
- def self.construct_event(payload, sig_header, secret, tolerance: DEFAULT_TOLERANCE)
11
+ def self.construct_event(payload, sig_header, secret,
12
+ tolerance: DEFAULT_TOLERANCE)
12
13
  Signature.verify_header(payload, sig_header, secret, tolerance: tolerance)
13
14
 
14
15
  # It's a good idea to parse the payload only after verifying it. We use
@@ -21,7 +22,7 @@ module Stripe
21
22
  end
22
23
 
23
24
  module Signature
24
- EXPECTED_SCHEME = "v1".freeze
25
+ EXPECTED_SCHEME = "v1"
25
26
 
26
27
  def self.compute_signature(payload, secret)
27
28
  OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("sha256"), secret, payload)
@@ -50,7 +51,8 @@ module Stripe
50
51
  # Returns true otherwise
51
52
  def self.verify_header(payload, header, secret, tolerance: nil)
52
53
  begin
53
- timestamp, signatures = get_timestamp_and_signatures(header, EXPECTED_SCHEME)
54
+ timestamp, signatures =
55
+ get_timestamp_and_signatures(header, EXPECTED_SCHEME)
54
56
  rescue StandardError
55
57
  raise SignatureVerificationError.new(
56
58
  "Unable to extract timestamp and signatures from header",
@@ -7,19 +7,28 @@ require "stripe/version"
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "stripe"
9
9
  s.version = Stripe::VERSION
10
- s.required_ruby_version = ">= 2.1.0"
10
+ s.required_ruby_version = ">= 2.3.0"
11
11
  s.summary = "Ruby bindings for the Stripe API"
12
- s.description = "Stripe is the easiest way to accept payments online. See https://stripe.com for details."
12
+ s.description = "Stripe is the easiest way to accept payments online. " \
13
+ "See https://stripe.com for details."
13
14
  s.author = "Stripe"
14
15
  s.email = "support@stripe.com"
15
16
  s.homepage = "https://stripe.com/docs/api/ruby"
16
17
  s.license = "MIT"
17
18
 
18
- s.add_dependency("faraday", "~> 0.13")
19
- s.add_dependency("net-http-persistent", "~> 3.0")
19
+ s.metadata = {
20
+ "bug_tracker_uri" => "https://github.com/stripe/stripe-ruby/issues",
21
+ "changelog_uri" =>
22
+ "https://github.com/stripe/stripe-ruby/blob/master/CHANGELOG.md",
23
+ "documentation_uri" => "https://stripe.com/docs/api/ruby",
24
+ "github_repo" => "ssh://github.com/stripe/stripe-ruby",
25
+ "homepage_uri" => "https://stripe.com/docs/api/ruby",
26
+ "source_code_uri" => "https://github.com/stripe/stripe-ruby",
27
+ }
20
28
 
21
29
  s.files = `git ls-files`.split("\n")
22
30
  s.test_files = `git ls-files -- test/*`.split("\n")
23
- s.executables = `git ls-files -- bin/*`.split("\n").map { |f| ::File.basename(f) }
31
+ s.executables = `git ls-files -- bin/*`.split("\n")
32
+ .map { |f| ::File.basename(f) }
24
33
  s.require_paths = ["lib"]
25
34
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require ::File.expand_path("../../test_helper", __FILE__)
3
+ require ::File.expand_path("../test_helper", __dir__)
4
4
 
5
5
  module Stripe
6
6
  class AccountLinkTest < Test::Unit::TestCase
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require ::File.expand_path("../../test_helper", __FILE__)
3
+ require ::File.expand_path("../test_helper", __dir__)
4
4
 
5
5
  module Stripe
6
6
  class AccountTest < Test::Unit::TestCase
@@ -24,15 +24,18 @@ module Stripe
24
24
  end
25
25
 
26
26
  should "be rejectable" do
27
- account_data = { id: "acct_foo" }
28
- stub_request(:get, "#{Stripe.api_base}/v1/accounts/acct_foo")
29
- .to_return(body: JSON.generate(account_data))
30
-
31
- stub_request(:post, "#{Stripe.api_base}/v1/accounts/acct_foo/reject")
32
- .to_return(body: JSON.generate(account_data))
33
-
34
27
  account = Stripe::Account.retrieve("acct_foo")
35
- account.reject(reason: "fraud")
28
+ account = account.reject(reason: "fraud")
29
+ assert_requested :post, "#{Stripe.api_base}/v1/accounts/#{account.id}/reject"
30
+ assert account.is_a?(Stripe::Account)
31
+ end
32
+
33
+ context ".reject" do
34
+ should "reject the account" do
35
+ account = Stripe::Account.reject("acct_foo", reason: "fraud")
36
+ assert_requested :post, "#{Stripe.api_base}/v1/accounts/#{account.id}/reject"
37
+ assert account.is_a?(Stripe::Account)
38
+ end
36
39
  end
37
40
 
38
41
  should "be creatable" do
@@ -54,11 +57,21 @@ module Stripe
54
57
  assert account.is_a?(Stripe::Account)
55
58
  end
56
59
 
57
- should "be deletable" do
58
- account = Stripe::Account.retrieve("acct_123")
59
- account = account.delete
60
- assert_requested :delete, "#{Stripe.api_base}/v1/accounts/#{account.id}"
61
- assert account.is_a?(Stripe::Account)
60
+ context "#delete" do
61
+ should "be deletable" do
62
+ account = Stripe::Account.retrieve("acct_123")
63
+ account = account.delete
64
+ assert_requested :delete, "#{Stripe.api_base}/v1/accounts/#{account.id}"
65
+ assert account.is_a?(Stripe::Account)
66
+ end
67
+ end
68
+
69
+ context ".delete" do
70
+ should "be deletable" do
71
+ account = Stripe::Account.delete("acct_123")
72
+ assert_requested :delete, "#{Stripe.api_base}/v1/accounts/acct_123"
73
+ assert account.is_a?(Stripe::Account)
74
+ end
62
75
  end
63
76
 
64
77
  should "be able to list Persons" do
@@ -69,22 +82,6 @@ module Stripe
69
82
  assert persons.data[0].is_a?(Stripe::Person)
70
83
  end
71
84
 
72
- context "#bank_account=" do
73
- should "warn that #bank_account= is deprecated" do
74
- old_stderr = $stderr
75
- $stderr = StringIO.new
76
- begin
77
- account = Stripe::Account.retrieve("acct_123")
78
- account.bank_account = "tok_123"
79
- message = "NOTE: Stripe::Account#bank_account= is " \
80
- "deprecated; use #external_account= instead"
81
- assert_match Regexp.new(message), $stderr.string
82
- ensure
83
- $stderr = old_stderr
84
- end
85
- end
86
- end
87
-
88
85
  context "#deauthorize" do
89
86
  should "deauthorize an account" do
90
87
  account = Stripe::Account.retrieve("acct_123")
@@ -100,7 +97,12 @@ module Stripe
100
97
 
101
98
  context "#legal_entity=" do
102
99
  should "disallow direct overrides" do
103
- account = Stripe::Account.retrieve("acct_123")
100
+ account = Stripe::Account.construct_from(
101
+ id: "acct_123",
102
+ legal_entity: {
103
+ first_name: "name",
104
+ }
105
+ )
104
106
 
105
107
  assert_raise NoMethodError do
106
108
  account.legal_entity = { first_name: "Blah" }
@@ -111,7 +113,7 @@ module Stripe
111
113
  end
112
114
 
113
115
  context "#serialize_params" do
114
- should "serialize an a new additional_owners" do
116
+ should "serialize a new additional_owners" do
115
117
  obj = Stripe::Util.convert_to_stripe_object({
116
118
  object: "account",
117
119
  legal_entity: Stripe::StripeObject.construct_from({
@@ -247,5 +249,164 @@ module Stripe
247
249
  assert_equal(expected, obj.serialize_params)
248
250
  end
249
251
  end
252
+
253
+ context "#retrieve_capability" do
254
+ should "retrieve a capability" do
255
+ capability = Stripe::Account.retrieve_capability(
256
+ "acct_123",
257
+ "acap_123"
258
+ )
259
+ assert_requested :get, "#{Stripe.api_base}/v1/accounts/acct_123/capabilities/acap_123"
260
+ assert capability.is_a?(Stripe::Capability)
261
+ end
262
+ end
263
+
264
+ context "#update_capability" do
265
+ should "update a capability" do
266
+ capability = Stripe::Account.update_capability(
267
+ "acct_123",
268
+ "acap_123",
269
+ requested: true
270
+ )
271
+ assert_requested :post, "#{Stripe.api_base}/v1/accounts/acct_123/capabilities/acap_123"
272
+ assert capability.is_a?(Stripe::Capability)
273
+ end
274
+ end
275
+
276
+ context "#list_capabilities" do
277
+ should "list the account's external accounts" do
278
+ capabilities = Stripe::Account.list_capabilities(
279
+ "acct_123"
280
+ )
281
+ assert_requested :get, "#{Stripe.api_base}/v1/accounts/acct_123/capabilities"
282
+ assert capabilities.is_a?(Stripe::ListObject)
283
+ assert capabilities.data.is_a?(Array)
284
+ end
285
+ end
286
+
287
+ context "#create_external_account" do
288
+ should "create an external account" do
289
+ external_account = Stripe::Account.create_external_account(
290
+ "acct_123",
291
+ external_account: "btok_123"
292
+ )
293
+ assert_requested :post, "#{Stripe.api_base}/v1/accounts/acct_123/external_accounts"
294
+ assert external_account.is_a?(Stripe::BankAccount)
295
+ end
296
+ end
297
+
298
+ context "#retrieve_external_account" do
299
+ should "retrieve an external account" do
300
+ external_account = Stripe::Account.retrieve_external_account(
301
+ "acct_123",
302
+ "ba_123"
303
+ )
304
+ assert_requested :get, "#{Stripe.api_base}/v1/accounts/acct_123/external_accounts/ba_123"
305
+ assert external_account.is_a?(Stripe::BankAccount)
306
+ end
307
+ end
308
+
309
+ context "#update_external_account" do
310
+ should "update an external account" do
311
+ external_account = Stripe::Account.update_external_account(
312
+ "acct_123",
313
+ "ba_123",
314
+ metadata: { foo: "bar" }
315
+ )
316
+ assert_requested :post, "#{Stripe.api_base}/v1/accounts/acct_123/external_accounts/ba_123"
317
+ assert external_account.is_a?(Stripe::BankAccount)
318
+ end
319
+ end
320
+
321
+ context "#delete_external_account" do
322
+ should "delete an external_account" do
323
+ external_account = Stripe::Account.delete_external_account(
324
+ "acct_123",
325
+ "ba_123"
326
+ )
327
+ assert_requested :delete, "#{Stripe.api_base}/v1/accounts/acct_123/external_accounts/ba_123"
328
+ assert external_account.deleted
329
+ assert_equal "ba_123", external_account.id
330
+ end
331
+ end
332
+
333
+ context "#list_external_accounts" do
334
+ should "list the account's external accounts" do
335
+ external_accounts = Stripe::Account.list_external_accounts(
336
+ "acct_123"
337
+ )
338
+ assert_requested :get, "#{Stripe.api_base}/v1/accounts/acct_123/external_accounts"
339
+ assert external_accounts.is_a?(Stripe::ListObject)
340
+ assert external_accounts.data.is_a?(Array)
341
+ end
342
+ end
343
+
344
+ context "#create_login_link" do
345
+ should "create a login link" do
346
+ login_link = Stripe::Account.create_login_link(
347
+ "acct_123"
348
+ )
349
+ assert_requested :post, "#{Stripe.api_base}/v1/accounts/acct_123/login_links"
350
+ assert login_link.is_a?(Stripe::LoginLink)
351
+ end
352
+ end
353
+
354
+ context "#create_person" do
355
+ should "create a person" do
356
+ person = Stripe::Account.create_person(
357
+ "acct_123",
358
+ first_name: "John",
359
+ last_name: "Doe"
360
+ )
361
+ assert_requested :post, "#{Stripe.api_base}/v1/accounts/acct_123/persons"
362
+ assert person.is_a?(Stripe::Person)
363
+ end
364
+ end
365
+
366
+ context "#retrieve_person" do
367
+ should "retrieve a person" do
368
+ person = Stripe::Account.retrieve_person(
369
+ "acct_123",
370
+ "person_123"
371
+ )
372
+ assert_requested :get, "#{Stripe.api_base}/v1/accounts/acct_123/persons/person_123"
373
+ assert person.is_a?(Stripe::Person)
374
+ end
375
+ end
376
+
377
+ context "#update_person" do
378
+ should "update a person" do
379
+ person = Stripe::Account.update_person(
380
+ "acct_123",
381
+ "person_123",
382
+ first_name: "John"
383
+ )
384
+ assert_requested :post, "#{Stripe.api_base}/v1/accounts/acct_123/persons/person_123"
385
+ assert person.is_a?(Stripe::Person)
386
+ end
387
+ end
388
+
389
+ context "#delete_person" do
390
+ should "delete an person" do
391
+ person = Stripe::Account.delete_person(
392
+ "acct_123",
393
+ "person_123"
394
+ )
395
+ assert_requested :delete, "#{Stripe.api_base}/v1/accounts/acct_123/persons/person_123"
396
+ assert person.deleted
397
+ assert_equal "person_123", person.id
398
+ end
399
+ end
400
+
401
+ context "#list_persons" do
402
+ should "list the account's external accounts" do
403
+ persons = Stripe::Account.list_persons(
404
+ "acct_123"
405
+ )
406
+ assert_requested :get, "#{Stripe.api_base}/v1/accounts/acct_123/persons"
407
+ assert persons.is_a?(Stripe::ListObject)
408
+ assert persons.data.is_a?(Array)
409
+ end
410
+ end
250
411
  end
251
412
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require ::File.expand_path("../../test_helper", __FILE__)
3
+ require ::File.expand_path("../test_helper", __dir__)
4
4
 
5
5
  module Stripe
6
6
  class AlipayAccountTest < Test::Unit::TestCase
@@ -1,14 +1,13 @@
1
- # -*- coding: utf-8 -*-
2
1
  # frozen_string_literal: true
3
2
 
4
- require ::File.expand_path("../../test_helper", __FILE__)
3
+ require ::File.expand_path("../test_helper", __dir__)
5
4
 
6
5
  module Stripe
7
6
  class ApiOperationsTest < Test::Unit::TestCase
8
7
  class UpdateableResource < APIResource
9
8
  include Stripe::APIOperations::Save
10
9
 
11
- OBJECT_NAME = "updateableresource".freeze
10
+ OBJECT_NAME = "updateableresource"
12
11
 
13
12
  def self.protected_fields
14
13
  [:protected]
@@ -35,7 +34,7 @@ module Stripe
35
34
  context ".nested_resource_class_methods" do
36
35
  class MainResource < APIResource
37
36
  extend Stripe::APIOperations::NestedResource
38
- OBJECT_NAME = "mainresource".freeze
37
+ OBJECT_NAME = "mainresource"
39
38
  nested_resource_class_methods :nested,
40
39
  operations: %i[create retrieve update delete list]
41
40
  end
@@ -1,14 +1,34 @@
1
- # -*- coding: utf-8 -*-
2
1
  # frozen_string_literal: true
3
2
 
4
- require ::File.expand_path("../../test_helper", __FILE__)
3
+ require ::File.expand_path("../test_helper", __dir__)
5
4
 
6
5
  module Stripe
7
6
  class ApiResourceTest < Test::Unit::TestCase
8
- class NestedTestAPIResource < Stripe::APIResource
7
+ class CustomMethodAPIResource < APIResource
8
+ OBJECT_NAME = "custom_method"
9
+ custom_method :my_method, http_verb: :post
10
+ end
11
+
12
+ class NestedTestAPIResource < APIResource
9
13
  save_nested_resource :external_account
10
14
  end
11
15
 
16
+ context ".custom_method" do
17
+ should "call to an RPC-style method" do
18
+ stub_request(:post, "#{Stripe.api_base}/v1/custom_methods/ch_123/my_method")
19
+ .to_return(body: JSON.generate({}))
20
+ CustomMethodAPIResource.my_method("ch_123")
21
+ end
22
+
23
+ should "raise an error if a non-ID is passed" do
24
+ e = assert_raises ArgumentError do
25
+ CustomMethodAPIResource.my_method(id: "ch_123")
26
+ end
27
+ assert_equal "id should be a string representing the ID of an API resource",
28
+ e.message
29
+ end
30
+ end
31
+
12
32
  context ".save_nested_resource" do
13
33
  should "can have a scalar set" do
14
34
  r = NestedTestAPIResource.new("test_resource")
@@ -251,14 +271,6 @@ module Stripe
251
271
  assert_equal c.created, 12_345
252
272
  end
253
273
 
254
- should "accessing a property other than id or parent on an unfetched object should fetch it" do
255
- stub_request(:get, "#{Stripe.api_base}/v1/charges")
256
- .with(query: { customer: "cus_123" })
257
- .to_return(body: JSON.generate(customer_fixture))
258
- c = Stripe::Customer.new("cus_123")
259
- c.charges
260
- end
261
-
262
274
  should "updating an object should issue a POST request with only the changed properties" do
263
275
  stub_request(:post, "#{Stripe.api_base}/v1/customers/cus_123")
264
276
  .with(body: { "description" => "another_mn" })
@@ -307,7 +319,7 @@ module Stripe
307
319
  charges = Stripe::Charge.list.data
308
320
  assert charges.is_a? Array
309
321
  assert charges[0].is_a? Stripe::Charge
310
- assert charges[0].source.is_a?(Stripe::StripeObject)
322
+ assert charges[0].payment_method_details.is_a?(Stripe::StripeObject)
311
323
  end
312
324
 
313
325
  should "passing in a stripe_account header should pass it through on call" do
@@ -375,20 +387,22 @@ module Stripe
375
387
  end
376
388
 
377
389
  should "correctly handle replaced nested objects" do
378
- acct = Stripe::Account.construct_from(id: "myid",
379
- legal_entity: {
380
- last_name: "Smith",
381
- address: {
382
- line1: "test",
383
- city: "San Francisco",
384
- },
385
- })
386
-
387
- stub_request(:post, "#{Stripe.api_base}/v1/accounts/myid")
388
- .with(body: { legal_entity: { address: { line1: "Test2", city: "" } } })
390
+ acct = Stripe::Account.construct_from(
391
+ id: "acct_123",
392
+ company: {
393
+ name: "company_name",
394
+ address: {
395
+ line1: "test",
396
+ city: "San Francisco",
397
+ },
398
+ }
399
+ )
400
+
401
+ stub_request(:post, "#{Stripe.api_base}/v1/accounts/acct_123")
402
+ .with(body: { company: { address: { line1: "Test2", city: "" } } })
389
403
  .to_return(body: JSON.generate("id" => "my_id"))
390
404
 
391
- acct.legal_entity.address = { line1: "Test2" }
405
+ acct.company.address = { line1: "Test2" }
392
406
  acct.save
393
407
  end
394
408
 
@@ -489,7 +503,84 @@ module Stripe
489
503
  end
490
504
  end
491
505
 
492
- @@fixtures = {}
506
+ context "#request_stripe_object" do
507
+ class HelloTestAPIResource < APIResource
508
+ OBJECT_NAME = "hello"
509
+ def say_hello(params = {}, opts = {})
510
+ request_stripe_object(
511
+ method: :post,
512
+ path: resource_url + "/say",
513
+ params: params,
514
+ opts: opts
515
+ )
516
+ end
517
+ end
518
+
519
+ setup do
520
+ Util.instance_variable_set(
521
+ :@object_classes,
522
+ Stripe::ObjectTypes.object_names_to_classes.merge(
523
+ "hello" => HelloTestAPIResource
524
+ )
525
+ )
526
+ end
527
+ teardown do
528
+ Util.class.instance_variable_set(:@object_classes, Stripe::ObjectTypes.object_names_to_classes)
529
+ end
530
+
531
+ should "make requests appropriately" do
532
+ stub_request(:post, "#{Stripe.api_base}/v1/hellos/hi_123/say")
533
+ .with(body: { foo: "bar" }, headers: { "Stripe-Account" => "acct_hi" })
534
+ .to_return(body: JSON.generate("object" => "hello"))
535
+
536
+ hello = HelloTestAPIResource.new(id: "hi_123")
537
+ hello.say_hello({ foo: "bar" }, stripe_account: "acct_hi")
538
+ end
539
+
540
+ should "update attributes in-place when it returns the same thing" do
541
+ stub_request(:post, "#{Stripe.api_base}/v1/hellos/hi_123/say")
542
+ .to_return(body: JSON.generate("object" => "hello", "additional" => "attribute"))
543
+
544
+ hello = HelloTestAPIResource.new(id: "hi_123")
545
+ hello.unsaved = "a value"
546
+ new_hello = hello.say_hello
547
+
548
+ # Doesn't matter if you use the return variable or the instance.
549
+ assert_equal(hello, new_hello)
550
+
551
+ # It updates new attributes in-place.
552
+ assert_equal("attribute", hello.additional)
553
+
554
+ # It removes unsaved attributes, but at least lets you know about them.
555
+ e = assert_raises(NoMethodError) { hello.unsaved }
556
+ assert_match("The 'unsaved' attribute was set in the past", e.message)
557
+ end
558
+
559
+ should "instantiate a new object of the appropriate class when it is different than the host class" do
560
+ stub_request(:post, "#{Stripe.api_base}/v1/hellos/hi_123/say")
561
+ .to_return(body: JSON.generate("object" => "goodbye", "additional" => "attribute"))
562
+
563
+ hello = HelloTestAPIResource.new(id: "hi_123")
564
+ hello.unsaved = "a value"
565
+ new_goodbye = hello.say_hello
566
+
567
+ # The returned value and the instance are different objects.
568
+ refute_equal(new_goodbye, hello)
569
+
570
+ # The returned value has stuff from the server.
571
+ assert_equal("attribute", new_goodbye.additional)
572
+ assert_equal("goodbye", new_goodbye.object)
573
+
574
+ # You instance doesn't have stuff from the server.
575
+ e = assert_raises(NoMethodError) { hello.additional }
576
+ refute_match(/was set in the past/, e.message)
577
+
578
+ # The instance preserves unset attributes on the original instance (not sure this is good behavior?)
579
+ assert_equal("a value", hello.unsaved)
580
+ end
581
+ end
582
+
583
+ @@fixtures = {} # rubocop:disable Style/ClassVars
493
584
  setup do
494
585
  if @@fixtures.empty?
495
586
  cache_fixture(:charge) do
@@ -501,19 +592,17 @@ module Stripe
501
592
  end
502
593
  end
503
594
 
504
- private
505
-
506
- def charge_fixture
595
+ private def charge_fixture
507
596
  @@fixtures[:charge]
508
597
  end
509
598
 
510
- def customer_fixture
599
+ private def customer_fixture
511
600
  @@fixtures[:customer]
512
601
  end
513
602
 
514
603
  # Expects to retrieve a fixture from stripe-mock (an API call should be
515
604
  # included in the block to yield to) and does very simple memoization.
516
- def cache_fixture(key)
605
+ private def cache_fixture(key)
517
606
  return @@fixtures[key] if @@fixtures.key?(key)
518
607
 
519
608
  obj = yield