Upgrade Rubocop and fix a bunch of issues (#786)

* Bump Rubocop to 0.57.2

* Style/StderrPuts: Use warn instead of .puts

* Style/ExpandPathArguments: Use expand_path('../test_helper', __dir__) instead of expand_path('../../test_helper', __FILE__)

* Style/Encoding: Unnecessary utf-8 encoding comment

* Style/StringLiterals: Prefer double-quoted strings

* Style/AccessModifierDeclarations

* Style/FormatStringToken: Prefer annotated tokens

* Naming/UncommunicativeMethodParamName

* Metrics/LineLength: set maximum line length to 100 characters

* Style/IfUnlessModifier: Favor modifier if usage when having a single-line body

* Style/ClassVars

* Metrics/LineLength: set maximum line length to 80 characters (default)

* Style/AccessModifierDeclarations: EnforcedStyle: inline
This commit is contained in:
Olivier Bellone 2019-05-24 10:43:42 -07:00 committed by GitHub
parent 7fa3585e82
commit ec91de6849
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
119 changed files with 515 additions and 353 deletions

View File

@ -13,6 +13,10 @@ Layout/IndentArray:
Layout/IndentHash:
EnforcedStyle: consistent
Metrics/LineLength:
Exclude:
- "test/**/*.rb"
Metrics/MethodLength:
# There's ~2 long methods in `StripeClient`. If we want to truncate those a
# little, we could move this to be closer to ~30 (but the default of 10 is
@ -22,11 +26,17 @@ Metrics/MethodLength:
Metrics/ModuleLength:
Enabled: false
Style/AccessModifierDeclarations:
EnforcedStyle: inline
Style/FrozenStringLiteralComment:
EnforcedStyle: always
Style/StringLiterals:
EnforcedStyle: double_quotes
Style/TrailingCommaInLiteral:
Style/TrailingCommaInArrayLiteral:
EnforcedStyleForMultiline: consistent_comma
Style/TrailingCommaInHashLiteral:
EnforcedStyleForMultiline: consistent_comma

View File

@ -1,6 +1,6 @@
# This configuration was generated by
# `rubocop --auto-gen-config`
# on 2019-03-25 18:32:26 -0700 using RuboCop version 0.50.0.
# on 2019-05-24 10:18:48 -0700 using RuboCop version 0.57.2.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
@ -15,7 +15,7 @@ Metrics/AbcSize:
Metrics/BlockLength:
Max: 498
# Offense count: 9
# Offense count: 11
# Configuration parameters: CountComments.
Metrics/ClassLength:
Max: 673
@ -24,12 +24,6 @@ Metrics/ClassLength:
Metrics/CyclomaticComplexity:
Max: 15
# Offense count: 364
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
# URISchemes: http, https
Metrics/LineLength:
Max: 310
# Offense count: 6
# Configuration parameters: CountKeywordArgs.
Metrics/ParameterLists:
@ -39,12 +33,6 @@ Metrics/ParameterLists:
Metrics/PerceivedComplexity:
Max: 17
# Offense count: 2
Style/ClassVars:
Exclude:
- 'lib/stripe/stripe_object.rb'
- 'test/stripe/api_resource_test.rb'
# Offense count: 78
# Offense count: 84
Style/Documentation:
Enabled: false

View File

@ -18,7 +18,9 @@ group :development do
# `Gemfile.lock` checked in, so to prevent good builds from suddenly going
# bad, pin to a specific version number here. Try to keep this relatively
# up-to-date, but it's not the end of the world if it's not.
gem "rubocop", "0.50.0"
# Note that 0.57.2 is the most recent version we can use until we drop
# support for Ruby 2.1.
gem "rubocop", "0.57.2"
# Rack 2.0+ requires Ruby >= 2.2.2 which is problematic for the test suite on
# older Ruby versions. Check Ruby the version here and put a maximum

View File

@ -116,7 +116,7 @@ require "stripe/webhook_endpoint"
require "stripe/oauth"
module Stripe
DEFAULT_CA_BUNDLE_PATH = ::File.dirname(__FILE__) + "/data/ca-certificates.crt"
DEFAULT_CA_BUNDLE_PATH = __dir__ + "/data/ca-certificates.crt"
@app_info = nil
@ -143,7 +143,8 @@ module Stripe
@enable_telemetry = false
class << self
attr_accessor :stripe_account, :api_key, :api_base, :verify_ssl_certs, :api_version, :client_id, :connect_base, :uploads_base,
attr_accessor :stripe_account, :api_key, :api_base, :verify_ssl_certs,
:api_version, :client_id, :connect_base, :uploads_base,
:open_timeout, :read_timeout, :proxy
attr_reader :max_network_retry_delay, :initial_network_retry_delay
@ -215,7 +216,8 @@ module Stripe
end
if !val.nil? && ![LEVEL_DEBUG, LEVEL_ERROR, LEVEL_INFO].include?(val)
raise ArgumentError, "log_level should only be set to `nil`, `debug` or `info`"
raise ArgumentError,
"log_level should only be set to `nil`, `debug` or `info`"
end
@log_level = val
end

View File

@ -18,10 +18,12 @@ module Stripe
operations: %i[retrieve update list],
resource_plural: "capabilities"
nested_resource_class_methods :external_account,
operations: %i[create retrieve update delete list]
operations: %i[create retrieve update delete
list]
nested_resource_class_methods :login_link, operations: %i[create]
nested_resource_class_methods :person,
operations: %i[create retrieve update delete list]
operations: %i[create retrieve update delete
list]
# This method is deprecated. Please use `#external_account=` instead.
save_nested_resource :bank_account
@ -37,13 +39,18 @@ module Stripe
# @override To make id optional
def self.retrieve(id = ARGUMENT_NOT_PROVIDED, opts = {})
id = id.equal?(ARGUMENT_NOT_PROVIDED) ? nil : Util.check_string_argument!(id)
id = if id.equal?(ARGUMENT_NOT_PROVIDED)
nil
else
Util.check_string_argument!(id)
end
# Account used to be a singleton, where this method's signature was
# `(opts={})`. For the sake of not breaking folks who pass in an OAuth
# key in opts, let's lurkily string match for it.
if opts == {} && id.is_a?(String) && id.start_with?("sk_")
# `super` properly assumes a String opts is the apiKey and normalizes as expected.
# `super` properly assumes a String opts is the apiKey and normalizes
# as expected.
opts = id
id = nil
end
@ -55,8 +62,9 @@ module Stripe
Util.convert_to_stripe_object(resp.data, opts)
end
# We are not adding a helper for capabilities here as the Account object already has a
# capabilities property which is a hash and not the sub-list of capabilities.
# We are not adding a helper for capabilities here as the Account object
# already has a capabilities property which is a hash and not the sub-list
# of capabilities.
def reject(params = {}, opts = {})
resp, opts = request(:post, resource_url + "/reject", params, opts)
@ -114,8 +122,11 @@ module Stripe
self["legal_entity"]
end
def legal_entity=(_)
raise NoMethodError, 'Overriding legal_entity can cause serious issues. Instead, set the individual fields of legal_entity like blah.legal_entity.first_name = \'Blah\''
def legal_entity=(_legal_entity)
raise NoMethodError,
"Overriding legal_entity can cause serious issues. Instead, set " \
"the individual fields of legal_entity like " \
"`account.legal_entity.first_name = 'Blah'`"
end
def deauthorize(client_id = nil, opts = {})
@ -128,15 +139,17 @@ module Stripe
ARGUMENT_NOT_PROVIDED = Object.new
private
def serialize_additional_owners(legal_entity, additional_owners)
original_value = legal_entity.instance_variable_get(:@original_values)[:additional_owners]
private def serialize_additional_owners(legal_entity, additional_owners)
original_value =
legal_entity
.instance_variable_get(:@original_values)[:additional_owners]
if original_value && original_value.length > additional_owners.length
# url params provide no mechanism for deleting an item in an array,
# just overwriting the whole array or adding new items. So let's not
# allow deleting without a full overwrite until we have a solution.
raise ArgumentError, "You cannot delete an item from an array, you must instead set a new array"
raise ArgumentError,
"You cannot delete an item from an array, you must instead " \
"set a new array"
end
update_hash = {}
@ -148,10 +161,11 @@ module Stripe
# StripeObject.
update = v.is_a?(StripeObject) ? v.serialize_params : v
if update != {} && (!original_value ||
update != legal_entity.serialize_params_value(original_value[i], nil, false, true))
update_hash[i.to_s] = update
end
next unless update != {} && (!original_value ||
update != legal_entity.serialize_params_value(original_value[i], nil,
false, true))
update_hash[i.to_s] = update
end
update_hash
end

View File

@ -13,15 +13,22 @@ module Stripe
"Alipay accounts cannot be accessed without a customer ID."
end
"#{Customer.resource_url}/#{CGI.escape(customer)}/sources/#{CGI.escape(id)}"
"#{Customer.resource_url}/#{CGI.escape(customer)}/sources" \
"/#{CGI.escape(id)}"
end
def self.update(_id, _params = nil, _opts = nil)
raise NotImplementedError, "Alipay accounts cannot be updated without a customer ID. Update an Alipay account by `a = customer.sources.retrieve('alipay_account_id'); a.save`"
raise NotImplementedError,
"Alipay accounts cannot be updated without a customer ID. " \
"Update an Alipay account using `Customer.update_source(" \
"'customer_id', 'alipay_account_id', update_params)`"
end
def self.retrieve(_id, _opts = nil)
raise NotImplementedError, "Alipay accounts cannot be retrieved without a customer ID. Retrieve an Alipay account using customer.sources.retrieve('alipay_account_id')"
raise NotImplementedError,
"Alipay accounts cannot be retrieved without a customer ID. " \
"Retrieve an Alipay account using `Customer.retrieve_source(" \
"'customer_id', 'alipay_account_id')`"
end
end
end

View File

@ -10,7 +10,8 @@ module Stripe
# methods `.create_reversal`, `.retrieve_reversal`, `.update_reversal`,
# etc. all become available.
module NestedResource
def nested_resource_class_methods(resource, path: nil, operations: nil, resource_plural: nil)
def nested_resource_class_methods(resource, path: nil, operations: nil,
resource_plural: nil)
resource_plural ||= "#{resource}s"
path ||= resource_plural
raise ArgumentError, "operations array required" if operations.nil?
@ -25,31 +26,36 @@ module Stripe
operations.each do |operation|
case operation
when :create
define_singleton_method(:"create_#{resource}") do |id, params = {}, opts = {}|
define_singleton_method(:"create_#{resource}") \
do |id, params = {}, opts = {}|
url = send(resource_url_method, id)
resp, opts = request(:post, url, params, opts)
Util.convert_to_stripe_object(resp.data, opts)
end
when :retrieve
define_singleton_method(:"retrieve_#{resource}") do |id, nested_id, opts = {}|
define_singleton_method(:"retrieve_#{resource}") \
do |id, nested_id, opts = {}|
url = send(resource_url_method, id, nested_id)
resp, opts = request(:get, url, {}, opts)
Util.convert_to_stripe_object(resp.data, opts)
end
when :update
define_singleton_method(:"update_#{resource}") do |id, nested_id, params = {}, opts = {}|
define_singleton_method(:"update_#{resource}") \
do |id, nested_id, params = {}, opts = {}|
url = send(resource_url_method, id, nested_id)
resp, opts = request(:post, url, params, opts)
Util.convert_to_stripe_object(resp.data, opts)
end
when :delete
define_singleton_method(:"delete_#{resource}") do |id, nested_id, params = {}, opts = {}|
define_singleton_method(:"delete_#{resource}") \
do |id, nested_id, params = {}, opts = {}|
url = send(resource_url_method, id, nested_id)
resp, opts = request(:delete, url, params, opts)
Util.convert_to_stripe_object(resp.data, opts)
end
when :list
define_singleton_method(:"list_#{resource_plural}") do |id, params = {}, opts = {}|
define_singleton_method(:"list_#{resource_plural}") \
do |id, params = {}, opts = {}|
url = send(resource_url_method, id)
resp, opts = request(:get, url, params, opts)
Util.convert_to_stripe_object(resp.data, opts)

View File

@ -31,12 +31,10 @@ module Stripe
[resp, opts_to_persist]
end
private
def warn_on_opts_in_params(params)
private def warn_on_opts_in_params(params)
Util::OPTS_USER_SPECIFIED.each do |opt|
if params.key?(opt)
$stderr.puts("WARNING: #{opt} should be in opts instead of params.")
warn("WARNING: #{opt} should be in opts instead of params.")
end
end
end
@ -46,9 +44,7 @@ module Stripe
base.extend(ClassMethods)
end
protected
def request(method, url, params = {}, opts = {})
protected def request(method, url, params = {}, opts = {})
opts = @opts.merge(Util.normalize_opts(opts))
self.class.request(method, url, params, opts)
end

View File

@ -76,9 +76,7 @@ module Stripe
base.extend(ClassMethods)
end
private
def save_url
private def save_url
# This switch essentially allows us "upsert"-like functionality. If the
# API resource doesn't have an ID set (suggesting that it's new) and
# its class responds to .create (which comes from

View File

@ -17,7 +17,9 @@ module Stripe
def self.resource_url
if self == APIResource
raise NotImplementedError, "APIResource is an abstract class. You should perform actions on its subclasses (Charge, Customer, etc.)"
raise NotImplementedError,
"APIResource is an abstract class. You should perform actions " \
"on its subclasses (Charge, Customer, etc.)"
end
# Namespaces are separated in object names with periods (.) and in URLs
# with forward slashes (/), so replace the former with the latter.
@ -62,7 +64,9 @@ module Stripe
# will send a POST request to `/v1/<object_name>/capture`.
def self.custom_method(name, http_verb:, http_path: nil)
unless %i[get post delete].include?(http_verb)
raise ArgumentError, "Invalid http_verb value: #{http_verb.inspect}. Should be one of :get, :post or :delete."
raise ArgumentError,
"Invalid http_verb value: #{http_verb.inspect}. Should be one " \
"of :get, :post or :delete."
end
http_path ||= name.to_s
define_singleton_method(name) do |id, params = {}, opts = {}|
@ -74,7 +78,11 @@ module Stripe
def resource_url
unless (id = self["id"])
raise InvalidRequestError.new("Could not determine which URL to request: #{self.class} instance has invalid ID: #{id.inspect}", "id")
raise InvalidRequestError.new(
"Could not determine which URL to request: #{self.class} instance " \
"has invalid ID: #{id.inspect}",
"id"
)
end
"#{self.class.resource_url}/#{CGI.escape(id)}"
end

View File

@ -7,7 +7,8 @@ module Stripe
OBJECT_NAME = "application_fee".freeze
nested_resource_class_methods :refund, operations: %i[create retrieve update list]
nested_resource_class_methods :refund,
operations: %i[create retrieve update list]
# If you don't need access to an updated fee object after the refund, it's
# more performant to just call `fee.refunds.create` directly.

View File

@ -8,15 +8,23 @@ module Stripe
OBJECT_NAME = "fee_refund".freeze
def resource_url
"#{ApplicationFee.resource_url}/#{CGI.escape(fee)}/refunds/#{CGI.escape(id)}"
"#{ApplicationFee.resource_url}/#{CGI.escape(fee)}/refunds" \
"/#{CGI.escape(id)}"
end
def self.update(_id, _params = nil, _opts = nil)
raise NotImplementedError, "Refunds cannot be updated without an application fee ID. Update a refund by using `a = appfee.refunds.retrieve('refund_id'); a.save`"
raise NotImplementedError,
"Application fee refunds cannot be updated without an " \
"application fee ID. Update an application fee refund using " \
"`ApplicationFee.update_refund('fee_id', 'refund_id', " \
"update_params)`"
end
def self.retrieve(_id, _api_key = nil)
raise NotImplementedError, "Refunds cannot be retrieved without an application fee ID. Retrieve a refund using appfee.refunds.retrieve('refund_id')"
raise NotImplementedError,
"Application fee refunds cannot be retrieved without an " \
"application fee ID. Retrieve an application fee refund using " \
"`ApplicationFee.retrieve_refund('fee_id', 'refund_id')`"
end
end
end

View File

@ -15,18 +15,30 @@ module Stripe
def resource_url
if respond_to?(:customer)
"#{Customer.resource_url}/#{CGI.escape(customer)}/sources/#{CGI.escape(id)}"
"#{Customer.resource_url}/#{CGI.escape(customer)}/sources" \
"/#{CGI.escape(id)}"
elsif respond_to?(:account)
"#{Account.resource_url}/#{CGI.escape(account)}/external_accounts/#{CGI.escape(id)}"
"#{Account.resource_url}/#{CGI.escape(account)}/external_accounts" \
"/#{CGI.escape(id)}"
end
end
def self.update(_id, _params = nil, _opts = nil)
raise NotImplementedError, "Bank accounts cannot be updated without an account ID. Update a bank account by using `a = account.external_accounts.retrieve('card_id'); a.save`"
raise NotImplementedError,
"Bank accounts cannot be updated without a customer ID or an " \
" account ID. Update a bank account using " \
"`Customer.update_source('customer_id', 'bank_account_id', " \
"update_params)` or `Account.update_external_account(" \
"'account_id', 'bank_account_id', update_params)`"
end
def self.retrieve(_id, _opts = nil)
raise NotImplementedError, "Bank accounts cannot be retrieved without an account ID. Retrieve a bank account using account.external_accounts.retrieve('card_id')"
raise NotImplementedError,
"Bank accounts cannot be retrieve without a customer ID or an " \
"account ID. Retrieve a bank account using " \
"`Customer.retrieve_source('customer_id', 'bank_account_id')` " \
"or `Account.retrieve_external_account('account_id', " \
"'bank_account_id')`"
end
end
end

View File

@ -14,7 +14,8 @@ module Stripe
def resource_url
if respond_to?(:customer) && !customer.nil? && customer != ""
"#{Customer.resource_url}/#{CGI.escape(customer)}/sources/#{CGI.escape(id)}"
"#{Customer.resource_url}/#{CGI.escape(customer)}/sources" \
"/#{CGI.escape(id)}"
else
"#{self.class.resource_url}/#{CGI.escape(id)}"
end

View File

@ -12,15 +12,22 @@ module Stripe
raise NotImplementedError,
"Capabilities cannot be accessed without an account ID."
end
"#{Account.resource_url}/#{CGI.escape(account)}/capabilities/#{CGI.escape(id)}"
"#{Account.resource_url}/#{CGI.escape(account)}/capabilities" \
"/#{CGI.escape(id)}"
end
def self.retrieve(_id, _opts = {})
raise NotImplementedError, "Capabilities cannot be retrieved without an account ID. Retrieve a capability using account.retrieve_capability('acct_123', 'acap_123')"
raise NotImplementedError,
"Capabilities cannot be retrieve without an account ID. " \
"Retrieve a capability using Account.retrieve_capability(" \
"'account_id', 'capability_id')`"
end
def self.update(_id, _params = nil, _opts = nil)
raise NotImplementedError, "Capabilities cannot be updated without an account ID. Update a capability using `p = account.update_capability('acct_123', 'acap_123', params)"
raise NotImplementedError,
"Capabilities cannot be updated without an account ID. Update a " \
"capability using Account.update_capability('account_id', " \
"'capability_id', update_params)`"
end
end
end

View File

@ -10,20 +10,31 @@ module Stripe
def resource_url
if respond_to?(:recipient) && !recipient.nil? && !recipient.empty?
"#{Recipient.resource_url}/#{CGI.escape(recipient)}/cards/#{CGI.escape(id)}"
"#{Recipient.resource_url}/#{CGI.escape(recipient)}/cards" \
"/#{CGI.escape(id)}"
elsif respond_to?(:customer) && !customer.nil? && !customer.empty?
"#{Customer.resource_url}/#{CGI.escape(customer)}/sources/#{CGI.escape(id)}"
"#{Customer.resource_url}/#{CGI.escape(customer)}/sources" \
"/#{CGI.escape(id)}"
elsif respond_to?(:account) && !account.nil? && !account.empty?
"#{Account.resource_url}/#{CGI.escape(account)}/external_accounts/#{CGI.escape(id)}"
"#{Account.resource_url}/#{CGI.escape(account)}/external_accounts" \
"/#{CGI.escape(id)}"
end
end
def self.update(_id, _params = nil, _opts = nil)
raise NotImplementedError, "Cards cannot be updated without a customer ID. Update a card using `c = customer.sources.retrieve('card_id'); c.save`"
raise NotImplementedError,
"Card cannot be updated without a customer ID or an account ID. " \
"Update a card using `Customer.update_source('customer_id', " \
"'card_id', update_params)` or `Account.update_external_account(" \
"'account_id', 'card_id', update_params)`"
end
def self.retrieve(_id, _opts = nil)
raise NotImplementedError, "Cards cannot be retrieved without a customer ID. Retrieve a card using customer.sources.retrieve('card_id')"
raise NotImplementedError,
"Card cannot be retrieved without a customer ID or an account " \
"ID. Retrieve a card using `Customer.retrieve_source(" \
"'customer_id', 'card_id')` or " \
"`Account.retrieve_external_account('account_id', 'card_id')`"
end
end
end

View File

@ -63,23 +63,21 @@ module Stripe
initialize_from(resp.data, opts)
end
private
def capture_url
private def capture_url
resource_url + "/capture"
end
def dispute_url
private def dispute_url
resource_url + "/dispute"
end
def close_dispute_url
private def close_dispute_url
resource_url + "/dispute/close"
end
# Note that this is actually the *old* refund URL and its use is no longer
# preferred.
def refund_url
private def refund_url
resource_url + "/refund"
end
end

View File

@ -14,8 +14,8 @@ module Stripe
save_nested_resource :source
nested_resource_class_methods :source,
operations: %i[create retrieve update delete list]
operations: %i[create retrieve update delete
list]
nested_resource_class_methods :tax_id,
operations: %i[create retrieve delete list]
@ -78,17 +78,15 @@ module Stripe
initialize_from({ discount: nil }, opts, true)
end
private
def discount_url
private def discount_url
resource_url + "/discount"
end
def subscription_url
private def subscription_url
resource_url + "/subscription"
end
def subscriptions_url
private def subscriptions_url
resource_url + "/subscriptions"
end
end

View File

@ -9,7 +9,10 @@ module Stripe
def self.create(params = {}, opts = {})
opts = Util.normalize_opts(opts)
raise ArgumentError, "stripe_version must be specified to create an ephemeral key" unless opts[:stripe_version]
unless opts[:stripe_version]
raise ArgumentError,
"stripe_version must be specified to create an ephemeral key"
end
super
end
end

View File

@ -18,8 +18,8 @@ module Stripe
attr_reader :request_id
# Initializes a StripeError.
def initialize(message = nil, http_status: nil, http_body: nil, json_body: nil,
http_headers: nil, code: nil)
def initialize(message = nil, http_status: nil, http_body: nil,
json_body: nil, http_headers: nil, code: nil)
@message = message
@http_status = http_status
@http_body = http_body
@ -60,8 +60,8 @@ module Stripe
attr_reader :param
# TODO: make code a keyword arg in next major release
def initialize(message, param, code, http_status: nil, http_body: nil, json_body: nil,
http_headers: nil)
def initialize(message, param, code, http_status: nil, http_body: nil,
json_body: nil, http_headers: nil)
super(message, http_status: http_status, http_body: http_body,
json_body: json_body, http_headers: http_headers,
code: code)
@ -79,8 +79,8 @@ module Stripe
class InvalidRequestError < StripeError
attr_accessor :param
def initialize(message, param, http_status: nil, http_body: nil, json_body: nil,
http_headers: nil, code: nil)
def initialize(message, param, http_status: nil, http_body: nil,
json_body: nil, http_headers: nil, code: nil)
super(message, http_status: http_status, http_body: http_body,
json_body: json_body, http_headers: http_headers,
code: code)
@ -113,8 +113,8 @@ module Stripe
module OAuth
# OAuthError is raised when the OAuth API returns an error.
class OAuthError < StripeError
def initialize(code, description, http_status: nil, http_body: nil, json_body: nil,
http_headers: nil)
def initialize(code, description, http_status: nil, http_body: nil,
json_body: nil, http_headers: nil)
super(description, http_status: http_status, http_body: http_body,
json_body: json_body, http_headers: http_headers,
code: code)

View File

@ -21,7 +21,8 @@ module Stripe
end
def mark_uncollectible(params = {}, opts = {})
resp, opts = request(:post, resource_url + "/mark_uncollectible", params, opts)
resp, opts = request(:post, resource_url + "/mark_uncollectible", params,
opts)
initialize_from(resp.data, opts)
end

View File

@ -26,12 +26,16 @@ module Stripe
self.filters = {}
end
def [](k)
case k
def [](key)
case key
when String, Symbol
super
else
raise ArgumentError, "You tried to access the #{k.inspect} index, but ListObject types only support String keys. (HINT: List calls return an object with a 'data' (which is the data array). You likely want to call #data[#{k.inspect}])"
raise ArgumentError,
"You tried to access the #{key.inspect} index, but ListObject " \
"types only support String keys. (HINT: List calls return an " \
"object with a 'data' (which is the data array). You likely " \
"want to call #data[#{key.inspect}])"
end
end
@ -68,7 +72,8 @@ module Stripe
def retrieve(id, opts = {})
id, retrieve_params = Util.normalize_id(id)
resp, opts = request(:get, "#{resource_url}/#{CGI.escape(id)}", retrieve_params, opts)
resp, opts = request(:get, "#{resource_url}/#{CGI.escape(id)}",
retrieve_params, opts)
Util.convert_to_stripe_object(resp.data, opts)
end

View File

@ -5,7 +5,10 @@ module Stripe
OBJECT_NAME = "login_link".freeze
def self.retrieve(_id, _opts = nil)
raise NotImplementedError, "Login links do not have IDs and cannot be retrieved. They can only be created using accounts.login_links.create"
raise NotImplementedError,
"Login links do not have IDs and cannot be retrieved. They can " \
"only be created using `Account.create_login_link('account_id', " \
"create_params)`"
end
end
end

View File

@ -21,13 +21,11 @@ module Stripe
Util.convert_to_stripe_object(resp.data, opts)
end
private
def pay_url
private def pay_url
resource_url + "/pay"
end
def returns_url
private def returns_url
resource_url + "/returns"
end
end

View File

@ -16,11 +16,16 @@ module Stripe
end
def self.retrieve(_id, _opts = {})
raise NotImplementedError, "Persons cannot be retrieved without an account ID. Retrieve a person using account.persons.retrieve('person_id')"
raise NotImplementedError,
"Persons cannot be retrieved without an account ID. Retrieve a " \
"person using `Account.retrieve_person('account_id', 'person_id')`"
end
def self.update(_id, _params = nil, _opts = nil)
raise NotImplementedError, "Persons cannot be updated without an account ID. Update a person using `p = account.persons.retrieve('person_id'); p.save`"
raise NotImplementedError,
"Persons cannot be updated without an account ID. Update a " \
"person using `Account.update_person('account_id', 'person_id', " \
"update_params)`"
end
end
end

View File

@ -8,15 +8,22 @@ module Stripe
OBJECT_NAME = "transfer_reversal".freeze
def resource_url
"#{Transfer.resource_url}/#{CGI.escape(transfer)}/reversals/#{CGI.escape(id)}"
"#{Transfer.resource_url}/#{CGI.escape(transfer)}/reversals" \
"/#{CGI.escape(id)}"
end
def self.update(_id, _params = nil, _opts = nil)
raise NotImplementedError, "Reversals cannot be updated without a transfer ID. Update a reversal using `r = transfer.reversals.retrieve('reversal_id'); r.save`"
raise NotImplementedError,
"Reversals cannot be updated without a transfer ID. Update a " \
"reversal using `r = Transfer.update_reversal('transfer_id', " \
"'reversal_id', update_params)`"
end
def self.retrieve(_id, _opts = {})
raise NotImplementedError, "Reversals cannot be retrieved without a transfer ID. Retrieve a reversal using transfer.reversals.retrieve('reversal_id')"
raise NotImplementedError,
"Reversals cannot be retrieved without a transfer ID. Retrieve " \
"a reversal using `Transfer.retrieve_reversal('transfer_id', " \
"'reversal_id')`"
end
end
end

View File

@ -4,7 +4,9 @@ module Stripe
class SingletonAPIResource < APIResource
def self.resource_url
if self == SingletonAPIResource
raise NotImplementedError, "SingletonAPIResource is an abstract class. You should perform actions on its subclasses (Account, etc.)"
raise NotImplementedError,
"SingletonAPIResource is an abstract class. You should " \
"perform actions on its subclasses (Balance, etc.)"
end
# Namespaces are separated in object names with periods (.) and in URLs
# with forward slashes (/), so replace the former with the latter.

View File

@ -16,7 +16,8 @@ module Stripe
"to a customer object."
end
url = "#{Customer.resource_url}/#{CGI.escape(customer)}/sources/#{CGI.escape(id)}"
url = "#{Customer.resource_url}/#{CGI.escape(customer)}/sources" \
"/#{CGI.escape(id)}"
resp, opts = request(:delete, url, params, opts)
initialize_from(resp.data, opts)
end
@ -28,7 +29,8 @@ module Stripe
deprecate :delete, "#detach", 2017, 10
def source_transactions(params = {}, opts = {})
resp, opts = request(:get, resource_url + "/source_transactions", params, opts)
resp, opts = request(:get, resource_url + "/source_transactions", params,
opts)
Util.convert_to_stripe_object(resp.data, opts)
end

View File

@ -20,7 +20,8 @@ module Stripe
end
def self.default_client
Thread.current[:stripe_client_default_client] ||= StripeClient.new(default_conn)
Thread.current[:stripe_client_default_client] ||=
StripeClient.new(default_conn)
end
# A default Faraday connection to be used when one isn't configured. This
@ -55,9 +56,10 @@ module Stripe
unless @verify_ssl_warned
@verify_ssl_warned = true
$stderr.puts("WARNING: Running without SSL cert verification. " \
warn("WARNING: Running without SSL cert verification. " \
"You should never do this in production. " \
"Execute 'Stripe.verify_ssl_certs = true' to enable verification.")
"Execute `Stripe.verify_ssl_certs = true` to enable " \
"verification.")
end
end
@ -65,23 +67,23 @@ module Stripe
end
end
# Checks if an error is a problem that we should retry on. This includes both
# socket errors that may represent an intermittent problem and some special
# HTTP statuses.
def self.should_retry?(e, num_retries)
# Checks if an error is a problem that we should retry on. This includes
# both socket errors that may represent an intermittent problem and some
# special HTTP statuses.
def self.should_retry?(error, num_retries)
return false if num_retries >= Stripe.max_network_retries
# Retry on timeout-related problems (either on open or read).
return true if e.is_a?(Faraday::TimeoutError)
return true if error.is_a?(Faraday::TimeoutError)
# Destination refused the connection, the connection was reset, or a
# variety of other connection failures. This could occur from a single
# saturated server, so retry in case it's intermittent.
return true if e.is_a?(Faraday::ConnectionFailed)
return true if error.is_a?(Faraday::ConnectionFailed)
if e.is_a?(Faraday::ClientError) && e.response
if error.is_a?(Faraday::ClientError) && error.response
# 409 conflict
return true if e.response[:status] == 409
return true if error.response[:status] == 409
end
false
@ -89,12 +91,15 @@ module Stripe
def self.sleep_time(num_retries)
# Apply exponential backoff with initial_network_retry_delay on the
# number of num_retries so far as inputs. Do not allow the number to exceed
# max_network_retry_delay.
sleep_seconds = [Stripe.initial_network_retry_delay * (2**(num_retries - 1)), Stripe.max_network_retry_delay].min
# number of num_retries so far as inputs. Do not allow the number to
# exceed max_network_retry_delay.
sleep_seconds = [
Stripe.initial_network_retry_delay * (2**(num_retries - 1)),
Stripe.max_network_retry_delay,
].min
# Apply some jitter by randomizing the value in the range of (sleep_seconds
# / 2) to (sleep_seconds).
# Apply some jitter by randomizing the value in the range of
# (sleep_seconds / 2) to (sleep_seconds).
sleep_seconds *= (0.5 * (1 + rand))
# But never sleep less than the base sleep seconds.
@ -170,7 +175,9 @@ module Stripe
context.idempotency_key = headers["Idempotency-Key"]
context.method = method
context.path = path
context.query_params = query_params ? params_encoder.encode(query_params) : nil
context.query_params = if query_params
params_encoder.encode(query_params)
end
# note that both request body and query params will be passed through
# `FaradayStripeEncoder`
@ -194,8 +201,6 @@ module Stripe
[resp, api_key]
end
private
# Used to workaround buggy behavior in Faraday: the library will try to
# reshape anything that we pass to `req.params` with one of its default
# encoders. I don't think this process is supposed to be lossy, but it is
@ -227,21 +232,22 @@ module Stripe
# We should never need to do this so it's not implemented.
def decode(_str)
raise NotImplementedError, "#{self.class.name} does not implement #decode"
raise NotImplementedError,
"#{self.class.name} does not implement #decode"
end
end
def api_url(url = "", api_base = nil)
private def api_url(url = "", api_base = nil)
(api_base || Stripe.api_base) + url
end
def check_api_key!(api_key)
private def check_api_key!(api_key)
unless api_key
raise AuthenticationError, "No API key provided. " \
'Set your API key using "Stripe.api_key = <API-KEY>". ' \
"You can generate API keys from the Stripe web interface. " \
"See https://stripe.com/api for details, or email support@stripe.com " \
"if you have any questions."
"See https://stripe.com/api for details, or email " \
"support@stripe.com if you have any questions."
end
return unless api_key =~ /\s/
@ -252,7 +258,7 @@ module Stripe
"email support@stripe.com if you have any questions.)"
end
def execute_request_with_rescues(api_base, context)
private def execute_request_with_rescues(api_base, context)
num_retries = 0
begin
request_start = Time.now
@ -263,12 +269,13 @@ module Stripe
if Stripe.enable_telemetry? && context.request_id
request_duration_ms = ((Time.now - request_start) * 1000).to_int
@last_request_metrics = StripeRequestMetrics.new(context.request_id, request_duration_ms)
@last_request_metrics =
StripeRequestMetrics.new(context.request_id, request_duration_ms)
end
# We rescue all exceptions from a request so that we have an easy spot to
# implement our retry logic across the board. We'll re-raise if it's a type
# of exception that we didn't expect to handle.
# implement our retry logic across the board. We'll re-raise if it's a
# type of exception that we didn't expect to handle.
rescue StandardError => e
# If we modify context we copy it into a new variable so as not to
# taint the original on a retry.
@ -306,7 +313,7 @@ module Stripe
resp
end
def general_api_error(status, body)
private def general_api_error(status, body)
APIError.new("Invalid response object from API: #{body.inspect} " \
"(HTTP response code was #{status})",
http_status: status, http_body: body)
@ -316,14 +323,14 @@ module Stripe
# end of a User-Agent string where it'll be fairly prominent in places like
# the Dashboard. Note that this formatting has been implemented to match
# other libraries, and shouldn't be changed without universal consensus.
def format_app_info(info)
private def format_app_info(info)
str = info[:name]
str = "#{str}/#{info[:version]}" unless info[:version].nil?
str = "#{str} (#{info[:url]})" unless info[:url].nil?
str
end
def handle_error_response(http_resp, context)
private def handle_error_response(http_resp, context)
begin
resp = StripeResponse.from_faraday_hash(http_resp)
error_data = resp.data[:error]
@ -343,7 +350,7 @@ module Stripe
raise(error)
end
def specific_api_error(resp, error_data, context)
private def specific_api_error(resp, error_data, context)
Util.log_error("Stripe API error",
status: resp.http_status,
error_code: error_data[:code],
@ -395,7 +402,7 @@ module Stripe
# Attempts to look at a response's error code and return an OAuth error if
# one matches. Will return `nil` if the code isn't recognized.
def specific_oauth_error(resp, error_code, context)
private def specific_oauth_error(resp, error_code, context)
description = resp.data[:error_description] || error_code
Util.log_error("Stripe OAuth error",
@ -411,12 +418,18 @@ module Stripe
},]
case error_code
when "invalid_client" then OAuth::InvalidClientError.new(*args)
when "invalid_grant" then OAuth::InvalidGrantError.new(*args)
when "invalid_request" then OAuth::InvalidRequestError.new(*args)
when "invalid_scope" then OAuth::InvalidScopeError.new(*args)
when "unsupported_grant_type" then OAuth::UnsupportedGrantTypeError.new(*args)
when "unsupported_response_type" then OAuth::UnsupportedResponseTypeError.new(*args)
when "invalid_client"
OAuth::InvalidClientError.new(*args)
when "invalid_grant"
OAuth::InvalidGrantError.new(*args)
when "invalid_request"
OAuth::InvalidRequestError.new(*args)
when "invalid_scope"
OAuth::InvalidScopeError.new(*args)
when "unsupported_grant_type"
OAuth::UnsupportedGrantTypeError.new(*args)
when "unsupported_response_type"
OAuth::UnsupportedResponseTypeError.new(*args)
else
# We'd prefer that all errors are typed, but we create a generic
# OAuthError in case we run into a code that we don't recognize.
@ -424,30 +437,33 @@ module Stripe
end
end
def handle_network_error(e, context, num_retries, api_base = nil)
private def handle_network_error(error, context, num_retries,
api_base = nil)
Util.log_error("Stripe network error",
error_message: e.message,
error_message: error.message,
idempotency_key: context.idempotency_key,
request_id: context.request_id)
case e
case error
when Faraday::ConnectionFailed
message = "Unexpected error communicating when trying to connect to Stripe. " \
"You may be seeing this message because your DNS is not working. " \
"To check, try running 'host stripe.com' from the command line."
message = "Unexpected error communicating when trying to connect to " \
"Stripe. You may be seeing this message because your DNS is not" \
"working. To check, try running `host stripe.com` from the " \
"command line."
when Faraday::SSLError
message = "Could not establish a secure connection to Stripe, you may " \
"need to upgrade your OpenSSL version. To check, try running " \
"'openssl s_client -connect api.stripe.com:443' from the " \
"command line."
message = "Could not establish a secure connection to Stripe, you " \
"may need to upgrade your OpenSSL version. To check, try running " \
"`openssl s_client -connect api.stripe.com:443` from the command " \
"line."
when Faraday::TimeoutError
api_base ||= Stripe.api_base
message = "Could not connect to Stripe (#{api_base}). " \
"Please check your internet connection and try again. " \
"If this problem persists, you should check Stripe's service status at " \
"https://twitter.com/stripestatus, or let us know at support@stripe.com."
"If this problem persists, you should check Stripe's service " \
"status at https://status.stripe.com, or let us know at " \
"support@stripe.com."
else
message = "Unexpected error communicating with Stripe. " \
@ -457,10 +473,11 @@ module Stripe
message += " Request was retried #{num_retries} times." if num_retries > 0
raise APIConnectionError, message + "\n\n(Network error: #{e.message})"
raise APIConnectionError,
message + "\n\n(Network error: #{error.message})"
end
def request_headers(api_key, method)
private def request_headers(api_key, method)
user_agent = "Stripe/v1 RubyBindings/#{Stripe::VERSION}"
unless Stripe.app_info.nil?
user_agent += " " + format_app_info(Stripe.app_info)
@ -473,7 +490,9 @@ module Stripe
}
if Stripe.enable_telemetry? && !@last_request_metrics.nil?
headers["X-Stripe-Client-Telemetry"] = JSON.generate(last_request_metrics: @last_request_metrics.payload)
headers["X-Stripe-Client-Telemetry"] = JSON.generate(
last_request_metrics: @last_request_metrics.payload
)
end
# It is only safe to retry network failures on post and delete
@ -500,7 +519,7 @@ module Stripe
headers
end
def log_request(context, num_retries)
private def log_request(context, num_retries)
Util.log_info("Request to Stripe API",
account: context.account,
api_version: context.api_version,
@ -513,9 +532,8 @@ module Stripe
idempotency_key: context.idempotency_key,
query_params: context.query_params)
end
private :log_request
def log_response(context, request_start, status, body)
private def log_response(context, request_start, status, body)
Util.log_info("Response from Stripe API",
account: context.account,
api_version: context.api_version,
@ -535,19 +553,18 @@ module Stripe
Util.log_debug("Dashboard link for request",
idempotency_key: context.idempotency_key,
request_id: context.request_id,
url: Util.request_id_dashboard_url(context.request_id, context.api_key))
url: Util.request_id_dashboard_url(context.request_id,
context.api_key))
end
private :log_response
def log_response_error(context, request_start, e)
private def log_response_error(context, request_start, error)
Util.log_error("Request error",
elapsed: Time.now - request_start,
error_message: e.message,
error_message: error.message,
idempotency_key: context.idempotency_key,
method: context.method,
path: context.path)
end
private :log_response_error
# RequestLogContext stores information about a request that's begin made so
# that we can log certain information. It's useful because it means that we
@ -630,7 +647,8 @@ module Stripe
end
def user_agent
lang_version = "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})"
lang_version = "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL} " \
"(#{RUBY_RELEASE_DATE})"
{
application: Stripe.app_info,
@ -646,7 +664,8 @@ module Stripe
end
end
# StripeRequestMetrics tracks metadata to be reported to stripe for metrics collection
# StripeRequestMetrics tracks metadata to be reported to stripe for metrics
# collection
class StripeRequestMetrics
# The Stripe request ID of the response.
attr_accessor :request_id

View File

@ -4,7 +4,7 @@ module Stripe
class StripeObject
include Enumerable
@@permanent_attributes = Set.new([:id])
@@permanent_attributes = Set.new([:id]) # rubocop:disable Style/ClassVars
# The default :id method is deprecated and isn't useful to us
undef :id if method_defined?(:id)
@ -93,10 +93,12 @@ module Stripe
# considered to be equal if they have the same set of values and each one
# of those values is the same.
def ==(other)
other.is_a?(StripeObject) && @values == other.instance_variable_get(:@values)
other.is_a?(StripeObject) &&
@values == other.instance_variable_get(:@values)
end
# Hash equality. As with `#==`, we consider two equivalent Stripe objects equal.
# Hash equality. As with `#==`, we consider two equivalent Stripe objects
# equal.
def eql?(other)
# Defer to the implementation on `#==`.
self == other
@ -121,7 +123,8 @@ module Stripe
def inspect
id_string = respond_to?(:id) && !id.nil? ? " id=#{id}" : ""
"#<#{self.class}:0x#{object_id.to_s(16)}#{id_string}> JSON: " + JSON.pretty_generate(@values)
"#<#{self.class}:0x#{object_id.to_s(16)}#{id_string}> JSON: " +
JSON.pretty_generate(@values)
end
# Re-initializes the object based on a hash of values (usually one that's
@ -162,12 +165,12 @@ module Stripe
end
end
def [](k)
@values[k.to_sym]
def [](key)
@values[key.to_sym]
end
def []=(k, v)
send(:"#{k}=", v)
def []=(key, value)
send(:"#{key}=", value)
end
def keys
@ -178,12 +181,13 @@ module Stripe
@values.values
end
def to_json(*_a)
def to_json(*_opts)
# TODO: pass opts to JSON.generate?
JSON.generate(@values)
end
def as_json(*a)
@values.as_json(*a)
def as_json(*opts)
@values.as_json(*opts)
end
def to_hash
@ -251,10 +255,10 @@ module Stripe
# values within in that its parent StripeObject doesn't know about.
#
unsaved = @unsaved_values.include?(k)
if options[:force] || unsaved || v.is_a?(StripeObject)
update_hash[k.to_sym] =
serialize_params_value(@values[k], @original_values[k], unsaved, options[:force], key: k)
end
next unless options[:force] || unsaved || v.is_a?(StripeObject)
update_hash[k.to_sym] = serialize_params_value(
@values[k], @original_values[k], unsaved, options[:force], key: k
)
end
# a `nil` that makes it out of `#serialize_params_value` signals an empty
@ -281,13 +285,11 @@ module Stripe
[]
end
protected
def metaclass
protected def metaclass
class << self; self; end
end
def remove_accessors(keys)
protected def remove_accessors(keys)
# not available in the #instance_eval below
protected_fields = self.class.protected_fields
@ -313,7 +315,7 @@ module Stripe
#
# Here we swallow that error and issue a warning so at least
# the program doesn't crash.
$stderr.puts("WARNING: Unable to remove method `#{method_name}`; " \
warn("WARNING: Unable to remove method `#{method_name}`; " \
"if custom, please consider renaming to a name that doesn't " \
"collide with an API property name.")
end
@ -322,7 +324,7 @@ module Stripe
end
end
def add_accessors(keys, values)
protected def add_accessors(keys, values)
# not available in the #instance_eval below
protected_fields = self.class.protected_fields
@ -359,7 +361,11 @@ module Stripe
end
end
def method_missing(name, *args)
# Disabling the cop because it's confused by the fact that the methods are
# protected, but we do define `#respond_to_missing?` just below. Hopefully
# this is fixed in more recent Rubocop versions.
# rubocop:disable Style/MissingRespondToMissing
protected def method_missing(name, *args)
# TODO: only allow setting in updateable classes.
if name.to_s.end_with?("=")
attr = name.to_s[0...-1].to_sym
@ -375,7 +381,9 @@ module Stripe
begin
mth = method(name)
rescue NameError
raise NoMethodError, "Cannot set #{attr} on this object. HINT: you can't set: #{@@permanent_attributes.to_a.join(', ')}"
raise NoMethodError,
"Cannot set #{attr} on this object. HINT: you can't set: " \
"#{@@permanent_attributes.to_a.join(', ')}"
end
return mth.call(args[0])
elsif @values.key?(name)
@ -390,11 +398,17 @@ module Stripe
# raise right away.
raise unless @transient_values.include?(name)
raise NoMethodError, e.message + ". HINT: The '#{name}' attribute was set in the past, however. It was then wiped when refreshing the object with the result returned by Stripe's API, probably as a result of a save(). The attributes currently available on this object are: #{@values.keys.join(', ')}"
raise NoMethodError,
e.message + ". HINT: The '#{name}' attribute was set in the " \
"past, however. It was then wiped when refreshing the object " \
"with the result returned by Stripe's API, probably as a " \
"result of a save(). The attributes currently available on " \
"this object are: #{@values.keys.join(', ')}"
end
end
# rubocop:enable Style/MissingRespondToMissing
def respond_to_missing?(symbol, include_private = false)
protected def respond_to_missing?(symbol, include_private = false)
@values && @values.key?(symbol) || super
end
@ -410,7 +424,7 @@ module Stripe
# * +:opts:+ Options for StripeObject like an API key.
# * +:partial:+ Indicates that the re-initialization should not attempt to
# remove accessors.
def initialize_from(values, opts, partial = false)
protected def initialize_from(values, opts, partial = false)
@opts = Util.normalize_opts(opts)
# the `#send` is here so that we can keep this method private
@ -420,8 +434,8 @@ module Stripe
added = Set.new(values.keys - @values.keys)
# Wipe old state before setting new. This is useful for e.g. updating a
# customer, where there is no persistent card parameter. Mark those values
# which don't persist as transient
# customer, where there is no persistent card parameter. Mark those
# values which don't persist as transient
remove_accessors(removed)
add_accessors(added, values)
@ -441,7 +455,8 @@ module Stripe
self
end
def serialize_params_value(value, original, unsaved, force, key: nil)
protected def serialize_params_value(value, original, unsaved, force,
key: nil)
if value.nil?
""
@ -516,11 +531,9 @@ module Stripe
end
end
private
# Produces a deep copy of the given object including support for arrays,
# hashes, and StripeObjects.
def self.deep_copy(obj)
private_class_method def self.deep_copy(obj)
case obj
when Array
obj.map { |e| deep_copy(e) }
@ -540,9 +553,8 @@ module Stripe
obj
end
end
private_class_method :deep_copy
def dirty_value!(value)
private def dirty_value!(value)
case value
when Array
value.map { |v| dirty_value!(v) }
@ -553,12 +565,14 @@ module Stripe
# Returns a hash of empty values for all the values that are in the given
# StripeObject.
def empty_values(obj)
private def empty_values(obj)
values = case obj
when Hash then obj
when StripeObject then obj.instance_variable_get(:@values)
else
raise ArgumentError, "#empty_values got unexpected object type: #{obj.class.name}"
raise ArgumentError,
"#empty_values got unexpected object type: " \
"#{obj.class.name}"
end
values.each_with_object({}) do |(k, _), update|

View File

@ -18,9 +18,7 @@ module Stripe
initialize_from({ discount: nil }, opts, true)
end
private
def discount_url
private def discount_url
resource_url + "/discount"
end
end

View File

@ -10,7 +10,8 @@ module Stripe
OBJECT_NAME = "subscription_item".freeze
def usage_record_summaries(params = {}, opts = {})
resp, opts = request(:get, resource_url + "/usage_record_summaries", params, opts)
resp, opts = request(:get, resource_url + "/usage_record_summaries",
params, opts)
Util.convert_to_stripe_object(resp.data, opts)
end
end

View File

@ -9,17 +9,26 @@ module Stripe
def resource_url
if !respond_to?(:schedule) || schedule.nil?
raise NotImplementedError,
"Subscription Schedule Revisions cannot be accessed without a Subscription Schedule ID."
"Subscription schedule revisions cannot be accessed without a " \
"subscription schedule ID."
end
"#{SubscriptionSchedule.resource_url}/#{CGI.escape(schedule)}/revisions/#{CGI.escape(id)}"
"#{SubscriptionSchedule.resource_url}/#{CGI.escape(schedule)}" \
"/revisions/#{CGI.escape(id)}"
end
def self.retrieve(_id, _opts = {})
raise NotImplementedError, "Subscription Schedule Revisions cannot be retrieved without a Subscription Schedule ID. Retrieve it using schedule.revisions.retrieve('revision_id')"
raise NotImplementedError,
"Subscription schedule revisions cannot be retrieved without a " \
"subscription schedule ID. Retrieve a subscribtion schedule " \
"revision using `SubscriptionSchedule.retrieve_revision(" \
"'schedule_id', 'revision_id')`"
end
def self.list(_id, _opts = {})
raise NotImplementedError, "Subscription Schedule Revisions cannot be listed without a Subscription Schedule ID. List those using schedule.revisions"
raise NotImplementedError,
"Subscription schedule revisions cannot be listed without a " \
"subscription schedule ID. List subscribtion schedule revisions " \
"using `SubscriptionSchedule.list_revisions('schedule_id')`"
end
end
end

View File

@ -10,13 +10,17 @@ module Stripe
def resource_url
if !respond_to?(:customer) || customer.nil?
raise NotImplementedError,
"Tax Ids cannot be accessed without a customer ID."
"Tax IDs cannot be accessed without a customer ID."
end
"#{Customer.resource_url}/#{CGI.escape(customer)}/tax_ids/#{CGI.escape(id)}"
"#{Customer.resource_url}/#{CGI.escape(customer)}/tax_ids" \
"/#{CGI.escape(id)}"
end
def self.retrieve(_id, _opts = {})
raise NotImplementedError, "Tax Ids cannot be retrieved without a customer ID. Retrieve a tax id using Customer.retrieve_tax_id('tax_id')"
raise NotImplementedError,
"Tax IDs cannot be retrieved without a customer ID. Retrieve a " \
"tax ID using `Customer.retrieve_tax_id('customer_id', " \
"'tax_id_id')`"
end
end
end

View File

@ -11,7 +11,8 @@ module Stripe
custom_method :cancel, http_verb: :post
nested_resource_class_methods :reversal, operations: %i[create retrieve update list]
nested_resource_class_methods :reversal,
operations: %i[create retrieve update list]
def cancel
resp, api_key = request(:post, cancel_url)

View File

@ -5,9 +5,18 @@ module Stripe
OBJECT_NAME = "usage_record".freeze
def self.create(params = {}, opts = {})
raise(ArgumentError, "Params must have a subscription_item key") unless params.key?(:subscription_item)
req_params = params.clone.delete_if { |key, _value| key == :subscription_item }
resp, opts = request(:post, "/v1/subscription_items/#{params[:subscription_item]}/usage_records", req_params, opts)
unless params.key?(:subscription_item)
raise ArgumentError, "Params must have a subscription_item key"
end
req_params = params.clone.delete_if do |key, _value|
key == :subscription_item
end
resp, opts = request(
:post,
"/v1/subscription_items/#{params[:subscription_item]}/usage_records",
req_params,
opts
)
Util.convert_to_stripe_object(resp.data, opts)
end
end

View File

@ -24,22 +24,23 @@ module Stripe
OPTS_USER_SPECIFIED + Set[:client] - Set[:idempotency_key]
).freeze
def self.objects_to_ids(h)
case h
def self.objects_to_ids(obj)
case obj
when APIResource
h.id
obj.id
when Hash
res = {}
h.each { |k, v| res[k] = objects_to_ids(v) unless v.nil? }
obj.each { |k, v| res[k] = objects_to_ids(v) unless v.nil? }
res
when Array
h.map { |v| objects_to_ids(v) }
obj.map { |v| objects_to_ids(v) }
else
h
obj
end
end
def self.object_classes # rubocop:disable Metrics/MethodLength
# rubocop:disable Metrics/LineLength
@object_classes ||= {
# data structures
ListObject::OBJECT_NAME => ListObject,
@ -122,6 +123,7 @@ module Stripe
UsageRecordSummary::OBJECT_NAME => UsageRecordSummary,
WebhookEndpoint::OBJECT_NAME => WebhookEndpoint,
}
# rubocop:enable Metrics/LineLength
end
# Converts a hash of fields or an array of hashes into a +StripeObject+ or
@ -143,8 +145,10 @@ module Stripe
when Array
data.map { |i| convert_to_stripe_object(i, opts) }
when Hash
# Try converting to a known object class. If none available, fall back to generic StripeObject
object_classes.fetch(data[:object], StripeObject).construct_from(data, opts)
# Try converting to a known object class. If none available, fall back
# to generic StripeObject
object_classes.fetch(data[:object], StripeObject)
.construct_from(data, opts)
else
data
end
@ -153,24 +157,24 @@ module Stripe
def self.log_error(message, data = {})
if !Stripe.logger.nil? ||
!Stripe.log_level.nil? && Stripe.log_level <= Stripe::LEVEL_ERROR
log_internal(message, data, color: :cyan,
level: Stripe::LEVEL_ERROR, logger: Stripe.logger, out: $stderr)
log_internal(message, data, color: :cyan, level: Stripe::LEVEL_ERROR,
logger: Stripe.logger, out: $stderr)
end
end
def self.log_info(message, data = {})
if !Stripe.logger.nil? ||
!Stripe.log_level.nil? && Stripe.log_level <= Stripe::LEVEL_INFO
log_internal(message, data, color: :cyan,
level: Stripe::LEVEL_INFO, logger: Stripe.logger, out: $stdout)
log_internal(message, data, color: :cyan, level: Stripe::LEVEL_INFO,
logger: Stripe.logger, out: $stdout)
end
end
def self.log_debug(message, data = {})
if !Stripe.logger.nil? ||
!Stripe.log_level.nil? && Stripe.log_level <= Stripe::LEVEL_DEBUG
log_internal(message, data, color: :blue,
level: Stripe::LEVEL_DEBUG, logger: Stripe.logger, out: $stdout)
log_internal(message, data, color: :blue, level: Stripe::LEVEL_DEBUG,
logger: Stripe.logger, out: $stdout)
end
end
@ -305,13 +309,13 @@ module Stripe
# Constant time string comparison to prevent timing attacks
# Code borrowed from ActiveSupport
def self.secure_compare(a, b)
return false unless a.bytesize == b.bytesize
def self.secure_compare(str_a, str_b)
return false unless str_a.bytesize == str_b.bytesize
l = a.unpack "C#{a.bytesize}"
l = str_a.unpack "C#{str_a.bytesize}"
res = 0
b.each_byte { |byte| res |= byte ^ l.shift }
str_b.each_byte { |byte| res |= byte ^ l.shift }
res.zero?
end
@ -358,21 +362,33 @@ module Stripe
# TODO: Make these named required arguments when we drop support for Ruby
# 2.0.
def self.log_internal(message, data = {}, color: nil, level: nil, logger: nil, out: nil)
def self.log_internal(message, data = {}, color: nil, level: nil,
logger: nil, out: nil)
data_str = data.reject { |_k, v| v.nil? }
.map do |(k, v)|
format("%s=%s", colorize(k, color, logger.nil? && !out.nil? && out.isatty), wrap_logfmt_value(v))
format("%<key>s=%<value>s",
key: colorize(k, color, logger.nil? && !out.nil? && out.isatty),
value: wrap_logfmt_value(v))
end.join(" ")
if !logger.nil?
# the library's log levels are mapped to the same values as the
# standard library's logger
logger.log(level,
format("message=%s %s", wrap_logfmt_value(message), data_str))
format("message=%<message>s %<data_str>s",
message: wrap_logfmt_value(message),
data_str: data_str))
elsif out.isatty
out.puts format("%s %s %s", colorize(level_name(level)[0, 4].upcase, color, out.isatty), message, data_str)
out.puts format("%<level>s %<message>s %<data_str>s",
level: colorize(level_name(level)[0, 4].upcase,
color, out.isatty),
message: message,
data_str: data_str)
else
out.puts format("message=%s level=%s %s", wrap_logfmt_value(message), level_name(level), data_str)
out.puts format("message=%<message>s level=%<level>s %<data_str>s",
message: wrap_logfmt_value(message),
level: level_name(level),
data_str: data_str)
end
end
private_class_method :log_internal
@ -390,7 +406,7 @@ module Stripe
if %r{[^\w\-/]} =~ val
# If the string contains any special characters, escape any double
# quotes it has, remove newlines, and wrap the whole thing in quotes.
format(%("%s"), val.gsub('"', '\"').delete("\n"))
format(%("%<value>s"), value: val.gsub('"', '\"').delete("\n"))
else
# Otherwise use the basic value if it looks like a standard set of
# characters (and allow a few special characters like hyphens, and

