stripe 2.8.0 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/History.txt +4 -0
- data/VERSION +1 -1
- data/lib/stripe.rb +4 -1
- data/lib/stripe/account.rb +6 -5
- data/lib/stripe/errors.rb +40 -0
- data/lib/stripe/oauth.rb +56 -0
- data/lib/stripe/stripe_client.rb +44 -12
- data/lib/stripe/version.rb +1 -1
- data/test/stripe/oauth_test.rb +85 -0
- data/test/stripe/stripe_client_test.rb +39 -3
- metadata +5 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 0f9ea5d1ce3e948a439878fadba81ef52b47c24e
         | 
| 4 | 
            +
              data.tar.gz: 00d62fe82daf1570ada3004672ddd15b6fe2425b
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 227094e5bb975bbd0acaf044d5f3708055fb8c12f043af80dd4851a8a784646f2f506d45c4a87ea166cbae285085623eb7aebb1366a1f5dec035a95437fede56
         | 
| 7 | 
            +
              data.tar.gz: 3158ef959bc7d5ed39bc26b9482515b3c8aec2fdf0d96d6f6a87c2481d254517688e994d6b6ea8fd7006a70d809f42af8ab76eb0caa621e6ec1f69bf47a85c9b
         | 
    
        data/History.txt
    CHANGED
    
    
    
        data/VERSION
    CHANGED
    
    | @@ -1 +1 @@ | |
| 1 | 
            -
            2. | 
| 1 | 
            +
            2.9.0
         | 
    
        data/lib/stripe.rb
    CHANGED
    
    | @@ -69,6 +69,9 @@ require 'stripe/three_d_secure' | |
| 69 69 | 
             
            require 'stripe/token'
         | 
| 70 70 | 
             
            require 'stripe/transfer'
         | 
| 71 71 |  | 
| 72 | 
            +
            # OAuth
         | 
| 73 | 
            +
            require 'stripe/oauth'
         | 
| 74 | 
            +
             | 
| 72 75 | 
             
            module Stripe
         | 
| 73 76 | 
             
              DEFAULT_CA_BUNDLE_PATH = File.dirname(__FILE__) + '/data/ca-certificates.crt'
         | 
| 74 77 |  | 
| @@ -90,7 +93,7 @@ module Stripe | |
| 90 93 | 
             
              @read_timeout = 80
         | 
| 91 94 |  | 
| 92 95 | 
             
              class << self
         | 
| 93 | 
            -
                attr_accessor :stripe_account, :api_key, :api_base, :verify_ssl_certs, :api_version, :connect_base, :uploads_base,
         | 
| 96 | 
            +
                attr_accessor :stripe_account, :api_key, :api_base, :verify_ssl_certs, :api_version, :client_id, :connect_base, :uploads_base,
         | 
| 94 97 | 
             
                              :open_timeout, :read_timeout
         | 
| 95 98 |  | 
| 96 99 | 
             
                attr_reader :max_network_retry_delay, :initial_network_retry_delay
         | 
    
        data/lib/stripe/account.rb
    CHANGED
    
    | @@ -93,11 +93,12 @@ module Stripe | |
| 93 93 | 
             
                  raise NoMethodError.new('Overridding legal_entity can cause serious issues. Instead, set the individual fields of legal_entity like blah.legal_entity.first_name = \'Blah\'')
         | 
| 94 94 | 
             
                end
         | 
| 95 95 |  | 
| 96 | 
            -
                def deauthorize(client_id, opts={})
         | 
| 97 | 
            -
                   | 
| 98 | 
            -
             | 
| 99 | 
            -
             | 
| 100 | 
            -
                   | 
| 96 | 
            +
                def deauthorize(client_id=nil, opts={})
         | 
| 97 | 
            +
                  params = {
         | 
| 98 | 
            +
                    client_id: client_id,
         | 
| 99 | 
            +
                    stripe_user_id: self.id,
         | 
| 100 | 
            +
                  }
         | 
| 101 | 
            +
                  OAuth.deauthorize(params, opts)
         | 
| 101 102 | 
             
                end
         | 
| 102 103 |  | 
| 103 104 | 
             
                ARGUMENT_NOT_PROVIDED = Object.new
         | 
    
        data/lib/stripe/errors.rb
    CHANGED
    
    | @@ -100,4 +100,44 @@ module Stripe | |
