From 6a58b99e7af3a2cf9347dc31dcd0c69a1b2014cb Mon Sep 17 00:00:00 2001 From: Youcef Mammar Date: Thu, 18 Oct 2018 18:37:12 +0200 Subject: [PATCH] fix(getRefinements): provide attributeName for type: query Closes #3205 * fix(dev-novel): add example to dev-novel with onlyListedAttributes * fix(getRefinements) test connectCurrentRefinedValues with query refinements and onlyListedAttributes: true * fix(current-refined-values): wrap query refinement with * fix(current-refined-values): add tests for defaultTemplates * fix(getRefinements): simplify tests for query --- .../stories/current-refined-values.stories.js | 30 +++++++++++ .../connectCurrentRefinedValues-test.js | 54 +++++++++++++++++++ src/lib/__tests__/utils-test.js | 25 +++++++++ src/lib/utils.js | 1 + .../defaultTemplates-test.js.snap | 7 +++ .../__tests__/defaultTemplates-test.js | 43 +++++++++++++++ .../defaultTemplates.js | 12 +++-- 7 files changed, 167 insertions(+), 5 deletions(-) create mode 100644 src/widgets/current-refined-values/__tests__/__snapshots__/defaultTemplates-test.js.snap create mode 100644 src/widgets/current-refined-values/__tests__/defaultTemplates-test.js diff --git a/dev/app/builtin/stories/current-refined-values.stories.js b/dev/app/builtin/stories/current-refined-values.stories.js index 96290f6942..8f84521ddd 100644 --- a/dev/app/builtin/stories/current-refined-values.stories.js +++ b/dev/app/builtin/stories/current-refined-values.stories.js @@ -105,5 +105,35 @@ export default () => { }, } ) + ) + .add( + 'with onlyListedAttributes', + wrapWithHits( + container => { + window.search.addWidget( + instantsearch.widgets.currentRefinedValues({ + container, + onlyListedAttributes: true, + clearsQuery: true, + attributes: [ + { + name: 'brand', + label: 'Brand', + }, + { + name: 'query', + }, + ], + }) + ); + }, + { + searchParameters: { + disjunctiveFacetsRefinements: { brand: ['Apple', 'Samsung'] }, + disjunctiveFacets: ['brand'], + numericRefinements: { price: { '>=': [100] } }, + }, + } + ) ); }; diff --git a/src/connectors/current-refined-values/__tests__/connectCurrentRefinedValues-test.js b/src/connectors/current-refined-values/__tests__/connectCurrentRefinedValues-test.js index 23e54febb6..077439509f 100644 --- a/src/connectors/current-refined-values/__tests__/connectCurrentRefinedValues-test.js +++ b/src/connectors/current-refined-values/__tests__/connectCurrentRefinedValues-test.js @@ -217,4 +217,58 @@ describe('connectCurrentRefinedValues', () => { secondRefine(secondValue); expect(helper.state.query).toBe(''); }); + + it('should provide the query as a refinement if clearsQuery is true, onlyListedAttributes is true and `query` is a listed attribute', () => { + const helper = jsHelper({}, '', {}); + + const rendering = jest.fn(); + const makeWidget = connectCurrentRefinedValues(rendering); + const widget = makeWidget({ + clearsQuery: true, + onlyListedAttributes: true, + attributes: [{ name: 'query' }], + }); + + helper.setQuery('foobar'); + + widget.init({ + helper, + state: helper.state, + createURL: () => '#', + onHistoryChange: () => {}, + }); + + const firstRenderingOptions = rendering.mock.calls[0][0]; + const refinements = firstRenderingOptions.refinements; + expect(refinements).toHaveLength(1); + const value = refinements[0]; + expect(value.type).toBe('query'); + expect(value.name).toBe('foobar'); + expect(value.query).toBe('foobar'); + }); + + it('should not provide the query as a refinement if clearsQuery is true, onlyListedAttributes is true but query is not listed in attributes', () => { + const helper = jsHelper({}, '', {}); + + const rendering = jest.fn(); + const makeWidget = connectCurrentRefinedValues(rendering); + const widget = makeWidget({ + clearsQuery: true, + onlyListedAttributes: true, + attributes: [{ name: 'brand' }], + }); + + helper.setQuery('foobar'); + + widget.init({ + helper, + state: helper.state, + createURL: () => '#', + onHistoryChange: () => {}, + }); + + const firstRenderingOptions = rendering.mock.calls[0][0]; + const refinements = firstRenderingOptions.refinements; + expect(refinements).toHaveLength(0); + }); }); diff --git a/src/lib/__tests__/utils-test.js b/src/lib/__tests__/utils-test.js index 7561a0e0fd..d6f1676cb5 100644 --- a/src/lib/__tests__/utils-test.js +++ b/src/lib/__tests__/utils-test.js @@ -342,6 +342,31 @@ describe('utils.getRefinements', () => { ); }); + it('should inject query facet if clearQuery === true', () => { + helper.setQuery('my query'); + const expected = [ + { + type: 'query', + attributeName: 'query', + name: 'my query', + query: 'my query', + }, + ]; + const clearsQuery = true; + expect(utils.getRefinements(results, helper.state, clearsQuery)).toEqual( + expected + ); + }); + + it('should retrieve one facetRefinement and not inject query facet if clearQuery === false', () => { + helper.setQuery('my query'); + const expected = []; + const clearsQuery = false; + expect(utils.getRefinements(results, helper.state, clearsQuery)).toEqual( + expected + ); + }); + it('should retrieve multiple facetsRefinements on one facet', () => { helper .toggleRefinement('facet1', 'facet1val1') diff --git a/src/lib/utils.js b/src/lib/utils.js index 727f5c5d38..81bf79ac4e 100644 --- a/src/lib/utils.js +++ b/src/lib/utils.js @@ -232,6 +232,7 @@ function getRefinements(results, state, clearsQuery) { type: 'query', name: state.query, query: state.query, + attributeName: 'query', }, ] : []; diff --git a/src/widgets/current-refined-values/__tests__/__snapshots__/defaultTemplates-test.js.snap b/src/widgets/current-refined-values/__tests__/__snapshots__/defaultTemplates-test.js.snap new file mode 100644 index 0000000000..78352420fc --- /dev/null +++ b/src/widgets/current-refined-values/__tests__/__snapshots__/defaultTemplates-test.js.snap @@ -0,0 +1,7 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`current-refined-values defaultTemplates \`item\` template does not show \`count\` when query refinement 1`] = `"Query : Samsu "`; + +exports[`current-refined-values defaultTemplates \`item\` template has a \`item\` default template 1`] = `"Brand : Samsung 4"`; + +exports[`current-refined-values defaultTemplates \`item\` template wraps query refinements with 1`] = `"Query : Samsu "`; diff --git a/src/widgets/current-refined-values/__tests__/defaultTemplates-test.js b/src/widgets/current-refined-values/__tests__/defaultTemplates-test.js new file mode 100644 index 0000000000..cfc94fa776 --- /dev/null +++ b/src/widgets/current-refined-values/__tests__/defaultTemplates-test.js @@ -0,0 +1,43 @@ +import defaultTemplates from '../defaultTemplates.js'; + +describe('current-refined-values defaultTemplates', () => { + describe('`item` template', () => { + it('has a `item` default template', () => { + const item = { + type: 'disjunction', + label: 'Brand', + operator: ':', + name: 'Samsung', + count: 4, + cssClasses: { + count: 'ais-current-refined-values--count', + }, + }; + expect(defaultTemplates.item(item)).toContain( + '4' + ); + expect(defaultTemplates.item(item)).toMatchSnapshot(); + }); + it('wraps query refinements with ', () => { + const item = { + type: 'query', + label: 'Query', + operator: ':', + name: 'Samsu', + }; + expect(defaultTemplates.item(item)).toContain('Query : Samsu'); + expect(defaultTemplates.item(item)).toMatchSnapshot(); + }); + it('does not show `count` when query refinement', () => { + const item = { + type: 'query', + label: 'Query', + operator: ':', + name: 'Samsu', + count: 22, + }; + expect(defaultTemplates.item(item)).not.toContain(22); + expect(defaultTemplates.item(item)).toMatchSnapshot(); + }); + }); +}); diff --git a/src/widgets/current-refined-values/defaultTemplates.js b/src/widgets/current-refined-values/defaultTemplates.js index 1e397d85ae..d4b76fbb6f 100644 --- a/src/widgets/current-refined-values/defaultTemplates.js +++ b/src/widgets/current-refined-values/defaultTemplates.js @@ -6,6 +6,7 @@ export default { }; function itemTemplate({ + type, label, operator, displayOperator, @@ -13,16 +14,17 @@ function itemTemplate({ name, count, cssClasses, - query, }) { const computedOperator = operator ? displayOperator : ''; const computedLabel = label ? `${label} ${computedOperator || ':'} ` : computedOperator; const countValue = count === undefined ? 0 : count; - const computedCount = query - ? '' - : `${countValue}`; + const computedCount = + type === 'query' + ? '' + : `${countValue}`; const computedExclude = exclude ? '-' : ''; - return `${computedLabel} ${computedExclude} ${name} ${computedCount}`; + const computedName = type === 'query' ? `${name}` : name; + return `${computedLabel} ${computedExclude} ${computedName} ${computedCount}`; }