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.
This commit is contained in:
Brandur 2016-08-25 10:54:08 -07:00
parent 980fd2bd07
commit d9b6f08ce5
3 changed files with 8 additions and 8 deletions

View File

@ -135,7 +135,7 @@ module Stripe
# do not sort the final output because arrays (and arrays of hashes
# especially) can be order sensitive, but do sort incoming parameters
params.sort_by { |(k, _)| k.to_s }.each do |key, value|
params.each do |key, value|
calculated_key = parent_key ? "#{parent_key}[#{key}]" : "#{key}"
if value.is_a?(Hash)
result += flatten_params(value, calculated_key)

View File

@ -105,7 +105,7 @@ module Stripe
}
@mock.expects(:post).
once.
with('https://api.stripe.com/v1/accounts/acct_foo', nil, 'legal_entity[address][line1]=2+Three+Four&legal_entity[first_name]=Bob').
with('https://api.stripe.com/v1/accounts/acct_foo', nil, 'legal_entity[first_name]=Bob&legal_entity[address][line1]=2+Three+Four').
returns(make_response(resp))
a = Stripe::Account.update('acct_foo', :legal_entity => {

View File

@ -36,8 +36,8 @@ module Stripe
[:d, { :a => "a", :b => "b" }],
[:e, [0, 1]],
[:f, [
{ :bar => "1", :foo => "2" },
{ :baz => "3", :foo => "4" },
{ :foo => "1", :ghi => "2" },
{ :foo => "3", :bar => "4" },
]],
]
assert_equal([
@ -52,10 +52,10 @@ module Stripe
# *The key here is the order*. In order to be properly interpreted as
# an array of hashes on the server, everything from a single hash must
# come in at once. A duplicate key in an array triggers a new element.
["f[][bar]", "1"],
["f[][foo]", "2"],
["f[][baz]", "3"],
["f[][foo]", "4"],
["f[][foo]", "1"],
["f[][ghi]", "2"],
["f[][foo]", "3"],
["f[][bar]", "4"],
], Stripe::Util.flatten_params(params))
end