| 100 100 | 
             
                  @sig_header = sig_header
         | 
| 101 101 | 
             
                end
         | 
| 102 102 | 
             
              end
         | 
| 103 | 
            +
             | 
| 104 | 
            +
              module OAuth
         | 
| 105 | 
            +
                # OAuthError is raised when the OAuth API returns an error.
         | 
| 106 | 
            +
                class OAuthError < StripeError
         | 
| 107 | 
            +
                  attr_accessor :code
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                  def initialize(code, description, http_status: nil, http_body: nil, json_body: nil,
         | 
| 110 | 
            +
                                 http_headers: nil)
         | 
| 111 | 
            +
                    super(description, http_status: http_status, http_body: http_body,
         | 
| 112 | 
            +
                      json_body: json_body, http_headers: http_headers)
         | 
| 113 | 
            +
                    @code = code
         | 
| 114 | 
            +
                  end
         | 
| 115 | 
            +
                end
         | 
| 116 | 
            +
             | 
| 117 | 
            +
                # InvalidGrantError is raised when a specified code doesn't exist, is
         | 
| 118 | 
            +
                # expired, has been used, or doesn't belong to you; a refresh token doesn't
         | 
| 119 | 
            +
                # exist, or doesn't belong to you; or if an API key's mode (live or test)
         | 
| 120 | 
            +
                # doesn't match the mode of a code or refresh token.
         | 
| 121 | 
            +
                class InvalidGrantError < OAuthError
         | 
| 122 | 
            +
                end
         | 
| 123 | 
            +
             | 
| 124 | 
            +
                # InvalidRequestError is raised when a code, refresh token, or grant type
         | 
| 125 | 
            +
                # parameter is not provided, but was required.
         | 
| 126 | 
            +
                class InvalidRequestError < OAuthError
         | 
| 127 | 
            +
                end
         | 
| 128 | 
            +
             | 
| 129 | 
            +
                # InvalidScopeError is raised when an invalid scope parameter is provided.
         | 
| 130 | 
            +
                class InvalidScopeError < OAuthError
         | 
| 131 | 
            +
                end
         | 
| 132 | 
            +
             | 
| 133 | 
            +
                # UnsupportedGrantTypeError is raised when an unuspported grant type
         | 
| 134 | 
            +
                # parameter is specified.
         | 
| 135 | 
            +
                class UnsupportedGrantTypeError < OAuthError
         | 
| 136 | 
            +
                end
         | 
| 137 | 
            +
             | 
| 138 | 
            +
                # UnsupportedResponseTypeError is raised when an unsupported response type
         | 
| 139 | 
            +
                # parameter is specified.
         | 
| 140 | 
            +
                class UnsupportedResponseTypeError < OAuthError
         | 
| 141 | 
            +
                end
         | 
| 142 | 
            +
              end
         | 
| 103 143 | 
             
            end
         | 
    
        data/lib/stripe/oauth.rb
    ADDED
    
    | @@ -0,0 +1,56 @@ | |
| 1 | 
            +
            module Stripe
         | 
| 2 | 
            +
              module OAuth
         | 
| 3 | 
            +
                module OAuthOperations
         | 
| 4 | 
            +
                  extend APIOperations::Request::ClassMethods
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                  def self.request(method, url, params, opts)
         | 
| 7 | 
            +
                    opts = Util.normalize_opts(opts)
         | 
| 8 | 
            +
                    opts[:client] ||= StripeClient.active_client
         | 
| 9 | 
            +
                    opts[:api_base] ||= Stripe.connect_base
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                    super(method, url, params, opts)
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def self.get_client_id(params={})
         | 
| 16 | 
            +
                  client_id = params[:client_id] || Stripe.client_id
         | 
| 17 | 
            +
                  unless client_id
         | 
