Skip to content

Commit c4de730

Browse files
samoussHaroenv
authored andcommitted
feat(connectHits): clear the state on dispose (#3816)
* test(connectHits): calls the unmount function * test(connectHits): rename jsHelper -> algoliasearchHelper * test(connectHits): consistent names for render/unmount function * feat(connectHits): remove TAG_PLACEHOLDER on dispose * feat(connectHits): do not throw without unmount function * feat(connectHits): remove TAG_PLACEHOLDER only with `escapeHTML` * test(connectHits): update test description
1 parent 8ae87d8 commit c4de730

File tree

2 files changed

+122
-46
lines changed

2 files changed

+122
-46
lines changed

src/connectors/hits/__tests__/connectHits-test.js

Lines changed: 107 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import jsHelper, { SearchResults } from 'algoliasearch-helper';
1+
import algoliasearchHelper, { SearchResults } from 'algoliasearch-helper';
22
import { TAG_PLACEHOLDER } from '../../../lib/escape-highlight';
33
import connectHits from '../connectHits';
44

@@ -21,10 +21,8 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/hits/js/#co
2121
});
2222

2323
it('Renders during init and render', () => {
24-
// test that the dummyRendering is called with the isFirstRendering
25-
// flag set accordingly
26-
const rendering = jest.fn();
27-
const makeWidget = connectHits(rendering);
24+
const renderFn = jest.fn();
25+
const makeWidget = connectHits(renderFn);
2826
const widget = makeWidget({ escapeHTML: true });
2927

3028
expect(widget.getConfiguration()).toEqual({
@@ -33,9 +31,9 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/hits/js/#co
3331
});
3432

3533
// test if widget is not rendered yet at this point
36-
expect(rendering).toHaveBeenCalledTimes(0);
34+
expect(renderFn).toHaveBeenCalledTimes(0);
3735

38-
const helper = jsHelper({}, '', {});
36+
const helper = algoliasearchHelper({}, '', {});
3937
helper.search = jest.fn();
4038

4139
widget.init({
@@ -45,9 +43,8 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/hits/js/#co
4543
onHistoryChange: () => {},
4644
});
4745

48-
expect(rendering).toHaveBeenCalledTimes(1);
49-
// test that rendering has been called during init with isFirstRendering = true
50-
expect(rendering).toHaveBeenLastCalledWith(
46+
expect(renderFn).toHaveBeenCalledTimes(1);
47+
expect(renderFn).toHaveBeenLastCalledWith(
5148
expect.objectContaining({ widgetParams: { escapeHTML: true } }),
5249
true
5350
);
@@ -59,17 +56,16 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/hits/js/#co
5956
createURL: () => '#',
6057
});
6158

62-
expect(rendering).toHaveBeenCalledTimes(2);
63-
// test that rendering has been called during init with isFirstRendering = false
64-
expect(rendering).toHaveBeenLastCalledWith(
59+
expect(renderFn).toHaveBeenCalledTimes(2);
60+
expect(renderFn).toHaveBeenLastCalledWith(
6561
expect.objectContaining({ widgetParams: { escapeHTML: true } }),
6662
false
6763
);
6864
});
6965

