Merge pull request #808 from stripe/ralex/unified_requests

Unify request/response handling
This commit is contained in:
Alex Rattray (Stripe) 2019-08-08 11:32:16 -07:00 committed by GitHub
commit d369e840b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 254 additions and 54 deletions

View File

@ -103,5 +103,16 @@ module Stripe
instance.refresh
instance
end
protected def request_stripe_object(method:, path:, params:, opts: {})
resp, opts = request(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)
else
Util.convert_to_stripe_object(resp.data, opts)
end
end
end
end

View File

@ -20,8 +20,12 @@ module Stripe
operations: %i[create retrieve update delete list]
def reject(params = {}, opts = {})
resp, opts = request(:post, resource_url + "/reject", params, opts)
initialize_from(resp.data, opts)
request_stripe_object(
method: :post,
path: resource_url + "/reject",
params: params,
opts: opts
)
end
save_nested_resource :external_account

View File

@ -11,8 +11,12 @@ module Stripe
custom_method :void_credit_note, http_verb: :post, http_path: "void"
def void_credit_note(params = {}, opts = {})
resp, opts = request(:post, resource_url + "/void", params, opts)
initialize_from(resp.data, opts)
request_stripe_object(
method: :post,
path: resource_url + "/void",
params: params,
opts: opts
)
end
end
end

View File

@ -10,8 +10,12 @@ module Stripe
custom_method :close, http_verb: :post
def close(params = {}, opts = {})
resp, opts = request(:post, resource_url + "/close", params, opts)
initialize_from(resp.data, opts)
request_stripe_object(
method: :post,
path: resource_url + "/close",
params: params,
opts: opts
)
end
def close_url

View File

@ -16,28 +16,48 @@ module Stripe
custom_method :void_invoice, http_verb: :post, http_path: "void"
def finalize_invoice(params = {}, opts = {})
resp, opts = request(:post, resource_url + "/finalize", params, opts)
initialize_from(resp.data, opts)
request_stripe_object(
method: :post,
path: resource_url + "/finalize",
params: params,
opts: opts
)
end
def mark_uncollectible(params = {}, opts = {})
resp, opts = request(:post, resource_url + "/mark_uncollectible", params, opts)
initialize_from(resp.data, opts)
request_stripe_object(
method: :post,
path: resource_url + "/mark_uncollectible",
params: params,
opts: opts
)
end
def pay(params = {}, opts = {})
resp, opts = request(:post, resource_url + "/pay", params, opts)
initialize_from(resp.data, opts)
request_stripe_object(
method: :post,
path: resource_url + "/pay",
params: params,
opts: opts
)
end
def send_invoice(params = {}, opts = {})
resp, opts = request(:post, resource_url + "/send", params, opts)
initialize_from(resp.data, opts)
request_stripe_object(
method: :post,
path: resource_url + "/send",
params: params,
opts: opts
)
end
def void_invoice(params = {}, opts = {})
resp, opts = request(:post, resource_url + "/void", params, opts)
initialize_from(resp.data, opts)
request_stripe_object(
method: :post,
path: resource_url + "/void",
params: params,
opts: opts
)
end
def self.upcoming(params, opts = {})

View File

@ -12,13 +12,21 @@ module Stripe
custom_method :decline, http_verb: :post
def approve(params = {}, opts = {})
resp, opts = request(:post, resource_url + "/approve", params, opts)
initialize_from(resp.data, opts)
request_stripe_object(
method: :post,
path: resource_url + "/approve",
params: params,
opts: opts
)
end
def decline(params = {}, opts = {})
resp, opts = request(:post, resource_url + "/decline", params, opts)
initialize_from(resp.data, opts)
request_stripe_object(
method: :post,
path: resource_url + "/decline",
params: params,
opts: opts
)
end
end
end

View File

@ -12,8 +12,12 @@ module Stripe
custom_method :details, http_verb: :get
def details(params = {}, opts = {})
resp, opts = request(:get, resource_url + "/details", params, opts)
Util.convert_to_stripe_object(resp.data, opts)
request_stripe_object(
method: :get,
path: resource_url + "/details",
params: params,
opts: opts
)
end
end
end

View File

