Skip to content

Commit 49564e1

Browse files
committed
feat(clearRefinements): Added two utils methods
Since currentRefinedValue will use the same methods because it embeds a "Clear all" link, they need to be extracted and able to only receive a subset of attributeNames.
1 parent fc3e15f commit 49564e1

File tree

4 files changed

+174
-10
lines changed

4 files changed

+174
-10
lines changed

src/lib/__tests__/utils-test.js

+137
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import expect from 'expect';
44
import jsdom from 'mocha-jsdom';
55
import algoliasearchHelper from 'algoliasearch-helper';
66
import utils from '../utils';
7+
import isEmpty from 'lodash/lang/isEmpty';
78

89
describe('getContainerNode', () => {
910
jsdom({useEach: true});
@@ -440,3 +441,139 @@ describe('getRefinements', function() {
440441
expect(utils.getRefinements(results, helper.state)).toInclude(expected[4]);
441442
});
442443
});
444+
445+
describe('clearRefinementsFromState', () => {
446+
let helper;
447+
let state;
448+
449+
beforeEach(() => {
450+
helper = algoliasearchHelper({}, 'my_index', {
451+
facets: ['facet1', 'facet2', 'numericFacet1', 'facetExclude1'],
452+
disjunctiveFacets: ['disjunctiveFacet1', 'numericDisjunctiveFacet'],
453+
hierarchicalFacets: [{
454+
name: 'hierarchicalFacet1',
455+
attributes: ['hierarchicalFacet1.lvl0', 'hierarchicalFacet1.lvl1'],
456+
separator: ' > '
457+
}]
458+
});
459+
helper
460+
.toggleRefinement('facet1', 'facet1val1')
461+
.toggleRefinement('facet1', 'facet1val2')
462+
.toggleRefinement('facet2', 'facet2val1')
463+
.toggleRefinement('facet2', 'facet2val2')
464+
.toggleRefinement('disjunctiveFacet1', 'facet1val1')
465+
.toggleRefinement('disjunctiveFacet1', 'facet1val2')
466+
.toggleExclude('facetExclude1', 'facetExclude1val1')
467+
.toggleExclude('facetExclude1', 'facetExclude1val2')
468+
.addNumericRefinement('numericFacet1', '>', '1')
469+
.addNumericRefinement('numericFacet1', '>', '2')
470+
.addNumericRefinement('numericDisjunctiveFacet1', '>', '1')
471+
.addNumericRefinement('numericDisjunctiveFacet1', '>', '2')
472+
.toggleRefinement('hierarchicalFacet1', 'hierarchicalFacet1lvl0val1')
473+
.addTag('tag1')
474+
.addTag('tag2');
475+
state = helper.state;
476+
});
477+
478+
context('without arguments', () => {
479+
it('should clear everything', () => {
480+
let newState = utils.clearRefinementsFromState(state);
481+
expect(isEmpty(newState.facetsRefinements)).toBe(true, 'state shouldn\'t have facetsRefinements');
482+
expect(isEmpty(newState.facetsExcludes)).toBe(true, 'state shouldn\'t have facetsExcludes');
483+
expect(isEmpty(newState.disjunctiveFacetsRefinements)).toBe(true, 'state shouldn\'t have disjunctiveFacetsRefinements');
484+
expect(isEmpty(newState.hierarchicalFacetsRefinements)).toBe(true, 'state shouldn\'t have hierarchicalFacetsRefinements');
485+
expect(isEmpty(newState.numericRefinements)).toBe(true, 'state shouldn\'t have numericRefinements');
486+
expect(isEmpty(newState.tagRefinements)).toBe(true, 'state shouldn\'t have tagRefinements');
487+
});
488+
});
489+
490+
it('should clear one facet', () => {
491+
let newState = utils.clearRefinementsFromState(state, ['facet1']);
492+
expect(isEmpty(newState.facetsRefinements)).toBe(false, 'state should have facetsRefinements');
493+
expect(isEmpty(newState.facetsExcludes)).toBe(false, 'state should have facetsExcludes');
494+
expect(isEmpty(newState.disjunctiveFacetsRefinements)).toBe(false, 'state should have disjunctiveFacetsRefinements');
495+
expect(isEmpty(newState.hierarchicalFacetsRefinements)).toBe(false, 'state should have hierarchicalFacetsRefinements');
496+
expect(isEmpty(newState.numericRefinements)).toBe(false, 'state should have numericRefinements');
497+
expect(isEmpty(newState.tagRefinements)).toBe(false, 'state should have tagRefinements');
498+
});
499+
500+
it('should clear facets', () => {
501+
let newState = utils.clearRefinementsFromState(state, ['facet1', 'facet2']);
502+
expect(isEmpty(newState.facetsRefinements)).toBe(true, 'state shouldn\'t have facetsRefinements');
503+
expect(isEmpty(newState.facetsExcludes)).toBe(false, 'state should have facetsExcludes');
504+
expect(isEmpty(newState.disjunctiveFacetsRefinements)).toBe(false, 'state should have disjunctiveFacetsRefinements');
505+
expect(isEmpty(newState.hierarchicalFacetsRefinements)).toBe(false, 'state should have hierarchicalFacetsRefinements');
506+
expect(isEmpty(newState.numericRefinements)).toBe(false, 'state should have numericRefinements');
507+
expect(isEmpty(newState.tagRefinements)).toBe(false, 'state should have tagRefinements');
508+
});
509+
510+
it('should clear excludes', () => {
511+
let newState = utils.clearRefinementsFromState(state, ['facetExclude1']);
512+
expect(isEmpty(newState.facetsRefinements)).toBe(false, 'state should have facetsRefinements');
513+
expect(isEmpty(newState.facetsExcludes)).toBe(true, 'state shouldn\'t have facetsExcludes');
514+
expect(isEmpty(newState.disjunctiveFacetsRefinements)).toBe(false, 'state should have disjunctiveFacetsRefinements');
515+
expect(isEmpty(newState.hierarchicalFacetsRefinements)).toBe(false, 'state should have hierarchicalFacetsRefinements');
516+
expect(isEmpty(newState.numericRefinements)).toBe(false, 'state should have numericRefinements');
517+
expect(isEmpty(newState.tagRefinements)).toBe(false, 'state should have tagRefinements');
518+
});
519+
520+
it('should clear disjunctive facets', () => {
521+
let newState = utils.clearRefinementsFromState(state, ['disjunctiveFacet1']);
522+
expect(isEmpty(newState.facetsRefinements)).toBe(false, 'state should have facetsRefinements');
523+
expect(isEmpty(newState.facetsExcludes)).toBe(false, 'state should have facetsExcludes');
524+
expect(isEmpty(newState.disjunctiveFacetsRefinements)).toBe(true, 'state shouldn\'t have disjunctiveFacetsRefinements');
525+
expect(isEmpty(newState.hierarchicalFacetsRefinements)).toBe(false, 'state should have hierarchicalFacetsRefinements');
526+
expect(isEmpty(newState.numericRefinements)).toBe(false, 'state should have numericRefinements');
527+
expect(isEmpty(newState.tagRefinements)).toBe(false, 'state should have tagRefinements');
528+
});
529+
530+
it('should clear hierarchical facets', () => {
531+
let newState = utils.clearRefinementsFromState(state, ['hierarchicalFacet1']);
532+
expect(isEmpty(newState.facetsRefinements)).toBe(false, 'state should have facetsRefinements');
533+
expect(isEmpty(newState.facetsExcludes)).toBe(false, 'state should have facetsExcludes');
534+
expect(isEmpty(newState.disjunctiveFacetsRefinements)).toBe(false, 'state should have disjunctiveFacetsRefinements');
535+
expect(isEmpty(newState.hierarchicalFacetsRefinements)).toBe(true, 'state shouldn\'t have hierarchicalFacetsRefinements');
536+
expect(isEmpty(newState.numericRefinements)).toBe(false, 'state should have numericRefinements');
537+
expect(isEmpty(newState.tagRefinements)).toBe(false, 'state should have tagRefinements');
538+
});
539+
540+
it('should clear one numeric facet', () => {
541+
let newState = utils.clearRefinementsFromState(state, ['numericFacet1']);
542+
expect(isEmpty(newState.facetsRefinements)).toBe(false, 'state should have facetsRefinements');
543+
expect(isEmpty(newState.facetsExcludes)).toBe(false, 'state should have facetsExcludes');
544+
expect(isEmpty(newState.disjunctiveFacetsRefinements)).toBe(false, 'state should have disjunctiveFacetsRefinements');
545+
expect(isEmpty(newState.hierarchicalFacetsRefinements)).toBe(false, 'state should have hierarchicalFacetsRefinements');
546+
expect(isEmpty(newState.numericRefinements)).toBe(false, 'state should have numericRefinements');
547+
expect(isEmpty(newState.tagRefinements)).toBe(false, 'state should have tagRefinements');
548+
});
549+
550+
it('should clear one numeric facet', () => {
551+
let newState = utils.clearRefinementsFromState(state, ['numericDisjunctiveFacet1']);
552+
expect(isEmpty(newState.facetsRefinements)).toBe(false, 'state should have facetsRefinements');
553+
expect(isEmpty(newState.facetsExcludes)).toBe(false, 'state should have facetsExcludes');
554+
expect(isEmpty(newState.disjunctiveFacetsRefinements)).toBe(false, 'state should have disjunctiveFacetsRefinements');
555+
expect(isEmpty(newState.hierarchicalFacetsRefinements)).toBe(false, 'state should have hierarchicalFacetsRefinements');
556+
expect(isEmpty(newState.numericRefinements)).toBe(false, 'state should have numericRefinements');
557+
expect(isEmpty(newState.tagRefinements)).toBe(false, 'state should have tagRefinements');
558+
});
559+
560+
it('should clear numeric facets', () => {
561+
let newState = utils.clearRefinementsFromState(state, ['numericFacet1', 'numericDisjunctiveFacet1']);
562+
expect(isEmpty(newState.facetsRefinements)).toBe(false, 'state should have facetsRefinements');
563+
expect(isEmpty(newState.facetsExcludes)).toBe(false, 'state should have facetsExcludes');
564+
expect(isEmpty(newState.disjunctiveFacetsRefinements)).toBe(false, 'state should have disjunctiveFacetsRefinements');
565+
expect(isEmpty(newState.hierarchicalFacetsRefinements)).toBe(false, 'state should have hierarchicalFacetsRefinements');
566+
expect(isEmpty(newState.numericRefinements)).toBe(true, 'state shouldn\'t have numericRefinements');
567+
expect(isEmpty(newState.tagRefinements)).toBe(false, 'state should have tagRefinements');
568+
});
569+
570+
it('should clear tags', () => {
571+
let newState = utils.clearRefinementsFromState(state, ['_tags']);
572+
expect(isEmpty(newState.facetsRefinements)).toBe(false, 'state should have facetsRefinements');
573+
expect(isEmpty(newState.facetsExcludes)).toBe(false, 'state should have facetsExcludes');
574+
expect(isEmpty(newState.disjunctiveFacetsRefinements)).toBe(false, 'state should have disjunctiveFacetsRefinements');
575+
expect(isEmpty(newState.hierarchicalFacetsRefinements)).toBe(false, 'state should have hierarchicalFacetsRefinements');
576+
expect(isEmpty(newState.numericRefinements)).toBe(false, 'state should have numericRefinements');
577+
expect(isEmpty(newState.tagRefinements)).toBe(true, 'state shouldn\'t have tagRefinements');
578+
});
579+
});