7066
it('sets the default configuration', () => {
71-
const rendering = jest.fn();
72-
const makeWidget = connectHits(rendering);
67+
const renderFn = jest.fn();
68+
const makeWidget = connectHits(renderFn);
7369
const widget = makeWidget();
7470

7571
expect(widget.getConfiguration()).toEqual({
@@ -79,11 +75,11 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/hits/js/#co
7975
});
8076

8177
it('Provides the hits and the whole results', () => {
82-
const rendering = jest.fn();
83-
const makeWidget = connectHits(rendering);
78+
const renderFn = jest.fn();
79+
const makeWidget = connectHits(renderFn);
8480
const widget = makeWidget({});
8581

86-
const helper = jsHelper({}, '', {});
82+
const helper = algoliasearchHelper({}, '', {});
8783
helper.search = jest.fn();
8884

8985
widget.init({
@@ -93,7 +89,7 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/hits/js/#co
9389
onHistoryChange: () => {},
9490
});
9591

96-
expect(rendering).toHaveBeenLastCalledWith(
92+
expect(renderFn).toHaveBeenLastCalledWith(
9793
expect.objectContaining({
9894
hits: [],
9995
results: undefined,
@@ -114,7 +110,7 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/hits/js/#co
114110
createURL: () => '#',
115111
});
116112

117-
expect(rendering).toHaveBeenLastCalledWith(
113+
expect(renderFn).toHaveBeenLastCalledWith(
118114
expect.objectContaining({
119115
hits,
120116
results,
@@ -124,11 +120,11 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/hits/js/#co
124120
});
125121

126122
it('escape highlight properties if requested', () => {
127-
const rendering = jest.fn();
128-
const makeWidget = connectHits(rendering);
123+
const renderFn = jest.fn();
124+
const makeWidget = connectHits(renderFn);
129125
const widget = makeWidget({ escapeHTML: true });
130126

131-
const helper = jsHelper({}, '', {});
127+
const helper = algoliasearchHelper({}, '', {});
132128
helper.search = jest.fn();
133129

134130
widget.init({
@@ -138,7 +134,7 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/hits/js/#co
138134
onHistoryChange: () => {},
139135
});
140136

141-
expect(rendering).toHaveBeenLastCalledWith(
137+
expect(renderFn).toHaveBeenLastCalledWith(
142138
expect.objectContaining({
143139
hits: [],
144140
results: undefined,
@@ -176,7 +172,7 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/hits/js/#co
176172

177173
escapedHits.__escaped = true;
178174

179-
expect(rendering).toHaveBeenLastCalledWith(
175+
expect(renderFn).toHaveBeenLastCalledWith(
180176
expect.objectContaining({
181177
hits: escapedHits,
182178
results,
@@ -186,13 +182,13 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/hits/js/#co
186182
});
187183

188184
it('transform items if requested', () => {
189-
const rendering = jest.fn();
190-
const makeWidget = connectHits(rendering);
185+
const renderFn = jest.fn();
186+
const makeWidget = connectHits(renderFn);
191187
const widget = makeWidget({
192188
transformItems: items => items.map(() => ({ name: 'transformed' })),
193189
});
194190

195-
const helper = jsHelper({}, '', {});
191+
const helper = algoliasearchHelper({}, '', {});
196192
helper.search = jest.fn();
197193

198194
widget.init({
@@ -202,7 +198,7 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/hits/js/#co
202198
onHistoryChange: () => {},
203199
});
204200

205-
expect(rendering).toHaveBeenNthCalledWith(
201+
expect(renderFn).toHaveBeenNthCalledWith(
206202
1,
207203
expect.objectContaining({ hits: [], results: undefined }),
208204
expect.anything()
@@ -221,7 +217,7 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/hits/js/#co
221217
const expectedHits = [{ name: 'transformed' }, { name: 'transformed' }];
222218
expectedHits.__escaped = true;
223219

224-
expect(rendering).toHaveBeenNthCalledWith(
220+
expect(renderFn).toHaveBeenNthCalledWith(
225221
2,
226222
expect.objectContaining({
227223
hits: expectedHits,
@@ -232,11 +228,11 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/hits/js/#co
232228
});
233229

234230
it('adds queryID if provided to results', () => {
235-
const rendering = jest.fn();
236-
const makeWidget = connectHits(rendering);
231+
const renderFn = jest.fn();
232+
const makeWidget = connectHits(renderFn);
237233
const widget = makeWidget({});
238234

239-
const helper = jsHelper({}, '', {});
235+
const helper = algoliasearchHelper({}, '', {});
240236
helper.search = jest.fn();
241237

242238
widget.init({
@@ -264,7 +260,7 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/hits/js/#co
264260
];
265261
expectedHits.__escaped = true;
266262

267-
expect(rendering).toHaveBeenNthCalledWith(
263+
expect(renderFn).toHaveBeenNthCalledWith(
268264
2,
269265
expect.objectContaining({
270266
hits: expectedHits,
@@ -274,8 +270,8 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/hits/js/#co
274270
});
275271

276272
it('transform items after escaping', () => {
277-
const rendering = jest.fn();
278-
const makeWidget = connectHits(rendering);
273+
const renderFn = jest.fn();
274+
const makeWidget = connectHits(renderFn);
279275
const widget = makeWidget({
280276
transformItems: items =>
281277
items.map(item => ({
@@ -289,7 +285,7 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/hits/js/#co
289285
escapeHTML: true,
290286
});
291287

292-
const helper = jsHelper({}, '', {});
288+
const helper = algoliasearchHelper({}, '', {});
293289
helper.search = jest.fn();
294290

295291
widget.init({
@@ -343,9 +339,10 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/hits/js/#co
343339
},
344340
},
345341
];
342+
346343
expectedHits.__escaped = true;
347344

348-
expect(rendering).toHaveBeenNthCalledWith(
345+
expect(renderFn).toHaveBeenNthCalledWith(
349346
2,
350347
expect.objectContaining({
351348
hits: expectedHits,
@@ -360,7 +357,7 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/hits/js/#co
360357
const makeWidget = connectHits(rendering);
361358
const widget = makeWidget({});
362359

363-
const helper = jsHelper({}, '', {});
360+
const helper = algoliasearchHelper({}, '', {});
364361
helper.search = jest.fn();
365362

366363
widget.init({
@@ -383,11 +380,76 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/hits/js/#co
383380
expect(results.hits.__escaped).toBe(true);
384381
});
385382

386-
it('does not throw without the unmount function', () => {
387-
const rendering = () => {};
388-
const makeWidget = connectHits(rendering);
389-
const widget = makeWidget({});
390-
const helper = jsHelper({}, '', {});
391-
expect(() => widget.dispose({ helper, state: helper.state })).not.toThrow();
383+
describe('dispose', () => {
384+
it('calls the unmount function', () => {
385+
const helper = algoliasearchHelper({}, '');
386+
387+
const renderFn = () => {};
388+
const unmountFn = jest.fn();
389+
const makeWidget = connectHits(renderFn, unmountFn);
390+
const widget = makeWidget();
391+
392+
expect(unmountFn).toHaveBeenCalledTimes(0);
393+
394+
widget.dispose({ helper, state: helper.state });
395+
396+
expect(unmountFn).toHaveBeenCalledTimes(1);
397+
});
398+
399+
it('does not throw without the unmount function', () => {
400+
const helper = algoliasearchHelper({}, '');
401+
402+
const renderFn = () => {};
403+
const makeWidget = connectHits(renderFn);
404+
const widget = makeWidget();
405+
406+
expect(() =>
407+
widget.dispose({ helper, state: helper.state })
408+
).not.toThrow();
409+
});
410+
411+
it('removes the TAG_PLACEHOLDER from the `SearchParameters`', () => {
412+
const helper = algoliasearchHelper({}, '', {
413+
...TAG_PLACEHOLDER,
414+
});
415+
416+
const renderFn = () => {};
417+
const makeWidget = connectHits(renderFn);
418+
const widget = makeWidget();
419+
420+
expect(helper.state.highlightPreTag).toBe(
421+
TAG_PLACEHOLDER.highlightPreTag
422+
);
423+
424+
expect(helper.state.highlightPostTag).toBe(
425+
TAG_PLACEHOLDER.highlightPostTag
426+
);
427+
428+
const nextState = widget.dispose({ helper, state: helper.state });
429+
430+
expect(nextState.highlightPreTag).toBeUndefined();
431+
expect(nextState.highlightPostTag).toBeUndefined();
432+
});
433+
434+
it('does not remove the TAG_PLACEHOLDER from the `SearchParameters` with `escapeHTML`', () => {
435+
const helper = algoliasearchHelper({}, '', {
436+
highlightPreTag: '<mark>',
437+
highlightPostTag: '</mark>',
438+
});
439+
440+
const renderFn = () => {};
441+
const makeWidget = connectHits(renderFn);
442+
const widget = makeWidget({
443+
escapeHTML: false,
444+
});
445+
446+
expect(helper.state.highlightPreTag).toBe('<mark>');
447+
expect(helper.state.highlightPostTag).toBe('</mark>');
448+
449+
const nextState = widget.dispose({ helper, state: helper.state });
450+
451+
expect(nextState.highlightPreTag).toBe('<mark>');
452+
expect(nextState.highlightPostTag).toBe('</mark>');
453+
});
392454
});
393455
});

src/connectors/hits/connectHits.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,22 @@ export default function connectHits(renderFn, unmountFn = noop) {
107107
);
108108
},
109109

110-
dispose() {
110+
dispose({ state }) {
111111
unmountFn();
112+
113+
if (!escapeHTML) {
114+
return state;
115+
}
116+
117+
return state.setQueryParameters(
118+
Object.keys(TAG_PLACEHOLDER).reduce(
119+
(acc, key) => ({
120+
...acc,
121+
[key]: undefined,
122+
}),
123+
{}
124+
)
125+
);
112126
},
113127
};
114128
};

0 commit comments

Comments
 (0)