@ -12,13 +12,21 @@ module Stripe
custom_method :return_order, http_verb: :post, http_path: "returns"
def pay(params = {}, opts = {})
resp, opts = request(:post, resource_url + "/pay", params, opts)
Util.convert_to_stripe_object(resp.data, opts)
request_stripe_object(
method: :post,
path: resource_url + "/pay",
params: params,
opts: opts
)
end
def return_order(params = {}, opts = {})
resp, opts = request(:post, resource_url + "/returns", params, opts)
Util.convert_to_stripe_object(resp.data, opts)
request_stripe_object(
method: :post,
path: resource_url + "/returns",
params: params,
opts: opts
)
end
private def pay_url

View File

@ -13,18 +13,30 @@ module Stripe
custom_method :confirm, http_verb: :post
def cancel(params = {}, opts = {})
resp, opts = request(:post, resource_url + "/cancel", params, opts)
initialize_from(resp.data, opts)
request_stripe_object(
method: :post,
path: resource_url + "/cancel",
params: params,
opts: opts
)
end
def capture(params = {}, opts = {})
resp, opts = request(:post, resource_url + "/capture", params, opts)
initialize_from(resp.data, opts)
request_stripe_object(
method: :post,
path: resource_url + "/capture",
params: params,
opts: opts
)
end
def confirm(params = {}, opts = {})
resp, opts = request(:post, resource_url + "/confirm", params, opts)
initialize_from(resp.data, opts)
request_stripe_object(
method: :post,
path: resource_url + "/confirm",
params: params,
opts: opts
)
end
end
end

View File

@ -12,13 +12,21 @@ module Stripe
custom_method :detach, http_verb: :post
def attach(params = {}, opts = {})
resp, opts = request(:post, resource_url + "/attach", params, opts)
initialize_from(resp.data, opts)
request_stripe_object(
method: :post,
path: resource_url + "/attach",
params: params,
opts: opts
)
end
def detach(params = {}, opts = {})
resp, opts = request(:post, resource_url + "/detach", params, opts)
initialize_from(resp.data, opts)
request_stripe_object(
method: :post,
path: resource_url + "/detach",
params: params,
opts: opts
)
end
end
end

View File

@ -11,8 +11,12 @@ module Stripe
custom_method :cancel, http_verb: :post
def cancel(params = {}, opts = {})
resp, opts = request(:post, resource_url + "/cancel", params, opts)
initialize_from(resp.data, opts)
request_stripe_object(
method: :post,
path: resource_url + "/cancel",
params: params,
opts: opts
)
end
def cancel_url

View File

@ -9,8 +9,12 @@ module Stripe
custom_method :approve, http_verb: :post
def approve(params = {}, opts = {})
resp, opts = request(:post, resource_url + "/approve", params, opts)
initialize_from(resp.data, opts)
request_stripe_object(
method: :post,
path: resource_url + "/approve",
params: params,
opts: opts
)
end
end
end

View File

@ -12,13 +12,21 @@ module Stripe
custom_method :confirm, http_verb: :post
def cancel(params = {}, opts = {})
resp, opts = request(:post, resource_url + "/cancel", params, opts)
initialize_from(resp.data, opts)
request_stripe_object(
method: :post,
path: resource_url + "/cancel",
params: params,
opts: opts
)
end
def confirm(params = {}, opts = {})
resp, opts = request(:post, resource_url + "/confirm", params, opts)
initialize_from(resp.data, opts)
request_stripe_object(
method: :post,
path: resource_url + "/confirm",
params: params,
opts: opts
)
end
end
end

View File

@ -10,8 +10,12 @@ module Stripe
custom_method :verify, http_verb: :post
def verify(params = {}, opts = {})
resp, opts = request(:post, resource_url + "/verify", params, opts)
initialize_from(resp.data, opts)
request_stripe_object(
method: :post,
path: resource_url + "/verify",
params: params,
opts: opts
)
end
def detach(params = {}, opts = {})

View File

@ -15,13 +15,21 @@ module Stripe
nested_resource_class_methods :revision, operations: %i[retrieve list]
def cancel(params = {}, opts = {})
resp, opts = request(:post, resource_url + "/cancel", params, opts)
initialize_from(resp.data, opts)
request_stripe_object(
method: :post,
path: resource_url + "/cancel",
params: params,
opts: opts
)
end
def release(params = {}, opts = {})
resp, opts = request(:post, resource_url + "/release", params, opts)
initialize_from(resp.data, opts)
request_stripe_object(
method: :post,
path: resource_url + "/release",
params: params,
opts: opts
)
end
def revisions(params = {}, opts = {})

