Merge pull request #499 from stripe/brandur-openapi-test-suite

100% OpenAPI-powered test suite
This commit is contained in:
Brandur 2017-02-14 12:48:33 -08:00 committed by GitHub
commit 5dd5d2b608
75 changed files with 40402 additions and 3026 deletions

4
.gitattributes vendored Normal file
View File

@ -0,0 +1,4 @@
# may be useful in hiding large schema changes in pull request diffs (but not
# using it for now)
spec/*.json binary
spec/*.yaml binary

13
Gemfile
View File

@ -3,18 +3,29 @@ source "https://rubygems.org"
gemspec
group :development do
gem 'committee', '2.0.0.pre6'
gem 'mocha', '~> 0.13.2'
gem 'pry'
gem 'rake'
gem 'shoulda-context'
gem 'sinatra'
gem 'test-unit'
gem 'webmock'
# 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
# constraint on Rack if necessary.
if RUBY_VERSION >= '2.2.2'
gem "rack", ">= 1.5"
else
gem "rack", ">= 1.5", "< 2.0"
end
platforms :mri do
# to avoid problems, bring Byebug in on just versions of Ruby under which
# it's known to work well
if Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.0.0')
gem 'byebug'
gem 'pry'
gem 'pry-byebug'
end
end

View File

@ -10,7 +10,7 @@ desc "update bundled certs"
task :update_certs do
require "restclient"
File.open(File.join(File.dirname(__FILE__), 'lib', 'data', 'ca-certificates.crt'), 'w') do |file|
resp = RestClient.get "https://raw.githubusercontent.com/bagder/ca-bundle/master/ca-bundle.crt"
resp = Faraday.get "https://raw.githubusercontent.com/bagder/ca-bundle/master/ca-bundle.crt"
abort("bad response when fetching bundle") unless resp.code == 200
file.write(resp.to_str)
end

View File

@ -6,7 +6,7 @@ require 'rbconfig'
require 'set'
require 'socket'
require 'rest-client'
require 'faraday'
require 'json'
# Version
@ -22,7 +22,9 @@ require 'stripe/api_operations/request'
# API resource support classes
require 'stripe/errors'
require 'stripe/util'
require 'stripe/stripe_client'
require 'stripe/stripe_object'
require 'stripe/stripe_response'
require 'stripe/list_object'
require 'stripe/api_resource'
require 'stripe/singleton_api_resource'
@ -66,35 +68,6 @@ require 'stripe/transfer'
module Stripe
DEFAULT_CA_BUNDLE_PATH = File.dirname(__FILE__) + '/data/ca-certificates.crt'
# Exceptions which we'd like to retry. This includes both socket errors that
# may represent an intermittent problem and some special HTTP statuses.
RETRY_EXCEPTIONS = [
# Destination refused the connection. This could occur from a single
# saturated server, so retry in case it's intermittent.
Errno::ECONNREFUSED,
# Connection reset. This occasionally occurs on a server problem, and
# deserves a retry because the server should terminate all requests
# properly even if they were invalid.
Errno::ECONNRESET,
# Timed out making the connection. It's worth retrying under this
# circumstance.
Errno::ETIMEDOUT,
# A server may respond with a 409 to indicate that there is a concurrent
# request executing with the same idempotency key. In the case that a
# request failed due to a connection problem and the client has retried too
# early, but the server is still executing the old request, we would like
# the client to continue retrying until getting a "real" response status
# back.
RestClient::Conflict,
# Retry on timeout-related problems. This shouldn't be lumped in with HTTP
# exceptions, but with RestClient it is.
RestClient::RequestTimeout,
].freeze
@api_base = 'https://api.stripe.com'
@connect_base = 'https://connect.stripe.com'
@uploads_base = 'https://uploads.stripe.com'
@ -103,7 +76,7 @@ module Stripe
@max_network_retry_delay = 2
@initial_network_retry_delay = 0.5
@ca_bundle_path = DEFAULT_CA_BUNDLE_PATH
@ca_bundle_path = DEFAULT_CA_BUNDLE_PATH
@ca_store = nil
@verify_ssl_certs = true
@ -117,10 +90,6 @@ module Stripe
attr_reader :max_network_retry_delay, :initial_network_retry_delay
end
def self.api_url(url='', api_base_url=nil)
(api_base_url || @api_base) + url
end
# The location of a file containing a bundle of CA certificates. By default
# the library will use an included bundle that can successfully validate
# Stripe certificates.
@ -152,62 +121,6 @@ module Stripe
end
end
def self.request(method, url, api_key, params={}, headers={}, api_base_url=nil)
api_base_url = api_base_url || @api_base
unless api_key ||= @api_key
raise AuthenticationError.new('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.')
end
if api_key =~ /\s/
raise AuthenticationError.new('Your API key is invalid, as it contains ' \
'whitespace. (HINT: You can double-check your API key from the ' \
'Stripe web interface. See https://stripe.com/api for details, or ' \
'email support@stripe.com if you have any questions.)')
end
if verify_ssl_certs
request_opts = {:verify_ssl => OpenSSL::SSL::VERIFY_PEER,
:ssl_cert_store => ca_store}
else
request_opts = {:verify_ssl => false}
unless @verify_ssl_warned
@verify_ssl_warned = true
$stderr.puts("WARNING: Running without SSL cert verification. " \
"You should never do this in production. " \
"Execute 'Stripe.verify_ssl_certs = true' to enable verification.")
end
end
params = Util.objects_to_ids(params)
url = api_url(url, api_base_url)
case method.to_s.downcase.to_sym
when :get, :head, :delete
# Make params into GET parameters
url += "#{URI.parse(url).query ? '&' : '?'}#{Util.encode_parameters(params)}" if params && params.any?
payload = nil
else
if headers[:content_type] && headers[:content_type] == "multipart/form-data"
payload = params
else
payload = Util.encode_parameters(params)
end
end
request_opts.update(:headers => request_headers(api_key, method).update(headers),
:method => method, :open_timeout => open_timeout,
:payload => payload, :url => url, :timeout => read_timeout)
response = execute_request_with_rescues(request_opts, api_base_url)
[parse(response), api_key]
end
def self.max_network_retries
@max_network_retries
end
@ -218,242 +131,6 @@ module Stripe
private
def self.api_error(error, resp, error_obj)
APIError.new(error[:message], resp.code, resp.body, error_obj, resp.headers)
end
def self.authentication_error(error, resp, error_obj)
AuthenticationError.new(error[:message], resp.code, resp.body, error_obj,
resp.headers)
end
def self.card_error(error, resp, error_obj)
CardError.new(error[:message], error[:param], error[:code],
resp.code, resp.body, error_obj, resp.headers)
end
def self.execute_request(opts)
RestClient::Request.execute(opts)
end
def self.execute_request_with_rescues(request_opts, api_base_url, retry_count = 0)
begin
response = execute_request(request_opts)
# 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.
rescue => e
if should_retry?(e, retry_count)
retry_count = retry_count + 1
sleep sleep_time(retry_count)
retry
end
case e
when SocketError
response = handle_restclient_error(e, request_opts, retry_count, api_base_url)
when RestClient::ExceptionWithResponse
if e.response
handle_api_error(e.response)
else
response = handle_restclient_error(e, request_opts, retry_count, api_base_url)
end
when RestClient::Exception, Errno::ECONNREFUSED, OpenSSL::SSL::SSLError
response = handle_restclient_error(e, request_opts, retry_count, api_base_url)
# Only handle errors when we know we can do so, and re-raise otherwise.
# This should be pretty infrequent.
else
raise
end
end
response
end
def self.general_api_error(rcode, rbody)
APIError.new("Invalid response object from API: #{rbody.inspect} " +
"(HTTP response code was #{rcode})", rcode, rbody)
end
def self.get_uname
if File.exist?('/proc/version')
File.read('/proc/version').strip
else
case RbConfig::CONFIG['host_os']
when /linux|darwin|bsd|sunos|solaris|cygwin/i
get_uname_from_system
when /mswin|mingw/i
get_uname_from_system_ver
else
"unknown platform"
end
end
end
def self.get_uname_from_system
(`uname -a 2>/dev/null` || '').strip
rescue Errno::ENOENT
"uname executable not found"
rescue Errno::ENOMEM # couldn't create subprocess
"uname lookup failed"
end
def self.get_uname_from_system_ver
(`ver` || '').strip
rescue Errno::ENOENT
"ver executable not found"
rescue Errno::ENOMEM # couldn't create subprocess
"uname lookup failed"
end
def self.handle_api_error(resp)
begin
error_obj = JSON.parse(resp.body)
error_obj = Util.symbolize_names(error_obj)
error = error_obj[:error]
raise StripeError.new unless error && error.is_a?(Hash)
rescue JSON::ParserError, StripeError
raise general_api_error(resp.code, resp.body)
end
case resp.code
when 400, 404
raise invalid_request_error(error, resp, error_obj)
when 401
raise authentication_error(error, resp, error_obj)
when 402
raise card_error(error, resp, error_obj)
when 403
raise permission_error(error, resp, error_obj)
when 429
raise rate_limit_error(error, resp, error_obj)
else
raise api_error(error, resp, error_obj)
end
end
def self.handle_restclient_error(e, request_opts, retry_count, api_base_url=nil)
api_base_url = @api_base unless api_base_url
connection_message = "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."
case e
when RestClient::RequestTimeout
message = "Could not connect to Stripe (#{api_base_url}). #{connection_message}"
when RestClient::ServerBrokeConnection
message = "The connection to the server (#{api_base_url}) broke before the " \
"request completed. #{connection_message}"
when OpenSSL::SSL::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."
when RestClient::SSLCertificateNotVerified
message = "Could not verify Stripe's SSL certificate. " \
"Please make sure that your network is not intercepting certificates. " \
"(Try going to https://api.stripe.com/v1 in your browser.) " \
"If this problem persists, let us know at support@stripe.com."
when SocketError
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."
else
message = "Unexpected error communicating with Stripe. " \
"If this problem persists, let us know at support@stripe.com."
end
if retry_count > 0
message += " Request was retried #{retry_count} times."
end
raise APIConnectionError.new(message + "\n\n(Network error: #{e.message})")
end
def self.invalid_request_error(error, resp, error_obj)
InvalidRequestError.new(error[:message], error[:param], resp.code,
resp.body, error_obj, resp.headers)
end
def self.parse(response)
begin
# Would use :symbolize_names => true, but apparently there is
# some library out there that makes symbolize_names not work.
response = JSON.parse(response.body)
rescue JSON::ParserError
raise general_api_error(response.code, response.body)
end
Util.symbolize_names(response)
end
def self.permission_error(error, resp, error_obj)
PermissionError.new(error[:message], resp.code, resp.body, error_obj, resp.headers)
end
def self.rate_limit_error(error, resp, error_obj)
RateLimitError.new(error[:message], resp.code, resp.body, error_obj,
resp.headers)
end
def self.request_headers(api_key, method)
headers = {
'User-Agent' => "Stripe/v1 RubyBindings/#{Stripe::VERSION}",
'Authorization' => "Bearer #{api_key}",
'Content-Type' => 'application/x-www-form-urlencoded'
}
# It is only safe to retry network failures on post and delete
# requests if we add an Idempotency-Key header
if [:post, :delete].include?(method) && self.max_network_retries > 0
headers['Idempotency-Key'] ||= SecureRandom.uuid
end
headers['Stripe-Version'] = api_version if api_version
headers['Stripe-Account'] = stripe_account if stripe_account
begin
headers.update('X-Stripe-Client-User-Agent' => JSON.generate(user_agent))
rescue => e
headers.update('X-Stripe-Client-Raw-User-Agent' => user_agent.inspect,
:error => "#{e} (#{e.class})")
end
end
def self.should_retry?(e, retry_count)
retry_count < self.max_network_retries &&
RETRY_EXCEPTIONS.any? { |klass| e.is_a?(klass) }
end
def self.sleep_time(retry_count)
# Apply exponential backoff with initial_network_retry_delay on the number
# of attempts so far as inputs. Do not allow the number to exceed
# max_network_retry_delay.
sleep_seconds = [initial_network_retry_delay * (2 ** (retry_count - 1)), max_network_retry_delay].min
# Apply some jitter by randomizing the value in the range of (sleep_seconds
# / 2) to (sleep_seconds).
sleep_seconds = sleep_seconds * (0.5 * (1 + rand()))
# But never sleep less than the base sleep seconds.
sleep_seconds = [initial_network_retry_delay, sleep_seconds].max
sleep_seconds
end
# DEPRECATED. Use `Util#encode_parameters` instead.
def self.uri_encode(params)
Util.encode_parameters(params)
@ -462,21 +139,4 @@ module Stripe
extend Gem::Deprecate
deprecate :uri_encode, "Stripe::Util#encode_parameters", 2016, 01
end
def self.user_agent
@uname ||= get_uname
lang_version = "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})"
{
:bindings_version => Stripe::VERSION,
:lang => 'ruby',
:lang_version => lang_version,
:platform => RUBY_PLATFORM,
:engine => defined?(RUBY_ENGINE) ? RUBY_ENGINE : '',
:publisher => 'stripe',
:uname => @uname,
:hostname => Socket.gethostname,
}
end
end

View File

@ -37,8 +37,8 @@ module Stripe
def reject(params={}, opts={})
opts = Util.normalize_opts(opts)
response, opts = request(:post, resource_url + '/reject', params, opts)
initialize_from(response, opts)
resp, opts = request(:post, resource_url + '/reject', params, opts)
initialize_from(resp.data, opts)
end
# Somewhat unfortunately, we attempt to do a special encoding trick when
@ -93,9 +93,9 @@ module Stripe
def deauthorize(client_id, opts={})
opts = {:api_base => Stripe.connect_base}.merge(Util.normalize_opts(opts))
response, opts = request(:post, '/oauth/deauthorize', { 'client_id' => client_id, 'stripe_user_id' => self.id }, opts)
resp, opts = request(:post, '/oauth/deauthorize', { 'client_id' => client_id, 'stripe_user_id' => self.id }, opts)
opts.delete(:api_base) # the api_base here is a one-off, don't persist it
Util.convert_to_stripe_object(response, opts)
Util.convert_to_stripe_object(resp.data, opts)
end
ARGUMENT_NOT_PROVIDED = Object.new

View File

@ -2,8 +2,8 @@ module Stripe
module APIOperations
module Create
def create(params={}, opts={})
response, opts = request(:post, resource_url, params, opts)
Util.convert_to_stripe_object(response, opts)
resp, opts = request(:post, resource_url, params, opts)
Util.convert_to_stripe_object(resp.data, opts)
end
end
end

View File

@ -3,8 +3,8 @@ module Stripe
module Delete
def delete(params={}, opts={})
opts = Util.normalize_opts(opts)
response, opts = request(:delete, resource_url, params, opts)
initialize_from(response, opts)
resp, opts = request(:delete, resource_url, params, opts)
initialize_from(resp.data, opts)
end
end
end

View File

@ -4,8 +4,8 @@ module Stripe
def list(filters={}, opts={})
opts = Util.normalize_opts(opts)
response, opts = request(:get, resource_url, filters, opts)
obj = ListObject.construct_from(response, opts)
resp, opts = request(:get, resource_url, filters, opts)
obj = ListObject.construct_from(resp.data, opts)
# set filters so that we can fetch the same limit, expansions, and
# predicates when accessing the next and previous pages

View File

@ -2,17 +2,23 @@ module Stripe
module APIOperations
module Request
module ClassMethods
OPTS_KEYS_TO_PERSIST = Set[:api_key, :api_base, :stripe_account, :stripe_version]
OPTS_KEYS_TO_PERSIST = Set[:api_key, :api_base, :client, :stripe_account, :stripe_version]
def request(method, url, params={}, opts={})
opts = Util.normalize_opts(opts)
opts[:client] ||= StripeClient.active_client
headers = opts.clone
api_key = headers.delete(:api_key)
api_base = headers.delete(:api_base)
client = headers.delete(:client)
# Assume all remaining opts must be headers
response, opts[:api_key] = Stripe.request(method, url, api_key, params, headers, api_base)
resp, opts[:api_key] = client.execute_request(
method, url,
api_base: api_base, api_key: api_key,
headers: headers, params: params
)
# Hash#select returns an array before 1.9
opts_to_persist = {}
@ -22,7 +28,7 @@ module Stripe
end
end
[response, opts_to_persist]
[resp, opts_to_persist]
end
end

View File

@ -21,8 +21,8 @@ module Stripe
end
end
response, opts = request(:post, "#{resource_url}/#{id}", params, opts)
Util.convert_to_stripe_object(response, opts)
resp, opts = request(:post, "#{resource_url}/#{id}", params, opts)
Util.convert_to_stripe_object(resp.data, opts)
end
end
@ -57,10 +57,8 @@ module Stripe
# generated a uri for this object with an identifier baked in
values.delete(:id)
response, opts = request(:post, save_url, values, opts)
initialize_from(response, opts)
self
resp, opts = request(:post, save_url, values, opts)
initialize_from(resp.data, opts)
end
def self.included(base)

View File

@ -54,8 +54,8 @@ module Stripe
end
def refresh
response, opts = request(:get, resource_url, @retrieve_params)
initialize_from(response, opts)
resp, opts = request(:get, resource_url, @retrieve_params)
initialize_from(resp.data, opts)
end
def self.retrieve(id, opts={})

View File

@ -5,8 +5,8 @@ module Stripe
extend Stripe::APIOperations::List
def verify(params={}, opts={})
response, opts = request(:post, resource_url + '/verify', params, opts)
initialize_from(response, opts)
resp, opts = request(:post, resource_url + '/verify', params, opts)
initialize_from(resp.data, opts)
end
def resource_url

View File

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

View File

@ -20,41 +20,41 @@ module Stripe
# from the server
self.refresh
else
response, opts = request(:post, refund_url, params, opts)
initialize_from(response, opts)
resp, opts = request(:post, refund_url, params, opts)
initialize_from(resp.data, opts)
end
end
def capture(params={}, opts={})
response, opts = request(:post, capture_url, params, opts)
initialize_from(response, opts)
resp, opts = request(:post, capture_url, params, opts)
initialize_from(resp.data, opts)
end
def update_dispute(params={}, opts={})
response, opts = request(:post, dispute_url, params, opts)
initialize_from({ :dispute => response }, opts, true)
resp, opts = request(:post, dispute_url, params, opts)
initialize_from({ :dispute => resp.data }, opts, true)
dispute
end
def close_dispute(params={}, opts={})
response, opts = request(:post, close_dispute_url, params, opts)
initialize_from(response, opts)
resp, opts = request(:post, close_dispute_url, params, opts)
initialize_from(resp.data, opts)
end
def mark_as_fraudulent
params = {
:fraud_details => { :user_report => 'fraudulent' }
}
response, opts = request(:post, resource_url, params)
initialize_from(response, opts)
resp, opts = request(:post, resource_url, params)
initialize_from(resp.data, opts)
end
def mark_as_safe
params = {
:fraud_details => { :user_report => 'safe' }
}
response, opts = request(:post, resource_url, params)
initialize_from(response, opts)
resp, opts = request(:post, resource_url, params)
initialize_from(resp.data, opts)
end
private

View File

@ -38,20 +38,20 @@ module Stripe
end
def cancel_subscription(params={}, opts={})
response, opts = request(:delete, subscription_url, params, opts)
initialize_from({ :subscription => response }, opts, true)
resp, opts = request(:delete, subscription_url, params, opts)
initialize_from({ :subscription => resp.data }, opts, true)
subscription
end
def update_subscription(params={}, opts={})
response, opts = request(:post, subscription_url, params, opts)
initialize_from({ :subscription => response }, opts, true)
resp, opts = request(:post, subscription_url, params, opts)
initialize_from({ :subscription => resp.data }, opts, true)
subscription
end
def create_subscription(params={}, opts={})
response, opts = request(:post, subscriptions_url, params, opts)
initialize_from({ :subscription => response }, opts, true)
resp, opts = request(:post, subscriptions_url, params, opts)
initialize_from({ :subscription => resp.data }, opts, true)
subscription
end

View File

@ -1,12 +1,11 @@
module Stripe
class Dispute < APIResource
extend Stripe::APIOperations::List
extend Stripe::APIOperations::Create
include Stripe::APIOperations::Save
def close(params={}, opts={})
response, opts = request(:post, close_url, params, opts)
initialize_from(response, opts)
resp, opts = request(:post, close_url, params, opts)
initialize_from(resp.data, opts)
end
def close_url

View File

@ -3,14 +3,22 @@ module Stripe
# errors derive.
class StripeError < StandardError
attr_reader :message
attr_reader :http_status
# Response contains a StripeResponse object that has some basic information
# about the response that conveyed the error.
attr_accessor :response
# These fields are now available as part of #response and that usage should
# be preferred.
attr_reader :http_body
attr_reader :http_headers
attr_reader :http_status
attr_reader :json_body # equivalent to #data
attr_reader :request_id
attr_reader :json_body
def initialize(message=nil, http_status=nil, http_body=nil, json_body=nil,
http_headers=nil)
# Initializes a StripeError.
def initialize(message=nil, http_status: nil, http_body: nil, json_body: nil,
http_headers: nil)
@message = message
@http_status = http_status
@http_body = http_body
@ -49,9 +57,10 @@ module Stripe
class CardError < StripeError
attr_reader :param, :code
def initialize(message, param, code, http_status=nil, http_body=nil, json_body=nil,
http_headers=nil)
super(message, http_status, http_body, json_body, http_headers)
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)
@param = param
@code = code
end
@ -62,9 +71,10 @@ module Stripe
class InvalidRequestError < StripeError
attr_accessor :param
def initialize(message, param, http_status=nil, http_body=nil, json_body=nil,
http_headers=nil)
super(message, http_status, http_body, json_body, http_headers)
def initialize(message, param, 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)
@param = param
end
end

View File

@ -5,13 +5,13 @@ module Stripe
extend Stripe::APIOperations::Create
def self.upcoming(params, opts={})
response, opts = request(:get, upcoming_url, params, opts)
Util.convert_to_stripe_object(response, opts)
resp, opts = request(:get, upcoming_url, params, opts)
Util.convert_to_stripe_object(resp.data, opts)
end
def pay(opts={})
response, opts = request(:post, pay_url, {}, opts)
initialize_from(response, opts)
resp, opts = request(:post, pay_url, {}, opts)
initialize_from(resp.data, opts)
end
private

View File

@ -64,8 +64,8 @@ module Stripe
def retrieve(id, opts={})
id, retrieve_params = Util.normalize_id(id)
response, opts = request(:get,"#{resource_url}/#{CGI.escape(id)}", retrieve_params, opts)
Util.convert_to_stripe_object(response, opts)
resp, opts = request(:get,"#{resource_url}/#{CGI.escape(id)}", retrieve_params, opts)
Util.convert_to_stripe_object(resp.data, opts)
end
# Fetches the next page in the resource list (if there is one).

View File

@ -5,13 +5,13 @@ module Stripe
include Stripe::APIOperations::Save
def pay(params, opts={})
response, opts = request(:post, pay_url, params, opts)
initialize_from(response, opts)
resp, opts = request(:post, pay_url, params, opts)
initialize_from(resp.data, opts)
end
def return_order(params, opts={})
response, opts = request(:post, returns_url, params, opts)
Util.convert_to_stripe_object(response, opts)
resp, opts = request(:post, returns_url, params, opts)
Util.convert_to_stripe_object(resp.data, opts)
end
private

View File

@ -1,7 +1,7 @@
module Stripe
class Reversal < APIResource
include Stripe::APIOperations::Save
extend Stripe::APIOperations::List
include Stripe::APIOperations::Save
def resource_url
"#{Transfer.resource_url}/#{CGI.escape(transfer)}/reversals/#{CGI.escape(id)}"

View File

@ -4,8 +4,8 @@ module Stripe
include Stripe::APIOperations::Save
def verify(params={}, opts={})
response, opts = request(:post, resource_url + '/verify', params, opts)
initialize_from(response, opts)
resp, opts = request(:post, resource_url + '/verify', params, opts)
initialize_from(resp.data, opts)
end
end
end

396
lib/stripe/stripe_client.rb Normal file
View File

@ -0,0 +1,396 @@
module Stripe
# StripeClient executes requests against the Stripe API and allows a user to
# recover both a resource a call returns as well as a response object that
# contains information on the HTTP call.
class StripeClient
attr_accessor :conn
# Initializes a new StripeClient. Expects a Faraday connection object, and
# uses a default connection unless one is passed.
def initialize(conn = nil)
self.conn = conn || self.class.default_conn
@system_profiler = SystemProfiler.new
end
def self.active_client
Thread.current[:stripe_client] || default_client
end
def self.default_client
@default_client ||= StripeClient.new(default_conn)
end
# A default Faraday connection to be used when one isn't configured. This
# object should never be mutated, and instead instantiating your own
# connection and wrapping it in a StripeClient object should be preferred.
def self.default_conn
# We're going to keep connections around so that we can take advantage
# of connection re-use, so make sure that we have a separate connection
# object per thread.
Thread.current[:stripe_client_default_conn] ||= begin
conn = Faraday.new do |c|
c.use Faraday::Request::UrlEncoded
c.use Faraday::Response::RaiseError
c.adapter Faraday.default_adapter
end
if Stripe.verify_ssl_certs
conn.ssl.verify = true
conn.ssl.cert_store = Stripe.ca_store
else
conn.ssl.verify = false
unless @verify_ssl_warned
@verify_ssl_warned = true
$stderr.puts("WARNING: Running without SSL cert verification. " \
"You should never do this in production. " \
"Execute 'Stripe.verify_ssl_certs = true' to enable verification.")
end
end
conn
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, retry_count)
return false if retry_count >= Stripe.max_network_retries
# Retry on timeout-related problems (either on open or read).
return true if e.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)
if e.is_a?(Faraday::ClientError) && e.response
# 409 conflict
return true if e.response[:status] == 409
end
false
end
def self.sleep_time(retry_count)
# Apply exponential backoff with initial_network_retry_delay on the
# number of attempts so far as inputs. Do not allow the number to exceed
# max_network_retry_delay.
sleep_seconds = [Stripe.initial_network_retry_delay * (2 ** (retry_count - 1)), Stripe.max_network_retry_delay].min
# Apply some jitter by randomizing the value in the range of (sleep_seconds
# / 2) to (sleep_seconds).
sleep_seconds = sleep_seconds * (0.5 * (1 + rand()))
# But never sleep less than the base sleep seconds.
sleep_seconds = [Stripe.initial_network_retry_delay, sleep_seconds].max
sleep_seconds
end
# Executes the API call within the given block. Usage looks like:
#
# client = StripeClient.new
# charge, resp = client.request { Charge.create }
#
def request(&block)
@last_response = nil
old_stripe_client = Thread.current[:stripe_client]
Thread.current[:stripe_client] = self
begin
res = block.call
[res, @last_response]
ensure
Thread.current[:stripe_client] = old_stripe_client
end
end
def execute_request(method, url,
api_base: nil, api_key: nil, headers: {}, params: {})
api_base ||= Stripe.api_base
api_key ||= Stripe.api_key
check_api_key!(api_key)
params = Util.objects_to_ids(params)
url = api_url(url, api_base)
case method.to_s.downcase.to_sym
when :get, :head, :delete
# Make params into GET parameters
url += "#{URI.parse(url).query ? '&' : '?'}#{Util.encode_parameters(params)}" if params && params.any?
payload = nil
else
if headers[:content_type] && headers[:content_type] == "multipart/form-data"
payload = params
else
payload = Util.encode_parameters(params)
end
end
http_resp = execute_request_with_rescues(api_base, 0) do
conn.run_request(
method,
url,
payload,
# TODO: Convert RestClient-style parameters.
request_headers(api_key, method).update(headers)
) do |req|
req.options.open_timeout = Stripe.open_timeout
req.options.timeout = Stripe.read_timeout
end
end
begin
resp = StripeResponse.from_faraday_response(http_resp)
rescue JSON::ParserError
raise general_api_error(http_resp.code, http_resp.body)
end
# Allows StripeClient#request to return a response object to a caller.
@last_response = resp
[resp, api_key]
end
private
def api_url(url='', api_base=nil)
(api_base || Stripe.api_base) + url
end
def check_api_key!(api_key)
unless api_key
raise AuthenticationError.new('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.')
end
if api_key =~ /\s/
raise AuthenticationError.new('Your API key is invalid, as it contains ' \
'whitespace. (HINT: You can double-check your API key from the ' \
'Stripe web interface. See https://stripe.com/api for details, or ' \
'email support@stripe.com if you have any questions.)')
end
end
def execute_request_with_rescues(api_base, retry_count, &block)
begin
resp = block.call
# 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.
rescue => e
if self.class.should_retry?(e, retry_count)
retry_count = retry_count + 1
sleep self.class.sleep_time(retry_count)
retry
end
case e
when Faraday::ClientError
if e.response
handle_api_error(e.response)
else
handle_network_error(e, retry_count, api_base)
end
# Only handle errors when we know we can do so, and re-raise otherwise.
# This should be pretty infrequent.
else
raise
end
end
resp
end
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)
end
def handle_api_error(http_resp)
begin
resp = StripeResponse.from_faraday_hash(http_resp)
error = resp.data[:error]
unless error && error.is_a?(Hash)
raise StripeError.new("Indeterminate error")
end
rescue JSON::ParserError, StripeError
raise general_api_error(http_resp[:status], http_resp[:body])
end
case resp.http_status
when 400, 404
error = InvalidRequestError.new(
error[:message], error[:param],
http_status: resp.http_status, http_body: resp.http_body,
json_body: resp.data, http_headers: resp.http_headers
)
when 401
error = AuthenticationError.new(
error[:message],
http_status: resp.http_status, http_body: resp.http_body,
json_body: resp.data, http_headers: resp.http_headers
)
when 402
error = CardError.new(
error[:message], error[:param], error[:code],
http_status: resp.http_status, http_body: resp.http_body,
json_body: resp.data, http_headers: resp.http_headers
)
when 403
error = PermissionError.new(
error[:message],
http_status: resp.http_status, http_body: resp.http_body,
json_body: resp.data, http_headers: resp.http_headers
)
when 429
error = RateLimitError.new(
error[:message],
http_status: resp.http_status, http_body: resp.http_body,
json_body: resp.data, http_headers: resp.http_headers
)
else
error = APIError.new(
error[:message],
http_status: resp.http_status, http_body: resp.http_body,
json_body: resp.data, http_headers: resp.http_headers
)
end
error.response = resp
raise(error)
end
def handle_network_error(e, retry_count, api_base=nil)
case e
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."
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."
when Faraday::TimeoutError
api_base = Stripe.api_base unless 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."
else
message = "Unexpected error communicating with Stripe. " \
"If this problem persists, let us know at support@stripe.com."
end
if retry_count > 0
message += " Request was retried #{retry_count} times."
end
raise APIConnectionError.new(message + "\n\n(Network error: #{e.message})")
end
def request_headers(api_key, method)
headers = {
'User-Agent' => "Stripe/v1 RubyBindings/#{Stripe::VERSION}",
'Authorization' => "Bearer #{api_key}",
'Content-Type' => 'application/x-www-form-urlencoded'
}
# It is only safe to retry network failures on post and delete
# requests if we add an Idempotency-Key header
if [:post, :delete].include?(method) && Stripe.max_network_retries > 0
headers['Idempotency-Key'] ||= SecureRandom.uuid
end
headers['Stripe-Version'] = Stripe.api_version if Stripe.api_version
headers['Stripe-Account'] = Stripe.stripe_account if Stripe.stripe_account
user_agent = @system_profiler.user_agent
begin
headers.update(
'X-Stripe-Client-User-Agent' => JSON.generate(user_agent)
)
rescue => e
headers.update(
'X-Stripe-Client-Raw-User-Agent' => user_agent.inspect,
:error => "#{e} (#{e.class})"
)
end
headers
end
# SystemProfiler extracts information about the system that we're running
# in so that we can generate a rich user agent header to help debug
# integrations.
class SystemProfiler
def self.get_uname
if File.exist?('/proc/version')
File.read('/proc/version').strip
else
case RbConfig::CONFIG['host_os']
when /linux|darwin|bsd|sunos|solaris|cygwin/i
get_uname_from_system
when /mswin|mingw/i
get_uname_from_system_ver
else
"unknown platform"
end
end
end
def self.get_uname_from_system
(`uname -a 2>/dev/null` || '').strip
rescue Errno::ENOENT
"uname executable not found"
rescue Errno::ENOMEM # couldn't create subprocess
"uname lookup failed"
end
def self.get_uname_from_system_ver
(`ver` || '').strip
rescue Errno::ENOENT
"ver executable not found"
rescue Errno::ENOMEM # couldn't create subprocess
"uname lookup failed"
end
def initialize
@uname = self.class.get_uname
end
def user_agent
lang_version = "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})"
{
:bindings_version => Stripe::VERSION,
:lang => 'ruby',
:lang_version => lang_version,
:platform => RUBY_PLATFORM,
:engine => defined?(RUBY_ENGINE) ? RUBY_ENGINE : '',
:publisher => 'stripe',
:uname => @uname,
:hostname => Socket.gethostname,
}
end
end
end
end

View File

@ -0,0 +1,48 @@
module Stripe
# StripeResponse encapsulates some vitals of a response that came back from
# the Stripe API.
class StripeResponse
# The data contained by the HTTP body of the response deserialized from
# JSON.
attr_accessor :data
# The raw HTTP body of the response.
attr_accessor :http_body
# A Hash of the HTTP headers of the response.
attr_accessor :http_headers
# The integer HTTP status code of the response.
attr_accessor :http_status
# The Stripe request ID of the response.
attr_accessor :request_id
# Initializes a StripeResponse object from a Hash like the kind returned as
# part of a Faraday exception.
#
# This may throw JSON::ParserError if the response body is not valid JSON.
def self.from_faraday_hash(http_resp)
resp = StripeResponse.new
resp.data = JSON.parse(http_resp[:body], symbolize_names: true)
resp.http_body = http_resp[:body]
resp.http_headers = http_resp[:headers]
resp.http_status = http_resp[:status]
resp.request_id = http_resp[:headers]["Request-Id"]
resp
end
# Initializes a StripeResponse object from a Faraday HTTP response object.
#
# This may throw JSON::ParserError if the response body is not valid JSON.
def self.from_faraday_response(http_resp)
resp = StripeResponse.new
resp.data = JSON.parse(http_resp.body, symbolize_names: true)
resp.http_body = http_resp.body
resp.http_headers = http_resp.headers
resp.http_status = http_resp.status
resp.request_id = http_resp.headers["Request-Id"]
resp
end
end
end

View File

@ -5,8 +5,8 @@ module Stripe
include Stripe::APIOperations::Save
def cancel
response, api_key = self.request(:post, cancel_url)
initialize_from(response, api_key)
resp, api_key = self.request(:post, cancel_url)
initialize_from(resp.data, api_key)
end
def cancel_url

View File

@ -68,18 +68,18 @@ module Stripe
#
# ==== Attributes
#
# * +resp+ - Hash of fields and values to be converted into a StripeObject.
# * +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(resp, opts)
case resp
def self.convert_to_stripe_object(data, opts)
case data
when Array
resp.map { |i| convert_to_stripe_object(i, opts) }
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(resp[:object], StripeObject).construct_from(resp, opts)
object_classes.fetch(data[:object], StripeObject).construct_from(data, opts)
else
resp
data
end
end

1409
spec/fixtures.json Normal file

File diff suppressed because it is too large Load Diff

1153
spec/fixtures.yaml Normal file

File diff suppressed because it is too large Load Diff

19949
spec/spec.json Normal file

File diff suppressed because it is too large Load Diff

15504
spec/spec.yaml Normal file

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,7 @@ spec = Gem::Specification.new do |s|
s.homepage = 'https://stripe.com/docs/api/ruby'
s.license = 'MIT'
s.add_dependency('rest-client', '>= 1.4', '< 4.0')
s.add_dependency('faraday', '~> 0')
s.files = `git ls-files`.split("\n")
s.test_files = `git ls-files -- test/*`.split("\n")

29
test/api_fixtures.rb Normal file
View File

@ -0,0 +1,29 @@
# APIFixtures loads fixture data generated by the core Stripe API so that we
# can have slightly more accurate and up-to-date resource information in our
# tests.
class APIFixtures
def initialize
@fixtures = ::JSON.parse(File.read("#{PROJECT_ROOT}/spec/fixtures.json"),
symbolize_names: true)
freeze_recursively(@fixtures)
end
def [](name)
@fixtures[name]
end
def fetch(*args)
@fixtures.fetch(*args)
end
private
def freeze_recursively(data)
data.each do |k, v|
if v.is_a?(Hash)
freeze_recursively(v)
end
end
data.freeze
end
end

125
test/api_stub_helpers.rb Normal file
View File

@ -0,0 +1,125 @@
require "json"
# Provides a set of helpers for a test suite that help to mock out the Stripe
# API.
module APIStubHelpers
protected
# Uses Webmock to stub out the Stripe API for testing purposes. The stub will
# by default respond on any routes that are defined in the bundled OpenAPI
# spec with generated response data.
#
# An `override_app` can be specified to get finer grain control over how a
# stubbed endpoint responds. It can be used to modify generated responses,
# mock expectations, or even to override the default stub completely.
def stub_api
stub_request(:any, /^#{Stripe.api_base}/).to_rack(new_api_stub)
end
def stub_connect
stub_request(:any, /^#{Stripe.connect_base}/).to_return(:body => "{}")
end
private
# APIStubMiddleware intercepts a response generated by Committee's stubbing
# middleware, and tries to replace it with a better version from a set of
# sample fixtures data generated from Stripe's core API service.
class APIStubMiddleware
API_FIXTURES = APIFixtures.new
def initialize(app)
@app = app
end
def call(env)
# We use a vendor specific prefix (`x-resourceId`) embedded in the schema
# of any resource in our spec to identify it (e.g. "charge"). This allows
# us to cross-reference that response with some data that we might find
# in our fixtures file so that we can respond with a higher fidelity
# response.
schema = env["committee.response_schema"]
resource_id = schema.data["x-resourceId"] || ""
if data = API_FIXTURES[resource_id.to_sym]
# standard top-level API resource
data = fixturize_lists_recursively(schema, data)
env["committee.response"] = data
elsif schema.properties["object"].enum == ["list"]
# top level list (like from a list endpoint)
data = fixturize_list(schema, env["committee.response"])
env["committee.response"] = data
else
raise "no fixture for: #{resource_id}"
end
@app.call(env)
end
private
# If schema looks like a Stripe list object, then we look up the resource
# that the list is supposed to include and inject it into `data` as a
# fixture. Also calls into that other schema recursively so that sublists
# within it will also be assigned a fixture.
def fixturize_list(schema, data)
object_schema = schema.properties["object"]
if object_schema && object_schema.enum == ["list"]
subschema = schema.properties["data"].items
resource_id = subschema.data["x-resourceId"] || ""
if subdata = API_FIXTURES[resource_id.to_sym]
subdata = fixturize_lists_recursively(subschema, subdata)
data = data ? data.dup : {}
data[:data] = [subdata]
end
end
data
end
# Examines each of the given schema's properties and calls #fixturize_list
# on them so that any sublists will be populated with sample fixture data.
def fixturize_lists_recursively(schema, data)
data = data.dup
schema.properties.each do |key, subschema|
data[key.to_sym] = fixturize_list(subschema, data[key.to_sym])
end
data
end
end
# A descendant of the standard `Sinatra::Base` that we can use to enrich
# certain types of responses.
class APIStubApp < Sinatra::Base
not_found do
"endpoint not found in API stub: #{request.request_method} #{request.path_info}"
end
end
# Finds the latest OpenAPI specification in ROOT/spec/ and parses it for
# use with Committee.
def self.initialize_spec
schema_data = ::JSON.parse(File.read("#{PROJECT_ROOT}/spec/spec.json"))
driver = Committee::Drivers::OpenAPI2.new
driver.parse(schema_data)
end
# Creates a new Rack app with Committee middleware it.
def new_api_stub
Rack::Builder.new {
use Committee::Middleware::RequestValidation, schema: @@spec,
params_response: true, strict: true
use Committee::Middleware::Stub, schema: @@spec,
call: true
use APIStubMiddleware
run APIStubApp.new
}
end
# Parse and initialize the OpenAPI spec only once for the entire test suite.
@@spec = initialize_spec
# The default override app. Doesn't respond on any route so generated
# responses will always take precedence.
@@default_override_app = Sinatra.new
end

View File

@ -2,50 +2,25 @@ require File.expand_path('../../test_helper', __FILE__)
module Stripe
class AccountTest < Test::Unit::TestCase
should "be retrievable" do
resp = make_account({
:charges_enabled => false,
:details_submitted => false,
:email => "test+bindings@stripe.com",
})
stub_request(:get, "#{Stripe.api_base}/v1/account").
to_return(body: JSON.generate(resp))
a = Stripe::Account.retrieve
assert_equal "test+bindings@stripe.com", a.email
assert !a.charges_enabled
assert !a.details_submitted
FIXTURE = API_FIXTURES.fetch(:account)
should "be listable" do
accounts = Stripe::Account.list
assert_requested :get, "#{Stripe.api_base}/v1/accounts"
assert accounts.data.kind_of?(Array)
assert accounts.data[0].kind_of?(Stripe::Account)
end
should "be retrievable via plural endpoint" do
resp = make_account({
:charges_enabled => false,
:details_submitted => false,
:email => "test+bindings@stripe.com",
})
stub_request(:get, "#{Stripe.api_base}/v1/accounts/acct_foo").
to_return(body: JSON.generate(resp))
a = Stripe::Account.retrieve('acct_foo')
assert_equal "test+bindings@stripe.com", a.email
assert !a.charges_enabled
assert !a.details_submitted
should "be retrievable using singular endpoint" do
account = Stripe::Account.retrieve
assert_requested :get, "#{Stripe.api_base}/v1/account"
assert account.kind_of?(Stripe::Account)
end
should "be retrievable using an API key as the only argument" do
account = mock
Stripe::Account.expects(:new).once.with(nil, {:api_key => 'sk_foobar'}).returns(account)
account.expects(:refresh).once
Stripe::Account.retrieve('sk_foobar')
end
should "allow access to keys by method" do
account = Stripe::Account.construct_from(make_account({
:keys => {
:publishable => 'publishable-key',
:secret => 'secret-key',
}
}))
assert_equal 'publishable-key', account.keys.publishable
assert_equal 'secret-key', account.keys.secret
should "be retrievable using plural endpoint" do
account = Stripe::Account.retrieve(FIXTURE[:id])
assert_requested :get, "#{Stripe.api_base}/v1/accounts/#{FIXTURE[:id]}"
assert account.kind_of?(Stripe::Account)
end
should "be rejectable" do
@ -60,210 +35,30 @@ module Stripe
account.reject(:reason => 'fraud')
end
should "be creatable" do
account = Stripe::Account.create(:metadata => {})
assert_requested :post, "#{Stripe.api_base}/v1/accounts"
assert account.kind_of?(Stripe::Account)
end
should "be saveable" do
resp = {
:id => 'acct_foo',
:legal_entity => {
:address => {
:line1 => '1 Two Three'
}
}
}
stub_request(:get, "#{Stripe.api_base}/v1/accounts/acct_foo").
to_return(body: JSON.generate(resp))
stub_request(:post, "#{Stripe.api_base}/v1/accounts/acct_foo").
to_return(body: JSON.generate(resp))
a = Stripe::Account.retrieve('acct_foo')
a.legal_entity.first_name = 'Bob'
a.legal_entity.address.line1 = '2 Three Four'
a.save
account = Stripe::Account.retrieve(FIXTURE[:id])
account.metadata['key'] = 'value'
account.save
assert_requested :post, "#{Stripe.api_base}/v1/accounts/#{FIXTURE[:id]}"
end
should "be updatable" do
resp = {
:id => 'acct_foo',
:business_name => 'ACME Corp',
}
stub_request(:post, "#{Stripe.api_base}/v1/accounts/acct_foo").
to_return(body: JSON.generate(resp))
a = Stripe::Account.update('acct_foo', :business_name => "ACME Corp")
assert_equal('ACME Corp', a.business_name)
should "be updateable" do
account = Stripe::Account.update(FIXTURE[:id], metadata: {foo: 'bar'})
assert_requested :post, "#{Stripe.api_base}/v1/accounts/#{FIXTURE[:id]}"
assert account.kind_of?(Stripe::Account)
end
should 'disallow direct overrides of legal_entity' do
account = Stripe::Account.construct_from(make_account({
:keys => {
:publishable => 'publishable-key',
:secret => 'secret-key',
},
:legal_entity => {
:first_name => 'Bling'
}
}))
assert_raise NoMethodError do
account.legal_entity = {:first_name => 'Blah'}
end
account.legal_entity.first_name = 'Blah'
end
should "be able to deauthorize an account" do
resp = {:id => 'acct_1234', :email => "test+bindings@stripe.com", :charge_enabled => false, :details_submitted => false}
stub_request(:get, "#{Stripe.api_base}/v1/account").
to_return(body: JSON.generate(resp))
a = Stripe::Account.retrieve
stub_request(:post, "#{Stripe.connect_base}/oauth/deauthorize").
with(body: { 'client_id' => 'ca_1234', 'stripe_user_id' => a.id}).
to_return(body: JSON.generate({ 'stripe_user_id' => a.id }))
a.deauthorize('ca_1234', 'sk_test_1234')
end
should "reject nil api keys" do
assert_raise TypeError do
Stripe::Account.retrieve(nil)
end
assert_raise TypeError do
Stripe::Account.retrieve(:api_key => nil)
end
end
should "be able to create a bank account" do
resp = {
:id => 'acct_1234',
:external_accounts => {
:object => "list",
:resource_url => "/v1/accounts/acct_1234/external_accounts",
:data => [],
}
}
stub_request(:get, "#{Stripe.api_base}/v1/account").
to_return(body: JSON.generate(resp))
a = Stripe::Account.retrieve
stub_request(:post, "#{Stripe.api_base}/v1/accounts/acct_1234/external_accounts").
with(body: { :external_account => 'btok_1234' }).
to_return(body: JSON.generate(resp))
a.external_accounts.create({:external_account => 'btok_1234'})
end
should "be able to retrieve a bank account" do
resp = {
:id => 'acct_1234',
:external_accounts => {
:object => "list",
:resource_url => "/v1/accounts/acct_1234/external_accounts",
:data => [{
:id => "ba_1234",
:object => "bank_account",
}],
}
}
stub_request(:get, "#{Stripe.api_base}/v1/account").
to_return(body: JSON.generate(resp))
a = Stripe::Account.retrieve
assert_equal(BankAccount, a.external_accounts.data[0].class)
end
should "#serialize_params an a new additional_owners" do
obj = Stripe::Util.convert_to_stripe_object({
:object => "account",
:legal_entity => Stripe::StripeObject.construct_from({
}),
}, {})
obj.legal_entity.additional_owners = [
{ :first_name => "Joe" },
{ :first_name => "Jane" },
]
expected = {
:legal_entity => {
:additional_owners => {
"0" => { :first_name => "Joe" },
"1" => { :first_name => "Jane" },
}
}
}
assert_equal(expected, obj.serialize_params)
end
should "#serialize_params on an partially changed additional_owners" do
obj = Stripe::Util.convert_to_stripe_object({
:object => "account",
:legal_entity => {
:additional_owners => [
Stripe::StripeObject.construct_from({
:first_name => "Joe"
}),
Stripe::StripeObject.construct_from({
:first_name => "Jane"
}),
]
}
}, {})
obj.legal_entity.additional_owners[1].first_name = "Stripe"
expected = {
:legal_entity => {
:additional_owners => {
"1" => { :first_name => "Stripe" }
}
}
}
assert_equal(expected, obj.serialize_params)
end
should "#serialize_params on an unchanged additional_owners" do
obj = Stripe::Util.convert_to_stripe_object({
:object => "account",
:legal_entity => {
:additional_owners => [
Stripe::StripeObject.construct_from({
:first_name => "Joe"
}),
Stripe::StripeObject.construct_from({
:first_name => "Jane"
}),
]
}
}, {})
expected = {
:legal_entity => {
:additional_owners => {}
}
}
assert_equal(expected, obj.serialize_params)
end
# Note that the empty string that we send for this one has a special
# meaning for the server, which interprets it as an array unset.
should "#serialize_params on an unset additional_owners" do
obj = Stripe::Util.convert_to_stripe_object({
:object => "account",
:legal_entity => {
:additional_owners => [
Stripe::StripeObject.construct_from({
:first_name => "Joe"
}),
Stripe::StripeObject.construct_from({
:first_name => "Jane"
}),
]
}
}, {})
obj.legal_entity.additional_owners = nil
expected = {
:legal_entity => {
:additional_owners => ""
}
}
assert_equal(expected, obj.serialize_params)
should "be deletable" do
account = Stripe::Account.retrieve(FIXTURE[:id])
account = account.delete
assert_requested :delete, "#{Stripe.api_base}/v1/accounts/#{FIXTURE[:id]}"
assert account.kind_of?(Stripe::Account)
end
context "#bank_account=" do
@ -271,8 +66,8 @@ module Stripe
old_stderr = $stderr
$stderr = StringIO.new
begin
a = Stripe::Account.new("test_account")
a.bank_account = "tok_123"
account = Stripe::Account.retrieve(FIXTURE[:id])
account.bank_account = "tok_123"
message = "NOTE: Stripe::Account#bank_account= is " +
"deprecated; use #external_account= instead"
assert_match Regexp.new(message), $stderr.string
@ -281,5 +76,129 @@ module Stripe
end
end
end
context "#deauthorize" do
should "deauthorize an account" do
account = Stripe::Account.retrieve(FIXTURE[:id])
# Unfortunately, the OpenAPI spec doesn't yet cover anything under the
# Connect endpoints, so for just stub this out with Webmock.
stub_request(:post, "#{Stripe.connect_base}/oauth/deauthorize").
with(body: { 'client_id' => 'ca_1234', 'stripe_user_id' => account.id}).
to_return(body: JSON.generate({ 'stripe_user_id' => account.id }))
account.deauthorize('ca_1234', 'sk_test_1234')
end
end
context "#legal_entity=" do
should 'disallow direct overrides' do
account = Stripe::Account.retrieve(FIXTURE[:id])
assert_raise NoMethodError do
account.legal_entity = {:first_name => 'Blah'}
end
account.legal_entity.first_name = 'Blah'
end
end
context "#serialize_params" do
should "serialize an a new additional_owners" do
obj = Stripe::Util.convert_to_stripe_object({
:object => "account",
:legal_entity => Stripe::StripeObject.construct_from({
}),
}, {})
obj.legal_entity.additional_owners = [
{ :first_name => "Joe" },
{ :first_name => "Jane" },
]
expected = {
:legal_entity => {
:additional_owners => {
"0" => { :first_name => "Joe" },
"1" => { :first_name => "Jane" },
}
}
}
assert_equal(expected, obj.serialize_params)
end
should "serialize on an partially changed additional_owners" do
obj = Stripe::Util.convert_to_stripe_object({
:object => "account",
:legal_entity => {
:additional_owners => [
Stripe::StripeObject.construct_from({
:first_name => "Joe"
}),
Stripe::StripeObject.construct_from({
:first_name => "Jane"
}),
]
}
}, {})
obj.legal_entity.additional_owners[1].first_name = "Stripe"
expected = {
:legal_entity => {
:additional_owners => {
"1" => { :first_name => "Stripe" }
}
}
}
assert_equal(expected, obj.serialize_params)
end
should "serialize on an unchanged additional_owners" do
obj = Stripe::Util.convert_to_stripe_object({
:object => "account",
:legal_entity => {
:additional_owners => [
Stripe::StripeObject.construct_from({
:first_name => "Joe"
}),
Stripe::StripeObject.construct_from({
:first_name => "Jane"
}),
]
}
}, {})
expected = {
:legal_entity => {
:additional_owners => {}
}
}
assert_equal(expected, obj.serialize_params)
end
# Note that the empty string that we send for this one has a special
# meaning for the server, which interprets it as an array unset.
should "serialize on an unset additional_owners" do
obj = Stripe::Util.convert_to_stripe_object({
:object => "account",
:legal_entity => {
:additional_owners => [
Stripe::StripeObject.construct_from({
:first_name => "Joe"
}),
Stripe::StripeObject.construct_from({
:first_name => "Jane"
}),
]
}
}, {})
obj.legal_entity.additional_owners = nil
expected = {
:legal_entity => {
:additional_owners => ""
}
}
assert_equal(expected, obj.serialize_params)
end
end
end
end

View File

@ -2,9 +2,17 @@ require File.expand_path('../../test_helper', __FILE__)
module Stripe
class AlipayAccountTest < Test::Unit::TestCase
should "raise if accessing Stripe::Alipay.account directly" do
FIXTURE = API_FIXTURES.fetch(:alipay_account)
should "raise on #retrieve" do
assert_raises NotImplementedError do
Stripe::AlipayAccount.retrieve "card_12345"
Stripe::AlipayAccount.retrieve FIXTURE[:id]
end
end
should "raise on #update" do
assert_raises NotImplementedError do
Stripe::AlipayAccount.update FIXTURE[:id], {}
end
end
end

View File

@ -73,33 +73,10 @@ module Stripe
end
end
should "specifying invalid api credentials should raise an exception" do
Stripe.api_key = "invalid"
assert_raises Stripe::AuthenticationError do
stub_request(:get, "#{Stripe.api_base}/v1/customers/failing_customer").
to_return(body: JSON.generate(make_invalid_api_key_error), status: 401)
Stripe::Customer.retrieve("failing_customer")
end
end
should "AuthenticationErrors should have an http status, http body, and JSON body" do
Stripe.api_key = "invalid"
begin
stub_request(:get, "#{Stripe.api_base}/v1/customers/failing_customer").
to_return(body: JSON.generate(make_invalid_api_key_error), status: 401)
Stripe::Customer.retrieve("failing_customer")
rescue Stripe::AuthenticationError => e
assert_equal(401, e.http_status)
assert_equal(true, !!e.http_body)
assert_equal(true, !!e.json_body[:error][:message])
assert_equal(make_invalid_api_key_error[:error][:message], e.json_body[:error][:message])
end
end
should "send expand on fetch properly" do
stub_request(:get, "#{Stripe.api_base}/v1/charges/ch_test_charge").
with(query: { "expand" => ["customer"] }).
to_return(body: JSON.generate(make_charge))
to_return(body: JSON.generate(API_FIXTURES.fetch(:charge)))
Stripe::Charge.retrieve({:id => 'ch_test_charge', :expand => [:customer]})
end
@ -107,7 +84,7 @@ module Stripe
should "preserve expand across refreshes" do
stub_request(:get, "#{Stripe.api_base}/v1/charges/ch_test_charge").
with(query: { "expand" => ["customer"] }).
to_return(body: JSON.generate(make_charge))
to_return(body: JSON.generate(API_FIXTURES.fetch(:charge)))
ch = Stripe::Charge.retrieve({:id => 'ch_test_charge', :expand => [:customer]})
ch.refresh
@ -115,69 +92,22 @@ module Stripe
should "send expand when fetching through ListObject" do
stub_request(:get, "#{Stripe.api_base}/v1/customers/c_test_customer").
to_return(body: JSON.generate(make_customer))
to_return(body: JSON.generate(API_FIXTURES.fetch(:customer)))
stub_request(:get, "#{Stripe.api_base}/v1/customers/c_test_customer/sources/cc_test_card").
with(query: { "expand" => ["customer"] }).
to_return(body: JSON.generate(make_customer))
to_return(body: JSON.generate(API_FIXTURES.fetch(:customer)))
customer = Stripe::Customer.retrieve('c_test_customer')
customer.sources.retrieve({:id => 'cc_test_card', :expand => [:customer]})
end
should "send stripe account as header when set" do
stripe_account = "acct_0000"
stub_request(:post, "#{Stripe.api_base}/v1/charges").
with(headers: {"Stripe-Account" => stripe_account}).
to_return(body: JSON.generate(make_customer))
Stripe::Charge.create({:card => {:number => '4242424242424242'}},
{:stripe_account => stripe_account, :api_key => 'sk_test_local'})
end
should "not send stripe account as header when not set" do
stub_request(:post, "#{Stripe.api_base}/v1/charges").
with { |req|
req.headers["Stripe-Account"].nil?
}.to_return(body: JSON.generate(make_charge))
Stripe::Charge.create({:card => {:number => '4242424242424242'}},
'sk_test_local')
end
should "handle error response with empty body" do
stub_request(:post, "#{Stripe.api_base}/v1/charges").
to_return(body: '', status: 500)
e = assert_raises Stripe::APIError do
Stripe::Charge.create
end
assert_equal 'Invalid response object from API: "" (HTTP response code was 500)', e.message
end
should "handle error response with non-object error value" do
stub_request(:post, "#{Stripe.api_base}/v1/charges").
to_return(body: JSON.generate({ error: "foo" }), status: 500)
e = assert_raises Stripe::APIError do
Stripe::Charge.create
end
assert_equal 'Invalid response object from API: "{\"error\":\"foo\"}" (HTTP response code was 500)', e.message
end
should "have default open and read timeouts" do
assert_equal Stripe.open_timeout, 30
assert_equal Stripe.read_timeout, 80
end
context "when specifying per-object credentials" do
context "with no global API key set" do
should "use the per-object credential when creating" do
stub_request(:post, "#{Stripe.api_base}/v1/charges").
with(headers: {"Authorization" => "Bearer sk_test_local"}).
to_return(body: JSON.generate(make_charge))
to_return(body: JSON.generate(API_FIXTURES.fetch(:charge)))
Stripe::Charge.create({:card => {:number => '4242424242424242'}},
'sk_test_local')
@ -196,7 +126,7 @@ module Stripe
should "use the per-object credential when creating" do
stub_request(:post, "#{Stripe.api_base}/v1/charges").
with(headers: {"Authorization" => "Bearer local"}).
to_return(body: JSON.generate(make_charge))
to_return(body: JSON.generate(API_FIXTURES.fetch(:charge)))
Stripe::Charge.create({:card => {:number => '4242424242424242'}},
'local')
@ -205,10 +135,10 @@ module Stripe
should "use the per-object credential when retrieving and making other calls" do
stub_request(:get, "#{Stripe.api_base}/v1/charges/ch_test_charge").
with(headers: {"Authorization" => "Bearer local"}).
to_return(body: JSON.generate(make_charge))
to_return(body: JSON.generate(API_FIXTURES.fetch(:charge)))
stub_request(:post, "#{Stripe.api_base}/v1/charges/ch_test_charge/refunds").
with(headers: {"Authorization" => "Bearer local"}).
to_return(body: JSON.generate(make_refund))
to_return(body: JSON.generate(API_FIXTURES.fetch(:refund)))
ch = Stripe::Charge.retrieve('ch_test_charge', 'local')
ch.refunds.create
@ -217,119 +147,43 @@ module Stripe
end
context "with valid credentials" do
should "send along the idempotency-key header" do
stub_request(:post, "#{Stripe.api_base}/v1/charges").
with(headers: {"Idempotency-Key" => "bar"}).
to_return(body: JSON.generate(make_charge))
Stripe::Charge.create({:card => {:number => '4242424242424242'}}, {
:idempotency_key => 'bar',
:api_key => 'local',
})
end
should "urlencode values in GET params" do
stub_request(:get, "#{Stripe.api_base}/v1/charges").
with(query: { customer: "test customer" }).
to_return(body: JSON.generate(make_charge_array))
to_return(body: JSON.generate({
data: [API_FIXTURES.fetch(:charge)]
}))
charges = Stripe::Charge.list(:customer => 'test customer').data
assert charges.kind_of? Array
end
should "construct URL properly with base query parameters" do
response = JSON.generate(make_invoice_customer_array)
stub_request(:get, "#{Stripe.api_base}/v1/invoices").
with(query: { customer: "test_customer" }).
to_return(body: response)
to_return(body: JSON.generate({
data: [API_FIXTURES.fetch(:invoice)],
url: "/v1/invoices"
}))
invoices = Stripe::Invoice.list(:customer => 'test_customer')
stub_request(:get, "#{Stripe.api_base}/v1/invoices").
with(query: { customer: "test_customer", paid: "true" }).
to_return(body: response)
to_return(body: JSON.generate({
data: [API_FIXTURES.fetch(:invoice)],
url: "/v1/invoices"
}))
invoices.list(:paid => true)
end
should "a 400 should give an InvalidRequestError with http status, body, and JSON body" do
stub_request(:post, "#{Stripe.api_base}/v1/charges").
to_return(body: JSON.generate(make_missing_id_error), status: 400)
begin
Stripe::Charge.create
rescue Stripe::InvalidRequestError => e
assert_equal(400, e.http_status)
assert_equal(true, !!e.http_body)
assert_equal(true, e.json_body.kind_of?(Hash))
end
end
should "a 401 should give an AuthenticationError with http status, body, and JSON body" do
stub_request(:post, "#{Stripe.api_base}/v1/charges").
to_return(body: JSON.generate(make_missing_id_error), status: 401)
begin
Stripe::Charge.create
rescue Stripe::AuthenticationError => e
assert_equal(401, e.http_status)
assert_equal(true, !!e.http_body)
assert_equal(true, e.json_body.kind_of?(Hash))
end
end
should "a 402 should give a CardError with http status, body, and JSON body" do
stub_request(:post, "#{Stripe.api_base}/v1/charges").
to_return(body: JSON.generate(make_missing_id_error), status: 402)
begin
Stripe::Charge.create
rescue Stripe::CardError => e
assert_equal(402, e.http_status)
assert_equal(true, !!e.http_body)
assert_equal(true, e.json_body.kind_of?(Hash))
end
end
should "a 403 should give a PermissionError with http status, body, and JSON body" do
stub_request(:post, "#{Stripe.api_base}/v1/charges").
to_return(body: JSON.generate(make_missing_id_error), status: 403)
begin
Stripe::Charge.create
rescue Stripe::PermissionError => e
assert_equal(403, e.http_status)
assert_equal(true, !!e.http_body)
assert_equal(true, e.json_body.kind_of?(Hash))
end
end
should "a 404 should give an InvalidRequestError with http status, body, and JSON body" do
stub_request(:post, "#{Stripe.api_base}/v1/charges").
to_return(body: JSON.generate(make_missing_id_error), status: 404)
begin
Stripe::Charge.create
rescue Stripe::InvalidRequestError => e
assert_equal(404, e.http_status)
assert_equal(true, !!e.http_body)
assert_equal(true, e.json_body.kind_of?(Hash))
end
end
should "a 429 should give a RateLimitError with http status, body, and JSON body" do
stub_request(:post, "#{Stripe.api_base}/v1/charges").
to_return(body: JSON.generate(make_missing_id_error), status: 429)
begin
Stripe::Charge.create
rescue Stripe::RateLimitError => e
assert_equal(429, e.http_status)
assert_equal(true, !!e.http_body)
assert_equal(true, e.json_body.kind_of?(Hash))
end
end
should "setting a nil value for a param should exclude that param from the request" do
stub_request(:get, "#{Stripe.api_base}/v1/charges").
with(query: { offset: 5, sad: false }).
to_return(body: JSON.generate({ :count => 1, :data => [make_charge] }))
to_return(body: JSON.generate({ :count => 1, :data => [API_FIXTURES.fetch(:charge)] }))
Stripe::Charge.list(:count => nil, :offset => 5, :sad => false)
stub_request(:post, "#{Stripe.api_base}/v1/charges").
with(body: { 'amount' => '50', 'currency' => 'usd' }).
to_return(body: JSON.generate({ :count => 1, :data => [make_charge] }))
to_return(body: JSON.generate({ :count => 1, :data => [API_FIXTURES.fetch(:charge)] }))
Stripe::Charge.create(:amount => 50, :currency => 'usd', :card => { :number => nil })
end
@ -348,27 +202,27 @@ module Stripe
should "making a GET request with parameters should have a query string and no body" do
stub_request(:get, "#{Stripe.api_base}/v1/charges").
with(query: { limit: 1 }).
to_return(body: JSON.generate({ :data => [make_charge] }))
to_return(body: JSON.generate({ :data => [API_FIXTURES.fetch(:charge)] }))
Stripe::Charge.list({ :limit => 1 })
end
should "making a POST request with parameters should have a body and no query string" do
stub_request(:post, "#{Stripe.api_base}/v1/charges").
with(body: {'amount' => '100', 'currency' => 'usd', 'card' => 'sc_token'}).
to_return(body: JSON.generate(make_charge))
to_return(body: JSON.generate(API_FIXTURES.fetch(:charge)))
Stripe::Charge.create({ :amount => 100, :currency => 'usd', :card => 'sc_token' })
end
should "loading an object should issue a GET request" do
stub_request(:get, "#{Stripe.api_base}/v1/customers/test_customer").
to_return(body: JSON.generate(make_customer))
to_return(body: JSON.generate(API_FIXTURES.fetch(:customer)))
c = Stripe::Customer.new("test_customer")
c.refresh
end
should "using array accessors should be the same as the method interface" do
stub_request(:get, "#{Stripe.api_base}/v1/customers/test_customer").
to_return(body: JSON.generate(make_customer))
to_return(body: JSON.generate(API_FIXTURES.fetch(:customer)))
c = Stripe::Customer.new("test_customer")
c.refresh
assert_equal c.created, c[:created]
@ -380,7 +234,7 @@ module Stripe
should "accessing a property other than id or parent on an unfetched object should fetch it" do
stub_request(:get, "#{Stripe.api_base}/v1/charges").
with(query: { customer: "test_customer" }).
to_return(body: JSON.generate(make_customer))
to_return(body: JSON.generate(API_FIXTURES.fetch(:customer)))
c = Stripe::Customer.new("test_customer")
c.charges
end
@ -388,8 +242,8 @@ module Stripe
should "updating an object should issue a POST request with only the changed properties" do
stub_request(:post, "#{Stripe.api_base}/v1/customers/c_test_customer").
with(body: { 'description' => 'another_mn' }).
to_return(body: JSON.generate(make_customer))
c = Stripe::Customer.construct_from(make_customer)
to_return(body: JSON.generate(API_FIXTURES.fetch(:customer)))
c = Stripe::Customer.construct_from(API_FIXTURES.fetch(:customer))
c.description = "another_mn"
c.save
end
@ -397,22 +251,13 @@ module Stripe
should "updating should merge in returned properties" do
stub_request(:post, "#{Stripe.api_base}/v1/customers/c_test_customer").
with(body: { 'description' => 'another_mn' }).
to_return(body: JSON.generate(make_customer))
to_return(body: JSON.generate(API_FIXTURES.fetch(:customer)))
c = Stripe::Customer.new("c_test_customer")
c.description = "another_mn"
c.save
assert_equal false, c.livemode
end
should "updating should send along the idempotency-key header" do
stub_request(:post, "#{Stripe.api_base}/v1/customers").
with(headers: {"Idempotency-Key" => "bar"}).
to_return(body: JSON.generate(make_customer))
c = Stripe::Customer.new
c.save({}, { :idempotency_key => 'bar' })
assert_equal false, c.livemode
end
should "updating should fail if api_key is overwritten with nil" do
c = Stripe::Customer.new
assert_raises TypeError do
@ -423,7 +268,7 @@ module Stripe
should "updating should use the supplied api_key" do
stub_request(:post, "#{Stripe.api_base}/v1/customers").
with(headers: {"Authorization" => "Bearer sk_test_local"}).
to_return(body: JSON.generate(make_customer))
to_return(body: JSON.generate(API_FIXTURES.fetch(:customer)))
c = Stripe::Customer.new
c.save({}, { :api_key => 'sk_test_local' })
assert_equal false, c.livemode
@ -432,107 +277,41 @@ module Stripe
should "deleting should send no props and result in an object that has no props other deleted" do
stub_request(:delete, "#{Stripe.api_base}/v1/customers/c_test_customer").
to_return(body: JSON.generate({ "id" => "test_customer", "deleted" => true }))
c = Stripe::Customer.construct_from(make_customer)
c = Stripe::Customer.construct_from(API_FIXTURES.fetch(:customer))
c.delete
assert_equal true, c.deleted
assert_raises NoMethodError do
c.livemode
end
end
should "loading an object with properties that have specific types should instantiate those classes" do
stub_request(:get, "#{Stripe.api_base}/v1/charges/test_charge").
to_return(body: JSON.generate(make_charge))
c = Stripe::Charge.retrieve("test_charge")
assert c.card.kind_of?(Stripe::StripeObject) && c.card.object == 'card'
end
should "loading all of an APIResource should return an array of recursively instantiated objects" do
stub_request(:get, "#{Stripe.api_base}/v1/charges").
to_return(body: JSON.generate(make_charge_array))
c = Stripe::Charge.list.data
assert c.kind_of? Array
assert c[0].kind_of? Stripe::Charge
assert c[0].card.kind_of?(Stripe::StripeObject) && c[0].card.object == 'card'
to_return(body: JSON.generate({
data: [API_FIXTURES.fetch(:charge)]
}))
charges = Stripe::Charge.list.data
assert charges.kind_of? Array
assert charges[0].kind_of? Stripe::Charge
assert charges[0].card.kind_of?(Stripe::StripeObject)
end
should "passing in a stripe_account header should pass it through on call" do
stub_request(:get, "#{Stripe.api_base}/v1/customers/c_test_customer").
with(headers: {"Stripe-Account" => "acct_abc"}).
to_return(body: JSON.generate(make_customer))
to_return(body: JSON.generate(API_FIXTURES.fetch(:customer)))
Stripe::Customer.retrieve("c_test_customer", {:stripe_account => 'acct_abc'})
end
should "passing in a stripe_account header should pass it through on save" do
stub_request(:get, "#{Stripe.api_base}/v1/customers/c_test_customer").
with(headers: {"Stripe-Account" => "acct_abc"}).
to_return(body: JSON.generate(make_customer))
to_return(body: JSON.generate(API_FIXTURES.fetch(:customer)))
c = Stripe::Customer.retrieve("c_test_customer", {:stripe_account => 'acct_abc'})
stub_request(:post, "#{Stripe.api_base}/v1/customers/c_test_customer").
with(headers: {"Stripe-Account" => "acct_abc"}).
to_return(body: JSON.generate(make_customer))
to_return(body: JSON.generate(API_FIXTURES.fetch(:customer)))
c.description = 'FOO'
c.save
end
context "error checking" do
should "404s should raise an InvalidRequestError" do
stub_request(:get, "#{Stripe.api_base}/v1/customers/test_customer").
to_return(body: JSON.generate(make_missing_id_error), status: 404)
rescued = false
begin
Stripe::Customer.new("test_customer").refresh
assert false #shouldn't get here either
rescue Stripe::InvalidRequestError => e # we don't use assert_raises because we want to examine e
rescued = true
assert e.kind_of? Stripe::InvalidRequestError
assert_equal "id", e.param
assert_equal "Missing id", e.message
end
assert_equal true, rescued
end
should "5XXs should raise an APIError" do
stub_request(:get, "#{Stripe.api_base}/v1/customers/test_customer").
to_return(body: JSON.generate(make_api_error), status: 500)
rescued = false
begin
Stripe::Customer.new("test_customer").refresh
assert false #shouldn't get here either
rescue Stripe::APIError => e # we don't use assert_raises because we want to examine e
rescued = true
assert e.kind_of? Stripe::APIError
end
assert_equal true, rescued
end
should "402s should raise a CardError" do
stub_request(:get, "#{Stripe.api_base}/v1/customers/test_customer").
to_return(body: JSON.generate(make_invalid_exp_year_error), status: 402)
rescued = false
begin
Stripe::Customer.new("test_customer").refresh
assert false #shouldn't get here either
rescue Stripe::CardError => e # we don't use assert_raises because we want to examine e
rescued = true
assert e.kind_of? Stripe::CardError
assert_equal "invalid_expiry_year", e.code
assert_equal "exp_year", e.param
assert_equal "Your card's expiration year is invalid", e.message
end
assert_equal true, rescued
end
end
should 'add key to nested objects' do
acct = Stripe::Account.construct_from({
:id => 'myid',
@ -713,149 +492,5 @@ module Stripe
account.save(:display_name => 'stripe', :metadata => {:key => 'value' })
end
end
context "with retries" do
setup do
Stripe.stubs(:max_network_retries).returns(2)
end
should 'retry failed network requests if specified and raise if error persists' do
Stripe.expects(:sleep_time).at_least_once.returns(0)
stub_request(:post, "#{Stripe.api_base}/v1/charges").
to_raise(Errno::ECONNREFUSED.new)
err = assert_raises Stripe::APIConnectionError do
Stripe::Charge.create(:amount => 50, :currency => 'usd', :card => { :number => nil })
end
assert_match(/Request was retried 2 times/, err.message)
end
should 'retry failed network requests if specified and return successful response' do
Stripe.expects(:sleep_time).at_least_once.returns(0)
i = 0
stub_request(:post, "#{Stripe.api_base}/v1/charges").
to_return { |_|
if i < 2
i += 1
raise Errno::ECONNREFUSED.new
else
{ body: JSON.generate({"id" => "myid"}) }
end
}
result = Stripe::Charge.create(:amount => 50, :currency => 'usd', :card => { :number => nil })
assert_equal "myid", result.id
end
should 'not add an idempotency key to GET requests' do
SecureRandom.expects(:uuid).times(0)
stub_request(:get, "#{Stripe.api_base}/v1/charges").
with { |req|
req.headers['Idempotency-Key'].nil?
}.to_return(body: JSON.generate(make_charge_array))
Stripe::Charge.list
end
should 'ensure there is always an idempotency_key on POST requests' do
SecureRandom.expects(:uuid).at_least_once.returns("random_key")
stub_request(:post, "#{Stripe.api_base}/v1/charges").
with(headers: {"Idempotency-Key" => "random_key"}).
to_return(body: JSON.generate(make_charge))
Stripe::Charge.create(:amount => 50, :currency => 'usd', :card => { :number => nil })
end
should 'ensure there is always an idempotency_key on DELETE requests' do
SecureRandom.expects(:uuid).at_least_once.returns("random_key")
c = Stripe::Customer.construct_from(make_customer)
stub_request(:delete, "#{Stripe.api_base}/v1/customers/#{c.id}").
with(headers: {"Idempotency-Key" => "random_key"}).
to_return(body: JSON.generate(make_charge))
c.delete
end
should 'not override a provided idempotency_key' do
# Note that this expectation looks like `:idempotency_key` instead of
# the header `Idempotency-Key` because it's user provided as seen
# below. The ones injected by the library itself look like headers
# (`Idempotency-Key`), but rest-client does allow this symbol
# formatting and will properly override the system generated one as
# expected.
stub_request(:post, "#{Stripe.api_base}/v1/charges").
with(headers: {"Idempotency-Key" => "provided_key"}).
to_return(body: JSON.generate(make_charge))
Stripe::Charge.create({:amount => 50, :currency => 'usd', :card => { :number => nil }}, {:idempotency_key => 'provided_key'})
end
end
context ".should_retry?" do
setup do
Stripe.stubs(:max_network_retries).returns(2)
end
should 'retry on a low-level network error' do
assert Stripe.should_retry?(Errno::ECONNREFUSED.new, 0)
end
should 'retry on timeout' do
assert Stripe.should_retry?(RestClient::RequestTimeout.new, 0)
end
should 'retry on a conflict' do
assert Stripe.should_retry?(RestClient::Conflict.new, 0)
end
should 'not retry at maximum count' do
refute Stripe.should_retry?(RuntimeError.new, Stripe.max_network_retries)
end
should 'not retry on a certificate validation error' do
refute Stripe.should_retry?(RestClient::SSLCertificateNotVerified.new('message'), 0)
end
end
context ".sleep_time" do
should "should grow exponentially" do
Stripe.stubs(:rand).returns(1)
Stripe.stubs(:max_network_retry_delay).returns(999)
assert_equal(Stripe.initial_network_retry_delay, Stripe.sleep_time(1))
assert_equal(Stripe.initial_network_retry_delay * 2, Stripe.sleep_time(2))
assert_equal(Stripe.initial_network_retry_delay * 4, Stripe.sleep_time(3))
assert_equal(Stripe.initial_network_retry_delay * 8, Stripe.sleep_time(4))
end
should "enforce the max_network_retry_delay" do
Stripe.stubs(:rand).returns(1)
Stripe.stubs(:initial_network_retry_delay).returns(1)
Stripe.stubs(:max_network_retry_delay).returns(2)
assert_equal(1, Stripe.sleep_time(1))
assert_equal(2, Stripe.sleep_time(2))
assert_equal(2, Stripe.sleep_time(3))
assert_equal(2, Stripe.sleep_time(4))
end
should "add some randomness" do
random_value = 0.8
Stripe.stubs(:rand).returns(random_value)
Stripe.stubs(:initial_network_retry_delay).returns(1)
Stripe.stubs(:max_network_retry_delay).returns(8)
base_value = Stripe.initial_network_retry_delay * (0.5 * (1 + random_value))
# the initial value cannot be smaller than the base,
# so the randomness is ignored
assert_equal(Stripe.initial_network_retry_delay, Stripe.sleep_time(1))
# after the first one, the randomness is applied
assert_equal(base_value * 2, Stripe.sleep_time(2))
assert_equal(base_value * 4, Stripe.sleep_time(3))
assert_equal(base_value * 8, Stripe.sleep_time(4))
end
end
end
end

View File

@ -2,32 +2,32 @@ require File.expand_path('../../test_helper', __FILE__)
module Stripe
class ApplePayDomainTest < Test::Unit::TestCase
should "create should return a new Apple Pay domain" do
stub_request(:post, "#{Stripe.api_base}/v1/apple_pay/domains").
to_return(body: JSON.generate(make_apple_pay_domain))
d = Stripe::ApplePayDomain.create
assert_equal "apwc_test_domain", d.id
end
FIXTURE = API_FIXTURES.fetch(:apple_pay_domain)
should "domains should be deletable" do
stub_request(:get, "#{Stripe.api_base}/v1/apple_pay/domains/apwc_test_domain").
to_return(body: JSON.generate(make_apple_pay_domain))
stub_request(:delete, "#{Stripe.api_base}/v1/apple_pay/domains/apwc_test_domain").
to_return(body: JSON.generate(make_apple_pay_domain(:deleted => true)))
domain = Stripe::ApplePayDomain.retrieve('apwc_test_domain')
domain.delete
assert domain.deleted
end
should "domains should be listable" do
stub_request(:get, "#{Stripe.api_base}/v1/apple_pay/domains").
to_return(body: JSON.generate(make_apple_pay_domain_array))
should "be listable" do
domains = Stripe::ApplePayDomain.list
assert_requested :get, "#{Stripe.api_base}/v1/apple_pay/domains"
assert domains.data.kind_of?(Array)
assert_equal 3, domains.data.length
domains.each do |domain|
assert domain.kind_of?(Stripe::ApplePayDomain)
end
assert domains.data[0].kind_of?(Stripe::ApplePayDomain)
end
should "be retrievable" do
domain = Stripe::ApplePayDomain.retrieve(FIXTURE[:id])
assert_requested :get, "#{Stripe.api_base}/v1/apple_pay/domains/#{FIXTURE[:id]}"
assert domain.kind_of?(Stripe::ApplePayDomain)
end
should "be creatable" do
domain = Stripe::ApplePayDomain.create(:domain_name => "example.com")
assert_requested :post, "#{Stripe.api_base}/v1/apple_pay/domains"
assert domain.kind_of?(Stripe::ApplePayDomain)
end
should "be deletable" do
domain = Stripe::ApplePayDomain.retrieve(FIXTURE[:id])
domain = domain.delete
assert_requested :delete, "#{Stripe.api_base}/v1/apple_pay/domains/#{FIXTURE[:id]}"
assert domain.kind_of?(Stripe::ApplePayDomain)
end
end
end

View File

@ -2,43 +2,37 @@ require File.expand_path('../../test_helper', __FILE__)
module Stripe
class ApplicationFeeRefundTest < Test::Unit::TestCase
should "refunds should be listable" do
stub_request(:get, "#{Stripe.api_base}/v1/application_fees/test_application_fee").
to_return(body: JSON.generate(make_application_fee))
FIXTURE = API_FIXTURES.fetch(:fee_refund)
application_fee = Stripe::ApplicationFee.retrieve('test_application_fee')
assert application_fee.refunds.first.kind_of?(Stripe::ApplicationFeeRefund)
setup do
application_fee_fixture = API_FIXTURES.fetch(:platform_earning)
@fee = Stripe::ApplicationFee.retrieve(application_fee_fixture[:id])
end
should "refunds should be updateable" do
stub_request(:get, "#{Stripe.api_base}/v1/application_fees/test_application_fee").
to_return(body: JSON.generate(make_application_fee))
should "be listable" do
refunds = @fee.refunds
application_fee = Stripe::ApplicationFee.retrieve('test_application_fee')
refund = application_fee.refunds.first
# notably this *doesn't* make an API call
assert_not_requested :get,
"#{Stripe.api_base}/v1/application_fees/#{@fee.id}/refunds"
stub_request(:post, "#{Stripe.api_base}/v1/application_fees/#{refund.fee}/refunds/#{refund.id}").
to_return(body: JSON.generate(make_application_fee_refund(:metadata => {'key' => 'value'})))
assert refunds.data.kind_of?(Array)
assert refunds.first.kind_of?(Stripe::ApplicationFeeRefund)
end
assert_equal nil, refund.metadata['key']
should "be creatable" do
refund = @fee.refunds.create
assert_requested :post,
"#{Stripe.api_base}/v1/application_fees/#{@fee.id}/refunds"
assert refund.kind_of?(Stripe::ApplicationFeeRefund)
end
refund.metadata['key'] = 'valu'
should "be saveable" do
refund = @fee.refunds.first
refund.metadata['key'] = 'value'
refund.save
assert_equal 'value', refund.metadata['key']
end
should "create should return a new refund" do
stub_request(:get, "#{Stripe.api_base}/v1/application_fees/test_application_fee").
to_return(body: JSON.generate(make_application_fee))
application_fee = Stripe::ApplicationFee.retrieve('test_application_fee')
stub_request(:post, "#{Stripe.api_base}/v1/application_fees/#{application_fee.id}/refunds").
to_return(body: JSON.generate(make_application_fee_refund(:id => 'test_new_refund')))
refund = application_fee.refunds.create(:amount => 20)
assert_equal 'test_new_refund', refund.id
assert_requested :post,
"#{Stripe.api_base}/v1/application_fees/#{@fee.id}/refunds/#{FIXTURE[:id]}"
end
end
end

View File

@ -2,24 +2,13 @@ require File.expand_path('../../test_helper', __FILE__)
module Stripe
class ApplicationFeeTest < Test::Unit::TestCase
should "application fees should be listable" do
stub_request(:get, "#{Stripe.api_base}/v1/application_fees").
to_return(body: JSON.generate(make_application_fee_array))
FIXTURE = API_FIXTURES.fetch(:platform_earning)
should "be listable" do
fees = Stripe::ApplicationFee.list
assert fees.data.kind_of? Array
fees.each do |fee|
assert fee.kind_of?(Stripe::ApplicationFee)
end
end
should "application fees should be refundable" do
fee = Stripe::ApplicationFee.construct_from(make_application_fee)
stub_request(:post, "#{Stripe.api_base}/v1/application_fees/#{fee.id}/refunds").
to_return(body: JSON.generate(make_application_fee_refund))
refund = fee.refunds.create
assert refund.is_a?(Stripe::ApplicationFeeRefund)
assert_requested :get, "#{Stripe.api_base}/v1/application_fees"
assert fees.data.kind_of?(Array)
assert fees.data[0].kind_of?(Stripe::ApplicationFee)
end
end
end

View File

@ -2,11 +2,10 @@ require File.expand_path('../../test_helper', __FILE__)
module Stripe
class BalanceTest < Test::Unit::TestCase
should "balance should be retrievable" do
stub_request(:get, "#{Stripe.api_base}/v1/balance").
to_return(body: JSON.generate(make_balance))
should "be retrievable" do
balance = Stripe::Balance.retrieve
assert_equal('balance', balance['object'])
assert_requested :get, "#{Stripe.api_base}/v1/balance"
assert balance.kind_of?(Stripe::Balance)
end
end
end

View File

@ -2,19 +2,40 @@ require File.expand_path('../../test_helper', __FILE__)
module Stripe
class BankAccountTest < Test::Unit::TestCase
FIXTURE = API_FIXTURES.fetch(:external_account_source)
should 'be verifiable' do
bank = Stripe::BankAccount.construct_from({
:id => 'ba_foo',
:customer => 'cus_bar'
})
context "#resource_url" do
should "return an external account URL" do
account_id = API_FIXTURES.fetch(:account)[:id]
bank_account = Stripe::BankAccount.construct_from(
account: account_id,
id: FIXTURE[:id]
)
assert_equal "/v1/accounts/#{account_id}/external_accounts/#{FIXTURE[:id]}",
bank_account.resource_url
end
stub_request(:post, "#{Stripe.api_base}/v1/customers/#{bank.customer}/sources/#{bank.id}/verify").
with(body: { 'amounts' => ['1', '2'] }).
to_return(body: JSON.generate(:status => 'verified'))
bank.verify(:amounts => [1,2])
should "return a customer URL" do
customer_id = API_FIXTURES.fetch(:customer)[:id]
bank_account = Stripe::BankAccount.construct_from(
customer: customer_id,
id: FIXTURE[:id]
)
assert_equal "/v1/customers/#{customer_id}/sources/#{FIXTURE[:id]}",
bank_account.resource_url
end
end
context "#verify" do
should 'verify the account' do
customer_id = API_FIXTURES.fetch(:customer)[:id]
bank_account = Stripe::BankAccount.construct_from({
customer: customer_id,
id: FIXTURE[:id]
})
bank_account = bank_account.verify(amounts: [1,2])
assert bank_account.kind_of?(Stripe::BankAccount)
end
end
end
end

View File

@ -2,62 +2,69 @@ require File.expand_path('../../test_helper', __FILE__)
module Stripe
class BitcoinReceiverTest < Test::Unit::TestCase
should "retrieve should retrieve bitcoin receiver" do
stub_request(:get, "#{Stripe.api_base}/v1/bitcoin/receivers/btcrcv_test_receiver").
to_return(body: JSON.generate(make_bitcoin_receiver))
receiver = Stripe::BitcoinReceiver.retrieve('btcrcv_test_receiver')
assert_equal 'btcrcv_test_receiver', receiver.id
end
FIXTURE = API_FIXTURES.fetch(:bitcoin_receiver)
should "create should create a bitcoin receiver" do
stub_request(:post, "#{Stripe.api_base}/v1/bitcoin/receivers").
to_return(body: JSON.generate(make_bitcoin_receiver))
receiver = Stripe::BitcoinReceiver.create
assert_equal "btcrcv_test_receiver", receiver.id
end
should "all should list bitcoin receivers" do
stub_request(:get, "#{Stripe.api_base}/v1/bitcoin/receivers").
to_return(body: JSON.generate(make_bitcoin_receiver_array))
should "be listable" do
receivers = Stripe::BitcoinReceiver.list
assert_equal 3, receivers.data.length
assert receivers.data.kind_of? Array
receivers.each do |receiver|
assert receiver.kind_of?(Stripe::BitcoinReceiver)
receiver.transactions.data.each do |transaction|
assert transaction.kind_of?(Stripe::BitcoinTransaction)
end
end
assert_requested :get, "#{Stripe.api_base}/v1/bitcoin/receivers"
assert receivers.data.kind_of?(Array)
assert receivers.first.kind_of?(Stripe::BitcoinReceiver)
end
should "update should update a bitcoin receiver" do
receiver = Stripe::BitcoinReceiver.construct_from(make_bitcoin_receiver)
should "be retrievable" do
receiver = Stripe::BitcoinReceiver.retrieve(FIXTURE[:id])
assert_requested :get,
"#{Stripe.api_base}/v1/bitcoin/receivers/#{FIXTURE[:id]}"
assert receiver.kind_of?(Stripe::BitcoinReceiver)
end
stub_request(:get, "#{Stripe.api_base}/v1/bitcoin/receivers/#{receiver.id}").
to_return(body: JSON.generate(make_bitcoin_receiver))
receiver.refresh
should "be creatable" do
receiver = Stripe::BitcoinReceiver.create(amount: 100, currency: "USD")
assert_requested :post, "#{Stripe.api_base}/v1/bitcoin/receivers"
assert receiver.kind_of?(Stripe::BitcoinReceiver)
end
stub_request(:post, "#{Stripe.api_base}/v1/bitcoin/receivers/#{receiver.id}").
with(body: { description: "details" }).
to_return(body: JSON.generate(make_bitcoin_receiver))
receiver.description = "details"
should "be saveable" do
receiver = Stripe::BitcoinReceiver.retrieve(FIXTURE[:id])
receiver.metadata['key'] = 'value'
receiver.save
assert_requested :post,
"#{Stripe.api_base}/v1/bitcoin/receivers/#{FIXTURE[:id]}"
end
should "delete a bitcoin receiver with no customer through top-level API" do
receiver = Stripe::BitcoinReceiver.construct_from(make_bitcoin_receiver)
stub_request(:delete, "#{Stripe.api_base}/v1/bitcoin/receivers/#{receiver.id}").
to_return(body: JSON.generate({:deleted => true, :id => "btcrcv_test_receiver"}))
receiver.delete
assert(receiver.deleted)
should "be updateable" do
receiver = Stripe::BitcoinReceiver.update(FIXTURE[:id], metadata: { key: 'value' })
assert_requested :post,
"#{Stripe.api_base}/v1/bitcoin/receivers/#{FIXTURE[:id]}"
assert receiver.kind_of?(Stripe::BitcoinReceiver)
end
should "delete a bitcoin receiver with a customer through customer's subresource API" do
receiver = Stripe::BitcoinReceiver.construct_from(make_bitcoin_receiver(:customer => 'customer_foo'))
stub_request(:delete, "#{Stripe.api_base}/v1/customers/customer_foo/sources/#{receiver.id}").
to_return(body: JSON.generate({:deleted => true, :id => "btcrcv_test_receiver"}))
receiver.delete
assert(receiver.deleted)
should "be deletable" do
receiver = Stripe::BitcoinReceiver.retrieve(FIXTURE[:id])
receiver = receiver.delete
assert_requested :delete,
"#{Stripe.api_base}/v1/bitcoin/receivers/#{FIXTURE[:id]}"
assert receiver.kind_of?(Stripe::BitcoinReceiver)
end
context "#resource_url" do
should "return a customer URL" do
customer_id = API_FIXTURES.fetch(:customer)[:id]
receiver = Stripe::BitcoinReceiver.construct_from(
customer: customer_id,
id: FIXTURE[:id]
)
assert_equal "/v1/customers/#{customer_id}/sources/#{FIXTURE[:id]}",
receiver.resource_url
end
should "return an absolute URL" do
receiver = Stripe::BitcoinReceiver.construct_from(
id: FIXTURE[:id]
)
assert_equal "/v1/bitcoin/receivers/#{FIXTURE[:id]}",
receiver.resource_url
end
end
end
end

View File

@ -2,24 +2,20 @@ require File.expand_path('../../test_helper', __FILE__)
module Stripe
class BitcoinTransactionTest < Test::Unit::TestCase
TEST_ID = "btctxn_test_transaction".freeze
FIXTURE = API_FIXTURES.fetch(:bitcoin_transaction)
should "retrieve should retrieve bitcoin receiver" do
stub_request(:get, "#{Stripe.api_base}/v1/bitcoin/transactions/#{TEST_ID}").
to_return(body: JSON.generate(make_bitcoin_transaction))
receiver = Stripe::BitcoinTransaction.retrieve(TEST_ID)
assert_equal TEST_ID, receiver.id
should "be listable" do
transactions = Stripe::BitcoinTransaction.list
assert_requested :get, "#{Stripe.api_base}/v1/bitcoin/transactions"
assert transactions.data.kind_of?(Array)
assert transactions.first.kind_of?(Stripe::BitcoinTransaction)
end
should "all should list bitcoin transactions" do
stub_request(:get, "#{Stripe.api_base}/v1/bitcoin/transactions").
to_return(body: JSON.generate(make_bitcoin_transaction_array))
transactions = Stripe::BitcoinTransaction.list
assert transactions.data.kind_of? Array
transactions.each do |transaction|
assert transaction.kind_of?(Stripe::BitcoinTransaction)
end
should "be retrievable" do
transaction = Stripe::BitcoinTransaction.retrieve(FIXTURE[:id])
assert_requested :get,
"#{Stripe.api_base}/v1/bitcoin/transactions/#{FIXTURE[:id]}"
assert transaction.kind_of?(Stripe::BitcoinTransaction)
end
end
end

View File

@ -1,61 +0,0 @@
require File.expand_path('../../test_helper', __FILE__)
module Stripe
class ChargeRefundTest < Test::Unit::TestCase
should "refunds should be listable" do
stub_request(:get, "#{Stripe.api_base}/v1/charges/test_charge").
to_return(body: JSON.generate(make_charge))
charge = Stripe::Charge.retrieve('test_charge')
assert charge.refunds.first.kind_of?(Stripe::Refund)
end
should "refunds should be refreshable" do
stub_request(:get, "#{Stripe.api_base}/v1/charges/test_charge").
to_return(body: JSON.generate(make_charge))
charge = Stripe::Charge.retrieve('test_charge')
refund = charge.refunds.first
stub_request(:get, "#{Stripe.api_base}/v1/refunds/#{refund.id}").
to_return(body: JSON.generate(make_refund))
refund.refresh
end
should "refunds should be updateable" do
stub_request(:get, "#{Stripe.api_base}/v1/charges/test_charge").
to_return(body: JSON.generate(make_charge))
charge = Stripe::Charge.retrieve('test_charge')
refund = charge.refunds.first
stub_request(:post, "#{Stripe.api_base}/v1/refunds/#{refund.id}").
with(body: { metadata: { key: "value" } }).
to_return(body: JSON.generate(make_refund))
refund.metadata['key'] = 'value'
refund.save
end
should "create a new refund" do
stub_request(:get, "#{Stripe.api_base}/v1/charges/test_charge").
to_return(body: JSON.generate(make_charge))
charge = Stripe::Charge.retrieve('test_charge')
stub_request(:post, "#{Stripe.api_base}/v1/charges/#{charge.id}/refunds").
with(body: { amount: "20" }).
to_return(body: JSON.generate(make_refund))
_ = charge.refunds.create(:amount => 20)
end
should "create a new refund with the old helper" do
stub_request(:get, "#{Stripe.api_base}/v1/charges/test_charge").
to_return(body: JSON.generate(make_charge))
charge = Stripe::Charge.retrieve('test_charge')
stub_request(:get, "#{Stripe.api_base}/v1/charges/#{charge.id}").
to_return(body: JSON.generate(charge))
stub_request(:post, "#{Stripe.api_base}/v1/charges/#{charge.id}/refunds").
with(body: { amount: "20" }).
to_return(body: JSON.generate(make_refund))
charge.refund(:amount => 20)
end
end
end

View File

@ -2,72 +2,58 @@ require File.expand_path('../../test_helper', __FILE__)
module Stripe
class ChargeTest < Test::Unit::TestCase
should "charges should be listable" do
stub_request(:get, "#{Stripe.api_base}/v1/charges").
to_return(body: JSON.generate(make_charge_array))
c = Stripe::Charge.list
assert c.data.kind_of? Array
c.each do |charge|
FIXTURE = API_FIXTURES.fetch(:charge)
should "be listable" do
charges = Stripe::Charge.list
assert_requested :get, "#{Stripe.api_base}/v1/charges"
assert charges.data.kind_of?(Array)
assert charges.data[0].kind_of?(Stripe::Charge)
end
should "be retrievable" do
charge = Stripe::Charge.retrieve(FIXTURE[:id])
assert_requested :get, "#{Stripe.api_base}/v1/charges/#{FIXTURE[:id]}"
assert charge.kind_of?(Stripe::Charge)
end
should "be creatable" do
charge = Stripe::Charge.create(
amount: 100,
currency: "USD",
source: API_FIXTURES.fetch(:source)[:id]
)
assert_requested :post, "#{Stripe.api_base}/v1/charges"
assert charge.kind_of?(Stripe::Charge)
end
should "be saveable" do
charge = Stripe::Charge.retrieve(FIXTURE[:id])
charge.metadata['key'] = 'value'
charge.save
assert_requested :post, "#{Stripe.api_base}/v1/charges/#{FIXTURE[:id]}"
end
should "be updateable" do
charge = Stripe::Charge.update(FIXTURE[:id], metadata: {foo: 'bar'})
assert_requested :post, "#{Stripe.api_base}/v1/charges/#{FIXTURE[:id]}"
assert charge.kind_of?(Stripe::Charge)
end
context "#mark_as_fraudulent" do
should "charges should be able to be marked as fraudulent" do
charge = Stripe::Charge.retrieve(FIXTURE[:id])
charge = charge.mark_as_fraudulent
assert charge.kind_of?(Stripe::Charge)
end
end
should "charges should not be deletable" do
stub_request(:get, "#{Stripe.api_base}/v1/charges/test_charge").
to_return(body: JSON.generate(make_charge))
c = Stripe::Charge.retrieve("test_charge")
assert_raises NoMethodError do
c.delete
context "#mark_as_safe" do
should "charges should be able to be marked as safe" do
charge = Stripe::Charge.retrieve(FIXTURE[:id])
charge = charge.mark_as_safe
assert charge.kind_of?(Stripe::Charge)
end
end
should "charges should be updateable" do
stub_request(:post, "#{Stripe.api_base}/v1/charges/test_charge").
with(body: { metadata: { foo: "bar" } }).
to_return(body: JSON.generate(make_charge))
_ = Stripe::Charge.update("test_charge", metadata: {foo: 'bar'})
end
should "charges should be saveable" do
stub_request(:get, "#{Stripe.api_base}/v1/charges/test_charge").
to_return(body: JSON.generate(make_charge))
c = Stripe::Charge.retrieve("test_charge")
stub_request(:post, "#{Stripe.api_base}/v1/charges/#{c.id}").
with(body: { mnemonic: "updated" }).
to_return(body: JSON.generate(make_charge))
c.mnemonic = "updated"
c.save
end
should "charges should be able to be marked as fraudulent" do
stub_request(:get, "#{Stripe.api_base}/v1/charges/test_charge").
to_return(body: JSON.generate(make_charge))
c = Stripe::Charge.retrieve("test_charge")
stub_request(:post, "#{Stripe.api_base}/v1/charges/#{c.id}").
with(body: { :fraud_details => { :user_report => 'fraudulent' } }).
to_return(body: JSON.generate(make_charge))
c.mark_as_fraudulent
end
should "charges should be able to be marked as safe" do
stub_request(:get, "#{Stripe.api_base}/v1/charges/test_charge").
to_return(body: JSON.generate(make_charge))
c = Stripe::Charge.retrieve("test_charge")
stub_request(:post, "#{Stripe.api_base}/v1/charges/#{c.id}").
with(body: { :fraud_details => { :user_report => 'safe' } }).
to_return(body: JSON.generate(make_charge))
c.mark_as_safe
end
should "create a new charge" do
stub_request(:post, "#{Stripe.api_base}/v1/charges").
with(body: { amount: "20" }).
to_return(body: JSON.generate(make_charge))
_ = Charge.create(:amount => 20)
end
end
end

View File

@ -2,19 +2,18 @@ require File.expand_path('../../test_helper', __FILE__)
module Stripe
class CountrySpecTest < Test::Unit::TestCase
should "be listable" do
stub_request(:get, "#{Stripe.api_base}/v1/country_specs").
to_return(body: JSON.generate(make_country_spec_array))
c = Stripe::CountrySpec.list
FIXTURE = API_FIXTURES.fetch(:country_spec)
assert(c.data.kind_of?(Array))
assert(c.data[0].kind_of?(Stripe::CountrySpec))
should "be listable" do
c = Stripe::CountrySpec.list
assert_requested :get, "#{Stripe.api_base}/v1/country_specs"
assert c.data.kind_of?(Array)
assert c.data[0].kind_of?(Stripe::CountrySpec)
end
should "be retrievable" do
stub_request(:get, "#{Stripe.api_base}/v1/country_specs/US").
to_return(body: JSON.generate(make_country_spec))
s = Stripe::CountrySpec.retrieve('US')
s = Stripe::CountrySpec.retrieve(FIXTURE[:id])
assert_requested :get, "#{Stripe.api_base}/v1/country_specs/#{FIXTURE[:id]}"
assert(s.kind_of?(Stripe::CountrySpec))
end
end

View File

@ -2,29 +2,43 @@ require File.expand_path('../../test_helper', __FILE__)
module Stripe
class CouponTest < Test::Unit::TestCase
should "create should return a new coupon" do
stub_request(:post, "#{Stripe.api_base}/v1/coupons").
to_return(body: JSON.generate(make_coupon))
_ = Stripe::Coupon.create
FIXTURE = API_FIXTURES.fetch(:coupon)
should "be listable" do
coupons = Stripe::Coupon.list
assert_requested :get, "#{Stripe.api_base}/v1/coupons"
assert coupons.data.kind_of?(Array)
assert coupons.first.kind_of?(Stripe::Coupon)
end
should "coupons should be saveable" do
stub_request(:get, "#{Stripe.api_base}/v1/coupons/test_coupon").
to_return(body: JSON.generate(make_coupon))
c = Stripe::Coupon.retrieve("test_coupon")
stub_request(:post, "#{Stripe.api_base}/v1/coupons/#{c.id}").
with(body: { metadata: { foo: "bar" } }).
to_return(body: JSON.generate(make_customer))
c.metadata['foo'] = 'bar'
c.save
should "be retrievable" do
coupon = Stripe::Coupon.retrieve(FIXTURE[:id])
assert_requested :get, "#{Stripe.api_base}/v1/coupons/#{FIXTURE[:id]}"
assert coupon.kind_of?(Stripe::Coupon)
end
should "coupons should be updateable" do
stub_request(:post, "#{Stripe.api_base}/v1/coupons/test_coupon").
with(body: { metadata: { foo: "bar" } }).
to_return(body: JSON.generate(make_customer))
_ = Stripe::Coupon.update("test_coupon", metadata: {foo: 'bar'})
should "be creatable" do
coupon = Stripe::Coupon.create(
percent_off: 25,
duration: 'repeating',
duration_in_months: 3,
id: '25OFF'
)
assert_requested :post, "#{Stripe.api_base}/v1/coupons"
assert coupon.kind_of?(Stripe::Coupon)
end
should "be saveable" do
coupon = Stripe::Coupon.retrieve(FIXTURE[:id])
coupon.metadata['key'] = 'value'
coupon.save
assert_requested :post, "#{Stripe.api_base}/v1/coupons/#{FIXTURE[:id]}"
end
should "be updateable" do
coupon = Stripe::Coupon.update(FIXTURE[:id], metadata: { key: 'value' })
assert_requested :post, "#{Stripe.api_base}/v1/coupons/#{FIXTURE[:id]}"
assert coupon.kind_of?(Stripe::Coupon)
end
end
end

View File

@ -2,62 +2,41 @@ require File.expand_path('../../test_helper', __FILE__)
module Stripe
class CustomerCardTest < Test::Unit::TestCase
def customer
stub_request(:get, "#{Stripe.api_base}/v1/customers/test_customer").
to_return(body: JSON.generate(make_customer))
Stripe::Customer.retrieve('test_customer')
FIXTURE = API_FIXTURES.fetch(:source)
setup do
@customer =
Stripe::Customer.retrieve(API_FIXTURES.fetch(:customer)[:id])
end
should "customer cards should be listable" do
c = customer
stub_request(:get, "#{Stripe.api_base}/v1/customers/#{c.id}/sources").
with(query: { object: "card" }).
to_return(body: JSON.generate(make_customer_card_array(customer.id)))
cards = c.sources.list(:object => "card").data
assert cards.kind_of? Array
assert cards[0].kind_of? Stripe::Card
should "be listable" do
sources = @customer.sources.list
assert sources.data.kind_of?(Array)
# because of the terrible :wildcard nature of sources, the API stub
# cannot currently replace this response with anything meaningful so we
# don't assert on the type of individual items like we do in other tests
end
should "customer cards should be deletable" do
c = customer
stub_request(:get, "#{Stripe.api_base}/v1/customers/#{c.id}/sources/card").
to_return(body: JSON.generate(make_card))
card = c.sources.retrieve('card')
stub_request(:delete, "#{Stripe.api_base}/v1/customers/#{card.customer}/sources/#{card.id}").
to_return(body: JSON.generate(make_card(:deleted => true)))
_ = card.delete
should "be creatable" do
card = @customer.sources.create(
source: API_FIXTURES.fetch(:token)[:id]
)
assert_requested :post, "#{Stripe.api_base}/v1/customers/#{@customer.id}/sources"
assert card.kind_of?(Stripe::BankAccount)
end
should "customer cards should be updateable" do
c = customer
should "be deletable" do
card = Stripe::Card.construct_from(FIXTURE.merge(customer: @customer.id))
card = card.delete
assert_requested :delete, "#{Stripe.api_base}/v1/customers/#{@customer.id}/sources/#{FIXTURE[:id]}"
assert card.kind_of?(Stripe::Card)
end
stub_request(:get, "#{Stripe.api_base}/v1/customers/#{c.id}/sources/card").
to_return(body: JSON.generate(make_card))
card = c.sources.retrieve('card')
stub_request(:post, "#{Stripe.api_base}/v1/customers/#{card.customer}/sources/#{card.id}").
with(body: { exp_year: "2100" }).
to_return(body: JSON.generate(make_card))
card.exp_year = "2100"
should "be saveable" do
card = Stripe::Card.construct_from(FIXTURE.merge(customer: @customer.id))
card.metadata['key'] = 'value'
card.save
end
should "create should return a new customer card" do
c = customer
stub_request(:post, "#{Stripe.api_base}/v1/customers/#{c.id}/sources").
with(body: { source: "tok_41YJ05ijAaWaFS" }).
to_return(body: JSON.generate(make_card))
_ = c.sources.create(:source => "tok_41YJ05ijAaWaFS")
end
should "raise if accessing Stripe::Card.retrieve directly" do
assert_raises NotImplementedError do
Stripe::Card.retrieve "card_12345"
end
assert_requested :post, "#{Stripe.api_base}/v1/customers/#{@customer.id}/sources/#{FIXTURE[:id]}"
end
end
end

View File

@ -2,112 +2,114 @@ require File.expand_path('../../test_helper', __FILE__)
module Stripe
class CustomerTest < Test::Unit::TestCase
should "customers should be listable" do
stub_request(:get, "#{Stripe.api_base}/v1/customers").
to_return(body: JSON.generate(make_customer_array))
c = Stripe::Customer.list.data
assert c.kind_of? Array
assert c[0].kind_of? Stripe::Customer
FIXTURE = API_FIXTURES.fetch(:customer)
should "be listable" do
customers = Stripe::Customer.list
assert_requested :get, "#{Stripe.api_base}/v1/customers"
assert customers.data.kind_of?(Array)
assert customers.first.kind_of?(Stripe::Customer)
end
should "customers should be deletable" do
stub_request(:delete, "#{Stripe.api_base}/v1/customers/test_customer").
to_return(body: JSON.generate(make_customer))
c = Stripe::Customer.new("test_customer")
c.delete
should "be retrievable" do
customer = Stripe::Customer.retrieve(FIXTURE[:id])
assert_requested :get, "#{Stripe.api_base}/v1/customers/#{FIXTURE[:id]}"
assert customer.kind_of?(Stripe::Customer)
end
should "customers should be saveable" do
stub_request(:get, "#{Stripe.api_base}/v1/customers/test_customer").
to_return(body: JSON.generate(make_customer))
c = Stripe::Customer.retrieve("test_customer")
stub_request(:post, "#{Stripe.api_base}/v1/customers/#{c.id}").
with(body: { mnemonic: "bar" }).
to_return(body: JSON.generate(make_customer))
c.mnemonic = "bar"
c.save
should "be creatable" do
customer = Stripe::Customer.create
assert_requested :post, "#{Stripe.api_base}/v1/customers"
assert customer.kind_of?(Stripe::Customer)
end
should "customers should be updateable" do
stub_request(:post, "#{Stripe.api_base}/v1/customers/test_customer").
with(body: { mnemonic: "bar" }).
to_return(body: JSON.generate(make_customer))
_ = Stripe::Customer.update("test_customer", mnemonic: "bar")
should "be saveable" do
customer = Stripe::Customer.retrieve(FIXTURE[:id])
customer.metadata['key'] = 'value'
customer.save
assert_requested :post, "#{Stripe.api_base}/v1/customers/#{FIXTURE[:id]}"
end
should "create should return a new customer" do
stub_request(:post, "#{Stripe.api_base}/v1/customers").
to_return(body: JSON.generate(make_customer))
_ = Stripe::Customer.create
should "be updateable" do
customer = Stripe::Customer.update(FIXTURE[:id], metadata: { key: 'value' })
assert_requested :post, "#{Stripe.api_base}/v1/customers/#{FIXTURE[:id]}"
assert customer.kind_of?(Stripe::Customer)
end
should "create_upcoming_invoice should create a new invoice" do
stub_request(:post, "#{Stripe.api_base}/v1/invoices").
with(body: { customer: "test_customer" }).
to_return(body: JSON.generate(make_customer))
_ = Stripe::Customer.new("test_customer").create_upcoming_invoice
should "be deletable" do
customer = Stripe::Customer.retrieve(FIXTURE[:id])
customer = customer.delete
assert_requested :delete, "#{Stripe.api_base}/v1/customers/#{FIXTURE[:id]}"
assert customer.kind_of?(Stripe::Customer)
end
should "be able to update a customer's subscription" do
stub_request(:get, "#{Stripe.api_base}/v1/customers/test_customer").
to_return(body: JSON.generate(make_customer))
c = Stripe::Customer.retrieve("test_customer")
stub_request(:post, "#{Stripe.api_base}/v1/customers/#{c.id}/subscription").
with(body: { plan: "silver" }).
to_return(body: JSON.generate(make_subscription))
_ = c.update_subscription({:plan => 'silver'})
context "#create_subscription" do
should "create a new subscription" do
customer = Stripe::Customer.retrieve(FIXTURE[:id])
subscription = customer.create_subscription({:plan => 'silver'})
assert subscription.kind_of?(Stripe::Subscription)
end
end
should "be able to cancel a customer's subscription" do
stub_request(:get, "#{Stripe.api_base}/v1/customers/test_customer").
to_return(body: JSON.generate(make_customer))
c = Stripe::Customer.retrieve("test_customer")
# Not an accurate response, but whatever
stub_request(:delete, "#{Stripe.api_base}/v1/customers/#{c.id}/subscription").
with(query: { at_period_end: "true" }).
to_return(body: JSON.generate(make_subscription))
c.cancel_subscription({:at_period_end => 'true'})
stub_request(:delete, "#{Stripe.api_base}/v1/customers/#{c.id}/subscription").
to_return(body: JSON.generate(make_subscription))
c.cancel_subscription
context "#create_upcoming_invoice" do
should "create a new invoice" do
customer = Stripe::Customer.retrieve(FIXTURE[:id])
invoice = customer.create_upcoming_invoice
assert invoice.kind_of?(Stripe::Invoice)
end
end
should "be able to create a subscription for a customer" do
c = Stripe::Customer.new("test_customer")
context "#update_subscription" do
should "update a subscription" do
customer = Stripe::Customer.retrieve(FIXTURE[:id])
stub_request(:post, "#{Stripe.api_base}/v1/customers/#{c.id}/subscriptions").
with(body: { plan: "silver" }).
to_return(body: JSON.generate(make_subscription))
_ = c.create_subscription({:plan => 'silver'})
# deprecated API and not in schema
stub_request(:post, "#{Stripe.api_base}/v1/customers/#{customer.id}/subscription").
with(body: { plan: "silver" }).
to_return(body: JSON.generate(API_FIXTURES[:subscription]))
subscription = customer.update_subscription({:plan => 'silver'})
assert subscription.kind_of?(Stripe::Subscription)
end
end
should "be able to delete a customer's discount" do
stub_request(:get, "#{Stripe.api_base}/v1/customers/test_customer").
to_return(body: JSON.generate(make_customer))
c = Stripe::Customer.retrieve("test_customer")
context "#cancel_subscription" do
should "cancel a subscription" do
customer = Stripe::Customer.retrieve(FIXTURE[:id])
stub_request(:delete, "#{Stripe.api_base}/v1/customers/#{c.id}/discount").
to_return(body: JSON.generate(make_delete_discount_response))
c.delete_discount
# deprecated API and not in schema
stub_request(:delete, "#{Stripe.api_base}/v1/customers/#{customer.id}/subscription").
with(query: { at_period_end: "true" }).
to_return(body: JSON.generate(API_FIXTURES[:subscription]))
subscription = customer.cancel_subscription({:at_period_end => 'true'})
assert subscription.kind_of?(Stripe::Subscription)
end
end
should "can have a token source set" do
c = Stripe::Customer.new("test_customer")
c.source = "tok_123"
assert_equal "tok_123", c.source
context "#delete_discount" do
should "delete a discount" do
customer = Stripe::Customer.retrieve(FIXTURE[:id])
stub_request(:delete, "#{Stripe.api_base}/v1/customers/#{customer.id}/discount").
to_return(body: JSON.generate(API_FIXTURES[:discount]))
discount = customer.delete_discount
assert discount.kind_of?(Stripe::Customer)
end
end
should "set a flag if given an object source" do
c = Stripe::Customer.new("test_customer")
c.source = {
:object => 'card'
}
assert_equal true, c.source.save_with_parent
context "source field" do
should "allow setting source with token" do
c = Stripe::Customer.new("test_customer")
c.source = "tok_123"
assert_equal "tok_123", c.source
end
should "allow setting source with hash and set flag" do
c = Stripe::Customer.new("test_customer")
c.source = {
:object => 'card'
}
assert_equal true, c.source.save_with_parent
end
end
end
end

View File

@ -2,47 +2,41 @@ require File.expand_path('../../test_helper', __FILE__)
module Stripe
class DisputeTest < Test::Unit::TestCase
should "disputes should be retrievable" do
stub_request(:get, "#{Stripe.api_base}/v1/disputes/dp_test_dispute").
to_return(body: JSON.generate(make_dispute))
d = Stripe::Dispute.retrieve('dp_test_dispute')
assert d.kind_of?(Stripe::Dispute)
FIXTURE = API_FIXTURES.fetch(:dispute)
should "be listable" do
disputes = Stripe::Dispute.list
assert_requested :get, "#{Stripe.api_base}/v1/disputes"
assert disputes.data.kind_of?(Array)
assert disputes.first.kind_of?(Stripe::Dispute)
end
should "disputes should be listable" do
stub_request(:get, "#{Stripe.api_base}/v1/disputes").
to_return(body: JSON.generate(make_dispute_array))
d = Stripe::Dispute.list
assert d.data.kind_of? Array
d.each do |dispute|
assert dispute.kind_of?(Stripe::Dispute)
should "be retrievable" do
dispute = Stripe::Dispute.retrieve(FIXTURE[:id])
assert_requested :get, "#{Stripe.api_base}/v1/disputes/#{FIXTURE[:id]}"
assert dispute.kind_of?(Stripe::Dispute)
end
should "be saveable" do
dispute = Stripe::Dispute.retrieve(FIXTURE[:id])
dispute.metadata['key'] = 'value'
dispute.save
assert_requested :post, "#{Stripe.api_base}/v1/disputes/#{FIXTURE[:id]}"
end
should "be updateable" do
dispute = Stripe::Dispute.update(FIXTURE[:id], metadata: { key: 'value' })
assert_requested :post, "#{Stripe.api_base}/v1/disputes/#{FIXTURE[:id]}"
assert dispute.kind_of?(Stripe::Dispute)
end
context "#close" do
should "be closeable" do
dispute = Stripe::Dispute.retrieve(FIXTURE[:id])
dispute.close
assert_requested :post,
"#{Stripe.api_base}/v1/disputes/#{FIXTURE[:id]}/close"
end
end
should "disputes should be closeable" do
stub_request(:post, "#{Stripe.api_base}/v1/disputes/dp_test_dispute/close").
to_return(body: JSON.generate(make_dispute))
d = Stripe::Dispute.new('dp_test_dispute')
d.close
end
should "disputes should be updateable" do
stub_request(:post, "#{Stripe.api_base}/v1/disputes/dp_test_dispute").
with(body: { metadata: { foo: "bar" } }).
to_return(body: JSON.generate(make_dispute))
_ = Stripe::Dispute.update("dp_test_dispute", metadata: {foo: 'bar'})
end
should "disputes should be saveable" do
stub_request(:get, "#{Stripe.api_base}/v1/disputes/dp_test_dispute").
to_return(body: JSON.generate(make_dispute))
d = Stripe::Dispute.retrieve('dp_test_dispute')
stub_request(:post, "#{Stripe.api_base}/v1/disputes/dp_test_dispute").
with(body: { evidence: { customer_name: "customer" } }).
to_return(body: JSON.generate(make_dispute))
d.evidence['customer_name'] = 'customer'
d.save
end
end
end

View File

@ -7,10 +7,10 @@ module Stripe
e = StripeError.new("message")
assert_equal "message", e.to_s
e = StripeError.new("message", 200)
e = StripeError.new("message", http_status: 200)
assert_equal "(Status 200) message", e.to_s
e = StripeError.new("message", nil, nil, nil, { :request_id => "request-id" })
e = StripeError.new("message", http_status: nil, http_body: nil, json_body: nil, http_headers: { :request_id => "request-id" })
assert_equal "(Request request-id) message", e.to_s
end
end

View File

@ -2,31 +2,46 @@ require File.expand_path('../../test_helper', __FILE__)
module Stripe
class FileUploadTest < Test::Unit::TestCase
should "create should return a new file" do
stub_request(:post, "#{Stripe.uploads_base}/v1/files").
to_return(body: JSON.generate(make_file))
# Note that these tests are written different from others because we
# don't have anything on the uploads service in our OpenAPI spec. This is
# something that should be looked into at some point. We may need to ship
# a separate spec for it though, so it's high effort with low reward for
# the time being.
FIXTURE = {
id: "fil_15ABpV2eZvKYlo2C7vu7XS5l",
object: "file_upload",
}.freeze
f = Stripe::FileUpload.create({
:purpose => "dispute_evidence",
:file => File.new(__FILE__),
})
assert_equal "fil_test_file", f.id
end
should "files should be retrievable" do
stub_request(:get, "#{Stripe.uploads_base}/v1/files/fil_test_file").
to_return(body: JSON.generate(make_file))
_ = Stripe::FileUpload.retrieve("fil_test_file")
end
should "files should be listable" do
should "be listable" do
stub_request(:get, "#{Stripe.uploads_base}/v1/files").
to_return(body: JSON.generate(make_file_array))
to_return(body: JSON.generate({
data: [FIXTURE],
object: 'list',
resource_url: '/v1/files'
}))
c = Stripe::FileUpload.list.data
assert c.kind_of? Array
assert c[0].kind_of? Stripe::FileUpload
files = Stripe::FileUpload.list
assert files.data.kind_of?(Array)
assert files.data[0].kind_of?(Stripe::FileUpload)
end
should "be retrievable" do
stub_request(:get, "#{Stripe.uploads_base}/v1/files/#{FIXTURE[:id]}").
to_return(body: JSON.generate(FIXTURE))
file = Stripe::FileUpload.retrieve(FIXTURE[:id])
assert file.kind_of?(Stripe::FileUpload)
end
should "be creatable" do
stub_request(:post, "#{Stripe.uploads_base}/v1/files").
to_return(body: JSON.generate(FIXTURE))
file = Stripe::FileUpload.create(
purpose: "dispute_evidence",
file: File.new(__FILE__),
)
assert file.kind_of?(Stripe::FileUpload)
end
end
end

View File

@ -2,17 +2,54 @@ require File.expand_path('../../test_helper', __FILE__)
module Stripe
class InvoiceItemTest < Test::Unit::TestCase
should "retrieve should retrieve invoice items" do
stub_request(:get, "#{Stripe.api_base}/v1/invoiceitems/ii_test_invoice_item").
to_return(body: JSON.generate(make_invoice_item))
_ = Stripe::InvoiceItem.retrieve('ii_test_invoice_item')
FIXTURE = API_FIXTURES.fetch(:invoice_item)
should "be listable" do
invoiceitems = Stripe::InvoiceItem.list
assert_requested :get, "#{Stripe.api_base}/v1/invoiceitems"
assert invoiceitems.data.kind_of?(Array)
assert invoiceitems.first.kind_of?(Stripe::InvoiceItem)
end
should "invoice items should be updateable" do
stub_request(:post, "#{Stripe.api_base}/v1/invoiceitems/ii_test_invoice_item").
with(body: { metadata: { foo: "bar" } }).
to_return(body: JSON.generate(make_invoice_item))
_ = Stripe::InvoiceItem.update("ii_test_invoice_item", metadata: {foo: 'bar'})
should "be retrievable" do
item = Stripe::InvoiceItem.retrieve(FIXTURE[:id])
assert_requested :get,
"#{Stripe.api_base}/v1/invoiceitems/#{FIXTURE[:id]}"
assert item.kind_of?(Stripe::InvoiceItem)
end
should "be creatable" do
item = Stripe::InvoiceItem.create(
amount: 100,
currency: "USD",
customer: API_FIXTURES[:customer][:id]
)
assert_requested :post,
"#{Stripe.api_base}/v1/invoiceitems"
assert item.kind_of?(Stripe::InvoiceItem)
end
should "be saveable" do
item = Stripe::InvoiceItem.retrieve(FIXTURE[:id])
item.metadata['key'] = 'value'
item.save
assert_requested :post,
"#{Stripe.api_base}/v1/invoiceitems/#{FIXTURE[:id]}"
end
should "be updateable" do
item = Stripe::InvoiceItem.update(FIXTURE[:id], metadata: { key: 'value' })
assert_requested :post,
"#{Stripe.api_base}/v1/invoiceitems/#{FIXTURE[:id]}"
assert item.kind_of?(Stripe::InvoiceItem)
end
should "be deletable" do
item = Stripe::InvoiceItem.retrieve(FIXTURE[:id])
item = item.delete
assert_requested :delete,
"#{Stripe.api_base}/v1/invoiceitems/#{FIXTURE[:id]}"
assert item.kind_of?(Stripe::InvoiceItem)
end
end
end

View File

@ -2,47 +2,65 @@ require File.expand_path('../../test_helper', __FILE__)
module Stripe
class InvoiceTest < Test::Unit::TestCase
should "retrieve should retrieve invoices" do
stub_request(:get, "#{Stripe.api_base}/v1/invoices/in_test_invoice").
to_return(body: JSON.generate(make_invoice))
i = Stripe::Invoice.retrieve('in_test_invoice')
assert_equal 'in_test_invoice', i.id
FIXTURE = API_FIXTURES.fetch(:invoice)
should "be listable" do
invoices = Stripe::Invoice.list
assert_requested :get, "#{Stripe.api_base}/v1/invoices"
assert invoices.data.kind_of?(Array)
assert invoices.first.kind_of?(Stripe::Invoice)
end
should "create should create a new invoice" do
stub_request(:post, "#{Stripe.api_base}/v1/invoices").
to_return(body: JSON.generate(make_invoice))
_ = Stripe::Invoice.create
should "be retrievable" do
invoice = Stripe::Invoice.retrieve(FIXTURE[:id])
assert_requested :get, "#{Stripe.api_base}/v1/invoices/#{FIXTURE[:id]}"
assert invoice.kind_of?(Stripe::Invoice)
end
should "pay should pay an invoice" do
stub_request(:get, "#{Stripe.api_base}/v1/invoices/in_test_invoice").
to_return(body: JSON.generate(make_invoice))
i = Stripe::Invoice.retrieve('in_test_invoice')
stub_request(:post, "#{Stripe.api_base}/v1/invoices/#{i.id}/pay").
to_return(body: JSON.generate(make_invoice))
i.pay
end
should "invoices should be updateable" do
stub_request(:post, "#{Stripe.api_base}/v1/invoices/test_invoice").
with(body: { metadata: { foo: "bar" } }).
to_return(body: JSON.generate(make_invoice))
_ = Stripe::Invoice.update("test_invoice", metadata: {foo: 'bar'})
end
should "be able to retrieve upcoming invoices" do
stub_request(:get, "#{Stripe.api_base}/v1/invoices/upcoming").
with(query: {
:customer => 'c_test_customer',
:subscription => 's_test_subscription',
}).
to_return(body: JSON.generate(make_invoice))
_ = Stripe::Invoice.upcoming(
:customer => 'c_test_customer',
:subscription => 's_test_subscription',
should "be creatable" do
invoice = Stripe::Invoice.create(
:customer => API_FIXTURES[:customer][:id]
)
assert_requested :post, "#{Stripe.api_base}/v1/invoices"
assert invoice.kind_of?(Stripe::Invoice)
end
should "be saveable" do
invoice = Stripe::Invoice.retrieve(FIXTURE[:id])
invoice.metadata['key'] = 'value'
invoice.save
assert_requested :post, "#{Stripe.api_base}/v1/invoices/#{FIXTURE[:id]}"
end
should "be updateable" do
invoice = Stripe::Invoice.update(FIXTURE[:id], metadata: { key: 'value' })
assert_requested :post, "#{Stripe.api_base}/v1/invoices/#{FIXTURE[:id]}"
assert invoice.kind_of?(Stripe::Invoice)
end
context "#pay" do
should "pay invoice" do
invoice = Stripe::Invoice.retrieve(FIXTURE[:id])
invoice = invoice.pay
assert_requested :post,
"#{Stripe.api_base}/v1/invoices/#{FIXTURE[:id]}/pay"
assert invoice.kind_of?(Stripe::Invoice)
end
end
context "#upcoming" do
should "retrieve upcoming invoices" do
invoice = Stripe::Invoice.upcoming(
customer: API_FIXTURES[:customer][:id],
subscription: API_FIXTURES[:subscription][:id]
)
assert_requested :get, "#{Stripe.api_base}/v1/invoices/upcoming",
query: {
customer: API_FIXTURES[:customer][:id],
subscription: API_FIXTURES[:subscription][:id]
}
assert invoice.kind_of?(Stripe::Invoice)
end
end
end
end

View File

@ -8,8 +8,10 @@ module Stripe
end
should "provide #count via enumerable" do
list = Stripe::ListObject.construct_from(make_charge_array)
assert_equal 3, list.count
list = Stripe::ListObject.construct_from({
data: [API_FIXTURES.fetch(:charge)]
})
assert_equal 1, list.count
end
should "provide #each" do
@ -152,8 +154,6 @@ module Stripe
# note that the name #all is deprecated, as is using it fetch the next page
# in a list
should "be able to retrieve full lists given a listobject" do
stub_request(:get, "#{Stripe.api_base}/v1/charges").
to_return(body: JSON.generate(make_charge_array))
c = Stripe::Charge.all
assert c.kind_of?(Stripe::ListObject)
assert_equal('/v1/charges', c.resource_url)

View File

@ -2,25 +2,20 @@ require File.expand_path('../../test_helper', __FILE__)
module Stripe
class OrderReturnTest < Test::Unit::TestCase
should "returns should be listable" do
stub_request(:get, "#{Stripe.api_base}/v1/order_returns").
to_return(body: JSON.generate(make_order_return_array))
returns = Stripe::OrderReturn.list
assert returns.data.kind_of?(Array)
returns.each do |ret|
assert ret.kind_of?(Stripe::OrderReturn)
end
FIXTURE = API_FIXTURES.fetch(:order_return)
should "be listable" do
order_returns = Stripe::OrderReturn.list
assert_requested :get, "#{Stripe.api_base}/v1/order_returns"
assert order_returns.data.kind_of?(Array)
assert order_returns.data[0].kind_of?(Stripe::OrderReturn)
end
should "returns should not be deletable" do
p = Stripe::OrderReturn.new("test_order")
assert_raises(NoMethodError) { p.delete }
end
should "returns should be immutable" do
p = Stripe::OrderReturn.new("test_order")
p.items = []
assert_raises(NoMethodError) { p.save }
should "be retrievable" do
order_return = Stripe::OrderReturn.retrieve(FIXTURE[:id])
assert_requested :get,
"#{Stripe.api_base}/v1/order_returns/#{FIXTURE[:id]}"
assert order_return.kind_of?(Stripe::OrderReturn)
end
end
end

View File

@ -2,65 +2,58 @@ require File.expand_path('../../test_helper', __FILE__)
module Stripe
class OrderTest < Test::Unit::TestCase
should "orders should be listable" do
stub_request(:get, "#{Stripe.api_base}/v1/orders").
to_return(body: JSON.generate(make_order_array))
FIXTURE = API_FIXTURES.fetch(:order)
should "be listable" do
orders = Stripe::Order.list
assert_requested :get, "#{Stripe.api_base}/v1/orders"
assert orders.data.kind_of?(Array)
orders.each do |order|
assert orders.first.kind_of?(Stripe::Order)
end
should "be retrievable" do
order = Stripe::Order.retrieve(FIXTURE[:id])
assert_requested :get, "#{Stripe.api_base}/v1/orders/#{FIXTURE[:id]}"
assert order.kind_of?(Stripe::Order)
end
should "be creatable" do
order = Stripe::Order.create(
currency: "USD"
)
assert_requested :post, "#{Stripe.api_base}/v1/orders"
assert order.kind_of?(Stripe::Order)
end
should "be saveable" do
order = Stripe::Order.retrieve(FIXTURE[:id])
order.metadata['key'] = 'value'
order.save
assert_requested :post, "#{Stripe.api_base}/v1/orders/#{FIXTURE[:id]}"
end
should "be updateable" do
order = Stripe::Order.update(FIXTURE[:id], metadata: { key: 'value' })
assert_requested :post, "#{Stripe.api_base}/v1/orders/#{FIXTURE[:id]}"
assert order.kind_of?(Stripe::Order)
end
context "#pay" do
should "pay an order" do
order = Stripe::Order.retrieve(FIXTURE[:id])
order = order.pay(token: API_FIXTURES.fetch(:token)[:id])
assert order.kind_of?(Stripe::Order)
end
end
should "orders should not be deletable" do
stub_request(:get, "#{Stripe.api_base}/v1/orders/or_test_order").
to_return(body: JSON.generate(make_order))
p = Stripe::Order.retrieve("or_test_order")
assert_raises NoMethodError do
p.delete
context "#return_order" do
should "return an order" do
order = Stripe::Order.retrieve(FIXTURE[:id])
order = order.return_order(:orders => [
{ parent: API_FIXTURES.fetch(:sku)[:id] }
])
assert order.kind_of?(Stripe::OrderReturn)
end
end
should "orders should be saveable" do
stub_request(:get, "#{Stripe.api_base}/v1/orders/or_test_order").
to_return(body: JSON.generate(make_order))
p = Stripe::Order.retrieve("or_test_order")
stub_request(:post, "#{Stripe.api_base}/v1/orders/#{p.id}").
with(body: { status: "fulfilled" }).
to_return(body: JSON.generate(make_order))
p.status = "fulfilled"
p.save
end
should "orders should be updateable" do
stub_request(:post, "#{Stripe.api_base}/v1/orders/or_test_order").
with(body: { status: "fulfilled" }).
to_return(body: JSON.generate(make_order))
_ = Stripe::Order.update("or_test_order", status: 'fulfilled')
end
should "pay should pay an order" do
stub_request(:get, "#{Stripe.api_base}/v1/orders/or_test_order").
to_return(body: JSON.generate(make_order))
order = Stripe::Order.retrieve('or_test_order')
stub_request(:post, "#{Stripe.api_base}/v1/orders/#{order.id}/pay").
with(body: { token: "test_token" }).
to_return(body: JSON.generate(make_order))
order.pay(:token => 'test_token')
end
should "return an order" do
stub_request(:get, "#{Stripe.api_base}/v1/orders/or_test_order").
to_return(body: JSON.generate(make_order))
order = Stripe::Order.retrieve('or_test_order')
stub_request(:post, "#{Stripe.api_base}/v1/orders/#{order.id}/returns").
with(body: { items: [{ parent: "sku_foo" }] }).
to_return(body: JSON.generate(make_order))
_ = order.return_order(:items => [{:parent => 'sku_foo'}])
end
end
end

View File

@ -2,33 +2,51 @@ require File.expand_path('../../test_helper', __FILE__)
module Stripe
class PlanTest < Test::Unit::TestCase
should "plans should be listable" do
stub_request(:get, "#{Stripe.api_base}/v1/plans").
to_return(body: JSON.generate(make_plan_array))
FIXTURE = API_FIXTURES.fetch(:plan)
should "be listable" do
plans = Stripe::Plan.list
assert_requested :get, "#{Stripe.api_base}/v1/plans"
assert plans.data.kind_of?(Array)
plans.each do |plan|
assert plan.kind_of?(Stripe::Plan)
end
assert plans.data[0].kind_of?(Stripe::Plan)
end
should "plans should be saveable" do
stub_request(:get, "#{Stripe.api_base}/v1/plans/test_plan").
to_return(body: JSON.generate(make_plan))
p = Stripe::Plan.retrieve("test_plan")
stub_request(:post, "#{Stripe.api_base}/v1/plans/#{p.id}").
with(body: { metadata: { foo: "bar" } }).
to_return(body: JSON.generate(make_plan))
p.metadata['foo'] = 'bar'
p.save
should "be retrievable" do
plan = Stripe::Plan.retrieve(FIXTURE[:id])
assert_requested :get, "#{Stripe.api_base}/v1/plans/#{FIXTURE[:id]}"
assert plan.kind_of?(Stripe::Plan)
end
should "plans should be updateable" do
stub_request(:post, "#{Stripe.api_base}/v1/plans/test_plan").
with(body: { metadata: { foo: "bar" } }).
to_return(body: JSON.generate(make_plan))
_ = Stripe::Plan.update("test_plan", metadata: {foo: 'bar'})
should "be creatable" do
plan = Stripe::Plan.create(
amount: 5000,
interval: "month",
name: "Sapphire elite",
currency: "usd",
id: "sapphire-elite"
)
assert_requested :post, "#{Stripe.api_base}/v1/plans"
assert plan.kind_of?(Stripe::Plan)
end
should "be saveable" do
plan = Stripe::Plan.retrieve(FIXTURE[:id])
plan.metadata['key'] = 'value'
plan.save
assert_requested :post, "#{Stripe.api_base}/v1/plans/#{FIXTURE[:id]}"
end
should "be updateable" do
plan = Stripe::Plan.update(FIXTURE[:id], metadata: {foo: 'bar'})
assert_requested :post, "#{Stripe.api_base}/v1/plans/#{FIXTURE[:id]}"
assert plan.kind_of?(Stripe::Plan)
end
should "be deletable" do
plan = Stripe::Plan.retrieve(FIXTURE[:id])
plan = plan.delete
assert_requested :delete, "#{Stripe.api_base}/v1/plans/#{FIXTURE[:id]}"
assert plan.kind_of?(Stripe::Plan)
end
end
end

View File

@ -2,44 +2,46 @@ require File.expand_path('../../test_helper', __FILE__)
module Stripe
class ProductTest < Test::Unit::TestCase
should "products should be listable" do
stub_request(:get, "#{Stripe.api_base}/v1/products").
to_return(body: JSON.generate(make_product_array))
FIXTURE = API_FIXTURES.fetch(:product)
should "be listable" do
products = Stripe::Product.list
assert_requested :get, "#{Stripe.api_base}/v1/products"
assert products.data.kind_of?(Array)
products.each do |product|
assert product.kind_of?(Stripe::Product)
end
assert products.data[0].kind_of?(Stripe::Product)
end
should "products should be deletable" do
stub_request(:get, "#{Stripe.api_base}/v1/products/test_product").
to_return(body: JSON.generate(make_product))
p = Stripe::Product.retrieve("test_product")
stub_request(:delete, "#{Stripe.api_base}/v1/products/#{p.id}").
to_return(body: JSON.generate(make_product))
p.delete
should "be retrievable" do
product = Stripe::Product.retrieve(FIXTURE[:id])
assert_requested :get, "#{Stripe.api_base}/v1/products/#{FIXTURE[:id]}"
assert product.kind_of?(Stripe::Product)
end
should "products should be saveable" do
stub_request(:get, "#{Stripe.api_base}/v1/products/test_product").
to_return(body: JSON.generate(make_product))
p = Stripe::Product.new("test_product")
p.refresh
stub_request(:post, "#{Stripe.api_base}/v1/products/#{p.id}").
with(body: { :description => "update" }).
to_return(body: JSON.generate(make_product))
p.description = "update"
p.save
should "be creatable" do
_ = Stripe::Product.create(
name: "My Product"
)
assert_requested :post, "#{Stripe.api_base}/v1/products"
end
should "products should be updateable" do
stub_request(:post, "#{Stripe.api_base}/v1/products/test_product").
with(body: { :description => "update" }).
to_return(body: JSON.generate(make_product))
_ = Stripe::Product.update("test_product", description: "update")
should "be saveable" do
product = Stripe::Product.retrieve(FIXTURE[:id])
product.metadata['key'] = 'value'
product.save
assert_requested :post, "#{Stripe.api_base}/v1/products/#{FIXTURE[:id]}"
end
should "be updateable" do
product = Stripe::Product.update(FIXTURE[:id], metadata: {foo: 'bar'})
assert_requested :post, "#{Stripe.api_base}/v1/products/#{FIXTURE[:id]}"
assert product.kind_of?(Stripe::Product)
end
should "be deletable" do
product = Stripe::Product.retrieve(FIXTURE[:id])
product = product.delete
assert_requested :delete, "#{Stripe.api_base}/v1/products/#{FIXTURE[:id]}"
assert product.kind_of?(Stripe::Product)
end
end
end

View File

@ -2,55 +2,39 @@ require File.expand_path('../../test_helper', __FILE__)
module Stripe
class RecipientCardTest < Test::Unit::TestCase
def recipient
stub_request(:get, "#{Stripe.api_base}/v1/recipients/test_recipient").
to_return(body: JSON.generate(make_recipient))
Stripe::Recipient.retrieve('test_recipient')
FIXTURE = API_FIXTURES.fetch(:source)
setup do
@recipient =
Stripe::Recipient.retrieve(API_FIXTURES.fetch(:transfer_recipient)[:id])
end
should "recipient cards should be listable" do
c = recipient
stub_request(:get, "#{Stripe.api_base}/v1/recipients/#{c.id}/cards").
to_return(body: JSON.generate(make_recipient_card_array(recipient.id)))
cards = c.cards.list.data
assert cards.kind_of? Array
assert cards[0].kind_of? Stripe::Card
should "be listable" do
cards = @recipient.cards.list
assert cards.data.kind_of?(Array)
assert cards.data[0].kind_of?(Stripe::Token)
end
should "recipient cards should be deletable" do
c = recipient
stub_request(:get, "#{Stripe.api_base}/v1/recipients/#{c.id}/cards/card").
to_return(body: JSON.generate(make_card(:recipient => 'test_recipient')))
card = c.cards.retrieve('card')
stub_request(:delete, "#{Stripe.api_base}/v1/recipients/#{card.recipient}/cards/#{card.id}").
to_return(body: JSON.generate(make_card(:deleted => true)))
_ = card.delete
should "be creatable" do
card = @recipient.cards.create(
card: API_FIXTURES.fetch(:token)[:id]
)
assert_requested :post, "#{Stripe.api_base}/v1/recipients/#{@recipient.id}/cards"
assert card.kind_of?(Stripe::Token)
end
should "recipient cards should be updateable" do
c = recipient
should "be deletable" do
card = Stripe::Card.construct_from(FIXTURE.merge(recipient: @recipient.id))
card = card.delete
assert_requested :delete, "#{Stripe.api_base}/v1/recipients/#{@recipient.id}/cards/#{FIXTURE[:id]}"
assert card.kind_of?(Stripe::Card)
end
stub_request(:get, "#{Stripe.api_base}/v1/recipients/#{c.id}/cards/card").
to_return(body: JSON.generate(make_card(:recipient => 'test_recipient')))
card = c.cards.retrieve('card')
stub_request(:post, "#{Stripe.api_base}/v1/recipients/#{card.recipient}/cards/#{card.id}").
with(body: { exp_year: "2100" }).
to_return(body: JSON.generate(make_card))
card.exp_year = "2100"
should "be saveable" do
card = Stripe::Card.construct_from(FIXTURE.merge(recipient: @recipient.id))
card.metadata['key'] = 'value'
card.save
end
should "create should return a new recipient card" do
c = recipient
stub_request(:post, "#{Stripe.api_base}/v1/recipients/#{c.id}/cards").
with(body: { card: "tok_41YJ05ijAaWaFS" }).
to_return(body: JSON.generate(make_card))
_ = c.cards.create(:card => "tok_41YJ05ijAaWaFS")
assert_requested :post, "#{Stripe.api_base}/v1/recipients/#{@recipient.id}/cards/#{FIXTURE[:id]}"
end
end
end

View File

@ -2,17 +2,48 @@ require File.expand_path('../../test_helper', __FILE__)
module Stripe
class RecipientTest < Test::Unit::TestCase
should "recipient should be retrievable" do
stub_request(:get, "#{Stripe.api_base}/v1/recipients/test_recipient").
to_return(body: JSON.generate(make_recipient))
_ = Stripe::Recipient.retrieve('test_recipient')
FIXTURE = API_FIXTURES.fetch(:transfer_recipient)
should "be listable" do
recipients = Stripe::Recipient.list
assert_requested :get, "#{Stripe.api_base}/v1/recipients"
assert recipients.data.kind_of?(Array)
assert recipients.data[0].kind_of?(Stripe::Recipient)
end
should "recipient should be updateable" do
stub_request(:post, "#{Stripe.api_base}/v1/recipients/test_recipient").
with(body: { metadata: { key: "value" } }).
to_return(body: JSON.generate(make_refund))
_ = Stripe::Recipient.update('test_recipient', metadata: { key: 'value' })
should "be retrievable" do
recipient = Stripe::Recipient.retrieve(FIXTURE[:id])
assert_requested :get, "#{Stripe.api_base}/v1/recipients/#{FIXTURE[:id]}"
assert recipient.kind_of?(Stripe::Recipient)
end
should "be creatable" do
recipient = Stripe::Recipient.create(
name: "Noah Jackson",
type: "individual"
)
assert_requested :post, "#{Stripe.api_base}/v1/recipients"
assert recipient.kind_of?(Stripe::Recipient)
end
should "be saveable" do
recipient = Stripe::Recipient.retrieve(FIXTURE[:id])
recipient.metadata['key'] = 'value'
recipient.save
assert_requested :post, "#{Stripe.api_base}/v1/recipients/#{FIXTURE[:id]}"
end
should "be updateable" do
recipient = Stripe::Recipient.update(FIXTURE[:id], metadata: {foo: 'bar'})
assert_requested :post, "#{Stripe.api_base}/v1/recipients/#{FIXTURE[:id]}"
assert recipient.kind_of?(Stripe::Recipient)
end
should "be deletable" do
recipient = Stripe::Recipient.retrieve(FIXTURE[:id])
recipient = recipient.delete
assert_requested :delete, "#{Stripe.api_base}/v1/recipients/#{FIXTURE[:id]}"
assert recipient.kind_of?(Stripe::Recipient)
end
end
end

View File

@ -2,37 +2,38 @@ require File.expand_path('../../test_helper', __FILE__)
module Stripe
class RefundTest < Test::Unit::TestCase
should "refunds should be listable" do
stub_request(:get, "#{Stripe.api_base}/v1/refunds").
to_return(body: JSON.generate(make_refund_array))
FIXTURE = API_FIXTURES.fetch(:refund)
should "be listable" do
refunds = Stripe::Refund.list
assert_requested :get, "#{Stripe.api_base}/v1/refunds"
assert refunds.data.kind_of?(Array)
assert refunds.first.kind_of?(Stripe::Refund)
end
should "refunds should be saveable" do
stub_request(:get, "#{Stripe.api_base}/v1/refunds/get_refund").
to_return(body: JSON.generate(make_refund))
refund = Stripe::Refund.retrieve('get_refund')
should "be retrievable" do
refund = Stripe::Refund.retrieve(FIXTURE[:id])
assert_requested :get, "#{Stripe.api_base}/v1/refunds/#{FIXTURE[:id]}"
assert refund.kind_of?(Stripe::Refund)
end
stub_request(:post, "#{Stripe.api_base}/v1/refunds/#{refund.id}").
with(body: { metadata: { key: "value" } }).
to_return(body: JSON.generate(make_refund))
should "be creatable" do
refund = Stripe::Refund.create(:charge => API_FIXTURES[:charge][:id])
assert_requested :post, "#{Stripe.api_base}/v1/refunds"
assert refund.kind_of?(Stripe::Refund)
end
should "be saveable" do
refund = Stripe::Refund.retrieve(FIXTURE[:id])
refund.metadata['key'] = 'value'
refund.save
assert_requested :post, "#{Stripe.api_base}/v1/refunds/#{FIXTURE[:id]}"
end
should "refunds should be updateable" do
stub_request(:post, "#{Stripe.api_base}/v1/refunds/update_refund").
with(body: { metadata: { key: "value" } }).
to_return(body: JSON.generate(make_refund))
_ = Stripe::Refund.update('update_refund', metadata: { key: 'value' })
end
should "create should return a new refund" do
stub_request(:post, "#{Stripe.api_base}/v1/refunds").
with(body: { charge: "test_charge" }).
to_return(body: JSON.generate(make_refund))
_ = Stripe::Refund.create(:charge => 'test_charge')
should "be updateable" do
refund = Stripe::Refund.update(FIXTURE[:id], metadata: { key: 'value' })
assert_requested :post, "#{Stripe.api_base}/v1/refunds/#{FIXTURE[:id]}"
assert refund.kind_of?(Stripe::Refund)
end
end
end

View File

@ -2,35 +2,42 @@ require File.expand_path('../../test_helper', __FILE__)
module Stripe
class ReversalTest < Test::Unit::TestCase
should "reversals should be listable" do
stub_request(:get, "#{Stripe.api_base}/v1/transfers/test_transfer").
to_return(body: JSON.generate(make_transfer))
transfer = Stripe::Transfer.retrieve('test_transfer')
assert transfer.reversals.first.kind_of?(Stripe::Reversal)
FIXTURE = API_FIXTURES.fetch(:transfer_reversal)
setup do
@transfer = Stripe::Transfer.retrieve(API_FIXTURES.fetch(:transfer)[:id])
end
should "reversals should be updateable" do
stub_request(:get, "#{Stripe.api_base}/v1/transfers/test_transfer").
to_return(body: JSON.generate(make_transfer))
transfer = Stripe::Transfer.retrieve('test_transfer')
reversal = transfer.reversals.first
should "be listable" do
reversals = @transfer.reversals.list
assert_requested :get,
"#{Stripe.api_base}/v1/transfers/#{@transfer.id}/reversals"
assert reversals.data.kind_of?(Array)
assert reversals.data[0].kind_of?(Stripe::Reversal)
end
stub_request(:post, "#{Stripe.api_base}/v1/transfers/#{transfer.id}/reversals/#{reversal.id}").
with(body: { metadata: { key: "value" } }).
to_return(body: JSON.generate(make_reversal))
should "be retrievable" do
reversal = @transfer.reversals.retrieve(FIXTURE[:id])
assert_requested :get,
"#{Stripe.api_base}/v1/transfers/#{@transfer.id}/reversals/#{FIXTURE[:id]}"
assert reversal.kind_of?(Stripe::Reversal)
end
should "be creatable" do
reversal = @transfer.reversals.create(
amount: 100
)
assert_requested :post,
"#{Stripe.api_base}/v1/transfers/#{@transfer.id}/reversals"
assert reversal.kind_of?(Stripe::Reversal)
end
should "be saveable" do
reversal = @transfer.reversals.retrieve(FIXTURE[:id])
reversal.metadata['key'] = 'value'
reversal.save
end
should "create should return a new reversal" do
stub_request(:get, "#{Stripe.api_base}/v1/transfers/test_transfer").
to_return(body: JSON.generate(make_transfer))
transfer = Stripe::Transfer.retrieve('test_transfer')
stub_request(:post, "#{Stripe.api_base}/v1/transfers/#{transfer.id}/reversals").
with(body: { amount: "20" }).
to_return(body: JSON.generate(make_reversal))
_ = transfer.reversals.create(:amount => 20)
assert_requested :post,
"#{Stripe.api_base}/v1/transfers/#{@transfer.id}/reversals/#{FIXTURE[:id]}"
end
end
end

View File

@ -2,32 +2,49 @@ require File.expand_path('../../test_helper', __FILE__)
module Stripe
class SKUTest < Test::Unit::TestCase
should "SKUs should be listable" do
stub_request(:get, "#{Stripe.api_base}/v1/skus").
to_return(body: JSON.generate(make_sku_array("test_product")))
FIXTURE = API_FIXTURES.fetch(:sku)
should "be listable" do
skus = Stripe::SKU.list
assert skus.data.kind_of? Array
skus.each do |sku|
assert sku.kind_of?(Stripe::SKU)
end
assert_requested :get, "#{Stripe.api_base}/v1/skus"
assert skus.data.kind_of?(Array)
assert skus.data[0].kind_of?(Stripe::SKU)
end
should "SKUs should be updateable" do
stub_request(:post, "#{Stripe.api_base}/v1/skus/test_sku").
with(body: { metadata: { foo: "bar" } }).
to_return(body: JSON.generate(make_sku))
_ = Stripe::SKU.update("test_sku", metadata: {foo: 'bar'})
should "be retrievable" do
sku = Stripe::SKU.retrieve(FIXTURE[:id])
assert_requested :get, "#{Stripe.api_base}/v1/skus/#{FIXTURE[:id]}"
assert sku.kind_of?(Stripe::SKU)
end
should "SKUs should be deletable" do
stub_request(:get, "#{Stripe.api_base}/v1/skus/test_sku").
to_return(body: JSON.generate(make_sku))
s = Stripe::SKU.retrieve("test_sku")
stub_request(:delete, "#{Stripe.api_base}/v1/skus/#{s.id}").
to_return(body: JSON.generate(make_sku(:deleted => true)))
s.delete
should "be creatable" do
_ = Stripe::SKU.create(
currency: "USD",
inventory: { type: "finite", quantity: 500 },
price: 100,
product: API_FIXTURES.fetch(:product)[:id]
)
assert_requested :post, "#{Stripe.api_base}/v1/skus"
end
should "be saveable" do
sku = Stripe::SKU.retrieve(FIXTURE[:id])
sku.metadata['key'] = 'value'
sku.save
assert_requested :post, "#{Stripe.api_base}/v1/skus/#{FIXTURE[:id]}"
end
should "be updateable" do
sku = Stripe::SKU.update(FIXTURE[:id], metadata: {foo: 'bar'})
assert_requested :post, "#{Stripe.api_base}/v1/skus/#{FIXTURE[:id]}"
assert sku.kind_of?(Stripe::SKU)
end
should "be deletable" do
sku = Stripe::SKU.retrieve(FIXTURE[:id])
sku = sku.delete
assert_requested :delete, "#{Stripe.api_base}/v1/skus/#{FIXTURE[:id]}"
assert sku.kind_of?(Stripe::SKU)
end
end
end

View File

@ -2,66 +2,42 @@ require File.expand_path('../../test_helper', __FILE__)
module Stripe
class SourceTest < Test::Unit::TestCase
should 'be creatable' do
stub_request(:post, "#{Stripe.api_base}/v1/sources").
with(body: { type: 'card', token: 'tok_test' }).
to_return(body: JSON.generate(make_source_card))
_ = Stripe::Source.create(
FIXTURE = API_FIXTURES.fetch(:source)
should "be retrievable" do
source = Stripe::Source.retrieve(FIXTURE[:id])
assert_requested :get, "#{Stripe.api_base}/v1/sources/#{FIXTURE[:id]}"
assert source.kind_of?(Stripe::Source)
end
should "be creatable" do
source = Stripe::Source.create(
type: 'card',
token: 'tok_test',
token: API_FIXTURES.fetch(:token)[:id]
)
assert_requested :post, "#{Stripe.api_base}/v1/sources"
assert source.kind_of?(Stripe::Card)
end
should 'be retrievable' do
stub_request(:get, "#{Stripe.api_base}/v1/sources/source_test_card").
to_return(body: JSON.generate(make_source_card))
_ = Stripe::Source.retrieve('source_test_card')
end
should 'be updatable' do
stub_request(:post, "#{Stripe.api_base}/v1/sources/source_test_card").
with(body: { metadata: { foo: "bar" } }).
to_return(body: JSON.generate(make_source_card))
_ = Stripe::Source.update('source_test_card', metadata: {foo: 'bar'})
end
should 'be saveable' do
stub_request(:get, "#{Stripe.api_base}/v1/sources/source_test_card").
to_return(body: JSON.generate(make_source_card))
source = Stripe::Source.retrieve('source_test_card')
stub_request(:post, "#{Stripe.api_base}/v1/sources/#{source.id}").
with(body: { metadata: { foo: "bar" } }).
to_return(body: JSON.generate(make_source_card))
source.metadata['foo'] = 'bar'
should "be saveable" do
source = Stripe::Source.retrieve(FIXTURE[:id])
source.metadata['key'] = 'value'
source.save
assert_requested :post, "#{Stripe.api_base}/v1/sources/#{FIXTURE[:id]}"
end
should 'not be deletable' do
stub_request(:get, "#{Stripe.api_base}/v1/sources/source_test_card").
to_return(body: JSON.generate(make_source_card))
source = Stripe::Source.retrieve('source_test_card')
should "be updateable" do
source = Stripe::Source.update(FIXTURE[:id], metadata: {foo: 'bar'})
assert_requested :post, "#{Stripe.api_base}/v1/sources/#{FIXTURE[:id]}"
assert source.kind_of?(Stripe::Card)
end
assert_raises NoMethodError do
source.delete
context "#verify" do
should "verify the source" do
source = Stripe::Source.retrieve(FIXTURE[:id])
source = source.verify(:values => [1,2])
assert source.kind_of?(Stripe::Source)
end
end
should 'not be listable' do
assert_raises NoMethodError do
Stripe::Source.list
end
end
should 'be verifiable' do
stub_request(:get, "#{Stripe.api_base}/v1/sources/source_test_card").
to_return(body: JSON.generate(make_source_card))
source = Stripe::Source.retrieve('source_test_card')
stub_request(:post, "#{Stripe.api_base}/v1/sources/#{source.id}/verify").
with(body: { amounts: ["1", "2"] }).
to_return(body: JSON.generate(make_source_card))
source.verify(:amounts => [1,2])
end
end
end

View File

@ -0,0 +1,428 @@
require File.expand_path('../../test_helper', __FILE__)
module Stripe
class StripeClientTest < Test::Unit::TestCase
context ".active_client" do
should "be .default_client outside of #request" do
assert_equal StripeClient.default_client, StripeClient.active_client
end
should "be active client inside of #request" do
client = StripeClient.new
client.request do
assert_equal client, StripeClient.active_client
end
end
end
context ".default_client" do
should "be a StripeClient" do
assert_kind_of StripeClient, StripeClient.default_client
end
end
context ".default_conn" do
should "be a Faraday::Connection" do
assert_kind_of Faraday::Connection, StripeClient.default_conn
end
should "be a different connection on each thread" do
other_thread_conn = nil
thread = Thread.new do
other_thread_conn = StripeClient.default_conn
end
thread.join
refute_equal StripeClient.default_conn, other_thread_conn
end
end
context ".should_retry?" do
setup do
Stripe.stubs(:max_network_retries).returns(2)
end
should 'retry on timeout' do
assert StripeClient.should_retry?(Faraday::TimeoutError.new(""), 0)
end
should 'retry on a failed connection' do
assert StripeClient.should_retry?(Faraday::ConnectionFailed.new(""), 0)
end
should 'retry on a conflict' do
error = make_rate_limit_error
e = Faraday::ClientError.new(error[:error][:message], { status: 409 })
assert StripeClient.should_retry?(e, 0)
end
should 'not retry at maximum count' do
refute StripeClient.should_retry?(RuntimeError.new, Stripe.max_network_retries)
end
should 'not retry on a certificate validation error' do
refute StripeClient.should_retry?(Faraday::SSLError.new(""), 0)
end
end
context ".sleep_time" do
should "should grow exponentially" do
StripeClient.stubs(:rand).returns(1)
Stripe.stubs(:max_network_retry_delay).returns(999)
assert_equal(Stripe.initial_network_retry_delay, StripeClient.sleep_time(1))
assert_equal(Stripe.initial_network_retry_delay * 2, StripeClient.sleep_time(2))
assert_equal(Stripe.initial_network_retry_delay * 4, StripeClient.sleep_time(3))
assert_equal(Stripe.initial_network_retry_delay * 8, StripeClient.sleep_time(4))
end
should "enforce the max_network_retry_delay" do
StripeClient.stubs(:rand).returns(1)
Stripe.stubs(:initial_network_retry_delay).returns(1)
Stripe.stubs(:max_network_retry_delay).returns(2)
assert_equal(1, StripeClient.sleep_time(1))
assert_equal(2, StripeClient.sleep_time(2))
assert_equal(2, StripeClient.sleep_time(3))
assert_equal(2, StripeClient.sleep_time(4))
end
should "add some randomness" do
random_value = 0.8
StripeClient.stubs(:rand).returns(random_value)
Stripe.stubs(:initial_network_retry_delay).returns(1)
Stripe.stubs(:max_network_retry_delay).returns(8)
base_value = Stripe.initial_network_retry_delay * (0.5 * (1 + random_value))
# the initial value cannot be smaller than the base,
# so the randomness is ignored
assert_equal(Stripe.initial_network_retry_delay, StripeClient.sleep_time(1))
# after the first one, the randomness is applied
assert_equal(base_value * 2, StripeClient.sleep_time(2))
assert_equal(base_value * 4, StripeClient.sleep_time(3))
assert_equal(base_value * 8, StripeClient.sleep_time(4))
end
end
context "#initialize" do
should "set Stripe.default_conn" do
client = StripeClient.new
assert_equal StripeClient.default_conn, client.conn
end
should "set a different connection if one was specified" do
conn = Faraday.new
client = StripeClient.new(conn)
assert_equal conn, client.conn
end
end
context "#execute_request" do
context "headers" do
should "support literal headers" do
stub_request(:post, "#{Stripe.api_base}/v1/account").
with(headers: { "Stripe-Account" => "bar" }).
to_return(body: JSON.generate(API_FIXTURES.fetch(:account)))
client = StripeClient.new
client.execute_request(:post, '/v1/account',
headers: { "Stripe-Account" => "bar" }
)
end
should "support RestClient-style header keys" do
stub_request(:post, "#{Stripe.api_base}/v1/account").
with(headers: { "Stripe-Account" => "bar" }).
to_return(body: JSON.generate(API_FIXTURES.fetch(:account)))
client = StripeClient.new
client.execute_request(:post, '/v1/account',
headers: { :stripe_account => "bar" }
)
end
end
context "Stripe-Account header" do
should "use a globally set header" do
Stripe.stripe_account = 'acct_1234'
stub_request(:post, "#{Stripe.api_base}/v1/account").
with(headers: {"Stripe-Account" => Stripe.stripe_account}).
to_return(body: JSON.generate(API_FIXTURES.fetch(:account)))
client = StripeClient.new
client.execute_request(:post, '/v1/account')
end
should "use a locally set header" do
stripe_account = "acct_0000"
stub_request(:post, "#{Stripe.api_base}/v1/account").
with(headers: {"Stripe-Account" => stripe_account}).
to_return(body: JSON.generate(API_FIXTURES.fetch(:account)))
client = StripeClient.new
client.execute_request(:post, '/v1/account',
headers: { :stripe_account => stripe_account }
)
end
should "not send it otherwise" do
stub_request(:post, "#{Stripe.api_base}/v1/account").
with { |req|
req.headers["Stripe-Account"].nil?
}.to_return(body: JSON.generate(API_FIXTURES.fetch(:account)))
client = StripeClient.new
client.execute_request(:post, '/v1/account')
end
end
context "error handling" do
should "handle error response with empty body" do
stub_request(:post, "#{Stripe.api_base}/v1/charges").
to_return(body: '', status: 500)
client = StripeClient.new
e = assert_raises Stripe::APIError do
client.execute_request(:post, '/v1/charges')
end
assert_equal 'Invalid response object from API: "" (HTTP response code was 500)', e.message
end
should "handle error response with non-object error value" do
stub_request(:post, "#{Stripe.api_base}/v1/charges").
to_return(body: JSON.generate({ error: "foo" }), status: 500)
client = StripeClient.new
e = assert_raises Stripe::APIError do
client.execute_request(:post, '/v1/charges')
end
assert_equal 'Invalid response object from API: "{\"error\":\"foo\"}" (HTTP response code was 500)', e.message
end
should "raise InvalidRequestError on 400" do
stub_request(:post, "#{Stripe.api_base}/v1/charges").
to_return(body: JSON.generate(make_missing_id_error), status: 400)
client = StripeClient.new
begin
client.execute_request(:post, '/v1/charges')
rescue Stripe::InvalidRequestError => e
assert_equal(400, e.http_status)
assert_equal(true, !!e.http_body)
assert_equal(true, e.json_body.kind_of?(Hash))
end
end
should "raise AuthenticationError on 401" do
stub_request(:post, "#{Stripe.api_base}/v1/charges").
to_return(body: JSON.generate(make_missing_id_error), status: 401)
client = StripeClient.new
begin
client.execute_request(:post, '/v1/charges')
rescue Stripe::AuthenticationError => e
assert_equal(401, e.http_status)
assert_equal(true, !!e.http_body)
assert_equal(true, e.json_body.kind_of?(Hash))
end
end
should "raise CardError on 402" do
stub_request(:post, "#{Stripe.api_base}/v1/charges").
to_return(body: JSON.generate(make_missing_id_error), status: 402)
client = StripeClient.new
begin
client.execute_request(:post, '/v1/charges')
rescue Stripe::CardError => e
assert_equal(402, e.http_status)
assert_equal(true, !!e.http_body)
assert_equal(true, e.json_body.kind_of?(Hash))
end
end
should "raise PermissionError on 403" do
stub_request(:post, "#{Stripe.api_base}/v1/charges").
to_return(body: JSON.generate(make_missing_id_error), status: 403)
client = StripeClient.new
begin
client.execute_request(:post, '/v1/charges')
rescue Stripe::PermissionError => e
assert_equal(403, e.http_status)
assert_equal(true, !!e.http_body)
assert_equal(true, e.json_body.kind_of?(Hash))
end
end
should "raise InvalidRequestError on 404" do
stub_request(:post, "#{Stripe.api_base}/v1/charges").
to_return(body: JSON.generate(make_missing_id_error), status: 404)
client = StripeClient.new
begin
client.execute_request(:post, '/v1/charges')
rescue Stripe::InvalidRequestError => e
assert_equal(404, e.http_status)
assert_equal(true, !!e.http_body)
assert_equal(true, e.json_body.kind_of?(Hash))
end
end
should "raise RateLimitError on 429" do
stub_request(:post, "#{Stripe.api_base}/v1/charges").
to_return(body: JSON.generate(make_rate_limit_error), status: 429)
client = StripeClient.new
begin
client.execute_request(:post, '/v1/charges')
rescue Stripe::RateLimitError => e
assert_equal(429, e.http_status)
assert_equal(true, !!e.http_body)
assert_equal(true, e.json_body.kind_of?(Hash))
end
end
end
context "idempotency keys" do
setup do
Stripe.stubs(:max_network_retries).returns(2)
end
should 'not add an idempotency key to GET requests' do
SecureRandom.expects(:uuid).times(0)
stub_request(:get, "#{Stripe.api_base}/v1/charges/#{API_FIXTURES.fetch(:charge)[:id]}").
with { |req|
req.headers['Idempotency-Key'].nil?
}.to_return(body: JSON.generate(API_FIXTURES.fetch(:charge)))
client = StripeClient.new
client.execute_request(:get, "/v1/charges/#{API_FIXTURES.fetch(:charge)[:id]}")
end
should 'ensure there is always an idempotency_key on POST requests' do
SecureRandom.expects(:uuid).at_least_once.returns("random_key")
stub_request(:post, "#{Stripe.api_base}/v1/charges").
with(headers: {"Idempotency-Key" => "random_key"}).
to_return(body: JSON.generate(API_FIXTURES.fetch(:charge)))
client = StripeClient.new
client.execute_request(:post, "/v1/charges")
end
should 'ensure there is always an idempotency_key on DELETE requests' do
SecureRandom.expects(:uuid).at_least_once.returns("random_key")
stub_request(:delete, "#{Stripe.api_base}/v1/charges/#{API_FIXTURES.fetch(:charge)[:id]}").
with(headers: {"Idempotency-Key" => "random_key"}).
to_return(body: JSON.generate(API_FIXTURES.fetch(:charge)))
client = StripeClient.new
client.execute_request(:delete, "/v1/charges/#{API_FIXTURES.fetch(:charge)[:id]}")
end
should 'not override a provided idempotency_key' do
# Note that this expectation looks like `:idempotency_key` instead of
# the header `Idempotency-Key` because it's user provided as seen
# below. The ones injected by the library itself look like headers
# (`Idempotency-Key`), but rest-client does allow this symbol
# formatting and will properly override the system generated one as
# expected.
stub_request(:post, "#{Stripe.api_base}/v1/charges").
with(headers: {"Idempotency-Key" => "provided_key"}).
to_return(body: JSON.generate(API_FIXTURES.fetch(:charge)))
client = StripeClient.new
client.execute_request(:post, "/v1/charges",
headers: {:idempotency_key => 'provided_key'})
end
end
context "retry logic" do
setup do
Stripe.stubs(:max_network_retries).returns(2)
end
should 'retry failed requests and raise if error persists' do
StripeClient.expects(:sleep_time).at_least_once.returns(0)
stub_request(:post, "#{Stripe.api_base}/v1/charges").
to_raise(Errno::ECONNREFUSED.new)
client = StripeClient.new
err = assert_raises Stripe::APIConnectionError do
client.execute_request(:post, '/v1/charges')
end
assert_match(/Request was retried 2 times/, err.message)
end
should 'retry failed requests and return successful response' do
StripeClient.expects(:sleep_time).at_least_once.returns(0)
i = 0
stub_request(:post, "#{Stripe.api_base}/v1/charges").
to_return { |_|
if i < 2
i += 1
raise Errno::ECONNREFUSED.new
else
{ body: JSON.generate({"id" => "myid"}) }
end
}
client = StripeClient.new
client.execute_request(:post, '/v1/charges')
end
end
end
context "#request" do
should "return a result and response object" do
stub_request(:post, "#{Stripe.api_base}/v1/charges").
to_return(body: JSON.generate(API_FIXTURES.fetch(:charge)))
client = StripeClient.new
charge, resp = client.request { Charge.create }
assert charge.is_a?(Charge)
assert resp.is_a?(StripeResponse)
assert_equal 200, resp.http_status
end
should "return the value of given block" do
client = StripeClient.new
ret, _ = client.request { 7 }
assert_equal 7, ret
end
should "reset local thread state after a call" do
begin
Thread.current[:stripe_client] = :stripe_client
client = StripeClient.new
client.request {}
assert_equal :stripe_client, Thread.current[:stripe_client]
ensure
Thread.current[:stripe_client] = nil
end
end
end
end
class SystemProfilerTest < Test::Unit::TestCase
context "#get_uname" do
should "run without failure" do
# Don't actually check the result because we try a variety of different
# strategies that will have different results depending on where this
# test and running. We're mostly making sure that no exception is thrown.
_ = StripeClient::SystemProfiler.get_uname
end
end
context "#get_uname_from_system" do
should "run without failure" do
# as above, just verify that an exception is not thrown
_ = StripeClient::SystemProfiler.get_uname_from_system
end
end
context "#get_uname_from_system_ver" do
should "run without failure" do
# as above, just verify that an exception is not thrown
_ = StripeClient::SystemProfiler.get_uname_from_system_ver
end
end
end
end

View File

@ -116,9 +116,13 @@ module Stripe
# customer comes with a `sources` list that makes a convenient object to
# perform tests on
customer = Stripe::Customer.construct_from(make_customer, opts)
obj = Stripe::StripeObject.construct_from({
sources: [
{}
]
}, opts)
source = customer.sources.first
source = obj.sources.first
# Pulling `@opts` as an instance variable here is not ideal, but it's
# important enough argument that the test here is worth it. we should
# consider exposing it publicly on a future pull (and possibly renaming

View File

@ -0,0 +1,46 @@
require File.expand_path('../../test_helper', __FILE__)
module Stripe
class StripeResponseTest < Test::Unit::TestCase
context ".from_faraday_hash" do
should "converts to StripeResponse" do
body = '{"foo": "bar"}'
headers = { "Request-Id" => "request-id" }
http_resp = {
body: body,
headers: headers,
status: 200,
}
resp = StripeResponse.from_faraday_hash(http_resp)
assert_equal JSON.parse(body, symbolize_names: true), resp.data
assert_equal body, resp.http_body
assert_equal headers, resp.http_headers
assert_equal 200, resp.http_status
assert_equal "request-id", resp.request_id
end
end
context ".from_faraday_response" do
should "converts to StripeResponse" do
body = '{"foo": "bar"}'
headers = { "Request-Id" => "request-id" }
env = Faraday::Env.from(
:status => 200, :body => body,
:response_headers => headers)
http_resp = Faraday::Response.new(env)
resp = StripeResponse.from_faraday_response(http_resp)
assert_equal JSON.parse(body, symbolize_names: true), resp.data
assert_equal body, resp.http_body
assert_equal headers, resp.http_headers
assert_equal 200, resp.http_status
assert_equal "request-id", resp.request_id
end
end
end
end

View File

@ -2,62 +2,53 @@ require File.expand_path('../../test_helper', __FILE__)
module Stripe
class SubscriptionItemTest < Test::Unit::TestCase
should "subscription items should be retrievable" do
stub_request(:get, "#{Stripe.api_base}/v1/subscription_items/si_test_subscription_item").
to_return(body: JSON.generate(make_subscription_item))
sub_item = Stripe::SubscriptionItem.retrieve('si_test_subscription_item')
FIXTURE = API_FIXTURES.fetch(:subscription_item)
assert sub_item.kind_of?(Stripe::SubscriptionItem)
should "be listable" do
items = Stripe::SubscriptionItem.list(
subscription: API_FIXTURES.fetch(:subscription)[:id]
)
assert_requested :get, "#{Stripe.api_base}/v1/subscription_items",
query: { subscription: API_FIXTURES.fetch(:subscription)[:id] }
assert items.data.kind_of?(Array)
assert items.data[0].kind_of?(Stripe::SubscriptionItem)
end
should "subscription items should be listable" do
stub_request(:get, "#{Stripe.api_base}/v1/subscription_items").
with(query: { subscription: "s_test_subscription", limit: "3" }).
to_return(body: JSON.generate(make_subscription_item_array))
sub_items = Stripe::SubscriptionItem.list(:subscription => 's_test_subscription', :limit => 3).data
assert sub_items.kind_of? Array
assert sub_items[0].kind_of? Stripe::SubscriptionItem
should "be retrievable" do
item = Stripe::SubscriptionItem.retrieve(FIXTURE[:id])
assert_requested :get, "#{Stripe.api_base}/v1/subscription_items/#{FIXTURE[:id]}"
assert item.kind_of?(Stripe::SubscriptionItem)
end
should "subscription items should be deletable" do
stub_request(:get, "#{Stripe.api_base}/v1/subscription_items/si_test_subscription_item").
to_return(body: JSON.generate(make_subscription_item))
sub_item = Stripe::SubscriptionItem.retrieve('si_test_subscription_item')
stub_request(:delete, "#{Stripe.api_base}/v1/subscription_items/#{sub_item.id}").
to_return(body: JSON.generate(make_subscription_item))
sub_item.delete
should "be creatable" do
item = Stripe::SubscriptionItem.create(
item: 'silver',
plan: API_FIXTURES.fetch(:plan)[:id],
quantity: 3,
subscription: API_FIXTURES.fetch(:subscription)[:id]
)
assert_requested :post, "#{Stripe.api_base}/v1/subscription_items"
assert item.kind_of?(Stripe::SubscriptionItem)
end
should "subscription items should be updateable" do
sid = 'si_test_subscription_item'
stub_request(:post, "#{Stripe.api_base}/v1/subscription_items/#{sid}").
with(body: { plan: "silver", quantity: "3" }).
to_return(body: JSON.generate(make_subscription_item))
_ = Stripe::SubscriptionItem.update(sid, {:plan => 'silver', :quantity => 3})
should "be saveable" do
item = Stripe::SubscriptionItem.retrieve(FIXTURE[:id])
item.quantity = 4
item.save
assert_requested :post, "#{Stripe.api_base}/v1/subscription_items/#{FIXTURE[:id]}"
end
should "subscription items should be saveable" do
stub_request(:get, "#{Stripe.api_base}/v1/subscription_items/si_test_subscription_item").
to_return(body: JSON.generate(make_subscription_item))
sub_item = Stripe::SubscriptionItem.retrieve('si_test_subscription_item')
stub_request(:post, "#{Stripe.api_base}/v1/subscription_items/#{sub_item.id}").
with(body: { plan: "silver", quantity: "3" }).
to_return(body: JSON.generate(make_subscription_item))
sub_item.plan = 'silver'
sub_item.quantity = 3
sub_item.save
should "be updateable" do
item = Stripe::SubscriptionItem.update(FIXTURE[:id], metadata: {foo: 'bar'})
assert_requested :post, "#{Stripe.api_base}/v1/subscription_items/#{FIXTURE[:id]}"
assert item.kind_of?(Stripe::SubscriptionItem)
end
should "create should return a new subscription item" do
stub_request(:post, "#{Stripe.api_base}/v1/subscription_items").
with(body: { plan: "silver", quantity: "3" }).
to_return(body: JSON.generate(make_subscription_item))
_ = Stripe::SubscriptionItem.create(:plan => 'silver', :quantity => 3)
should "be deletable" do
item = Stripe::SubscriptionItem.retrieve(FIXTURE[:id])
item = item.delete
assert_requested :delete, "#{Stripe.api_base}/v1/subscription_items/#{FIXTURE[:id]}"
assert item.kind_of?(Stripe::SubscriptionItem)
end
end
end

View File

@ -2,136 +2,59 @@ require File.expand_path('../../test_helper', __FILE__)
module Stripe
class SubscriptionTest < Test::Unit::TestCase
should "subscriptions should be retrievable by customer" do
stub_request(:get, "#{Stripe.api_base}/v1/customers/c_test_customer").
to_return(body: JSON.generate(make_customer))
customer = Stripe::Customer.retrieve('c_test_customer')
FIXTURE = API_FIXTURES.fetch(:subscription)
stub_request(:get, "#{Stripe.api_base}/v1/customers/c_test_customer/subscriptions/s_test_subscription").
to_return(body: JSON.generate(make_subscription))
_ = customer.subscriptions.retrieve('s_test_subscription')
should "be listable" do
subscriptions = Stripe::Subscription.list
assert_requested :get, "#{Stripe.api_base}/v1/subscriptions"
assert subscriptions.data.kind_of?(Array)
assert subscriptions.data[0].kind_of?(Stripe::Subscription)
end
should "subscriptions should be listable by customer" do
stub_request(:get, "#{Stripe.api_base}/v1/customers/c_test_customer").
to_return(body: JSON.generate(make_customer))
customer = Stripe::Customer.retrieve('c_test_customer')
stub_request(:get, "#{Stripe.api_base}/v1/customers/c_test_customer/subscriptions").
to_return(body: JSON.generate(make_customer_subscription_array('c_test_customer')))
subs = customer.subscriptions.list
assert subs.kind_of?(Stripe::ListObject)
assert subs.data.kind_of?(Array)
assert subs.data[0].kind_of? Stripe::Subscription
should "be retrievable" do
subscription = Stripe::Subscription.retrieve(FIXTURE[:id])
assert_requested :get,
"#{Stripe.api_base}/v1/subscriptions/#{FIXTURE[:id]}"
assert subscription.kind_of?(Stripe::Subscription)
end
should "subscriptions should be creatable by customer" do
stub_request(:get, "#{Stripe.api_base}/v1/customers/c_test_customer").
to_return(body: JSON.generate(make_customer))
customer = Stripe::Customer.retrieve('c_test_customer')
stub_request(:post, "#{Stripe.api_base}/v1/customers/c_test_customer/subscriptions").
with(body: { plan: "silver" }).
to_return(body: JSON.generate(make_subscription))
_ = customer.subscriptions.create(:plan => 'silver')
should "be creatable" do
subscription = Stripe::Subscription.create(
customer: API_FIXTURES.fetch(:customer)[:id]
)
assert_requested :post, "#{Stripe.api_base}/v1/subscriptions"
assert subscription.kind_of?(Stripe::Subscription)
end
should "subscriptions should be retrievable" do
stub_request(:get, "#{Stripe.api_base}/v1/subscriptions/s_test_subscription").
to_return(body: JSON.generate(make_subscription))
sub = Stripe::Subscription.retrieve('s_test_subscription')
assert sub.kind_of?(Stripe::Subscription)
should "be saveable" do
subscription = Stripe::Subscription.retrieve(FIXTURE[:id])
subscription.metadata['key'] = 'value'
subscription.save
assert_requested :post,
"#{Stripe.api_base}/v1/subscriptions/#{FIXTURE[:id]}"
end
should "subscriptions should be listable" do
stub_request(:get, "#{Stripe.api_base}/v1/subscriptions").
to_return(body: JSON.generate(make_subscription_array))
subs = Stripe::Subscription.list.data
assert subs.kind_of? Array
assert subs[0].kind_of? Stripe::Subscription
should "be updateable" do
subscription = Stripe::Subscription.update(FIXTURE[:id], metadata: {foo: 'bar'})
assert_requested :post,
"#{Stripe.api_base}/v1/subscriptions/#{FIXTURE[:id]}"
assert subscription.kind_of?(Stripe::Subscription)
end
should "subscriptions should be listable with filters" do
stub_request(:get, "#{Stripe.api_base}/v1/subscriptions").
with(query: { customer: "c_test_customer", limit: "3", plan: "gold" }).
to_return(body: JSON.generate(make_subscription_array))
subs = Stripe::Subscription.all(:customer => 'c_test_customer', :limit => 3, :plan => 'gold')
assert subs.kind_of?(Stripe::ListObject)
assert subs.data.kind_of?(Array)
assert subs.data[0].kind_of? Stripe::Subscription
should "be deletable" do
subscription = Stripe::Subscription.retrieve(FIXTURE[:id])
subscription = subscription.delete
assert_requested :delete,
"#{Stripe.api_base}/v1/subscriptions/#{FIXTURE[:id]}"
assert subscription.kind_of?(Stripe::Subscription)
end
should "subscriptions should be refreshable" do
stub_request(:get, "#{Stripe.api_base}/v1/subscriptions/s_test_subscription").
to_return(body: JSON.generate(make_subscription))
sub = Stripe::Subscription.retrieve('s_test_subscription')
sub.refresh
end
should "subscriptions should be deletable" do
stub_request(:get, "#{Stripe.api_base}/v1/subscriptions/s_test_subscription").
to_return(body: JSON.generate(make_subscription))
sub = Stripe::Subscription.retrieve('s_test_subscription')
stub_request(:delete, "#{Stripe.api_base}/v1/subscriptions/#{sub.id}").
with(query: { at_period_end: "true" }).
to_return(body: JSON.generate(make_subscription))
sub.delete :at_period_end => true
stub_request(:delete, "#{Stripe.api_base}/v1/subscriptions/#{sub.id}").
to_return(body: JSON.generate(make_subscription))
sub.delete
end
should "subscriptions should be updateable" do
sid = 's_test_subscription'
stub_request(:post, "#{Stripe.api_base}/v1/subscriptions/#{sid}").
with(body: { status: "active" }).
to_return(body: JSON.generate(make_subscription))
_ = Stripe::Subscription.update(sid, :status => 'active')
end
should "subscription items should be updateable" do
sid = 's_test_subscription'
stub_request(:post, "#{Stripe.api_base}/v1/subscriptions/#{sid}").
with(body: { items: [{plan: "gold", quantity: "1"}, {plan: "silver", quantity: "2" }] }).
to_return(body: JSON.generate(make_subscription))
_ = Stripe::Subscription.update(sid, :items => [{:plan => 'gold', :quantity =>1}, {:plan => 'silver', :quantity =>2}])
end
should "subscriptions should be saveable" do
stub_request(:get, "#{Stripe.api_base}/v1/subscriptions/s_test_subscription").
to_return(body: JSON.generate(make_subscription))
sub = Stripe::Subscription.retrieve('s_test_subscription')
stub_request(:post, "#{Stripe.api_base}/v1/subscriptions/#{sub.id}").
with(body: { status: "active" }).
to_return(body: JSON.generate(make_subscription))
sub.status = 'active'
sub.save
end
should "create should return a new subscription" do
stub_request(:post, "#{Stripe.api_base}/v1/subscriptions").
with(body: { customer: "c_test_customer", plan: "gold" }).
to_return(body: JSON.generate(make_subscription))
_ = Stripe::Subscription.create(:plan => 'gold', :customer => 'c_test_customer')
end
should "be able to delete a subscriptions's discount" do
stub_request(:post, "#{Stripe.api_base}/v1/subscriptions").
to_return(body: JSON.generate(make_subscription))
sub = Stripe::Subscription.create(:plan => 'gold', :customer => 'c_test_customer', coupon: 'forever')
stub_request(:delete, "#{Stripe.api_base}/v1/subscriptions/#{sub.id}/discount").
to_return(body: JSON.generate(make_delete_discount_response))
sub.delete_discount
assert_equal nil, sub.discount
context "#delete_discount" do
should "be able to delete a subscriptions's discount" do
subscription = Stripe::Subscription.retrieve(FIXTURE[:id])
subscription = subscription.delete_discount
assert subscription.kind_of?(Stripe::Subscription)
end
end
end
end

View File

@ -2,23 +2,22 @@ require File.expand_path('../../test_helper', __FILE__)
module Stripe
class ThreeDSecureTest < Test::Unit::TestCase
should "retrieve an existing 3D Secure object" do
stub_request(:get, "#{Stripe.api_base}/v1/3d_secure/tdsrc_test").
to_return(body: JSON.generate(make_three_d_secure))
tds = Stripe::ThreeDSecure.retrieve("tdsrc_test")
assert_equal "tdsrc_test", tds.id
FIXTURE = API_FIXTURES.fetch(:three_d_secure)
should "be retrievable" do
secure = Stripe::ThreeDSecure.retrieve(FIXTURE[:id])
assert_requested :get, "#{Stripe.api_base}/v1/3d_secure/#{FIXTURE[:id]}"
assert secure.kind_of?(Stripe::ThreeDSecure)
end
should "create should return a new 3D Secure object" do
stub_request(:post, "#{Stripe.api_base}/v1/3d_secure").
with(body: { card: "tok_test", amount: "1500", currency: "usd", return_url: "https://example.org/3d-secure-result" }).
to_return(body: JSON.generate(make_three_d_secure))
should "be creatable" do
_ = Stripe::ThreeDSecure.create(
:card => "tok_test",
:amount => 1500,
:currency => "usd",
:return_url => "https://example.org/3d-secure-result"
card: API_FIXTURES.fetch(:token)[:id],
amount: 1500,
currency: "usd",
return_url: "https://example.org/3d-secure-result"
)
assert_requested :post, "#{Stripe.api_base}/v1/3d_secure"
end
end
end

View File

@ -2,35 +2,49 @@ require File.expand_path('../../test_helper', __FILE__)
module Stripe
class TransferTest < Test::Unit::TestCase
should "retrieve should retrieve transfer" do
stub_request(:get, "#{Stripe.api_base}/v1/transfers/tr_test_transfer").
to_return(body: JSON.generate(make_transfer))
transfer = Stripe::Transfer.retrieve('tr_test_transfer')
assert_equal 'tr_test_transfer', transfer.id
FIXTURE = API_FIXTURES.fetch(:transfer)
should "be listable" do
transfers = Stripe::Transfer.list
assert_requested :get, "#{Stripe.api_base}/v1/transfers"
assert transfers.data.kind_of?(Array)
assert transfers.data[0].kind_of?(Stripe::Transfer)
end
should "create should create a transfer" do
stub_request(:post, "#{Stripe.api_base}/v1/transfers").
to_return(body: JSON.generate(make_transfer))
transfer = Stripe::Transfer.create
assert_equal "tr_test_transfer", transfer.id
should "be retrievable" do
transfer = Stripe::Transfer.retrieve(FIXTURE[:id])
assert_requested :get, "#{Stripe.api_base}/v1/transfers/#{FIXTURE[:id]}"
assert transfer.kind_of?(Stripe::Transfer)
end
should "create should update a transfer" do
stub_request(:post, "#{Stripe.api_base}/v1/transfers/test_transfer").
with(body: { metadata: { foo: "bar" } }).
to_return(body: JSON.generate(make_transfer))
Stripe::Transfer.update("test_transfer", metadata: {foo: 'bar'})
should "be creatable" do
transfer = Stripe::Transfer.create(
amount: 100,
currency: "USD"
)
assert_requested :post, "#{Stripe.api_base}/v1/transfers"
assert transfer.kind_of?(Stripe::Transfer)
end
should "cancel should cancel a transfer" do
stub_request(:get, "#{Stripe.api_base}/v1/transfers/tr_test_transfer").
to_return(body: JSON.generate(make_transfer))
transfer = Stripe::Transfer.retrieve('tr_test_transfer')
should "be saveable" do
transfer = Stripe::Transfer.retrieve(FIXTURE[:id])
transfer.metadata['key'] = 'value'
transfer.save
assert_requested :post, "#{Stripe.api_base}/v1/transfers/#{FIXTURE[:id]}"
end
stub_request(:post, "#{Stripe.api_base}/v1/transfers/tr_test_transfer/cancel").
to_return(body: JSON.generate(make_canceled_transfer))
transfer.cancel
should "be updateable" do
transfer = Stripe::Transfer.update(FIXTURE[:id], metadata: {foo: 'bar'})
assert_requested :post, "#{Stripe.api_base}/v1/transfers/#{FIXTURE[:id]}"
assert transfer.kind_of?(Stripe::Transfer)
end
context "#cancel" do
should "cancel a transfer" do
transfer = Stripe::Transfer.retrieve(FIXTURE[:id])
transfer = transfer.cancel
assert transfer.kind_of?(Stripe::Transfer)
end
end
end
end

View File

@ -34,36 +34,8 @@ class StripeTest < Test::Unit::TestCase
end
end
should "makes requests with the Stripe-Account header" do
Stripe.stripe_account = 'acct_1234'
stub_request(:post, "#{Stripe.api_base}/v1/account").
with(headers: {"Stripe-Account" => Stripe.stripe_account}).
to_return(body: JSON.generate(make_account))
Stripe.request(:post, '/v1/account', 'sk_live12334566')
end
context "#get_uname" do
should "run without failure" do
# Don't actually check the result because we try a variety of different
# strategies that will have different results depending on where this
# test and running. We're mostly making sure that no exception is thrown.
_ = Stripe.get_uname
end
end
context "#get_uname_from_system" do
should "run without failure" do
# as above, just verify that an exception is not thrown
_ = Stripe.get_uname_from_system
end
end
context "#get_uname_from_system_ver" do
should "run without failure" do
# as above, just verify that an exception is not thrown
_ = Stripe.get_uname_from_system_ver
end
should "have default open and read timeouts" do
assert_equal Stripe.open_timeout, 30
assert_equal Stripe.read_timeout, 80
end
end

View File

@ -1,514 +1,11 @@
module Stripe
module TestData
def make_account(params={})
def make_error(type, message)
{
:charges_enabled => false,
:details_submitted => false,
:email => "test+bindings@stripe.com",
}.merge(params)
end
def make_balance(params={})
{
:pending => [
{:amount => 12345, :currency => "usd"}
],
:available => [
{:amount => 6789, :currency => "usd"}
],
:livemode => false,
:object => "balance"
}.merge(params)
end
def make_balance_transaction(params={})
{
:amount => 100,
:net => 41,
:currency => "usd",
:type => "charge",
:created => 1371945005,
:available_on => 1372549805,
:status => "pending",
:description => "A test balance transaction",
:fee => 59,
:object => "balance_transaction"
}.merge(params)
end
def make_balance_transaction_array
{
:data => [make_balance_transaction, make_balance_transaction, make_balance_transaction],
:object => "list",
:resource_url => "/v1/balance/history"
}
end
def make_application_fee(params={})
id = params[:id] || 'fee_test_fee'
{
:refunded => false,
:amount => 100,
:application => "ca_test_application",
:user => "acct_test_user",
:charge => "ch_test_charge",
:id => id,
:livemode => false,
:currency => "usd",
:object => "application_fee",
:refunds => make_application_fee_refund_array(id),
:created => 1304114826
}.merge(params)
end
def make_application_fee_refund(params = {})
{
:object => 'fee_refund',
:amount => 30,
:currency => "usd",
:created => 1308595038,
:id => "ref_test_app_fee_refund",
:fee => "ca_test_application",
:metadata => {}
}.merge(params)
end
def make_application_fee_array
{
:data => [make_application_fee, make_application_fee, make_application_fee],
:object => 'list',
:resource_url => '/v1/application_fees'
}
end
def make_application_fee_refund_array(fee_id)
{
:data => [make_application_fee_refund, make_application_fee_refund, make_application_fee_refund],
:object => 'list',
:resource_url => '/v1/application_fees/' + fee_id + '/refunds'
}
end
def make_customer(params={})
id = params[:id] || 'c_test_customer'
{
:subscription_history => [],
:bills => [],
:charges => [],
:livemode => false,
:object => "customer",
:id => id,
:default_card => "cc_test_card",
:created => 1304114758,
:sources => make_customer_card_array(id),
:metadata => {},
:subscriptions => make_customer_subscription_array(id)
}.merge(params)
end
def make_customer_array
{
:data => [make_customer, make_customer, make_customer],
:object => 'list',
:resource_url => '/v1/customers'
}
end
def make_charge(params={})
id = params[:id] || 'ch_test_charge'
{
:refunded => false,
:paid => true,
:amount => 100,
:card => {
:type => "Visa",
:last4 => "4242",
:exp_month => 11,
:country => "US",
:exp_year => 2012,
:id => "cc_test_card",
:object => "card"
},
:id => id,
:reason => "execute_charge",
:livemode => false,
:currency => "usd",
:object => "charge",
:created => 1304114826,
:refunds => make_refund_array(id),
:metadata => {},
:outcome => {
type: 'authorized',
reason: nil,
seller_message: 'Payment complete.',
network_status: 'approved_by_network',
},
}.merge(params)
end
def make_charge_array
{
:data => [make_charge, make_charge, make_charge],
:object => 'list',
:resource_url => '/v1/charges'
}
end
def make_dispute(params={})
id = params[:id] || 'dp_test_dispute'
{
:id => id,
:charge => "ch_test_charge",
:amount => 500,
:created => 1304114758,
:status => 'needs_response',
:livemode => false,
:currency => 'usd',
:object => 'dispute',
:reason => 'fraudulent',
:evidence => {},
}.merge(params)
end
def make_dispute_array
{
:data => [make_dispute, make_dispute, make_dispute],
:object => 'list',
:resource_url => '/v1/disputes'
}
end
def make_recipient_card_array(recipient_id)
{
:data => [make_card, make_card, make_card],
:object => 'list',
:resource_url => '/v1/recipients/' + recipient_id + '/cards'
}
end
def make_customer_card_array(customer_id)
{
:data => [make_card, make_card, make_card],
:object => 'list',
:resource_url => '/v1/customers/' + customer_id + '/sources'
}
end
def make_card(params={})
{
:type => "Visa",
:last4 => "4242",
:exp_month => 11,
:country => "US",
:exp_year => 2012,
:id => "cc_test_card",
:customer => 'c_test_customer',
:object => "card"
}.merge(params)
end
def make_coupon(params={})
{
:duration => 'repeating',
:duration_in_months => 3,
:percent_off => 25,
:id => "co_test_coupon",
:object => "coupon",
:metadata => {},
}.merge(params)
end
def make_file(params={})
{
:object => "file_upload",
:id => "fil_test_file",
:created => 1403047735,
:size => 4908,
:purpose => params[:purpose] || "dispute_evidence",
:resource_url => nil,
:type => nil,
}
end
def make_file_array
{
:data => [make_file, make_file, make_file],
:object => 'list',
:resource_url => '/v1/files'
}
end
#FIXME nested overrides would be better than hardcoding plan_id
def make_subscription(params = {})
plan = params.delete(:plan) || 'gold'
{
:current_period_end => 1308681468,
:status => "trialing",
:plan => {
:interval => "month",
:amount => 7500,
:trial_period_days => 30,
:object => "plan",
:identifier => plan
},
:current_period_start => 1308595038,
:start => 1308595038,
:object => "subscription",
:trial_start => 1308595038,
:trial_end => 1308681468,
:customer => "c_test_customer",
:id => 's_test_subscription'
}.merge(params)
end
def make_subscription_item(params = {})
plan = params.delete(:plan) || 'gold'
{
:id => "si_test_subscription_item",
:object => "subscription_item",
:created => 1473875521,
:plan => {
:id => plan,
:object => "plan",
:amount => 1000,
:created => 1468349629,
:currency => "usd",
:interval => "month",
},
:quantity => 1
}.merge(params)
end
def make_refund(params = {})
{
:object => 'refund',
:amount => 30,
:currency => "usd",
:created => 1308595038,
:id => "ref_test_refund",
:charge => "ch_test_charge",
:metadata => {}
}.merge(params)
end
def make_subscription_array
{
:data => [make_subscription, make_subscription, make_subscription],
:object => 'list',
:resource_url => '/v1/subscriptions'
}
end
def make_subscription_item_array
{
:data => [make_subscription_item, make_subscription_item, make_subscription_item],
:object => 'list',
:resource_url => '/v1/subscription_items'
}
end
def make_customer_subscription_array(customer_id)
{
:data => [make_subscription, make_subscription, make_subscription],
:object => 'list',
:resource_url => '/v1/customers/' + customer_id + '/subscriptions'
}
end
def make_refund_array(charge=nil)
p = charge ? {:charge => charge} : {}
{
:data => [make_refund(p), make_refund(p), make_refund(p)],
:object => 'list',
:resource_url => charge ? "/v1/charges/#{charge}/refunds" : '/v1/refunds'
}
end
def make_reversal_array(transfer_id)
{
:data => [make_reversal, make_reversal, make_reversal],
:object => 'list',
:resource_url => '/v1/transfers/' + transfer_id + '/reversals'
}
end
def make_invoice(params={})
{
:id => 'in_test_invoice',
:object => 'invoice',
:livemode => false,
:amount_due => 1000,
:attempt_count => 0,
:attempted => false,
:closed => false,
:currency => 'usd',
:customer => 'c_test_customer',
:date => 1349738950,
:lines => {
:object => 'list',
:data => [
{
:id => 'ii_test_invoice_item',
:object => 'invoiceitem',
:livemode => false,
:amount => 1000,
:currency => 'usd',
:customer => 'c_test_customer',
:date => 1349738950,
:description => "A Test Invoice Item",
:invoice => 'in_test_invoice'
},
],
},
:paid => false,
:period_end => 1349738950,
:period_start => 1349738950,
:starting_balance => 0,
:subtotal => 1000,
:total => 1000,
:charge => nil,
:discount => nil,
:ending_balance => nil,
:next_payment_attempt => 1349825350,
}.merge(params)
end
def make_invoice_item(params={})
{
id: "ii_test_invoice_item",
object: "invoiceitem",
date: 1466982411,
invoice: "in_test_invoice",
livemode: false,
metadata: {},
}.merge(params)
end
def make_invoice_customer_array
{
:data => [make_invoice],
:object => 'list',
:resource_url => '/v1/invoices?customer=test_customer'
}
end
def make_recipient(params={})
id = params[:id] || 'rp_test_recipient'
{
:name => "Stripe User",
:type => "individual",
:livemode => false,
:object => "recipient",
:id => "rp_test_recipient",
:cards => make_recipient_card_array(id),
:default_card => "debit_test_card",
:active_account => {
:last4 => "6789",
:bank_name => "STRIPE TEST BANK",
:country => "US",
:object => "bank_account"
},
:created => 1304114758,
:verified => true,
:metadata => {}
}.merge(params)
end
def make_recipient_array
{
:data => [make_recipient, make_recipient, make_recipient],
:object => 'list',
:resource_url => '/v1/recipients'
}
end
def make_transfer(params={})
{
:status => 'pending',
:amount => 100,
:account => {
:object => 'bank_account',
:country => 'US',
:bank_name => 'STRIPE TEST BANK',
:last4 => '6789'
},
:recipient => 'test_recipient',
:fee => 0,
:fee_details => [],
:id => "tr_test_transfer",
:reversals => make_reversal_array('tr_test_transfer'),
:livemode => false,
:currency => "usd",
:object => "transfer",
:date => 1304114826,
:metadata => {}
}.merge(params)
end
def make_transfer_array
{
:data => [make_transfer, make_transfer, make_transfer],
:object => 'list',
:resource_url => '/v1/transfers'
}
end
def make_canceled_transfer
make_transfer.merge({
:status => 'canceled'
})
end
def make_reversal(params={})
{
:object => 'transfer_reversal',
:amount => 30,
:currency => "usd",
:created => 1308595038,
:id => "ref_test_reversal",
:transfer => "tr_test_transfer",
:metadata => {}
}.merge(params)
end
def make_bitcoin_receiver(params={})
{
:id => 'btcrcv_test_receiver',
:amount => 100,
:currency => 'usd',
:description => 'some details',
:metadata => {},
:object => 'bitcoin_receiver',
:customer => nil,
:transactions => make_bitcoin_transaction_array
}.merge(params)
end
def make_bitcoin_receiver_array
{
:data => [make_bitcoin_receiver, make_bitcoin_receiver, make_bitcoin_receiver],
:object => 'list',
:resource_url => '/v1/bitcoin/receivers'
}
end
def make_bitcoin_transaction(params={})
{
:id => 'btctxn_test_transaction',
:object => 'bitcoin_transaction',
:amount => 100,
:currency => 'usd',
:bitcoin_amount => 90,
:receiver => 'btcrcv_test_receiver'
}.merge(params)
end
def make_bitcoin_transaction_array
{
:data => [make_bitcoin_transaction, make_bitcoin_transaction, make_bitcoin_transaction],
:object => 'list',
:resource_url => "/v1/bitcoin/receivers/btcrcv_test_receiver/transactions"
:error => {
:type => type,
:message => message,
}
}
end
@ -558,400 +55,5 @@ module Stripe
}
}
end
def make_delete_discount_response
{
:deleted => true,
:id => "di_test_coupon"
}
end
def make_product(params={})
{
:id => "pr_test_product",
:created => 1441992477,
:updated => 1441992477,
:object => "product",
:livemode => false,
:name => "Test Product",
:caption => "Comfy comfu",
:description => "Testing",
:active => true,
:attributes => [],
:shippable => true,
:metadata => {},
:url => "http://example.com/product",
:package_dimensions => nil,
:images => [],
:skus => make_sku_array("pr_test_product")
}.merge(params)
end
def make_product_array
{
:object => "list",
:resource_url => "/v1/products",
:data => [
make_product,
make_product,
make_product,
],
}
end
def make_sku(params={})
{
:id => "12345",
:created => 1441992494,
:updated => 1441992494,
:object => "sku",
:livemode => false,
:product => "pr_test_product",
:image => nil,
:active => true,
:price => 999,
:currency => "usd",
:inventory => {
:type => "infinite",
:quantity => nil,
:value => nil,
},
:attributes => {},
:metadata => {},
:package_dimensions => nil,
}.merge(params)
end
def make_sku_array(product_id, params={})
{
:object => "list",
:resource_url => "/v1/skus",
:data => [
make_sku(:product => product_id),
make_sku(:product => product_id),
make_sku(:product => product_id),
]
}
end
def make_order(params={})
{
:id => "or_16kg0uDAu10Yox5RReNVCthv",
:created => 1442171988,
:updated => nil,
:object => "order",
:livemode => false,
:status => "created",
:metadata => {},
:customer => nil,
:shipping => {
:name => "Jenny Rosen",
:address => {
:line1 => "1234 Main street",
:line2 => nil,
:city => "Anytown",
:state => nil,
:postal_code => "123456",
:country => "US"
},
:phone => nil,
},
:email => nil,
:items => [
{
:parent => "sk_16bHXrDAu10Yox5RU2007dpU",
:object => "order_item",
:type => "sku",
:description => "T-shirt",
:amount => 1500,
:currency => "usd",
:quantity => nil,
}
],
:shipping_methods => nil,
:selected_shipping_method => nil,
:amount => 1500,
:currency => "usd",
:charge => nil,
}.merge(params)
end
def make_order_array(params={})
{
:object => "list",
:resource_url => "/v1/orders",
:data => [
make_order,
make_order,
make_order,
]
}
end
def make_paid_order(params={})
make_order.merge({
:status => "paid",
:charge => make_charge,
}).merge(params)
end
def make_partially_returned_order(params={})
make_paid_order.merge({
:returns => make_order_return_array,
}).merge(params)
end
def make_order_return(params={})
{
:id => "orret_18CI1jDAu10Yox5R5kGPgbLN",
:object => "order_return",
:amount => 1220,
:created => 1463529303,
:currency => "usd",
:items => [
{
:object => "order_item",
:amount => 200,
:currency => "usd",
:description => "Just a SKU",
:parent => "sku_80NAUPJ9dpYtck",
:quantity => 2,
:type => "sku"
},
{
:object => "order_item",
:amount => 20,
:currency => "usd",
:description => "Fair enough",
:parent => nil,
:quantity => nil,
:type => "tax"
},
],
:livemode => false,
:order => "or_189jaGDAu10Yox5R0F6LoH6K",
:refund => nil,
}.merge(params)
end
def make_order_return_array
{
:object => "list",
:resource_url => "/v1/order_returns",
:data => [
make_order_return,
make_order_return,
make_order_return,
]
}
end
def make_country_spec_array
{
:object => "list",
:resource_url => "/v1/country_specs",
:data => [
make_country_spec,
make_country_spec,
make_country_spec,
]
}
end
def make_country_spec(params={})
{
:id => "US",
:object => "country_spec",
:supported_bank_account_currencies => {
:usd => ["US"]
},
:supported_payment_currencies => [
"usd", "aed", "afn", "all"
],
:supported_payment_methods => [
"alipay",
"card",
"stripe"
],
:verification_fields =>
{
:individual => {
:minimum => [
"external_account",
"legal_entity.address.city",
"tos_acceptance.date",
"tos_acceptance.ip"
],
:additional => [
"legal_entity.personal_id_number",
"legal_entity.verification.document"
]
},
:company => {
:minimum => [
"external_account",
"legal_entity.address.city",
"legal_entity.address.line1",
"tos_acceptance.ip"
],
:additional => [
"legal_entity.personal_id_number",
"legal_entity.verification.document"
]
}
}
}.merge(params)
end
def make_plan(params={})
{
id: "silver",
object: "plan",
amount: 1000,
created: 1463962497,
currency: "usd",
interval: "year",
interval_count: 1,
livemode: false,
metadata: {},
name: "Silver",
statement_descriptor: nil,
trial_period_days: nil,
}.merge(params)
end
def make_plan_array
{
:object => "list",
:resource_url => "/v1/plans",
:data => [
make_plan,
make_plan,
make_plan,
]
}
end
def make_three_d_secure(params={})
{
:id => 'tdsrc_test',
:object => 'three_d_secure',
:amount => 1500,
:authenticate => true,
:card => make_card,
:created => 1456908210,
:currency => 'usd',
:livemode => false,
:redirect_url => nil,
:status => 'succeeded',
}.merge(params)
end
def make_apple_pay_domain(params={})
{
:id => "apwc_test_domain",
:object => "apple_pay_domain",
:domain_name => "test.com",
:livemode => false
}.merge(params)
end
def make_apple_pay_domain_array
{
:object => "list",
:resource_url => "/v1/apple_pay/domains",
:data => [
make_apple_pay_domain,
make_apple_pay_domain,
make_apple_pay_domain
]
}
end
def make_source_card(params={})
id = params[:id] || 'src_test_card'
{
:id => id,
:object => 'source',
:type => 'card',
:amount => nil,
:card => {
:address_line1_check => nil,
:address_zip_check => nil,
:brand => 'Visa',
:country => 'US',
:cvc_check => 'unchecked',
:description => nil,
:dynamic_last4 => nil,
:exp_month => 1,
:exp_year => 2020,
:fingerprint => 'NrVafqTONZfbLkQK',
:funding => 'credit',
:google_reference => nil,
:iin => nil,
:issuer => nil,
:last4 => '4242',
:three_d_secure => 'optional',
:tokenization_method => 'nil',
},
:client_secret => 'src_client_secret_test',
:created => 1484841032,
:currency => nil,
:flow => 'none',
:livemode => false,
:metadata => {},
:owner => {
:address => nil,
:email => nil,
:name => nil,
:phone => nil,
:verified_address => nil,
:verified_email => nil,
:verified_name => nil,
:verified_phone => nil,
},
:status => 'chargeable',
:usage => 'reusable',
}.merge(params)
end
def make_source_ach_debit(params={})
id = params[:id] || 'src_test_ach_debit'
{
:id => id,
:object => 'source',
:type => 'ach_debit',
:ach_debit => {
:country => 'US',
:fingerprint => 'yY5BWKwnW98uydOa',
:last4 => '6789',
:routing_number => '110000000',
:type => 'individual',
},
:amount => nil,
:client_secret => 'src_client_secret_test',
:created => 1484842122,
:currency => 'usd',
:flow => 'verification',
:livemode => false,
:metadata => {},
:owner => {
:address => nil,
:email => nil,
:name => 'Jenny Rosen',
:phone => nil,
:verified_address => nil,
:verified_email => nil,
:verified_name => nil,
:verified_phone => nil,
},
:status => 'pending',
:usage => 'reusable',
:verification => {
:attempts_remaining => 10,
:status => 'pending',
},
}.merge(params)
end
end
end

View File

@ -1,17 +1,38 @@
require 'committee'
require 'sinatra'
require 'stripe'
require 'test/unit'
require 'mocha/setup'
require 'stringio'
require 'shoulda/context'
require 'webmock/test_unit'
PROJECT_ROOT = File.expand_path("../../", __FILE__)
require File.expand_path('../api_fixtures', __FILE__)
require File.expand_path('../api_stub_helpers', __FILE__)
require File.expand_path('../test_data', __FILE__)
class Test::Unit::TestCase
include APIStubHelpers
include Stripe::TestData
include Mocha
# Fixtures are available in tests using something like:
#
# API_FIXTURES[:charge][:id]
#
API_FIXTURES = APIFixtures.new
setup do
Stripe.api_key = "foo"
# Stub the Stripe API with a default stub. Note that this method can be
# called again in test bodies in order to override responses on particular
# endpoints.
stub_api
stub_connect
end
teardown do