Skip to content

Commit

Permalink
fix(configure): update lifecycle state (#3994)
Browse files Browse the repository at this point in the history
  • Loading branch information
francoischalifour authored and Haroenv committed Oct 23, 2019
1 parent f1beff6 commit 3d8d967
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 55 deletions.
128 changes: 96 additions & 32 deletions src/connectors/configure/__tests__/connectConfigure-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,64 +73,128 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/configure/j

it('should apply searchParameters', () => {
const makeWidget = connectConfigure();
const widget = makeWidget({ searchParameters: { analytics: true } });
const widget = makeWidget({
searchParameters: {
analytics: true,
},
});

const config = widget.getConfiguration(SearchParameters.make({}));
expect(config).toEqual({ analytics: true });
expect(widget.getConfiguration(new SearchParameters({}))).toEqual(
new SearchParameters({
analytics: true,
})
);
});

it('should apply searchParameters with a higher priority', () => {
const makeWidget = connectConfigure();
const widget = makeWidget({ searchParameters: { analytics: true } });

{
const config = widget.getConfiguration(
SearchParameters.make({ analytics: false })
);
expect(config).toEqual({ analytics: true });
}

{
const config = widget.getConfiguration(
SearchParameters.make({ analytics: false, extra: true })
);
expect(config).toEqual({ analytics: true });
}
const widget = makeWidget({
searchParameters: {
analytics: true,
},
});

expect(
widget.getConfiguration(
new SearchParameters({
analytics: false,
})
)
).toEqual(
new SearchParameters({
analytics: true,
})
);

expect(
widget.getConfiguration(
new SearchParameters({
analytics: false,
clickAnalytics: true,
})
)
).toEqual(
new SearchParameters({
analytics: true,
clickAnalytics: true,
})
);
});

it('should apply new searchParameters on refine()', () => {
const renderFn = jest.fn();
const makeWidget = connectConfigure(renderFn, jest.fn());
const widget = makeWidget({ searchParameters: { analytics: true } });
const widget = makeWidget({
searchParameters: {
analytics: true,
},
});

helper.setState(widget.getConfiguration());
helper.setState(
widget.getConfiguration(
new SearchParameters({
// This facet is added outside of the widget params
// so it shouldn't be overridden when calling `refine`.
facets: ['brand'],
})
)
);
widget.init({ helper });

expect(widget.getConfiguration()).toEqual({ analytics: true });
expect(helper.state.analytics).toEqual(true);
expect(widget.getConfiguration(new SearchParameters({}))).toEqual(
new SearchParameters({
analytics: true,
})
);
expect(helper.state).toEqual(
new SearchParameters({
analytics: true,
facets: ['brand'],
})
);

const { refine } = renderFn.mock.calls[0][0];
expect(refine).toBe(widget._refine);

refine({ hitsPerPage: 3 });
refine({ hitsPerPage: 3, facets: ['rating'] });

expect(widget.getConfiguration()).toEqual({ hitsPerPage: 3 });
expect(helper.state.analytics).toBe(undefined);
expect(helper.state.hitsPerPage).toBe(3);
expect(widget.getConfiguration(new SearchParameters({}))).toEqual(
new SearchParameters({
hitsPerPage: 3,
facets: ['rating'],
})
);
expect(helper.state).toEqual(
new SearchParameters({
hitsPerPage: 3,
facets: ['brand', 'rating'],
})
);
});

it('should dispose all the state set by configure', () => {
const makeWidget = connectConfigure();
const widget = makeWidget({ searchParameters: { analytics: true } });
const widget = makeWidget({
searchParameters: {
analytics: true,
},
});

helper.setState(widget.getConfiguration());
helper.setState(widget.getConfiguration(new SearchParameters({})));
widget.init({ helper });

expect(widget.getConfiguration()).toEqual({ analytics: true });
expect(helper.state.analytics).toBe(true);
expect(widget.getConfiguration(new SearchParameters({}))).toEqual(
new SearchParameters({
analytics: true,
})
);
expect(helper.state).toEqual(
new SearchParameters({
analytics: true,
})
);

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

expect(nextState.analytics).toBe(undefined);
expect(nextState).toEqual(new SearchParameters({}));
});
});
51 changes: 28 additions & 23 deletions src/connectors/configure/connectConfigure.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import algoliasearchHelper from 'algoliasearch-helper';
import {
createDocumentationMessageGenerator,
enhanceConfiguration,
isPlainObject,
mergeSearchParameters,
noop,
} from '../../lib/utils';

Expand All @@ -10,6 +11,21 @@ const withUsage = createDocumentationMessageGenerator({
connector: true,
});

function getInitialSearchParameters(state, widgetParams) {
// We leverage the helper internals to remove the `widgetParams` from
// the state. The function `setQueryParameters` omits the values that
// are `undefined` on the next state.
return state.setQueryParameters(
Object.keys(widgetParams.searchParameters).reduce(
(acc, key) => ({
...acc,
[key]: undefined,
}),
{}
)
);
}

/**
* @typedef {Object} CustomConfigureWidgetOptions
* @property {Object} searchParameters The Configure widget options are search parameters
Expand Down Expand Up @@ -41,8 +57,8 @@ export default function connectConfigure(renderFn = noop, unmountFn = noop) {
return {
$$type: 'ais.configure',

getConfiguration() {
return widgetParams.searchParameters;
getConfiguration(state) {
return state.setQueryParameters(widgetParams.searchParameters);
},

init({ helper }) {
Expand All @@ -60,10 +76,14 @@ export default function connectConfigure(renderFn = noop, unmountFn = noop) {
refine(helper) {
return searchParameters => {
// merge new `searchParameters` with the ones set from other widgets
const actualState = this.removeSearchParameters(helper.state);
const nextSearchParameters = enhanceConfiguration(actualState, {
getConfiguration: () => searchParameters,
});
const actualState = getInitialSearchParameters(
helper.state,
widgetParams
);
const nextSearchParameters = mergeSearchParameters(
actualState,
new algoliasearchHelper.SearchParameters(searchParameters)
);

// trigger a search with the new merged searchParameters
helper.setState(nextSearchParameters).search();
Expand All @@ -86,22 +106,7 @@ export default function connectConfigure(renderFn = noop, unmountFn = noop) {
dispose({ state }) {
unmountFn();

return this.removeSearchParameters(state);
},

removeSearchParameters(state) {
// We leverage the Helper internals to remove the `widgetParams` from
// the state. The function `setQueryParameters` omits the values that
// are `undefined` on the next state.
return state.setQueryParameters(
Object.keys(widgetParams.searchParameters).reduce(
(acc, key) => ({
...acc,
[key]: undefined,
}),
{}
)
);
return getInitialSearchParameters(state, widgetParams);
},
};
};
Expand Down

0 comments on commit 3d8d967

Please sign in to comment.