View File

@ -11,8 +11,12 @@ module Stripe
custom_method :cancel, http_verb: :post
def cancel(params = {}, opts = {})
resp, opts = request(:post, resource_url + "/cancel", params, opts)
initialize_from(resp.data, opts)
request_stripe_object(
method: :post,
path: resource_url + "/cancel",
params: params,
opts: opts
)
end
end
end

View File

@ -15,8 +15,12 @@ module Stripe
operations: %i[create retrieve update list]
def cancel(params = {}, opts = {})
resp, opts = request(:post, resource_url + "/cancel", params, opts)
initialize_from(resp.data, opts)
request_stripe_object(
method: :post,
path: resource_url + "/cancel",
params: params,
opts: opts
)
end
def cancel_url

View File

@ -43,6 +43,10 @@ module Stripe
@object_classes ||= Stripe::ObjectTypes.object_names_to_classes
end
def self.object_name_matches_class?(object_name, klass)
Util.object_classes[object_name] == klass
end
# Converts a hash of fields or an array of hashes into a +StripeObject+ or
# array of +StripeObject+s. These new objects will be created as a concrete
# type as dictated by their `object` field (e.g. an `object` value of

View File

@ -511,6 +511,83 @@ module Stripe
end
end
context "#request_stripe_object" do
class HelloTestAPIResource < APIResource
OBJECT_NAME = "hello".freeze
def say_hello(params = {}, opts = {})
request_stripe_object(
method: :post,
path: resource_url + "/say",
params: params,
opts: opts
)
end
end
setup do
Util.instance_variable_set(
:@object_classes,
Stripe::ObjectTypes.object_names_to_classes.merge(
"hello" => HelloTestAPIResource
)
)
end
teardown do
Util.class.instance_variable_set(:@object_classes, Stripe::ObjectTypes.object_names_to_classes)
end
should "make requests appropriately" do
stub_request(:post, "#{Stripe.api_base}/v1/hellos/hi_123/say")
.with(body: { foo: "bar" }, headers: { "Stripe-Account" => "acct_hi" })
.to_return(body: JSON.generate("object" => "hello"))
hello = HelloTestAPIResource.new(id: "hi_123")
hello.say_hello({ foo: "bar" }, stripe_account: "acct_hi")
end
should "update attributes in-place when it returns the same thing" do
stub_request(:post, "#{Stripe.api_base}/v1/hellos/hi_123/say")
.to_return(body: JSON.generate("object" => "hello", "additional" => "attribute"))
hello = HelloTestAPIResource.new(id: "hi_123")
hello.unsaved = "a value"
new_hello = hello.say_hello
# Doesn't matter if you use the return variable or the instance.
assert_equal(hello, new_hello)
# It updates new attributes in-place.
assert_equal("attribute", hello.additional)
# It removes unsaved attributes, but at least lets you know about them.
e = assert_raises(NoMethodError) { hello.unsaved }
assert_match("The 'unsaved' attribute was set in the past", e.message)
end
should "instantiate a new object of the appropriate class when it is different than the host class" do
stub_request(:post, "#{Stripe.api_base}/v1/hellos/hi_123/say")
.to_return(body: JSON.generate("object" => "goodbye", "additional" => "attribute"))
hello = HelloTestAPIResource.new(id: "hi_123")
hello.unsaved = "a value"
new_goodbye = hello.say_hello
# The returned value and the instance are different objects.
refute_equal(new_goodbye, hello)
# The returned value has stuff from the server.
assert_equal("attribute", new_goodbye.additional)
assert_equal("goodbye", new_goodbye.object)
# You instance doesn't have stuff from the server.
e = assert_raises(NoMethodError) { hello.additional }
refute_match(/was set in the past/, e.message)
# The instance preserves unset attributes on the original instance (not sure this is good behavior?)
assert_equal("a value", hello.unsaved)
end
end
@@fixtures = {} # rubocop:disable Style/ClassVars
setup do
if @@fixtures.empty?