src/lib/utils.js

+25-1
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@ let reduce = require('lodash/collection/reduce');
22
let forEach = require('lodash/collection/forEach');
33
let find = require('lodash/collection/find');
44
let get = require('lodash/object/get');
5+
let isEmpty = require('lodash/lang/isEmpty');
56

67
let utils = {
78
getContainerNode,
89
bemHelper,
910
prepareTemplateProps,
1011
isSpecialClick,
1112
isDomElement,
12-
getRefinements
13+
getRefinements,
14+
clearRefinementsFromState,
15+
clearRefinementsAndSearch
1316
};
1417

1518
/**
@@ -181,4 +184,25 @@ function getRefinements(results, state) {
181184
return res;
182185
}
183186

187+
function clearRefinementsFromState(state, attributeNames) {
188+
if (isEmpty(attributeNames)) {
189+
state = state.clearTags();
190+
state = state.clearRefinements();
191+
return state;
192+
}
193+
194+
forEach(attributeNames, (attributeName) => {
195+
if (attributeName === '_tags') {
196+
state = state.clearTags();
197+
} else {
198+
state = state.clearRefinements(attributeName);
199+
}
200+
});
201+
return state;
202+
}
203+
204+
function clearRefinementsAndSearch(helper, attributeNames) {
205+
helper.setState(clearRefinementsFromState(helper.state, attributeNames)).search();
206+
}
207+
184208
module.exports = utils;

src/widgets/clear-all/__tests__/clear-all-test.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ describe('clearAll()', () => {
4141
results = {};
4242
helper = {
4343
state: {
44-
clearRefinements: sinon.spy(),
45-
clearTags: sinon.spy()
44+
clearRefinements: sinon.stub().returnsThis(),
45+
clearTags: sinon.stub().returnsThis()
4646
},
4747
search: sinon.spy()
4848
};

src/widgets/clear-all/clear-all.js

+10-7
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
let React = require('react');
22
let ReactDOM = require('react-dom');
33

4-
let {bemHelper, getContainerNode, prepareTemplateProps, getRefinements} = require('../../lib/utils.js');
4+
let {
5+
bemHelper,
6+
getContainerNode,
7+
prepareTemplateProps,
8+
getRefinements,
9+
clearRefinementsFromState,
10+
clearRefinementsAndSearch
11+
} = require('../../lib/utils.js');
512
let bem = bemHelper('ais-clear-all');
613
let cx = require('classnames');
714

@@ -51,10 +58,6 @@ function clearAll({
5158
}
5259

5360
return {
54-
_clearAll: function(helper) {
55-
helper.clearTags().clearRefinements().search();
56-
},
57-
5861
render: function({results, helper, state, templatesConfig, createURL}) {
5962
let hasRefinements = getRefinements(results, state).length !== 0;
6063

@@ -66,9 +69,9 @@ function clearAll({
6669
link: cx(bem('link'), userCssClasses.link)
6770
};
6871

69-
let url = createURL(state.clearRefinements());
72+
let url = createURL(clearRefinementsFromState(state));
7073

71-
let handleClick = this._clearAll.bind(null, helper);
74+
let handleClick = clearRefinementsAndSearch.bind(null, helper);
7275

7376
let templateProps = prepareTemplateProps({
7477
defaultTemplates,

0 commit comments

Comments
 (0)