| 18 | 
            +
                    raise AuthenticationError.new('No client_id provided. ' \
         | 
| 19 | 
            +
                      'Set your client_id using "Stripe.client_id = <CLIENT-ID>". ' \
         | 
| 20 | 
            +
                      'You can find your client_ids in your Stripe dashboard at ' \
         | 
| 21 | 
            +
                      'https://dashboard.stripe.com/account/applications/settings, ' \
         | 
| 22 | 
            +
                      'after registering your account as a platform. See ' \
         | 
| 23 | 
            +
                      'https://stripe.com/docs/connect/standalone-accounts for details, ' \
         | 
| 24 | 
            +
                      'or email support@stripe.com if you have any questions.')
         | 
| 25 | 
            +
                  end
         | 
| 26 | 
            +
                  client_id
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                def self.authorize_url(params={}, opts={})
         | 
| 30 | 
            +
                  base = opts[:connect_base] || Stripe.connect_base
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  params[:client_id] = get_client_id(params)
         | 
| 33 | 
            +
                  params[:response_type] ||= 'code'
         | 
| 34 | 
            +
                  query = Util.encode_parameters(params)
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  "#{base}/oauth/authorize?#{query}"
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                def self.token(params={}, opts={})
         | 
| 40 | 
            +
                  opts = Util.normalize_opts(opts)
         | 
| 41 | 
            +
                  resp, opts = OAuthOperations.request(
         | 
| 42 | 
            +
                    :post, '/oauth/token', params, opts)
         | 
| 43 | 
            +
                  # This is just going to return a generic StripeObject, but that's okay
         | 
| 44 | 
            +
                  Util.convert_to_stripe_object(resp.data, opts)
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                def self.deauthorize(params={}, opts={})
         | 
| 48 | 
            +
                  opts = Util.normalize_opts(opts)
         | 
| 49 | 
            +
                  params[:client_id] = get_client_id(params)
         | 
| 50 | 
            +
                  resp, opts = OAuthOperations.request(
         | 
| 51 | 
            +
                    :post, '/oauth/deauthorize', params, opts)
         | 
| 52 | 
            +
                  # This is just going to return a generic StripeObject, but that's okay
         | 
| 53 | 
            +
                  Util.convert_to_stripe_object(resp.data, opts)
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
              end
         | 
| 56 | 
            +
            end
         | 
    
        data/lib/stripe/stripe_client.rb
    CHANGED
    
    | @@ -197,7 +197,7 @@ module Stripe | |
| 197 197 | 
             
                    case e
         | 
| 198 198 | 
             
                    when Faraday::ClientError
         | 
| 199 199 | 
             
                      if e.response
         | 
| 200 | 
            -
                         | 
| 200 | 
            +
                        handle_error_response(e.response)
         | 
| 201 201 | 
             
                      else
         | 
| 202 202 | 
             
                        handle_network_error(e, retry_count, api_base)
         | 
| 203 203 | 
             
                      end
         | 
| @@ -229,12 +229,12 @@ module Stripe | |
| 229 229 | 
             
                  str
         | 
| 230 230 | 
             
                end
         | 
| 231 231 |  | 
| 232 | 
            -
                def  | 
| 232 | 
            +
                def handle_error_response(http_resp)
         | 
| 233 233 | 
             
                  begin
         | 
| 234 234 | 
             
                    resp = StripeResponse.from_faraday_hash(http_resp)
         | 
| 235 | 
            -
                     | 
| 235 | 
            +
                    error_data = resp.data[:error]
         | 
| 236 236 |  | 
| 237 | 
            -
                    unless  | 
| 237 | 
            +
                    unless error_data
         | 
| 238 238 | 
             
                      raise StripeError.new("Indeterminate error")
         | 
| 239 239 | 
             
                    end
         | 
| 240 240 |  | 
| @@ -242,47 +242,79 @@ module Stripe | |
| 242 242 | 
             
                    raise general_api_error(http_resp[:status], http_resp[:body])
         | 
| 243 243 | 
             
                  end
         | 
| 244 244 |  | 
| 245 | 
            +
                  if error_data.is_a?(String)
         | 
| 246 | 
            +
                    error = specific_oauth_error(resp, error_data)
         | 
| 247 | 
            +
                  end
         | 
| 248 | 
            +
                  if error.nil?
         | 
| 249 | 
            +
                    error = specific_api_error(resp, error_data)
         | 
| 250 | 
            +
                  end
         | 
| 251 | 
            +
             | 
| 252 | 
            +
                  error.response = resp
         | 
| 253 | 
            +
                  raise(error)
         | 
