Skip to content

Commit c0fe7bb

Browse files
committed
feat(index): add mergeSearchParameters function (#3917)
* feat(index): add mergeSearchParameters function ```js mergeSearchParameters(a, b, c) // new search parameters ``` - overrides left-to-right on uncontrolled parameters - merges controlled parameters - overrides left-to-right on duplicate attributes Co-authored-by: samouss <samouss@users.noreply.github.com> * fix(support): add polyfill for findIndex This is the same one as in helper v3 * chore: fix lint * chore: remove compose * change test titles * chore(merge): use in index widget * chore: reorder * fix typo
1 parent 632e06b commit c0fe7bb

File tree

4 files changed

+520
-11
lines changed

4 files changed

+520
-11
lines changed
Lines changed: 370 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,370 @@
1+
import algoliasearchHelper from 'algoliasearch-helper';
2+
import merge from '../mergeSearchParameters';
3+
4+
describe('mergeSearchParameters', () => {
5+
it('overrides non-managed parameters', () => {
6+
const actual = merge(
7+
algoliasearchHelper.SearchParameters.make({
8+
// Inherit
9+
hitsPerPage: 2,
10+
attributesToSnippet: ['description'],
11+
// Overridden
12+
query: 'Samsung',
13+
attributesToHighlight: ['name'],
14+
}),
15+
algoliasearchHelper.SearchParameters.make({
16+
// hitsPerPage: 2,
17+
// attributesToSnippet: ['description'],
18+
query: 'Apple',
19+
attributesToHighlight: ['name', 'author'],
20+
}),
21+
algoliasearchHelper.SearchParameters.make({
22+
// hitsPerPage: 2,
23+
// attributesToSnippet: ['description'],
24+
// attributesToHighlight: ['name', 'author'],
25+
query: 'Apple iPhone',
26+
distinct: true,
27+
})
28+
);
29+
30+
expect(actual).toEqual(
31+
algoliasearchHelper.SearchParameters.make({
32+
hitsPerPage: 2,
33+
attributesToSnippet: ['description'],
34+
attributesToHighlight: ['name', 'author'],
35+
query: 'Apple iPhone',
36+
distinct: true,
37+
})
38+
);
39+
});
40+
41+
it('merges `facets` parameters', () => {
42+
const actual = merge(
43+
algoliasearchHelper.SearchParameters.make({
44+
facets: ['brand'],
45+
}),
46+
algoliasearchHelper.SearchParameters.make({
47+
facets: ['categories'],
48+
}),
49+
algoliasearchHelper.SearchParameters.make({
50+
facets: ['brand', 'colors'],
51+
})
52+
);
53+
54+
expect(actual).toEqual(
55+
algoliasearchHelper.SearchParameters.make({
56+
facets: ['brand', 'categories', 'colors'],
57+
})
58+
);
59+
});
60+
61+
it('merges `disjunctiveFacets` parameters', () => {
62+
const actual = merge(
63+
algoliasearchHelper.SearchParameters.make({
64+
disjunctiveFacets: ['brand'],
65+
}),
66+
algoliasearchHelper.SearchParameters.make({
67+
disjunctiveFacets: ['categories'],
68+
}),
69+
algoliasearchHelper.SearchParameters.make({
70+
disjunctiveFacets: ['brand', 'colors'],
71+
})
72+
);
73+
74+
expect(actual).toEqual(
75+
algoliasearchHelper.SearchParameters.make({
76+
disjunctiveFacets: ['brand', 'categories', 'colors'],
77+
})
78+
);
79+
});
80+
81+
it('merges `facetsRefinements` parameters, overrides conflicts', () => {
82+
const actual = merge(
83+
algoliasearchHelper.SearchParameters.make({
84+
facets: ['brand'],
85+
facetsRefinements: {
86+
brand: ['Samsung'],
87+
},
88+
}),
89+
algoliasearchHelper.SearchParameters.make({
90+
facets: ['categories'],
91+
facetsRefinements: {
92+
categories: ['TVs'],
93+
},
94+
}),
95+
algoliasearchHelper.SearchParameters.make({
96+
facets: ['brand', 'colors'],
97+
facetsRefinements: {
98+
brand: ['Apple'],
99+
colors: ['Red'],
100+
},
101+
})
102+
);
103+
104+
expect(actual).toEqual(
105+
algoliasearchHelper.SearchParameters.make({
106+
facets: ['brand', 'categories', 'colors'],
107+
facetsRefinements: {
108+
brand: ['Apple'],
109+
categories: ['TVs'],
110+
colors: ['Red'],
111+
},
112+
})
113+
);
114+
});
115+
116+
it('merges `facetsExcludes` parameters, overrides conflicts', () => {
117+
const actual = merge(
118+
algoliasearchHelper.SearchParameters.make({
119+
facets: ['brand'],
120+
facetsExcludes: {
121+
brand: ['Samsung'],
122+
},
123+
}),
124+
algoliasearchHelper.SearchParameters.make({
125+
facets: ['categories'],
126+
facetsExcludes: {
127+
categories: ['TVs'],
128+
},
129+
}),
130+
algoliasearchHelper.SearchParameters.make({
131+
facets: ['brand', 'colors'],
132+
facetsExcludes: {
133+
brand: ['Apple'],
134+
colors: ['Red'],
135+
},
136+
})
137+
);
138+
139+
expect(actual).toEqual(
140+
algoliasearchHelper.SearchParameters.make({
141+
facets: ['brand', 'categories', 'colors'],
142+
facetsExcludes: {
143+
brand: ['Apple'],
144+
categories: ['TVs'],
145+
colors: ['Red'],
146+
},
147+
})
148+
);
149+
});
150+
151+
it('merges `disjunctiveFacetsRefinements` parameters, overrides conflicts', () => {
152+
const actual = merge(
153+
algoliasearchHelper.SearchParameters.make({
154+
disjunctiveFacets: ['brand'],
155+
disjunctiveFacetsRefinements: {
156+
brand: ['Samsung'],
157+
},
158+
}),
159+
algoliasearchHelper.SearchParameters.make({
160+
disjunctiveFacets: ['categories'],
161+
disjunctiveFacetsRefinements: {
162+
categories: ['TVs'],
163+
},
164+
}),
165+
algoliasearchHelper.SearchParameters.make({
166+
disjunctiveFacets: ['brand', 'colors'],
167+
disjunctiveFacetsRefinements: {
168+
brand: ['Apple'],
169+
colors: ['Red'],
170+
},
171+
})
172+
);
173+
174+
expect(actual).toEqual(
175+
algoliasearchHelper.SearchParameters.make({
176+
disjunctiveFacets: ['brand', 'categories', 'colors'],
177+
disjunctiveFacetsRefinements: {
178+
brand: ['Apple'],
179+
categories: ['TVs'],
180+
colors: ['Red'],
181+
},
182+
})
183+
);
184+
});
185+
186+
it('merges `numericRefinements` parameters, overrides conflicts', () => {
187+
const actual = merge(
188+
algoliasearchHelper.SearchParameters.make({
189+
numericRefinements: {
190+
price: {
191+
'>=': [10],
192+
'<=': [100],
193+
},
194+
},
195+
}),
196+
algoliasearchHelper.SearchParameters.make({
197+
numericRefinements: {
198+
rating: {
199+
'>=': [3],
200+
},
201+
},
202+
}),
203+
algoliasearchHelper.SearchParameters.make({
204+
numericRefinements: {
205+
price: {
206+
'>': [100],
207+
},
208+
vote: {
209+
'>=': [50],
210+
},
211+
},
212+
})
213+
);
214+
215+
expect(actual).toEqual(
216+
algoliasearchHelper.SearchParameters.make({
217+
numericRefinements: {
218+
price: {
219+
'>': [100],
220+
},
221+
rating: {
222+
'>=': [3],
223+
},
224+
vote: {
225+
'>=': [50],
226+
},
227+
},
228+
})
229+
);
230+
});
231+
232+
it('merges `tagRefinements` parameters, overrides conflicts', () => {
233+
const actual = merge(
234+
algoliasearchHelper.SearchParameters.make({
235+
tagRefinements: ['brand'],
236+
}),
237+
algoliasearchHelper.SearchParameters.make({
238+
tagRefinements: ['categories'],
239+
}),
240+
algoliasearchHelper.SearchParameters.make({
241+
tagRefinements: ['brand', 'colors'],
242+
})
243+
);
244+
245+
expect(actual).toEqual(
246+
algoliasearchHelper.SearchParameters.make({
247+
tagRefinements: ['brand', 'categories', 'colors'],
248+
})
249+
);
250+
});
251+
252+
it('merges `hierarchicalFacets` parameters, overrides conflicts', () => {
253+
const actual = merge(
254+
algoliasearchHelper.SearchParameters.make({
255+
hierarchicalFacets: [
256+
{
257+
name: 'categories',
258+
attributes: ['categories.lvl0', 'categories.lvl1'],
259+
},
260+
],
261+
}),
262+
algoliasearchHelper.SearchParameters.make({
263+
hierarchicalFacets: [
264+
{
265+
name: 'department',
266+
attributes: ['department.lvl0', 'department.lvl1'],
267+
},
268+
],
269+
}),
270+
algoliasearchHelper.SearchParameters.make({
271+
hierarchicalFacets: [
272+
{
273+
name: 'categories',
274+
attributes: ['topLevelCategories', 'subLevelCategories'],
275+
},
276+
{
277+
name: 'folders',
278+
attributes: ['folders.lvl0', 'folders.lvl1'],
279+
},
280+
],
281+
})
282+
);
283+
284+
expect(actual).toEqual(
285+
algoliasearchHelper.SearchParameters.make({
286+
hierarchicalFacets: [
287+
{
288+
name: 'categories',
289+
attributes: ['topLevelCategories', 'subLevelCategories'],
290+
},
291+
{
292+
name: 'department',
293+
attributes: ['department.lvl0', 'department.lvl1'],
294+
},
295+
{
296+
name: 'folders',
297+
attributes: ['folders.lvl0', 'folders.lvl1'],
298+
},
299+
],
300+
})
301+
);
302+
});
303+
304+
it('merges `hierarchicalFacetsRefinements` parameters, overrides conflicts', () => {
305+
const actual = merge(
306+
algoliasearchHelper.SearchParameters.make({
307+
hierarchicalFacets: [
308+
{
309+
name: 'categories',
310+
attributes: ['categories.lvl0', 'categories.lvl1'],
311+
},
312+
],
313+
hierarchicalFacetsRefinements: {
314+
categories: ['Appliances > Fans'],
315+
},
316+
}),
317+
algoliasearchHelper.SearchParameters.make({
318+
hierarchicalFacets: [
319+
{
320+
name: 'department',
321+
attributes: ['department.lvl0', 'department.lvl1'],
322+
},
323+
],
324+
hierarchicalFacetsRefinements: {
325+
department: ['Engineering > Squad'],
326+
},
327+
}),
328+
algoliasearchHelper.SearchParameters.make({
329+
hierarchicalFacets: [
330+
{
331+
name: 'categories',
332+
attributes: ['topLevelCategories', 'subLevelCategories'],
333+
},
334+
{
335+
name: 'folders',
336+
attributes: ['folders.lvl0', 'folders.lvl1'],
337+
},
338+
],
339+
hierarchicalFacetsRefinements: {
340+
categories: ['Cell Phones > Prepaid Phones'],
341+
folders: ['Music > Artist > Mike Miller'],
342+
},
343+
})
344+
);
345+
346+
expect(actual).toEqual(
347+
algoliasearchHelper.SearchParameters.make({
348+
hierarchicalFacets: [
349+
{
350+
name: 'categories',
351+
attributes: ['topLevelCategories', 'subLevelCategories'],
352+
},
353+
{
354+
name: 'department',
355+
attributes: ['department.lvl0', 'department.lvl1'],
356+
},
357+
{
358+
name: 'folders',
359+
attributes: ['folders.lvl0', 'folders.lvl1'],
360+
},
361+
],
362+
hierarchicalFacetsRefinements: {
363+
categories: ['Cell Phones > Prepaid Phones'],
364+
department: ['Engineering > Squad'],
365+
folders: ['Music > Artist > Mike Miller'],
366+
},
367+
})
368+
);
369+
});
370+
});

src/lib/utils/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export { default as escape } from './escape';
2222
export { default as find } from './find';
2323
export { default as findIndex } from './findIndex';
2424
export { default as mergeDeep } from './mergeDeep';
25+
export { default as mergeSearchParameters } from './mergeSearchParameters';
2526
export { default as resolveSearchParameters } from './resolveSearchParameters';
2627
export { warning, deprecate } from './logger';
2728
export {

0 commit comments

Comments
 (0)