From a12ff9cdb89228b1b789c1eecd4aae9c53d7eb97 Mon Sep 17 00:00:00 2001 From: helenye-stripe <111009531+helenye-stripe@users.noreply.github.com> Date: Tue, 9 Apr 2024 10:52:43 -0700 Subject: [PATCH] Add last_response to StripeObject (#1377) * Add last_response to StripeObject * Add more data to test and fix README --- README.md | 12 +++++------- lib/stripe/api_operations/request.rb | 4 ++-- lib/stripe/api_operations/save.rb | 2 +- lib/stripe/api_operations/singleton_save.rb | 2 +- lib/stripe/api_resource.rb | 6 +++--- lib/stripe/stripe_object.rb | 11 ++++++++--- lib/stripe/util.rb | 6 +++--- test/stripe/stripe_client_test.rb | 15 +++++++++++++++ test/stripe/stripe_object_test.rb | 7 +++++++ 9 files changed, 45 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 00b797ab7..302926cae 100644 --- a/README.md +++ b/README.md @@ -150,15 +150,13 @@ puts customer.unknown # raises NoMethodError ### Accessing a response object -Get access to response objects by initializing a client and using its `request` -method: +Get access to response objects by using the `last_response` property of the returned resource: ```ruby -client = Stripe::StripeClient.new -customer, resp = client.request do - Stripe::Customer.retrieve('cus_123456789',) -end -puts resp.request_id +customer = Stripe::Customer.retrieve('cus_123456789') + +print(customer.last_response.http_status) # to retrieve status code +print(customer.last_response.http_headers) # to retrieve headers ``` ### Configuring a proxy diff --git a/lib/stripe/api_operations/request.rb b/lib/stripe/api_operations/request.rb index 505e45696..fd10a7c97 100644 --- a/lib/stripe/api_operations/request.rb +++ b/lib/stripe/api_operations/request.rb @@ -27,7 +27,7 @@ def execute_resource_request_stream(method, url, private def request_stripe_object(method:, path:, params:, opts: {}, usage: []) resp, opts = execute_resource_request(method, path, params, opts, usage) - Util.convert_to_stripe_object_with_params(resp.data, params, opts) + Util.convert_to_stripe_object_with_params(resp.data, params, opts, resp) end private def execute_resource_request_internal(client_request_method_sym, @@ -129,7 +129,7 @@ def self.included(base) private def request_stripe_object(method:, path:, params:, opts: {}, usage: []) resp, opts = execute_resource_request(method, path, params, opts, usage) - Util.convert_to_stripe_object_with_params(resp.data, params, opts) + Util.convert_to_stripe_object_with_params(resp.data, params, opts, resp) end # See notes on `alias` above. diff --git a/lib/stripe/api_operations/save.rb b/lib/stripe/api_operations/save.rb index 8c8efadcf..ecf1052cd 100644 --- a/lib/stripe/api_operations/save.rb +++ b/lib/stripe/api_operations/save.rb @@ -67,7 +67,7 @@ def save(params = {}, opts = {}) values.delete(:id) resp, opts = execute_resource_request(:post, save_url, values, opts, ["save"]) - initialize_from(resp.data, opts) + initialize_from(resp.data, opts, resp) end extend Gem::Deprecate deprecate :save, "the `update` class method (for examples " \ diff --git a/lib/stripe/api_operations/singleton_save.rb b/lib/stripe/api_operations/singleton_save.rb index d1e367cd0..0fe074588 100644 --- a/lib/stripe/api_operations/singleton_save.rb +++ b/lib/stripe/api_operations/singleton_save.rb @@ -62,7 +62,7 @@ def save(params = {}, opts = {}) values = serialize_params(self).merge(params) resp, opts = execute_resource_request(:post, resource_url, values, opts, ["save"]) - initialize_from(resp.data, opts) + initialize_from(resp.data, opts, resp) end extend Gem::Deprecate deprecate :save, "the `update` class method (for examples " \ diff --git a/lib/stripe/api_resource.rb b/lib/stripe/api_resource.rb index 75191e947..1af656123 100644 --- a/lib/stripe/api_resource.rb +++ b/lib/stripe/api_resource.rb @@ -89,7 +89,7 @@ def resource_url def refresh resp, opts = execute_resource_request(:get, resource_url, @retrieve_params) - initialize_from(resp.data, opts) + initialize_from(resp.data, opts, resp) end def self.retrieve(id, opts = {}) @@ -104,9 +104,9 @@ def request_stripe_object(method:, path:, params:, opts: {}) # If we're getting back this thing, update; otherwise, instantiate. if Util.object_name_matches_class?(resp.data[:object], self.class) - initialize_from(resp.data, opts) + initialize_from(resp.data, opts, resp) else - Util.convert_to_stripe_object_with_params(resp.data, params, opts) + Util.convert_to_stripe_object_with_params(resp.data, params, opts, resp) end end diff --git a/lib/stripe/stripe_object.rb b/lib/stripe/stripe_object.rb index 1df9c59bf..b2f173def 100644 --- a/lib/stripe/stripe_object.rb +++ b/lib/stripe/stripe_object.rb @@ -4,6 +4,8 @@ module Stripe class StripeObject include Enumerable + attr_reader :last_response + @@permanent_attributes = Set.new([:id]) # rubocop:disable Style/ClassVars # The default :id method is deprecated and isn't useful to us @@ -80,13 +82,14 @@ def initialize(id = nil, opts = {}) @unsaved_values = Set.new @transient_values = Set.new @values[:id] = id if id + @last_response = nil end - def self.construct_from(values, opts = {}) + def self.construct_from(values, opts = {}, last_response = nil) values = Stripe::Util.symbolize_names(values) # work around protected #initialize_from for now - new(values[:id]).send(:initialize_from, values, opts) + new(values[:id]).send(:initialize_from, values, opts, last_response) end # Determines the equality of two Stripe objects. Stripe objects are @@ -424,7 +427,9 @@ class << self; self; end # * +:opts:+ Options for StripeObject like an API key. # * +:partial:+ Indicates that the re-initialization should not attempt to # remove accessors. - protected def initialize_from(values, opts) + protected def initialize_from(values, opts, last_response = nil) + @last_response = last_response + @opts = Util.normalize_opts(opts) # the `#send` is here so that we can keep this method private diff --git a/lib/stripe/util.rb b/lib/stripe/util.rb index 56d553811..babea24be 100644 --- a/lib/stripe/util.rb +++ b/lib/stripe/util.rb @@ -90,7 +90,7 @@ def self.custom_method(resource, target, name, http_verb, http_path) opts ) - Util.convert_to_stripe_object_with_params(resp.data, params, opts) + Util.convert_to_stripe_object_with_params(resp.data, params, opts, resp) end end @@ -124,7 +124,7 @@ def self.convert_to_stripe_object(data, opts = {}) # * +data+ - Hash of fields and values to be converted into a StripeObject. # * +opts+ - Options for +StripeObject+ like an API key that will be reused # on subsequent API calls. - def self.convert_to_stripe_object_with_params(data, params, opts = {}) + def self.convert_to_stripe_object_with_params(data, params, opts = {}, last_response = nil) opts = normalize_opts(opts) case data @@ -135,7 +135,7 @@ def self.convert_to_stripe_object_with_params(data, params, opts = {}) # to generic StripeObject object_name = data[:object] || data["object"] obj = object_classes.fetch(object_name, StripeObject) - .construct_from(data, opts) + .construct_from(data, opts, last_response) # set filters so that we can fetch the same limit, expansions, and # predicates when accessing the next and previous pages diff --git a/test/stripe/stripe_client_test.rb b/test/stripe/stripe_client_test.rb index b9edbdc21..e119b0519 100644 --- a/test/stripe/stripe_client_test.rb +++ b/test/stripe/stripe_client_test.rb @@ -1584,5 +1584,20 @@ class SystemProfilerTest < Test::Unit::TestCase _ = StripeClient::SystemProfiler.uname_from_system_ver end end + + context "#last_response" do + should "return last_response with StripeObjects" do + stub_request(:get, "#{Stripe.api_base}/v1/charges") + .to_return(body: '{"id": "ch_123", "amount": "100"}') + charge = Stripe::Charge.list + assert_not_nil charge.last_response + assert charge.last_response.is_a?(Stripe::StripeResponse) + assert_equal 200, charge.last_response.http_status + assert_not_nil charge.last_response.http_headers + assert charge.last_response.http_headers.is_a?(Stripe::StripeResponseHeaders) + assert_not_nil charge.last_response.data + assert_equal({ id: "ch_123", amount: "100" }, charge.last_response.data) + end + end end end diff --git a/test/stripe/stripe_object_test.rb b/test/stripe/stripe_object_test.rb index 80dde23dc..0a4ec43fc 100644 --- a/test/stripe/stripe_object_test.rb +++ b/test/stripe/stripe_object_test.rb @@ -506,5 +506,12 @@ class WithAdditiveObjectParam < Stripe::StripeObject # rubocop:todo Lint/Constan # Value still accessible with hash syntax assert_equal "something", obj.metadata[:class] end + + context "#last_response" do + should "return raw response in last_response of object" do + obj = Stripe::StripeObject.construct_from({}, {}, { foo: "bar" }) + assert_equal({ foo: "bar" }, obj.last_response) + end + end end end