| 254 | 
            +
                end
         | 
| 255 | 
            +
             | 
| 256 | 
            +
                def specific_api_error(resp, error_data)
         | 
| 245 257 | 
             
                  case resp.http_status
         | 
| 246 258 | 
             
                  when 400, 404
         | 
| 247 259 | 
             
                    error = InvalidRequestError.new(
         | 
| 248 | 
            -
                       | 
| 260 | 
            +
                      error_data[:message], error_data[:param],
         | 
| 249 261 | 
             
                      http_status: resp.http_status, http_body: resp.http_body,
         | 
| 250 262 | 
             
                      json_body: resp.data, http_headers: resp.http_headers
         | 
| 251 263 | 
             
                    )
         | 
| 252 264 | 
             
                  when 401
         | 
| 253 265 | 
             
                    error = AuthenticationError.new(
         | 
| 254 | 
            -
                       | 
| 266 | 
            +
                      error_data[:message],
         | 
| 255 267 | 
             
                      http_status: resp.http_status, http_body: resp.http_body,
         | 
| 256 268 | 
             
                      json_body: resp.data, http_headers: resp.http_headers
         | 
| 257 269 | 
             
                    )
         | 
| 258 270 | 
             
                  when 402
         | 
| 259 271 | 
             
                    error = CardError.new(
         | 
| 260 | 
            -
                       | 
| 272 | 
            +
                      error_data[:message], error_data[:param], error_data[:code],
         | 
| 261 273 | 
             
                      http_status: resp.http_status, http_body: resp.http_body,
         | 
| 262 274 | 
             
                      json_body: resp.data, http_headers: resp.http_headers
         | 
| 263 275 | 
             
                    )
         | 
| 264 276 | 
             
                  when 403
         | 
| 265 277 | 
             
                    error = PermissionError.new(
         | 
| 266 | 
            -
                       | 
| 278 | 
            +
                      error_data[:message],
         | 
| 267 279 | 
             
                      http_status: resp.http_status, http_body: resp.http_body,
         | 
| 268 280 | 
             
                      json_body: resp.data, http_headers: resp.http_headers
         | 
| 269 281 | 
             
                    )
         | 
| 270 282 | 
             
                  when 429
         | 
| 271 283 | 
             
                    error = RateLimitError.new(
         | 
| 272 | 
            -
                       | 
| 284 | 
            +
                      error_data[:message],
         | 
| 273 285 | 
             
                      http_status: resp.http_status, http_body: resp.http_body,
         | 
| 274 286 | 
             
                      json_body: resp.data, http_headers: resp.http_headers
         | 
| 275 287 | 
             
                    )
         | 
| 276 288 | 
             
                  else
         | 
| 277 289 | 
             
                    error = APIError.new(
         | 
| 278 | 
            -
                       | 
| 290 | 
            +
                      error_data[:message],
         | 
| 279 291 | 
             
                      http_status: resp.http_status, http_body: resp.http_body,
         | 
| 280 292 | 
             
                      json_body: resp.data, http_headers: resp.http_headers
         | 
| 281 293 | 
             
                    )
         | 
| 282 294 | 
             
                  end
         | 
| 283 295 |  | 
| 284 | 
            -
                  error | 
| 285 | 
            -
             | 
| 296 | 
            +
                  error
         | 
| 297 | 
            +
                end
         | 
| 298 | 
            +
             | 
| 299 | 
            +
                # Attempts to look at a response's error code and return an OAuth error if
         | 
| 300 | 
            +
                # one matches. Will return `nil` if the code isn't recognized.
         | 
| 301 | 
            +
                def specific_oauth_error(resp, error_code)
         | 
| 302 | 
            +
                  description = resp.data[:error_description] || error_code
         | 
| 303 | 
            +
             | 
| 304 | 
            +
                  args = [error_code, description, {
         | 
| 305 | 
            +
                    http_status: resp.http_status, http_body: resp.http_body,
         | 
| 306 | 
            +
                    json_body: resp.data, http_headers: resp.http_headers
         | 
| 307 | 
            +
                  }]
         | 
| 308 | 
            +
             | 
| 309 | 
            +
                  case error_code
         | 