View File

@ -8,7 +8,8 @@ module Stripe
#
# This may raise JSON::ParserError if the payload is not valid JSON, or
# SignatureVerificationError if the signature verification fails.
def self.construct_event(payload, sig_header, secret, tolerance: DEFAULT_TOLERANCE)
def self.construct_event(payload, sig_header, secret,
tolerance: DEFAULT_TOLERANCE)
Signature.verify_header(payload, sig_header, secret, tolerance: tolerance)
# It's a good idea to parse the payload only after verifying it. We use
@ -50,7 +51,8 @@ module Stripe
# Returns true otherwise
def self.verify_header(payload, header, secret, tolerance: nil)
begin
timestamp, signatures = get_timestamp_and_signatures(header, EXPECTED_SCHEME)
timestamp, signatures =
get_timestamp_and_signatures(header, EXPECTED_SCHEME)
rescue StandardError
raise SignatureVerificationError.new(
"Unable to extract timestamp and signatures from header",

View File

@ -9,7 +9,8 @@ Gem::Specification.new do |s|
s.version = Stripe::VERSION
s.required_ruby_version = ">= 2.1.0"
s.summary = "Ruby bindings for the Stripe API"
s.description = "Stripe is the easiest way to accept payments online. See https://stripe.com for details."
s.description = "Stripe is the easiest way to accept payments online. " \
"See https://stripe.com for details."
s.author = "Stripe"
s.email = "support@stripe.com"
s.homepage = "https://stripe.com/docs/api/ruby"
@ -20,6 +21,7 @@ Gem::Specification.new do |s|
s.files = `git ls-files`.split("\n")
s.test_files = `git ls-files -- test/*`.split("\n")
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| ::File.basename(f) }
s.executables = `git ls-files -- bin/*`.split("\n")
.map { |f| ::File.basename(f) }
s.require_paths = ["lib"]
end

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class AccountLinkTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class AccountTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class AlipayAccountTest < Test::Unit::TestCase

