diff --git a/CHANGELOG.md b/CHANGELOG.md index 57b136f19..b15425e45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 10.4.0 - 2023-12-22 +* [#1303](https://github.com/stripe/stripe-ruby/pull/1303) Update generated code + * Add support for new resource `FinancialConnections.Transaction` + * Add support for `list` and `retrieve` methods on resource `Transaction` + * Add support for `subscribe` and `unsubscribe` methods on resource `FinancialConnections.Account` +* [#1304](https://github.com/stripe/stripe-ruby/pull/1304) Add support for updatable singleton resources + ## 10.4.0-beta.1 - 2023-12-14 Updated stable APIs to the latest version diff --git a/OPENAPI_VERSION b/OPENAPI_VERSION index 4dcad4de2..8f5da3930 100644 --- a/OPENAPI_VERSION +++ b/OPENAPI_VERSION @@ -1 +1 @@ -v715 \ No newline at end of file +v737 \ No newline at end of file diff --git a/lib/stripe.rb b/lib/stripe.rb index d20604b61..b706b920b 100644 --- a/lib/stripe.rb +++ b/lib/stripe.rb @@ -26,6 +26,7 @@ require "stripe/api_operations/nested_resource" require "stripe/api_operations/request" require "stripe/api_operations/save" +require "stripe/api_operations/singleton_save" require "stripe/api_operations/search" # API resource support classes diff --git a/lib/stripe/api_operations/singleton_save.rb b/lib/stripe/api_operations/singleton_save.rb new file mode 100644 index 000000000..d1e367cd0 --- /dev/null +++ b/lib/stripe/api_operations/singleton_save.rb @@ -0,0 +1,86 @@ +# frozen_string_literal: true + +module Stripe + module APIOperations + module SingletonSave + module ClassMethods + # Updates a singleton API resource + # + # Updates the identified resource with the passed in parameters. + # + # ==== Attributes + # + # * +params+ - A hash of parameters to pass to the API + # * +opts+ - A Hash of additional options (separate from the params / + # object values) to be added to the request. E.g. to allow for an + # idempotency_key to be passed in the request headers, or for the + # api_key to be overwritten. See + # {APIOperations::Request.execute_resource_request}. + def update(params = {}, opts = {}) + params.each_key do |k| + raise ArgumentError, "Cannot update protected field: #{k}" if protected_fields.include?(k) + end + + request_stripe_object( + method: :post, + path: resource_url, + params: params, + opts: opts + ) + end + end + + # The `save` method is DEPRECATED and will be removed in a future major + # version of the library. Use the `update` method on the resource instead. + # + # Updates a singleton API resource. + # + # If the resource doesn't yet have an assigned ID and the resource is one + # that can be created, then the method attempts to create the resource. + # The resource is updated otherwise. + # + # ==== Attributes + # + # * +params+ - Overrides any parameters in the resource's serialized data + # and includes them in the create or update. If +:req_url:+ is included + # in the list, it overrides the update URL used for the create or + # update. + # * +opts+ - A Hash of additional options (separate from the params / + # object values) to be added to the request. E.g. to allow for an + # idempotency_key to be passed in the request headers, or for the + # api_key to be overwritten. See + # {APIOperations::Request.execute_resource_request}. + def save(params = {}, opts = {}) + # We started unintentionally (sort of) allowing attributes sent to + # +save+ to override values used during the update. So as not to break + # the API, this makes that official here. + update_attributes(params) + + # Now remove any parameters that look like object attributes. + params = params.reject { |k, _| respond_to?(k) } + + values = serialize_params(self).merge(params) + + resp, opts = execute_resource_request(:post, resource_url, values, opts, ["save"]) + initialize_from(resp.data, opts) + end + extend Gem::Deprecate + deprecate :save, "the `update` class method (for examples " \ + "see https://github.com/stripe/stripe-ruby" \ + "/wiki/Migration-guide-for-v8)", 2022, 11 + + def self.included(base) + # Set `metadata` as additive so that when it's set directly we remember + # to clear keys that may have been previously set by sending empty + # values for them. + # + # It's possible that not every object with `Save` has `metadata`, but + # it's a close enough heuristic, and having this option set when there + # is no `metadata` field is not harmful. + base.additive_object_param(:metadata) + + base.extend(ClassMethods) + end + end + end +end diff --git a/lib/stripe/resources/confirmation_token.rb b/lib/stripe/resources/confirmation_token.rb index 2b5a3327f..71f1acae8 100644 --- a/lib/stripe/resources/confirmation_token.rb +++ b/lib/stripe/resources/confirmation_token.rb @@ -5,6 +5,8 @@ module Stripe # ConfirmationTokens help transport client side data collected by Stripe JS over # to your server for confirming a PaymentIntent or SetupIntent. If the confirmation # is successful, values present on the ConfirmationToken are written onto the Intent. + # + # To learn more or request access, visit the related guided: [Finalize payments on the server using Confirmation Tokens](https://stripe.com/docs/payments/finalize-payments-on-the-server-confirmation-tokens). class ConfirmationToken < APIResource OBJECT_NAME = "confirmation_token" end diff --git a/lib/stripe/resources/file.rb b/lib/stripe/resources/file.rb index c389adf4a..2bfaf103d 100644 --- a/lib/stripe/resources/file.rb +++ b/lib/stripe/resources/file.rb @@ -5,7 +5,7 @@ module Stripe # This object represents files hosted on Stripe's servers. You can upload # files with the [create file](https://stripe.com/docs/api#create_file) request # (for example, when uploading dispute evidence). Stripe also - # creates files independetly (for example, the results of a [Sigma scheduled + # creates files independently (for example, the results of a [Sigma scheduled # query](https://stripe.com/docs/api#scheduled_queries)). # # Related guide: [File upload guide](https://stripe.com/docs/file-upload) diff --git a/lib/stripe/resources/tax/settings.rb b/lib/stripe/resources/tax/settings.rb index 6a177a0a6..2a4e25531 100644 --- a/lib/stripe/resources/tax/settings.rb +++ b/lib/stripe/resources/tax/settings.rb @@ -7,7 +7,7 @@ module Tax # # Related guide: [Using the Settings API](https://stripe.com/docs/tax/settings-api) class Settings < SingletonAPIResource - include Stripe::APIOperations::Save + include Stripe::APIOperations::SingletonSave OBJECT_NAME = "tax.settings" end diff --git a/test/stripe/api_resource_test.rb b/test/stripe/api_resource_test.rb index 1f2597a7d..4d8e0909d 100644 --- a/test/stripe/api_resource_test.rb +++ b/test/stripe/api_resource_test.rb @@ -795,6 +795,59 @@ def say_hello(params = {}, opts = {}) end end + context "singleton resource" do + class TestSingletonResource < SingletonAPIResource # rubocop:todo Lint/ConstantDefinitionInBlock + include Stripe::APIOperations::SingletonSave + OBJECT_NAME = "test.singleton" + end + + setup do + Util.instance_variable_set( + :@object_classes, + Stripe::ObjectTypes.object_names_to_classes.merge( + "test.singleton" => TestSingletonResource + ) + ) + end + teardown do + Util.class.instance_variable_set(:@object_classes, Stripe::ObjectTypes.object_names_to_classes) + end + + should "be retrievable" do + stub_request(:get, "#{Stripe.api_base}/v1/test/singleton") + .with(query: { foo: "bar" }, headers: { "Stripe-Account" => "acct_hi" }) + .to_return(body: JSON.generate({ object: "test.singleton", result: "hi!" })) + + settings = TestSingletonResource.retrieve({ foo: "bar" }, { stripe_account: "acct_hi" }) + assert settings.is_a? TestSingletonResource + assert_equal "hi!", settings.result + end + + should "be updatable" do + stub_request(:post, "#{Stripe.api_base}/v1/test/singleton") + .with(body: { foo: "bar" }, headers: { "Stripe-Account" => "acct_hi" }) + .to_return(body: JSON.generate({ object: "test.singleton", result: "hi!" })) + + settings = TestSingletonResource.update({ foo: "bar" }, { stripe_account: "acct_hi" }) + assert settings.is_a? TestSingletonResource + assert_equal "hi!", settings.result + end + + should "be saveable" do + stub_request(:get, "#{Stripe.api_base}/v1/test/singleton") + .to_return(body: JSON.generate({ object: "test.singleton", result: "hi!" })) + + stub_request(:post, "#{Stripe.api_base}/v1/test/singleton") + .with(body: { result: "hello" }) + .to_return(body: JSON.generate({ object: "test.singleton", result: "hello" })) + + settings = TestSingletonResource.retrieve + settings.result = "hello" + settings.save + assert_requested :post, "#{Stripe.api_base}/v1/test/singleton", times: 1 + end + end + @@fixtures = {} # rubocop:disable Style/ClassVars setup do if @@fixtures.empty? diff --git a/test/stripe/generated_examples_test.rb b/test/stripe/generated_examples_test.rb index 8e9daf53c..d30523e15 100644 --- a/test/stripe/generated_examples_test.rb +++ b/test/stripe/generated_examples_test.rb @@ -613,6 +613,14 @@ class CodegennedExampleTest < Test::Unit::TestCase Stripe::FinancialConnections::Account.refresh_account("fca_xyz", { features: ["balance"] }) assert_requested :post, "#{Stripe.api_base}/v1/financial_connections/accounts/fca_xyz/refresh" end + should "Test financial connections accounts subscribe post" do + Stripe::FinancialConnections::Account.subscribe("fa_123", { features: ["transactions"] }) + assert_requested :post, "#{Stripe.api_base}/v1/financial_connections/accounts/fa_123/subscribe" + end + should "Test financial connections accounts unsubscribe post" do + Stripe::FinancialConnections::Account.unsubscribe("fa_123", { features: ["transactions"] }) + assert_requested :post, "#{Stripe.api_base}/v1/financial_connections/accounts/fa_123/unsubscribe" + end should "Test financial connections sessions get" do Stripe::FinancialConnections::Session.retrieve("fcsess_xyz") assert_requested :get, "#{Stripe.api_base}/v1/financial_connections/sessions/fcsess_xyz?" @@ -642,6 +650,14 @@ class CodegennedExampleTest < Test::Unit::TestCase }) assert_requested :post, "#{Stripe.api_base}/v1/financial_connections/sessions" end + should "Test financial connections transactions get" do + Stripe::FinancialConnections::Transaction.retrieve("tr_123") + assert_requested :get, "#{Stripe.api_base}/v1/financial_connections/transactions/tr_123?" + end + should "Test financial connections transactions get 2" do + Stripe::FinancialConnections::Transaction.list({ account: "fca_xyz" }) + assert_requested :get, "#{Stripe.api_base}/v1/financial_connections/transactions?account=fca_xyz" + end should "Test identity verification reports get" do Stripe::Identity::VerificationReport.list({ limit: 3 }) assert_requested :get, "#{Stripe.api_base}/v1/identity/verification_reports?limit=3" @@ -1580,6 +1596,30 @@ class CodegennedExampleTest < Test::Unit::TestCase Stripe::TaxRate.update("txr_xxxxxxxxxxxxx", { active: false }) assert_requested :post, "#{Stripe.api_base}/v1/tax_rates/txr_xxxxxxxxxxxxx" end + should "Test tax registrations get" do + Stripe::Tax::Registration.list({ status: "all" }) + assert_requested :get, "#{Stripe.api_base}/v1/tax/registrations?status=all" + end + should "Test tax registrations post" do + Stripe::Tax::Registration.create({ + country: "IE", + country_options: { ie: { type: "oss_union" } }, + active_from: "now", + }) + assert_requested :post, "#{Stripe.api_base}/v1/tax/registrations" + end + should "Test tax registrations post 2" do + Stripe::Tax::Registration.update("taxreg_xxxxxxxxxxxxx", { expires_at: "now" }) + assert_requested :post, "#{Stripe.api_base}/v1/tax/registrations/taxreg_xxxxxxxxxxxxx" + end + should "Test tax settings get" do + Stripe::Tax::Settings.retrieve + assert_requested :get, "#{Stripe.api_base}/v1/tax/settings?" + end + should "Test tax settings post" do + Stripe::Tax::Settings.update({ defaults: { tax_code: "txcd_10000000" } }) + assert_requested :post, "#{Stripe.api_base}/v1/tax/settings" + end should "Test tax transactions create from calculation post" do Stripe::Tax::Transaction.create_from_calculation({ calculation: "xxx",