Skip to content

Commit

Permalink
fix(routing): support parsing URLs with up to 100 refinements (#3671)
Browse files Browse the repository at this point in the history
  • Loading branch information
francoischalifour committed Apr 10, 2019
1 parent 2c9e38d commit 6ddcfb6
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 1 deletion.
70 changes: 70 additions & 0 deletions src/lib/__tests__/RoutingManager-test.js
@@ -1,4 +1,5 @@
/* globals jsdom */
import qs from 'qs';
import instantsearch from '../main';
import RoutingManager from '../RoutingManager';
import historyRouter from '../routers/history';
Expand Down Expand Up @@ -585,4 +586,73 @@ describe('RoutingManager', () => {
setWindowTitle.mockRestore();
});
});

describe('parseURL', () => {
const createFakeUrlWithRefinements = ({ length }) =>
[
'https://website.com/',
Array.from(
{ length },
(_v, i) => `refinementList[brand][${i}]=brand-${i}`
).join('&'),
].join('?');

test('should parse refinements with more than 20 filters per category as array', () => {
jsdom.reconfigure({
url: createFakeUrlWithRefinements({ length: 22 }),
});

const router = historyRouter();
const parsedUrl = router.parseURL({
qsModule: qs,
location: window.location,
});

expect(parsedUrl.refinementList.brand).toBeInstanceOf(Array);
expect(parsedUrl).toMatchInlineSnapshot(`
Object {
"refinementList": Object {
"brand": Array [
"brand-0",
"brand-1",
"brand-2",
"brand-3",
"brand-4",
"brand-5",
"brand-6",
"brand-7",
"brand-8",
"brand-9",
"brand-10",
"brand-11",
"brand-12",
"brand-13",
"brand-14",
"brand-15",
"brand-16",
"brand-17",
"brand-18",
"brand-19",
"brand-20",
"brand-21",
],
},
}
`);
});

test('should support returning 100 refinements as array', () => {
jsdom.reconfigure({
url: createFakeUrlWithRefinements({ length: 100 }),
});

const router = historyRouter();
const parsedUrl = router.parseURL({
qsModule: qs,
location: window.location,
});

expect(parsedUrl.refinementList.brand).toBeInstanceOf(Array);
});
});
});
12 changes: 11 additions & 1 deletion src/lib/routers/history.js
Expand Up @@ -12,7 +12,17 @@ function defaultCreateURL({ qsModule, routeState, location }) {
}

function defaultParseURL({ qsModule, location }) {
return qsModule.parse(location.search.slice(1));
// `qs` by default converts arrays with more than 20 items to an object.
// We want to avoid this because the data structure manipulated can therefore vary.
// Setting the limit to `100` seems a good number because the engine's default is 100
// (it can go up to 1000 but it is very unlikely to select more than 100 items in the UI).
//
// Using an `arrayLimit` of `n` allows `n + 1` items.
//
// See:
// - https://github.com/ljharb/qs#parsing-arrays
// - https://www.algolia.com/doc/api-reference/api-parameters/maxValuesPerFacet/
return qsModule.parse(location.search.slice(1), { arrayLimit: 99 });
}

function setWindowTitle(title) {
Expand Down

0 comments on commit 6ddcfb6

Please sign in to comment.