Skip to content

Commit

Permalink
feat(connectHits): clear the state on dispose (#3816)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
samouss authored and Haroenv committed Oct 23, 2019
1 parent 8ae87d8 commit c4de730
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 46 deletions.
152 changes: 107 additions & 45 deletions src/connectors/hits/__tests__/connectHits-test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import jsHelper, { SearchResults } from 'algoliasearch-helper';
import algoliasearchHelper, { SearchResults } from 'algoliasearch-helper';
import { TAG_PLACEHOLDER } from '../../../lib/escape-highlight';
import connectHits from '../connectHits';

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

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

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

// test if widget is not rendered yet at this point
expect(rendering).toHaveBeenCalledTimes(0);
expect(renderFn).toHaveBeenCalledTimes(0);

const helper = jsHelper({}, '', {});
const helper = algoliasearchHelper({}, '', {});
helper.search = jest.fn();

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

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

expect(rendering).toHaveBeenCalledTimes(2);
// test that rendering has been called during init with isFirstRendering = false
expect(rendering).toHaveBeenLastCalledWith(
expect(renderFn).toHaveBeenCalledTimes(2);
expect(renderFn).toHaveBeenLastCalledWith(
expect.objectContaining({ widgetParams: { escapeHTML: true } }),
false
);
});

it('sets the default configuration', () => {
const rendering = jest.fn();
const makeWidget = connectHits(rendering);
const renderFn = jest.fn();
const makeWidget = connectHits(renderFn);
const widget = makeWidget();

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

it('Provides the hits and the whole results', () => {
const rendering = jest.fn();
const makeWidget = connectHits(rendering);
const renderFn = jest.fn();
const makeWidget = connectHits(renderFn);
const widget = makeWidget({});

const helper = jsHelper({}, '', {});
const helper = algoliasearchHelper({}, '', {});
helper.search = jest.fn();

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

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

expect(rendering).toHaveBeenLastCalledWith(
expect(renderFn).toHaveBeenLastCalledWith(
expect.objectContaining({
hits,
results,
Expand All @@ -124,11 +120,11 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/hits/js/#co
});

it('escape highlight properties if requested', () => {
const rendering = jest.fn();
const makeWidget = connectHits(rendering);
const renderFn = jest.fn();
const makeWidget = connectHits(renderFn);
const widget = makeWidget({ escapeHTML: true });

const helper = jsHelper({}, '', {});
const helper = algoliasearchHelper({}, '', {});
helper.search = jest.fn();

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

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

escapedHits.__escaped = true;

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

it('transform items if requested', () => {
const rendering = jest.fn();
const makeWidget = connectHits(rendering);
const renderFn = jest.fn();
const makeWidget = connectHits(renderFn);
const widget = makeWidget({
transformItems: items => items.map(() => ({ name: 'transformed' })),
});

const helper = jsHelper({}, '', {});
const helper = algoliasearchHelper({}, '', {});
helper.search = jest.fn();

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

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

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

it('adds queryID if provided to results', () => {
const rendering = jest.fn();
const makeWidget = connectHits(rendering);
const renderFn = jest.fn();
const makeWidget = connectHits(renderFn);
const widget = makeWidget({});

const helper = jsHelper({}, '', {});
const helper = algoliasearchHelper({}, '', {});
helper.search = jest.fn();

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

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

it('transform items after escaping', () => {
const rendering = jest.fn();
const makeWidget = connectHits(rendering);
const renderFn = jest.fn();
const makeWidget = connectHits(renderFn);
const widget = makeWidget({
transformItems: items =>
items.map(item => ({
Expand All @@ -289,7 +285,7 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/hits/js/#co
escapeHTML: true,
});

const helper = jsHelper({}, '', {});
const helper = algoliasearchHelper({}, '', {});
helper.search = jest.fn();

widget.init({
Expand Down Expand Up @@ -343,9 +339,10 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/hits/js/#co
},
},
];

expectedHits.__escaped = true;

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

const helper = jsHelper({}, '', {});
const helper = algoliasearchHelper({}, '', {});
helper.search = jest.fn();

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

it('does not throw without the unmount function', () => {
const rendering = () => {};
const makeWidget = connectHits(rendering);
const widget = makeWidget({});
const helper = jsHelper({}, '', {});
expect(() => widget.dispose({ helper, state: helper.state })).not.toThrow();
describe('dispose', () => {
it('calls the unmount function', () => {
const helper = algoliasearchHelper({}, '');

const renderFn = () => {};
const unmountFn = jest.fn();
const makeWidget = connectHits(renderFn, unmountFn);
const widget = makeWidget();

expect(unmountFn).toHaveBeenCalledTimes(0);

widget.dispose({ helper, state: helper.state });

expect(unmountFn).toHaveBeenCalledTimes(1);
});

it('does not throw without the unmount function', () => {
const helper = algoliasearchHelper({}, '');

const renderFn = () => {};
const makeWidget = connectHits(renderFn);
const widget = makeWidget();

expect(() =>
widget.dispose({ helper, state: helper.state })
).not.toThrow();
});

it('removes the TAG_PLACEHOLDER from the `SearchParameters`', () => {
const helper = algoliasearchHelper({}, '', {
...TAG_PLACEHOLDER,
});

const renderFn = () => {};
const makeWidget = connectHits(renderFn);
const widget = makeWidget();

expect(helper.state.highlightPreTag).toBe(
TAG_PLACEHOLDER.highlightPreTag
);

expect(helper.state.highlightPostTag).toBe(
TAG_PLACEHOLDER.highlightPostTag
);

const nextState = widget.dispose({ helper, state: helper.state });

expect(nextState.highlightPreTag).toBeUndefined();
expect(nextState.highlightPostTag).toBeUndefined();
});

it('does not remove the TAG_PLACEHOLDER from the `SearchParameters` with `escapeHTML`', () => {
const helper = algoliasearchHelper({}, '', {
highlightPreTag: '<mark>',
highlightPostTag: '</mark>',
});

const renderFn = () => {};
const makeWidget = connectHits(renderFn);
const widget = makeWidget({
escapeHTML: false,
});

expect(helper.state.highlightPreTag).toBe('<mark>');
expect(helper.state.highlightPostTag).toBe('</mark>');

const nextState = widget.dispose({ helper, state: helper.state });

expect(nextState.highlightPreTag).toBe('<mark>');
expect(nextState.highlightPostTag).toBe('</mark>');
});
});
});
16 changes: 15 additions & 1 deletion src/connectors/hits/connectHits.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,22 @@ export default function connectHits(renderFn, unmountFn = noop) {
);
},

dispose() {
dispose({ state }) {
unmountFn();

if (!escapeHTML) {
return state;
}

return state.setQueryParameters(
Object.keys(TAG_PLACEHOLDER).reduce(
(acc, key) => ({
...acc,
[key]: undefined,
}),
{}
)
);
},
};
};
Expand Down

0 comments on commit c4de730

Please sign in to comment.