View File

@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class ApiOperationsTest < Test::Unit::TestCase

View File

@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class ApiResourceTest < Test::Unit::TestCase
@ -491,7 +490,7 @@ module Stripe
end
end
@@fixtures = {}
@@fixtures = {} # rubocop:disable Style/ClassVars
setup do
if @@fixtures.empty?
cache_fixture(:charge) do
@ -503,19 +502,17 @@ module Stripe
end
end
private
def charge_fixture
private def charge_fixture
@@fixtures[:charge]
end
def customer_fixture
private def customer_fixture
@@fixtures[:customer]
end
# Expects to retrieve a fixture from stripe-mock (an API call should be
# included in the block to yield to) and does very simple memoization.
def cache_fixture(key)
private def cache_fixture(key)
return @@fixtures[key] if @@fixtures.key?(key)
obj = yield

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class ApplePayDomainTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class ApplicationFeeRefundTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class ApplicationFeeTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class BalanceTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class BankAccountTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class CapabilityTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class ChargeTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../../test_helper", __FILE__)
require ::File.expand_path("../../test_helper", __dir__)
module Stripe
module Checkout

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class CountrySpecTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class CouponTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class CreditNoteTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class CustomerCardTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class CustomerTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class DisputeTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class EphemeralKeyTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class StripeErrorTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class ExchangeRateTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class FileLinkTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class FileTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
# This is a strict copy of `FileTest`, except that it uses

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class InvoiceItemTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class InvoiceLineItemTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class InvoiceTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class IssuerFraudRecordTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../../test_helper", __FILE__)
require ::File.expand_path("../../test_helper", __dir__)
module Stripe
module Issuing

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../../test_helper", __FILE__)
require ::File.expand_path("../../test_helper", __dir__)
module Stripe
module Issuing

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../../test_helper", __FILE__)
require ::File.expand_path("../../test_helper", __dir__)
module Stripe
module Issuing

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../../test_helper", __FILE__)
require ::File.expand_path("../../test_helper", __dir__)
module Stripe
module Issuing

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../../test_helper", __FILE__)
require ::File.expand_path("../../test_helper", __dir__)
module Stripe
module Issuing

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class ListObjectTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class LoginLinkTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class OAuthTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class OrderReturnTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class OrderTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
TEST_RESOURCE_ID = "pi_123".freeze

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class PaymentMethodTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class PayoutTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class PersonTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class PlanTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class ProductTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../../test_helper", __FILE__)
require ::File.expand_path("../../test_helper", __dir__)
module Stripe
module Radar

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../../test_helper", __FILE__)
require ::File.expand_path("../../test_helper", __dir__)
module Stripe
module Radar

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../../test_helper", __FILE__)
require ::File.expand_path("../../test_helper", __dir__)
module Stripe
module Radar

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class RecipientTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class RefundTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../../test_helper", __FILE__)
require ::File.expand_path("../../test_helper", __dir__)
module Stripe
module Reporting

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../../test_helper", __FILE__)
require ::File.expand_path("../../test_helper", __dir__)
module Stripe
module Reporting

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class ReversalTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class ReviewTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../../test_helper", __FILE__)
require ::File.expand_path("../../test_helper", __dir__)
module Stripe
module Issuing

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class SKUTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class SourceTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class SourceTransactionTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class StripeClientTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class StripeObjectTest < Test::Unit::TestCase

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require ::File.expand_path("../../test_helper", __FILE__)
require ::File.expand_path("../test_helper", __dir__)
module Stripe
class StripeResponseTest < Test::Unit::TestCase

Some files were not shown because too many files have changed in this diff Show More