27 Commits

Author SHA1 Message Date
Olivier Bellone
21db64fe0e
Use ::File instead of File 2018-08-27 15:32:10 +02:00
Brandur
c1ff8bdc4c Integer-index encode all arrays
Changes all arrays from classic Rack encoding:

``` sh
arr[]=...&arr[]=...&arr[]=...
```

To integer-indexed encoding:

``` sh
arr[0]=...&arr[1]=...&arr[2]=...
```

We think that this should be tractable now that we've fully converted
all endpoints over to the new AbstractAPIMethod infrastructure on the
backend (although we should do a little more testing to make sure that
all endpoints still work).

As part of the conversion, we also remove any places that we were "spot
encoding" to get required integer-indexed syntax. This should now all be
built in.
2018-08-14 14:44:43 -07:00
Jason Webster
9d0cd25897 Do not colorize output destined for configured logger
This changes the predicate supplied to the #colorize method to ensure
that if a logger is set, the colorizing ANSI escape codes are not applied.

This definitely appears to have been the intention behind the original
implementation, but the tests didn't reflect how .log_internal was
actually called. In reality, it is always supplied with an `out:`
argument, not nil. This caused all logger bound output to also be
colorized.
2018-07-19 12:28:28 -04:00
Brandur
863da48398 Add frozen_string_literal to every file and enforce Rubocop rule
Adds the magic `frozen_string_literal: true` comment to every file and
enables a Rubocop rule to make sure that it's always going to be there
going forward as well.

See here for more background [1], but the basic idea is that unlike many
other languages, static strings in code are mutable by default. This has
since been acknowledged as not a particularly good idea, and the
intention is to rectify the mistake when Ruby 3 comes out, where all
string literals will be frozen. The `frozen_string_literal` magic
comment was introduced in Ruby 2.3 as a way of easing the transition,
and allows libraries and projects to freeze their literals in advance.

I don't think this is breaking in any way: it's possible that users
might've been pulling out one of are literals somehow and mutating it,
but that would probably not have been useful for anything and would
certainly not be recommended, so I'm quite comfortable pushing this
change through as a minor version.

As discussed in #641.

[1] https://stackoverflow.com/a/37799399
2018-05-10 14:56:14 -07:00
Brandur
b4e64969cc Don't persist idempotency_key option between API requests
Excludes `idempotency_key` from opts to persist between API requests.
Obviously the same idempotency key is not something that we ever want to
use again.

Fixes #598.
2017-10-16 13:00:32 -07:00
Olivier Bellone
e02ff7f849
Start using RuboCop for linting 2017-09-27 21:28:25 +02:00
Brandur
1ca67cb954 Correct behavior for error logging
A few changes:

* Add a new `Util.log_error` method which will forward to the equivalent
  of `#error` on a logger.
