Skip to content

Commit

Permalink
Fix arrayFormat bracket-separator with a URL encoded value (#392)
Browse files Browse the repository at this point in the history
  • Loading branch information
scottenock authored Oct 9, 2024
1 parent 4287e77 commit 19c43d4
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 11 deletions.
2 changes: 1 addition & 1 deletion base.js
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ function parserForArrayFormat(options) {

const arrayValue = value === null
? []
: value.split(options.arrayFormatSeparator).map(item => decode(item, options));
: decode(value, options).split(options.arrayFormatSeparator);

if (accumulator[key] === undefined) {
accumulator[key] = arrayValue;
Expand Down
35 changes: 25 additions & 10 deletions test/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ test('handle multiple values and preserve appearance order with indexes', t => {
});

test('query strings params including embedded `=`', t => {
t.deepEqual(queryString.parse('?param=https%3A%2F%2Fsomeurl%3Fid%3D2837'), {param: 'https://someurl?id=2837'});
const value = 'https://someurl?id=2837';
t.deepEqual(queryString.parse(`param=${encodeURIComponent(value)}`), {param: 'https://someurl?id=2837'});
});

test('object properties', t => {
Expand Down Expand Up @@ -215,6 +216,16 @@ test('query strings having a brackets+separator array and format option as `brac
}), {foo: ['']});
});

test('query strings having a brackets+separator array and format option as `bracket-separator` with a URL encoded value', t => {
const key = 'foo[]';
const value = 'a,b,c,d,e,f';
t.deepEqual(queryString.parse(`?${encodeURIComponent(key)}=${encodeURIComponent(value)}`, {
arrayFormat: 'bracket-separator',
}), {
foo: ['a', 'b', 'c', 'd', 'e', 'f'],
});
});

test('query strings having = within parameters (i.e. GraphQL IDs)', t => {
t.deepEqual(queryString.parse('foo=bar=&foo=ba=z='), {foo: ['bar=', 'ba=z=']});
});
Expand Down Expand Up @@ -305,7 +316,8 @@ test('decode keys and values', t => {
});

test('disable decoding of keys and values', t => {
t.deepEqual(queryString.parse('tags=postal%20office,burger%2C%20fries%20and%20coke', {decode: false}), {tags: 'postal%20office,burger%2C%20fries%20and%20coke'});
const value = 'postal office,burger, fries and coke';
t.deepEqual(queryString.parse(`tags=${encodeURIComponent(value)}`, {decode: false}), {tags: 'postal%20office%2Cburger%2C%20fries%20and%20coke'});
});

test('number value returns as string by default', t => {
Expand Down Expand Up @@ -376,7 +388,8 @@ test('parse throws TypeError for invalid arrayFormatSeparator', t => {
});

test('query strings having comma encoded and format option as `comma`', t => {
t.deepEqual(queryString.parse('foo=zero%2Cone,two%2Cthree', {arrayFormat: 'comma'}), {
const values = ['zero,one', 'two,three'];
t.deepEqual(queryString.parse(`foo=${encodeURIComponent(values[0])},${encodeURIComponent(values[1])}`, {arrayFormat: 'comma'}), {
foo: [
'zero,one',
'two,three',
Expand All @@ -392,7 +405,8 @@ test('value should not be decoded twice with `arrayFormat` option set as `separa

// See https://github.com/sindresorhus/query-string/issues/242
test('value separated by encoded comma will not be parsed as array with `arrayFormat` option set to `comma`', t => {
t.deepEqual(queryString.parse('id=1%2C2%2C3', {arrayFormat: 'comma', parseNumbers: true}), {
const value = '1,2,3';
t.deepEqual(queryString.parse(`id=${encodeURIComponent(value)}`, {arrayFormat: 'comma', parseNumbers: true}), {
id: [1, 2, 3],
});
});
Expand All @@ -406,7 +420,8 @@ test('query strings having (:list) colon-list-separator arrays including null va
});

test('types option: can override a parsed number to be a string ', t => {
t.deepEqual(queryString.parse('phoneNumber=%2B380951234567', {
const phoneNumber = '+380951234567';
t.deepEqual(queryString.parse(`phoneNumber=${encodeURIComponent(phoneNumber)}`, {
parseNumbers: true,
types: {
phoneNumber: 'string',
Expand All @@ -426,7 +441,7 @@ test('types option: can override a parsed boolean value to be a string', t => {
});

test('types option: can override parsed numbers arrays to be string[]', t => {
t.deepEqual(queryString.parse('ids=999%2C998%2C997&items=1%2C2%2C3', {
t.deepEqual(queryString.parse('ids=999,998,997&items=1,2,3', {
arrayFormat: 'comma',
parseNumbers: true,
types: {
Expand All @@ -439,7 +454,7 @@ test('types option: can override parsed numbers arrays to be string[]', t => {
});

test('types option: can override string arrays to be number[]', t => {
t.deepEqual(queryString.parse('ids=001%2C002%2C003&items=1%2C2%2C3', {
t.deepEqual(queryString.parse('ids=1,2,3&items=1,2,3', {
arrayFormat: 'comma',
types: {
ids: 'number[]',
Expand All @@ -451,7 +466,7 @@ test('types option: can override string arrays to be number[]', t => {
});

test('types option: can override an array to be string', t => {
t.deepEqual(queryString.parse('ids=001%2C002%2C003&items=1%2C2%2C3', {
t.deepEqual(queryString.parse('ids=001,002,003&items=1,2,3', {
arrayFormat: 'comma',
parseNumbers: true,
types: {
Expand Down Expand Up @@ -488,7 +503,7 @@ test('types option: when value is not of specified type, it will safely parse th
});

test('types option: array types will have no effect if arrayFormat is set to "none"', t => {
t.deepEqual(queryString.parse('ids=001%2C002%2C003&foods=apple%2Corange%2Cmango', {
t.deepEqual(queryString.parse('ids=001,002,003&foods=apple,orange,mango', {
arrayFormat: 'none',
types: {
ids: 'number[]',
Expand All @@ -512,7 +527,7 @@ test('types option: will parse the value as number if specified in type but pars
});

test('types option: all supported types work in conjunction with one another', t => {
t.deepEqual(queryString.parse('ids=001%2C002%2C003&items=1%2C2%2C3&price=22%2E00&numbers=1%2C2%2C3&double=5&number=20', {
t.deepEqual(queryString.parse('ids=001,002,003&items=1,2,3&price=22.00&numbers=1,2,3&double=5&number=20', {
arrayFormat: 'comma',
types: {
ids: 'string',
Expand Down

0 comments on commit 19c43d4

Please sign in to comment.