Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add last_response to StripeObject #1377

Merged
merged 3 commits into from
Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 5 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions lib/stripe/api_operations/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion lib/stripe/api_operations/save.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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 " \
Expand Down
2 changes: 1 addition & 1 deletion lib/stripe/api_operations/singleton_save.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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 " \
Expand Down
6 changes: 3 additions & 3 deletions lib/stripe/api_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {})
Expand All @@ -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

Expand Down
11 changes: 8 additions & 3 deletions lib/stripe/stripe_object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions lib/stripe/util.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
15 changes: 15 additions & 0 deletions test/stripe/stripe_client_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
7 changes: 7 additions & 0 deletions test/stripe/stripe_object_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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