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.
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.
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.
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.)
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.
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.