| 310 | 
            +
                  when 'invalid_grant'             then OAuth::InvalidGrantError.new(*args)
         | 
| 311 | 
            +
                  when 'invalid_request'           then OAuth::InvalidRequestError.new(*args)
         | 
| 312 | 
            +
                  when 'invalid_scope'             then OAuth::InvalidScopeError.new(*args)
         | 
| 313 | 
            +
                  when 'unsupported_grant_type'    then OAuth::UnsupportedGrantTypeError.new(*args)
         | 
| 314 | 
            +
                  when 'unsupported_response_type' then OAuth::UnsupportedResponseTypeError.new(*args)
         | 
| 315 | 
            +
                  else
         | 
| 316 | 
            +
                    nil
         | 
| 317 | 
            +
                  end
         | 
| 286 318 | 
             
                end
         | 
| 287 319 |  | 
| 288 320 | 
             
                def handle_network_error(e, retry_count, api_base=nil)
         | 
    
        data/lib/stripe/version.rb
    CHANGED
    
    
| @@ -0,0 +1,85 @@ | |
| 1 | 
            +
            require File.expand_path('../../test_helper', __FILE__)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Stripe
         | 
| 4 | 
            +
              class OAuthTest < Test::Unit::TestCase
         | 
| 5 | 
            +
                setup do
         | 
| 6 | 
            +
                  Stripe.client_id = 'ca_test'
         | 
| 7 | 
            +
                end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                teardown do
         | 
| 10 | 
            +
                  Stripe.client_id = nil
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                context ".authorize_url" do
         | 
| 14 | 
            +
                  should "return the authorize URL" do
         | 
| 15 | 
            +
                    uri_str = OAuth.authorize_url({
         | 
| 16 | 
            +
                      scope: 'read_write',
         | 
| 17 | 
            +
                      state: 'csrf_token',
         | 
| 18 | 
            +
                      stripe_user: {
         | 
| 19 | 
            +
                        email: 'test@example.com',
         | 
| 20 | 
            +
                        url: 'https://example.com/profile/test',
         | 
| 21 | 
            +
                        country: 'US',
         | 
| 22 | 
            +
                      },
         | 
| 23 | 
            +
                    })
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                    uri = URI::parse(uri_str)
         | 
| 26 | 
            +
                    params = CGI::parse(uri.query)
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                    assert_equal('https', uri.scheme)
         | 
| 29 | 
            +
                    assert_equal('connect.stripe.com', uri.host)
         | 
| 30 | 
            +
                    assert_equal('/oauth/authorize', uri.path)
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                    assert_equal(['ca_test'], params['client_id'])
         | 
| 33 | 
            +
                    assert_equal(['read_write'], params['scope'])
         | 
| 34 | 
            +
                    assert_equal(['test@example.com'], params['stripe_user[email]'])
         | 
| 35 | 
            +
                    assert_equal(['https://example.com/profile/test'], params['stripe_user[url]'])
         | 
| 36 | 
            +
                    assert_equal(['US'], params['stripe_user[country]'])
         | 
| 37 | 
            +
                  end
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                context ".token" do
         | 
| 41 | 
            +
                  should "exchange a code for an access token" do
         | 
| 42 | 
            +
                    # The OpenAPI fixtures don't cover the OAuth endpoints, so we just
         | 
| 43 | 
            +
                    # stub the request manually.
         | 
| 44 | 
            +
                    stub_request(:post, "#{Stripe.connect_base}/oauth/token").
         | 
| 45 | 
            +
                      with(body: {
         | 
| 46 | 
            +
                        'grant_type' => 'authorization_code',
         | 
| 47 | 
            +
                        'code' => 'this_is_an_authorization_code',
         | 
| 48 | 
            +
                      }).
         | 
| 49 | 
            +
                      to_return(body: JSON.generate({
         | 
| 50 | 
            +
                        access_token: 'sk_access_token',
         | 
| 51 | 
            +
                        scope: 'read_only',
         | 
| 52 | 
            +
                        livemode: false,
         | 
| 53 | 
            +
                        token_type: 'bearer',
         | 
| 54 | 
            +
                        refresh_token: 'sk_refresh_token',
         | 
| 55 | 
            +
                        stripe_user_id: 'acct_test',
         | 
| 56 | 
            +
                        stripe_publishable_key: 'pk_test',
         | 
| 57 | 
            +
                      }))
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                    resp = OAuth.token({
         | 
| 60 | 
            +
                      grant_type: 'authorization_code',
         | 
| 61 | 
            +
                      code: 'this_is_an_authorization_code',
         | 
| 62 | 
            +
                    })
         | 