* Move errors produced by `StripeClient` to use `Util.log_error`.
* Change standard stdout logging behavior to log to stderr in the case
  of `Util.log_error.
* Change `Stripe.log_level` values to be an enum in a similar fashion as
  the standard library's built in `Logger`.
2017-08-11 11:45:43 -07:00
Brandur
cb111a8e74 Add support for setting a logger
Adds support for setting `Stripe.logger` to a logger that's compatible
with `Logger` from Ruby's standard library. In set, the library will no
longer log to stdout, and instead emit straight to the logger and defer
decision on what log level to print to it.

Addresses a request in #566.
2017-08-11 11:22:14 -07:00
Brandur
ce69d749e1 Implement STRIPE_LOG for stripe-ruby
Adds logging support for stripe-ruby in a similar way that we did it for
stripe-python [1], with the idea that users you can optionally get some
additional low-cost-to-configure logging for operational visibility or
debugging.

I made a few tweaks from the Python implementation (which I'll try to
contribute back to there):

* Added an elapsed parameter to responses so you can tell how long they
  lasted.
* Mixed in idempotency_key to all lines that users have a way to
  aggregate logs related to a request from start to finish.
* Standardized naming between different log lines as much as possible.
* Detect a TTY and produce output that's colorized and formatted.

[1] https://github.com/stripe/stripe-python/pull/269
2017-08-03 13:39:15 -07:00
Kyle Conroy
c131bcbcac Correctly encode the subscription items array (#467)
* Correctly encode the subscription items array

* Use super

* Handle non-arrays as well

* Also encode items on create
2016-09-27 13:46:57 -07:00
Brandur
6cd72a1eb4 Fix word reversal 2016-08-25 17:11:55 -07:00
Brandur
7df3a4bdd6 One more test case to show that the check is recursive 2016-08-25 17:09:50 -07:00
Brandur
a5a9eb94db Produce an error on bad array of maps
This produces an error when we detect an "array of maps" that cannot be
encoded with `application/x-www-form-urlencoded`; that is to say, one
that does not have each hash starting with a consistent key that will
allow a Rack-compliant server to recognize boundaries.

So for example, this is fine:

```
items: [
    { :type => 'sku', :parent => 'sku_94ZYSC0wppRTbk' },
    { :type => 'discount', :amount => -10000, :currency => 'cad', :description => 'potato' }
],
```

But this is _not_ okay:

```
items: [
    { :type => 'sku', :parent => 'sku_94ZYSC0wppRTbk' },
    { :amount => -10000, :currency => 'cad', :description => 'potato', :type => 'discount' }
],
```

(`type` should be moved to the beginning of the array.)

The purpose of this change is to give users better feedback when they
run into an encoding problem like this one. Currently, they just get
something confusing from the server, and someone on support usually
needs to examine a request log to figure out what happened.

CI will fail until the changes in #453 are brought in.
2016-08-25 17:07:56 -07:00
Brandur
d9b6f08ce5 Don't alphabetize encoded maps by key
Alphabetizing maps being encoded by key can cause problems because the
server side Rack relies on the fact that that a new array item will
start with a repeated key.

For example, given this encoding:

```
items: [
    { :type => 'sku', :parent => 'sku_94ZYSC0wppRTbk' },
    { :type => 'discount', :amount => -10000, :currency => 'cad', :description => 'potato' }
],
```

We need to have `type` appear first so that an array boundary is
recognized. So the encoded form should take:

```
items[][type]=sku&items[][parent]=...&items[][type]=discount&items[][amount]=...
```

But currently `type` gets sorted to the back, so we get something more
like:

```
items[][parent]=...&items[][type]=...&items[][amount]=...&items[][currency]=...&items[][description]=...&items[][type]=potato
```

Which the server will receive as this:

```
items: [
    { :type => 'sku', :parent => 'sku_94ZYSC0wppRTbk', :amount => -10000, :currency => 'cad', :description => 'potato' }
    { :type => 'discount' }
],
```

Here we remove the alphabetization to fix the problem and correct a bad
test.
2016-08-25 10:54:08 -07:00
Brandur
03b64a059d Remove test hacks introduced to work around Ruby 1.8 limitations 2015-11-04 16:41:59 -08:00
Brandur
159335078c For completeness, add a test case with an empty string 2015-11-03 13:38:59 -08:00
Brandur
431ef3b1f2 Special case the serialization of account's additional_owners
We attempt to do a special encoding trick when serializing
`additional_owners` under an account: when updating a value, we actually
send the update parameters up as an integer-indexed hash rather than an
array. So instead of this:

    field[]=item1&field[]=item2&field[]=item3

We send this:

    field[0]=item1&field[1]=item2&field[2]=item3

The trouble is that this had previously been built into the core library
as the default handling for all arrays. Because of this, it was
impossible to resize a non-`additional_owners` array as described in
more detail in #340.

This patch special cases `additional_owners` and brings sane behavior
back to normal arrays along with a test suite so that we try to build
some better guarantees around both the general and non-general cases.
2015-10-27 09:07:41 -07:00
Brandur
216218aeb0 Order hack to make 1.8.7 tests happy
It turns out that the tests had been working ... but mostly by virtue of
luck only. This should stabilize them more permanently.
2015-10-20 12:15:36 -07:00
Brandur
ca8b49e5fd Use array as input instead of hash (for 1.8.7 tests) 2015-10-10 12:12:57 -07:00
Brandur
395d16b8c1 Remove sorting hack from parameter encoding
I added this for a regression suite so that 1.8.7 could pass its tests,
but unfortunately this caused a regression in the way that parameters
are encoded for arrays of hashes. This patch reverts the change and adds
tests to detect a future regression.

(And 1.8.7 is expected to fail on this initial commit.)
2015-10-10 12:12:57 -07:00
Brandur
eb8787754c Replace deprecated URI.escape with a customized CGI.escape
Replaces my original attempt in #319 in a way that doesn't depend on
`URI.encode_www_form` which doesn't exist in 1.8.7. This should
hopefully get us the best of all worlds.

Caveats around use of `+` instead of `%20` as detailed in #319 still
apply.

Fixes #286.
2015-10-06 14:46:58 -07:00
Brandur
5853fd47dd Add one more set of tests for #url_encode 2015-10-06 14:38:14 -07:00
Brandur
a48fd12c70 Add regression suite for testing parameter encoding
Pulls the test suite out of #319 so that we can get some coverage around
parameter encoding. This should prevent any recurrence of #318.

Also includes a little bit of refactoring.
2015-10-06 14:04:02 -07:00
Bob Long
c269e9bd9b Safer argument parsing (attempt 2) 2015-03-25 15:15:02 +00:00
Brian Krausz
4d611c62f7 Support persisted use of Stripe-Account header everywhere
Including implicit use in /v1/accounts/ endpoints
2015-02-09 23:38:34 -08:00
Kyle Conroy
e3a68bb3b9 Replace api_key with an options hash
For now, only two options are supported: `api_key` and
`idempotency_key`. In the future, we'll be adding support for additional
headers as needed.
2014-12-17 23:23:46 -08:00
David Czarnecki
e593b0e0df Breakup tests into separate test files 2013-03-22 17:20:04 -04:00