diff --git a/packages/algoliasearch-helper/src/SearchResults/index.js b/packages/algoliasearch-helper/src/SearchResults/index.js index 453a063699..36af0dba1b 100644 --- a/packages/algoliasearch-helper/src/SearchResults/index.js +++ b/packages/algoliasearch-helper/src/SearchResults/index.js @@ -241,7 +241,7 @@ function SearchResults(state, results, options) { // Make every key of the result options reachable from the instance var opts = defaultsPure(options, { - persistHierarchicalRootCount: false, + persistHierarchicalRootCount: true, }); Object.keys(opts).forEach(function (key) { self[key] = opts[key]; diff --git a/packages/algoliasearch-helper/test/datasets/SearchParameters/search.dataset.js b/packages/algoliasearch-helper/test/datasets/SearchParameters/search.dataset.js index 7ab07b44df..639de95f25 100644 --- a/packages/algoliasearch-helper/test/datasets/SearchParameters/search.dataset.js +++ b/packages/algoliasearch-helper/test/datasets/SearchParameters/search.dataset.js @@ -336,7 +336,7 @@ function getData() { index: 'test_hotels-node', hitsPerPage: 20, nbHits: 4, - persistHierarchicalRootCount: false, + persistHierarchicalRootCount: true, nbPages: 1, page: 0, params: diff --git a/packages/algoliasearch-helper/test/spec/algoliasearch.helper/searchOnce.js b/packages/algoliasearch-helper/test/spec/algoliasearch.helper/searchOnce.js index 0d9e5141ca..bad494c381 100644 --- a/packages/algoliasearch-helper/test/spec/algoliasearch.helper/searchOnce.js +++ b/packages/algoliasearch-helper/test/spec/algoliasearch.helper/searchOnce.js @@ -3,7 +3,7 @@ var algoliasearchHelper = require('../../../index'); var SearchParameters = require('../../../src/SearchParameters'); -test('searchOnce should call the algolia client according to the number of refinements and call callback with no error and with results when no error', function (done) { +test('searchOnce should call the algolia client according to the number of refinements and call callback with no error and with results when no error', async function () { var testData = require('../../datasets/SearchParameters/search.dataset')(); var client = { @@ -21,76 +21,72 @@ test('searchOnce should call the algolia client according to the number of refin .addDisjunctiveFacetRefinement('city', 'Paris') .addDisjunctiveFacetRefinement('city', 'New York'); - helper.searchOnce(parameters, function (err, data) { - expect(err).toBe(null); - - // shame deepclone, to remove any associated methods coming from the results - expect(JSON.parse(JSON.stringify(data))).toEqual( - JSON.parse(JSON.stringify(testData.responseHelper)) - ); - - var cityValues = data.getFacetValues('city'); - var expectedCityValues = [ - { name: 'Paris', escapedValue: 'Paris', count: 3, isRefined: true }, - { name: 'New York', escapedValue: 'New York', count: 1, isRefined: true }, - { - name: 'San Francisco', - escapedValue: 'San Francisco', - count: 1, - isRefined: false, - }, - ]; - - expect(cityValues).toEqual(expectedCityValues); - - var cityValuesCustom = data.getFacetValues('city', { - sortBy: ['count:asc', 'name:asc'], - }); - var expectedCityValuesCustom = [ - { name: 'New York', escapedValue: 'New York', count: 1, isRefined: true }, - { - name: 'San Francisco', - escapedValue: 'San Francisco', - count: 1, - isRefined: false, - }, - { name: 'Paris', escapedValue: 'Paris', count: 3, isRefined: true }, - ]; - - expect(cityValuesCustom).toEqual(expectedCityValuesCustom); - - var cityValuesFn = data.getFacetValues('city', { - sortBy: function (a, b) { - return a.count - b.count; - }, - }); - var expectedCityValuesFn = [ - { name: 'New York', escapedValue: 'New York', count: 1, isRefined: true }, - { - name: 'San Francisco', - escapedValue: 'San Francisco', - count: 1, - isRefined: false, - }, - { name: 'Paris', escapedValue: 'Paris', count: 3, isRefined: true }, - ]; - - expect(cityValuesFn).toEqual(expectedCityValuesFn); - - expect(client.search).toHaveBeenCalledTimes(1); - - var queries = client.search.mock.calls[0][0]; - for (var i = 0; i < queries.length; i++) { - var query = queries[i]; - expect(query.query).toBeUndefined(); - expect(query.params.query).toBeUndefined(); - } - - done(); + const { content } = await helper.searchOnce(parameters); + + // shame deepclone, to remove any associated methods coming from the results + expect(JSON.parse(JSON.stringify(content))).toEqual( + JSON.parse(JSON.stringify(testData.responseHelper)) + ); + + var cityValues = content.getFacetValues('city'); + var expectedCityValues = [ + { name: 'Paris', escapedValue: 'Paris', count: 3, isRefined: true }, + { name: 'New York', escapedValue: 'New York', count: 1, isRefined: true }, + { + name: 'San Francisco', + escapedValue: 'San Francisco', + count: 1, + isRefined: false, + }, + ]; + + expect(cityValues).toEqual(expectedCityValues); + + var cityValuesCustom = content.getFacetValues('city', { + sortBy: ['count:asc', 'name:asc'], }); + var expectedCityValuesCustom = [ + { name: 'New York', escapedValue: 'New York', count: 1, isRefined: true }, + { + name: 'San Francisco', + escapedValue: 'San Francisco', + count: 1, + isRefined: false, + }, + { name: 'Paris', escapedValue: 'Paris', count: 3, isRefined: true }, + ]; + + expect(cityValuesCustom).toEqual(expectedCityValuesCustom); + + var cityValuesFn = content.getFacetValues('city', { + sortBy: function (a, b) { + return a.count - b.count; + }, + }); + var expectedCityValuesFn = [ + { name: 'New York', escapedValue: 'New York', count: 1, isRefined: true }, + { + name: 'San Francisco', + escapedValue: 'San Francisco', + count: 1, + isRefined: false, + }, + { name: 'Paris', escapedValue: 'Paris', count: 3, isRefined: true }, + ]; + + expect(cityValuesFn).toEqual(expectedCityValuesFn); + + expect(client.search).toHaveBeenCalledTimes(1); + + var queries = client.search.mock.calls[0][0]; + for (var i = 0; i < queries.length; i++) { + var query = queries[i]; + expect(query.query).toBeUndefined(); + expect(query.params.query).toBeUndefined(); + } }); -test('searchOnce should call the algolia client according to the number of refinements and call callback with error and no results when error', function (done) { +test('searchOnce should call the algolia client according to the number of refinements and call callback with error and no results when error', async function () { var error = { message: 'error' }; var client = { search: jest.fn().mockImplementationOnce(function () { @@ -107,19 +103,14 @@ test('searchOnce should call the algolia client according to the number of refin .addDisjunctiveFacetRefinement('city', 'Paris') .addDisjunctiveFacetRefinement('city', 'New York'); - helper.searchOnce(parameters, function (err, data) { - expect(err).toBe(error); - expect(data).toBe(null); - - expect(client.search).toHaveBeenCalledTimes(1); + await expect(() => helper.searchOnce(parameters)).rejects.toEqual(error); - var queries = client.search.mock.calls[0][0]; - for (var i = 0; i < queries.length; i++) { - var query = queries[i]; - expect(query.query).toBeUndefined(); - expect(query.params.query).toBeUndefined(); - } + expect(client.search).toHaveBeenCalledTimes(1); - done(); - }); + var queries = client.search.mock.calls[0][0]; + for (var i = 0; i < queries.length; i++) { + var query = queries[i]; + expect(query.query).toBeUndefined(); + expect(query.params.query).toBeUndefined(); + } }); diff --git a/packages/algoliasearch-helper/test/spec/hierarchical-facets/simple-usage.js b/packages/algoliasearch-helper/test/spec/hierarchical-facets/simple-usage.js index 54230e4437..1011e8d675 100644 --- a/packages/algoliasearch-helper/test/spec/hierarchical-facets/simple-usage.js +++ b/packages/algoliasearch-helper/test/spec/hierarchical-facets/simple-usage.js @@ -87,19 +87,26 @@ describe('hierarchical facets: simple usage', function () { }); test('persistHierarchicalRootCount: false', function (done) { - var helper = algoliasearchHelper(client, indexName, { - hierarchicalFacets: [ - { - name: 'categories', - attributes: [ - 'categories.lvl0', - 'categories.lvl1', - 'categories.lvl2', - 'categories.lvl3', - ], - }, - ], - }); + var helper = algoliasearchHelper( + client, + indexName, + { + hierarchicalFacets: [ + { + name: 'categories', + attributes: [ + 'categories.lvl0', + 'categories.lvl1', + 'categories.lvl2', + 'categories.lvl3', + ], + }, + ], + }, + { + persistHierarchicalRootCount: false, + } + ); helper.toggleFacetRefinement('categories', 'beers > IPA > Flying dog'); diff --git a/packages/algoliasearch-helper/test/spec/hierarchical-facets/sort-by.js b/packages/algoliasearch-helper/test/spec/hierarchical-facets/sort-by.js index 079d149f4e..3f87b23bca 100644 --- a/packages/algoliasearch-helper/test/spec/hierarchical-facets/sort-by.js +++ b/packages/algoliasearch-helper/test/spec/hierarchical-facets/sort-by.js @@ -1,6 +1,6 @@ 'use strict'; -test('hierarchical facets: using sortBy', function (done) { +test('hierarchical facets: using sortBy', async function () { var algoliasearch = require('algoliasearch'); algoliasearch = algoliasearch.algoliasearch || algoliasearch; @@ -30,6 +30,7 @@ test('hierarchical facets: using sortBy', function (done) { var algoliaResponse = { results: [ + // for hits { query: 'a', index: indexName, @@ -45,6 +46,7 @@ test('hierarchical facets: using sortBy', function (done) { 'categories.lvl2': { 'beers > IPA > Flying dog': 1 }, }, }, + // deepest level { query: 'a', index: indexName, @@ -54,8 +56,8 @@ test('hierarchical facets: using sortBy', function (done) { nbPages: 1, hitsPerPage: 1, facets: { - 'categories.lvl0': { beers: 5 }, - 'categories.lvl1': { 'beers > IPA': 5 }, + 'categories.lvl0': { beers: 1 }, + 'categories.lvl1': { 'beers > IPA': 1 }, 'categories.lvl2': { 'beers > IPA > Flying dog': 1, 'beers > IPA > Anchor steam': 1, @@ -63,6 +65,7 @@ test('hierarchical facets: using sortBy', function (done) { }, }, }, + // root level { query: 'a', index: indexName, @@ -75,6 +78,19 @@ test('hierarchical facets: using sortBy', function (done) { 'categories.lvl0': { beers: 5 }, }, }, + // other levels + { + query: 'a', + index: indexName, + hits: [{ objectID: 'one' }], + nbHits: 1, + page: 0, + nbPages: 1, + hitsPerPage: 1, + facets: { + 'categories.lvl1': { 'beers > IPA': 5 }, + }, + }, ], }; @@ -143,8 +159,10 @@ test('hierarchical facets: using sortBy', function (done) { }); helper.setQuery('a').search(); - helper.once('result', function (event) { - expect(event.results.hierarchicalFacets).toEqual(expectedHelperResponse); - done(); + + const { results } = await new Promise(function (resolve) { + helper.once('result', resolve); }); + + expect(results.hierarchicalFacets).toEqual(expectedHelperResponse); }); diff --git a/packages/instantsearch-core/src/__tests__/instantsearch.test.tsx b/packages/instantsearch-core/src/__tests__/instantsearch.test.tsx index d2e2bbecff..0c42821409 100644 --- a/packages/instantsearch-core/src/__tests__/instantsearch.test.tsx +++ b/packages/instantsearch-core/src/__tests__/instantsearch.test.tsx @@ -865,7 +865,7 @@ describe('start', () => { searchClient, indexName, undefined, - { persistHierarchicalRootCount: false } + { persistHierarchicalRootCount: true } ); }); @@ -887,7 +887,7 @@ describe('start', () => { searchClient, indexName, undefined, - future + { persistHierarchicalRootCount: true } ); }); diff --git a/packages/instantsearch-core/src/instantsearch.ts b/packages/instantsearch-core/src/instantsearch.ts index bf08fdc793..a48e8e0a0c 100644 --- a/packages/instantsearch-core/src/instantsearch.ts +++ b/packages/instantsearch-core/src/instantsearch.ts @@ -52,7 +52,7 @@ export const INSTANTSEARCH_FUTURE_DEFAULTS: Required< InstantSearchOptions['future'] > = { preserveSharedStateOnUnmount: false, - persistHierarchicalRootCount: false, + persistHierarchicalRootCount: true, }; /** diff --git a/packages/instantsearch-core/src/types/instantsearch.ts b/packages/instantsearch-core/src/types/instantsearch.ts index bbca3bfbbe..c858654f6b 100644 --- a/packages/instantsearch-core/src/types/instantsearch.ts +++ b/packages/instantsearch-core/src/types/instantsearch.ts @@ -108,9 +108,9 @@ export type InstantSearchOptions< * * If `true`, the count of the root level stays the same as the count of all children levels. * - * @default false + * @default true */ - persistHierarchicalRootCount?: boolean; // @MAJOR change the default to true + persistHierarchicalRootCount?: boolean; // @MAJOR remove the option }; }; diff --git a/packages/instantsearch-core/src/widgets/__tests__/index-widget.test.ts b/packages/instantsearch-core/src/widgets/__tests__/index-widget.test.ts index 48ea187006..7b01396d80 100644 --- a/packages/instantsearch-core/src/widgets/__tests__/index-widget.test.ts +++ b/packages/instantsearch-core/src/widgets/__tests__/index-widget.test.ts @@ -3346,7 +3346,7 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/index-widge nbPages: 1, page: 0, params: '', - persistHierarchicalRootCount: false, + persistHierarchicalRootCount: true, processingTimeMS: 0, query: 'iphone', };