| 63 | 
            +
                    assert_equal('sk_access_token', resp.access_token)
         | 
| 64 | 
            +
                  end
         | 
| 65 | 
            +
                end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                context ".deauthorize" do
         | 
| 68 | 
            +
                  should "deauthorize an account" do
         | 
| 69 | 
            +
                    # The OpenAPI fixtures don't cover the OAuth endpoints, so we just
         | 
| 70 | 
            +
                    # stub the request manually.
         | 
| 71 | 
            +
                    stub_request(:post, "#{Stripe.connect_base}/oauth/deauthorize").
         | 
| 72 | 
            +
                      with(body: {
         | 
| 73 | 
            +
                        'client_id' => 'ca_test',
         | 
| 74 | 
            +
                        'stripe_user_id' => 'acct_test_deauth',
         | 
| 75 | 
            +
                      }).
         | 
| 76 | 
            +
                      to_return(body: JSON.generate({
         | 
| 77 | 
            +
                        stripe_user_id: 'acct_test_deauth',
         | 
| 78 | 
            +
                      }))
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                    resp = OAuth.deauthorize({stripe_user_id: 'acct_test_deauth'})
         | 
| 81 | 
            +
                    assert_equal('acct_test_deauth', resp.stripe_user_id)
         | 
| 82 | 
            +
                  end
         | 
| 83 | 
            +
                end
         | 
| 84 | 
            +
              end
         | 
| 85 | 
            +
            end
         | 
| @@ -243,16 +243,16 @@ module Stripe | |
| 243 243 | 
             
                      assert_equal 'Invalid response object from API: "" (HTTP response code was 200)', e.message
         | 
| 244 244 | 
             
                    end
         | 
| 245 245 |  | 
| 246 | 
            -
                    should "handle error response with  | 
| 246 | 
            +
                    should "handle error response with unknown value" do
         | 
| 247 247 | 
             
                      stub_request(:post, "#{Stripe.api_base}/v1/charges").
         | 
