1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
|
# frozen_string_literal: true
require 'rack/utils'
RSpec.describe Faraday::NestedParamsEncoder do
it_behaves_like 'a params encoder'
it 'decodes arrays' do
query = 'a[1]=one&a[2]=two&a[3]=three'
expected = { 'a' => %w[one two three] }
expect(subject.decode(query)).to eq(expected)
end
it 'decodes hashes' do
query = 'a[b1]=one&a[b2]=two&a[b][c]=foo'
expected = { 'a' => { 'b1' => 'one', 'b2' => 'two', 'b' => { 'c' => 'foo' } } }
expect(subject.decode(query)).to eq(expected)
end
it 'decodes nested arrays rack compat' do
query = 'a[][one]=1&a[][two]=2&a[][one]=3&a[][two]=4'
expected = Rack::Utils.parse_nested_query(query)
expect(subject.decode(query)).to eq(expected)
end
it 'decodes nested array mixed types' do
query = 'a[][one]=1&a[]=2&a[]=&a[]'
expected = Rack::Utils.parse_nested_query(query)
expect(subject.decode(query)).to eq(expected)
end
it 'decodes nested ignores invalid array' do
query = '[][a]=1&b=2'
expected = { 'a' => '1', 'b' => '2' }
expect(subject.decode(query)).to eq(expected)
end
it 'decodes nested ignores repeated array notation' do
query = 'a[][][]=1'
expected = { 'a' => ['1'] }
expect(subject.decode(query)).to eq(expected)
end
it 'decodes nested ignores malformed keys' do
query = '=1&[]=2'
expected = {}
expect(subject.decode(query)).to eq(expected)
end
it 'decodes nested subkeys dont have to be in brackets' do
query = 'a[b]c[d]e=1'
expected = { 'a' => { 'b' => { 'c' => { 'd' => { 'e' => '1' } } } } }
expect(subject.decode(query)).to eq(expected)
end
it 'decodes nested final value overrides any type' do
query = 'a[b][c]=1&a[b]=2'
expected = { 'a' => { 'b' => '2' } }
expect(subject.decode(query)).to eq(expected)
end
it 'encodes rack compat' do
params = { a: [{ one: '1', two: '2' }, '3', ''] }
result = Faraday::Utils.unescape(Faraday::NestedParamsEncoder.encode(params)).split('&')
escaped = Rack::Utils.build_nested_query(params)
expected = Rack::Utils.unescape(escaped).split('&')
expect(result).to match_array(expected)
end
it 'encodes empty string array value' do
expected = 'baz=&foo%5Bbar%5D='
result = Faraday::NestedParamsEncoder.encode(foo: { bar: '' }, baz: '')
expect(result).to eq(expected)
end
it 'encodes nil array value' do
expected = 'baz&foo%5Bbar%5D'
result = Faraday::NestedParamsEncoder.encode(foo: { bar: nil }, baz: nil)
expect(result).to eq(expected)
end
it 'encodes empty array value' do
expected = 'baz%5B%5D&foo%5Bbar%5D%5B%5D'
result = Faraday::NestedParamsEncoder.encode(foo: { bar: [] }, baz: [])
expect(result).to eq(expected)
end
it 'encodes boolean values' do
params = { a: true, b: false }
expect(subject.encode(params)).to eq('a=true&b=false')
end
it 'encodes boolean values in array' do
params = { a: [true, false] }
expect(subject.encode(params)).to eq('a%5B%5D=true&a%5B%5D=false')
end
it 'encodes unsorted when asked' do
params = { b: false, a: true }
expect(subject.encode(params)).to eq('a=true&b=false')
Faraday::NestedParamsEncoder.sort_params = false
expect(subject.encode(params)).to eq('b=false&a=true')
Faraday::NestedParamsEncoder.sort_params = true
end
it 'encodes arrays indices when asked' do
params = { a: [0, 1, 2] }
expect(subject.encode(params)).to eq('a%5B%5D=0&a%5B%5D=1&a%5B%5D=2')
Faraday::NestedParamsEncoder.array_indices = true
expect(subject.encode(params)).to eq('a%5B0%5D=0&a%5B1%5D=1&a%5B2%5D=2')
Faraday::NestedParamsEncoder.array_indices = false
end
shared_examples 'a wrong decoding' do
it do
expect { subject.decode(query) }.to raise_error(TypeError) do |e|
expect(e.message).to eq(error_message)
end
end
end
context 'when expecting hash but getting string' do
let(:query) { 'a=1&a[b]=2' }
let(:error_message) { "expected Hash (got String) for param `a'" }
it_behaves_like 'a wrong decoding'
end
context 'when expecting hash but getting array' do
let(:query) { 'a[]=1&a[b]=2' }
let(:error_message) { "expected Hash (got Array) for param `a'" }
it_behaves_like 'a wrong decoding'
end
context 'when expecting nested hash but getting non nested' do
let(:query) { 'a[b]=1&a[b][c]=2' }
let(:error_message) { "expected Hash (got String) for param `b'" }
it_behaves_like 'a wrong decoding'
end
context 'when expecting array but getting hash' do
let(:query) { 'a[b]=1&a[]=2' }
let(:error_message) { "expected Array (got Hash) for param `a'" }
it_behaves_like 'a wrong decoding'
end
context 'when expecting array but getting string' do
let(:query) { 'a=1&a[]=2' }
let(:error_message) { "expected Array (got String) for param `a'" }
it_behaves_like 'a wrong decoding'
end
end
|