Skip to content
This repository has been archived by the owner on Jul 11, 2023. It is now read-only.

Commit

Permalink
fix(toggleRefinement): keep an empty array when clearing (#738)
Browse files Browse the repository at this point in the history
* fix(toggleRefinement): keep an empty array when clearing

When clearing a refinement using `toggleRefinement` we want to keep the empty refinement object for that attribute, because we use it to override a deeper refinement of that attribute in IS.js with federated search

* chore: add additional tests & fix for numeric

* consequences

* chore: add comment
  • Loading branch information
Haroenv committed Nov 18, 2019
1 parent c6aa31b commit 5b3fc11
Show file tree
Hide file tree
Showing 9 changed files with 413 additions and 44 deletions.
15 changes: 8 additions & 7 deletions src/SearchParameters/RefinementList.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,11 @@ var lib = {
*/
removeRefinement: function removeRefinement(refinementList, attribute, value) {
if (value === undefined) {
return lib.clearRefinement(refinementList, attribute);
// we use the "filter" form of clearRefinement, since it leaves empty values as-is
// the form with a string will remove the attribute completely
return lib.clearRefinement(refinementList, function(v, f) {
return attribute === f;
});
}

var valueAsString = '' + value;
Expand Down Expand Up @@ -107,14 +111,11 @@ var lib = {
var facetList = values.filter(function(value) {
return !attribute(value, key, refinementType);
});
if (facetList.length > 0) {
if (facetList.length !== values.length) {
hasChanged = true;
}
memo[key] = facetList;
} else {

if (facetList.length !== values.length) {
hasChanged = true;
}
memo[key] = facetList;

return memo;
}, {});
Expand Down
11 changes: 4 additions & 7 deletions src/SearchParameters/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -664,16 +664,13 @@ SearchParameters.prototype = {
var predicateResult = attribute({val: value, op: operator}, key, 'numeric');
if (!predicateResult) outValues.push(value);
});
if (outValues.length > 0) {
if (outValues.length !== values.length) hasChanged = true;
operatorList[operator] = outValues;
if (outValues.length !== values.length) {
hasChanged = true;
}
else hasChanged = true;
operatorList[operator] = outValues;
});

if (objectHasKeys(operatorList)) {
memo[key] = operatorList;
}
memo[key] = operatorList;

return memo;
}, {});
Expand Down
3 changes: 3 additions & 0 deletions src/SearchResults/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,9 @@ function getFacetStatsIfAvailable(facetList, facetName) {
* See the [refinement type](#Refinement) for an exhaustive view of the available
* data.
*
* Note that for a numeric refinement, results are grouped per operator, this
* means that it will return responses for operators which are empty.
*
* @return {Array.<Refinement>} all the refinements
*/
SearchResults.prototype.getRefinements = function() {
Expand Down
14 changes: 11 additions & 3 deletions test/spec/SearchParameters/numericFilters.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,25 @@

var SearchParameters = require('../../../src/SearchParameters');

var attribute = 'attribute';
var operator = '=';

/* Ensure that we add and then remove the same value, and get a state equivalent to the initial one */
function testSameValue(value) {
var attribute = 'attribute';
var operator = '=';

var state0 = new SearchParameters();
var state1 = state0.addNumericRefinement(attribute, operator, value);
var stateEmpty = new SearchParameters({
numericRefinements: {
[attribute]: {
[operator]: []
}
}
});
expect(state1.isNumericRefined(attribute, operator, value)).toBeTruthy();
var state2 = state1.removeNumericRefinement(attribute, operator, value);
expect(state2.isNumericRefined(attribute, operator, value)).toBeFalsy();
expect(state2).toEqual(state0);
expect(state2).toEqual(stateEmpty);
}

test('Should be able to add remove strings', function() {
Expand Down
304 changes: 304 additions & 0 deletions test/spec/SearchParameters/removeXFacetRefinement.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,304 @@
'use strict';

var SearchParameters = require('../../../src/SearchParameters');

describe('removeDisjunctiveFacetRefinement', function() {
test('removeDisjunctiveFacetRefinement(attribute)', function() {
var state = new SearchParameters({
disjunctiveFacets: ['attribute'],
disjunctiveFacetsRefinements: {
attribute: ['value']
}
});

expect(state.removeDisjunctiveFacetRefinement('attribute')).toEqual(
new SearchParameters({
disjunctiveFacets: ['attribute'],
disjunctiveFacetsRefinements: {
attribute: []
}
})
);
});

test('removeDisjunctiveFacetRefinement(attribute, value)', function() {
var state = new SearchParameters({
disjunctiveFacets: ['attribute'],
disjunctiveFacetsRefinements: {
attribute: ['value', 'value2']
}
});

expect(state.removeDisjunctiveFacetRefinement('attribute', 'value')).toEqual(
new SearchParameters({
disjunctiveFacets: ['attribute'],
disjunctiveFacetsRefinements: {
attribute: ['value2']
}
})
);
});

test('removeDisjunctiveFacetRefinement(attribute, lastValue)', function() {
var state = new SearchParameters({
disjunctiveFacets: ['attribute'],
disjunctiveFacetsRefinements: {
attribute: ['value']
}
});

expect(state.removeDisjunctiveFacetRefinement('attribute', 'value')).toEqual(
new SearchParameters({
disjunctiveFacets: ['attribute'],
disjunctiveFacetsRefinements: {
attribute: []
}
})
);
});
});

describe('removeFacetRefinement', function() {
test('removeFacetRefinement(attribute)', function() {
var state = new SearchParameters({
facets: ['attribute'],
facetsRefinements: {
attribute: ['value']
}
});

expect(state.removeFacetRefinement('attribute')).toEqual(
new SearchParameters({
facets: ['attribute'],
facetsRefinements: {
attribute: []
}
})
);
});

test('removeFacetRefinement(attribute, value)', function() {
var state = new SearchParameters({
facets: ['attribute'],
facetsRefinements: {
attribute: ['value', 'value2']
}
});

expect(state.removeFacetRefinement('attribute', 'value')).toEqual(
new SearchParameters({
facets: ['attribute'],
facetsRefinements: {
attribute: ['value2']
}
})
);
});

test('removeFacetRefinement(attribute, lastValue)', function() {
var state = new SearchParameters({
facets: ['attribute'],
facetsRefinements: {
attribute: ['value']
}
});

expect(state.removeFacetRefinement('attribute', 'value')).toEqual(
new SearchParameters({
facets: ['attribute'],
facetsRefinements: {
attribute: []
}
})
);
});
});

describe('removeExcludeRefinement', function() {
test('removeExcludeRefinement(attribute)', function() {
var state = new SearchParameters({
facets: ['attribute'],
facetsExcludes: {
attribute: ['value']
}
});

expect(state.removeExcludeRefinement('attribute')).toEqual(
new SearchParameters({
facets: ['attribute'],
facetsExcludes: {
attribute: []
}
})
);
});

test('removeExcludeRefinement(attribute, value)', function() {
var state = new SearchParameters({
facets: ['attribute'],
facetsExcludes: {
attribute: ['value', 'value2']
}
});

expect(state.removeExcludeRefinement('attribute', 'value')).toEqual(
new SearchParameters({
facets: ['attribute'],
facetsExcludes: {
attribute: ['value2']
}
})
);
});

test('removeExcludeRefinement(attribute, lastValue)', function() {
var state = new SearchParameters({
facets: ['attribute'],
facetsExcludes: {
attribute: ['value']
}
});

expect(state.removeExcludeRefinement('attribute', 'value')).toEqual(
new SearchParameters({
facets: ['attribute'],
facetsExcludes: {
attribute: []
}
})
);
});
});

describe('removeTagRefinement', function() {
test('removeTagRefinement(tag)', function() {
var state = new SearchParameters({
tagRefinements: ['tag', 'tag2']
});

expect(state.removeTagRefinement('tag')).toEqual(
new SearchParameters({
tagRefinements: ['tag2']
})
);
});

test('removeTagRefinement(lastTag)', function() {
var state = new SearchParameters({
tagRefinements: ['lastTag']
});

expect(state.removeTagRefinement('lastTag')).toEqual(
new SearchParameters({
tagRefinements: []
})
);
});
});

describe('removeHierarchicalFacetRefinement', function() {
// NOTE: removeHierarchicalFacetRefinement only allows to remove a whole attribute
test('removeHierarchicalFacetRefinement(attribute)', function() {
var state = new SearchParameters({
hierarchicalFacets: [{name: 'attribute'}],
hierarchicalFacetsRefinements: {
attribute: ['value', 'value2']
}
});

expect(state.removeHierarchicalFacetRefinement('attribute')).toEqual(
new SearchParameters({
hierarchicalFacets: [{name: 'attribute'}],
hierarchicalFacetsRefinements: {
attribute: []
}
})
);
});
});

describe('removeNumericRefinement', function() {
test('removeNumericRefinement(attribute)', function() {
var state = new SearchParameters({
numericRefinements: {
attribute: {
'>=': [100]
}
}
});

expect(state.removeNumericRefinement('attribute')).toEqual(
new SearchParameters({
numericRefinements: {
attribute: {
'>=': []
}
}
})
);
});

test('removeNumericRefinement(attribute, operator)', function() {
var state = new SearchParameters({
numericRefinements: {
attribute: {
'>=': [100]
}
}
});

expect(state.removeNumericRefinement('attribute', '>=')).toEqual(
new SearchParameters({
numericRefinements: {
attribute: {
'>=': []
}
}
})
);
});

test('removeNumericRefinement(attribute, operator, value)', function() {
var state = new SearchParameters({
numericRefinements: {
attribute: {
'<': [100],
'>=': [100, 200]
}
}
});

expect(state.removeNumericRefinement('attribute', '>=', 100)).toEqual(
new SearchParameters({
numericRefinements: {
attribute: {
'<': [100],
'>=': [200]
}
}
})
);
});

test('removeNumericRefinement(attribute, operator, lastValue)', function() {
var state = new SearchParameters({
numericRefinements: {
attribute: {
'<': [100],
'>=': [100, 200]
}
}
});

expect(state.removeNumericRefinement('attribute', '<', 100)).toEqual(
new SearchParameters({
numericRefinements: {
attribute: {
'<': [],
'>=': [100, 200]
}
}
})
);
});
});
Loading

0 comments on commit 5b3fc11

Please sign in to comment.