| 248 | 
            -
                        to_return(body: JSON.generate({  | 
| 248 | 
            +
                        to_return(body: JSON.generate({ bar: "foo" }), status: 500)
         | 
| 249 249 |  | 
| 250 250 | 
             
                      client = StripeClient.new
         | 
| 251 251 | 
             
                      e = assert_raises Stripe::APIError do
         | 
| 252 252 | 
             
                        client.execute_request(:post, '/v1/charges')
         | 
| 253 253 | 
             
                      end
         | 
| 254 254 |  | 
| 255 | 
            -
                      assert_equal 'Invalid response object from API: "{\" | 
| 255 | 
            +
                      assert_equal 'Invalid response object from API: "{\"bar\":\"foo\"}" (HTTP response code was 500)', e.message
         | 
| 256 256 | 
             
                    end
         | 
| 257 257 |  | 
| 258 258 | 
             
                    should "raise InvalidRequestError on 400" do
         | 
| @@ -332,6 +332,42 @@ module Stripe | |
| 332 332 | 
             
                        assert_equal(true, e.json_body.kind_of?(Hash))
         | 
| 333 333 | 
             
                      end
         | 
| 334 334 | 
             
                    end
         | 
| 335 | 
            +
             | 
| 336 | 
            +
                    should "raise OAuth::InvalidRequestError when error is a string with value 'invalid_request'" do
         | 
| 337 | 
            +
                      stub_request(:post, "#{Stripe.connect_base}/oauth/token").
         | 
| 338 | 
            +
                        to_return(body: JSON.generate({
         | 
| 339 | 
            +
                          error: "invalid_request",
         | 
| 340 | 
            +
                          error_description: "No grant type specified",
         | 
| 341 | 
            +
                        }), status: 400)
         | 
| 342 | 
            +
             | 
| 343 | 
            +
                      client = StripeClient.new
         | 
| 344 | 
            +
                      opts = {api_base: Stripe.connect_base}
         | 
| 345 | 
            +
                      e = assert_raises Stripe::OAuth::InvalidRequestError do
         | 
| 346 | 
            +
                        client.execute_request(:post, '/oauth/token', opts)
         | 
| 347 | 
            +
                      end
         | 
| 348 | 
            +
             | 
| 349 | 
            +
                      assert_equal(400, e.http_status)
         | 
| 350 | 
            +
                      assert_equal(true, !!e.http_body)
         | 
| 351 | 
            +
                      assert_equal('No grant type specified', e.message)
         | 
| 352 | 
            +
                    end
         | 
| 353 | 
            +
             | 
| 354 | 
            +
                    should "raise OAuth::InvalidGrantError when error is a string with value 'invalid_grant'" do
         | 
| 355 | 
            +
                      stub_request(:post, "#{Stripe.connect_base}/oauth/token").
         | 
| 356 | 
            +
                        to_return(body: JSON.generate({
         | 
| 357 | 
            +
                          error: "invalid_grant",
         | 
| 358 | 
            +
                          error_description: "This authorization code has already been used. All tokens issued with this code have been revoked.",
         | 
| 359 | 
            +
                        }), status: 400)
         | 
| 360 | 
            +
             | 
| 361 | 
            +
                      client = StripeClient.new
         | 
| 362 | 
            +
                      opts = {api_base: Stripe.connect_base}
         | 
| 363 | 
            +
                      e = assert_raises Stripe::OAuth::InvalidGrantError do
         | 
| 364 | 
            +
                        client.execute_request(:post, '/oauth/token', opts)
         | 
| 365 | 
            +
                      end
         | 
| 366 | 
            +
             | 
| 367 | 
            +
                      assert_equal(400, e.http_status)
         | 
| 368 | 
            +
                      assert_equal('invalid_grant', e.code)
         | 
| 369 | 
            +
                      assert_equal('This authorization code has already been used. All tokens issued with this code have been revoked.', e.message)
         | 
| 370 | 
            +
                    end
         | 
| 335 371 | 
             
                  end
         | 
| 336 372 |  | 
| 337 373 | 
             
                  context "idempotency keys" do
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: stripe
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 2. | 
| 4 | 
            +
              version: 2.9.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Stripe
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2017- | 
| 11 | 
            +
            date: 2017-05-18 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: faraday
         | 
| @@ -75,6 +75,7 @@ files: | |
| 75 75 | 
             
            - lib/stripe/invoice_item.rb
         | 
| 76 76 | 
             
            - lib/stripe/invoice_line_item.rb
         | 
| 77 77 | 
             
            - lib/stripe/list_object.rb
         | 
| 78 | 
            +
            - lib/stripe/oauth.rb
         | 
| 78 79 | 
             
            - lib/stripe/order.rb
         | 
| 79 80 | 
             
            - lib/stripe/order_return.rb
         | 
| 80 81 | 
             
            - lib/stripe/payout.rb
         | 
| @@ -128,6 +129,7 @@ files: | |
| 128 129 | 
             
            - test/stripe/invoice_line_item_test.rb
         | 
| 129 130 | 
             
            - test/stripe/invoice_test.rb
         | 
| 130 131 | 
             
            - test/stripe/list_object_test.rb
         | 
| 132 | 
            +
            - test/stripe/oauth_test.rb
         | 
| 131 133 | 
             
            - test/stripe/order_return_test.rb
         | 
| 132 134 | 
             
            - test/stripe/order_test.rb
         | 
| 133 135 | 
             
            - test/stripe/payout_test.rb
         | 
| @@ -201,6 +203,7 @@ test_files: | |
| 201 203 | 
             
            - test/stripe/invoice_line_item_test.rb
         | 
| 202 204 | 
             
            - test/stripe/invoice_test.rb
         | 
| 203 205 | 
             
            - test/stripe/list_object_test.rb
         | 
| 206 | 
            +
            - test/stripe/oauth_test.rb
         | 
| 204 207 | 
             
            - test/stripe/order_return_test.rb
         | 
| 205 208 | 
             
            - test/stripe/order_test.rb
         | 
| 206 209 | 
             
            - test/stripe/payout_test.rb
         |