diff --git a/src/connectors/sort-by/__tests__/connectSortBy-test.js b/src/connectors/sort-by/__tests__/connectSortBy-test.js index 5348e6ca06..20c956febf 100644 --- a/src/connectors/sort-by/__tests__/connectSortBy-test.js +++ b/src/connectors/sort-by/__tests__/connectSortBy-test.js @@ -11,6 +11,7 @@ import { createInitOptions, createRenderOptions, } from '../../../../test/mock/createWidget'; +import { createSingleSearchResponse } from '../../../../test/mock/createAPIResponse'; describe('connectSortBy', () => { describe('Usage', () => { @@ -257,6 +258,169 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/sort-by/js/ } }); + describe('getRenderState', () => { + test('returns the render state', () => { + const renderFn = jest.fn(); + const unmountFn = jest.fn(); + const createSortBy = connectSortBy(renderFn, unmountFn); + const sortBy = createSortBy({ + items: [ + { label: 'default', value: 'index_default' }, + { label: 'asc', value: 'index_asc' }, + { label: 'desc', value: 'index_desc' }, + ], + }); + const helper = algoliasearchHelper( + createSearchClient(), + 'index_default', + { + index: 'index_default', + } + ); + + const renderState1 = sortBy.getRenderState( + { + sortBy: {}, + }, + createInitOptions({ helper }) + ); + + expect(renderState1.sortBy).toEqual({ + currentRefinement: 'index_default', + refine: undefined, + hasNoResults: true, + options: [ + { label: 'default', value: 'index_default' }, + { label: 'asc', value: 'index_asc' }, + { label: 'desc', value: 'index_desc' }, + ], + widgetParams: { + items: [ + { label: 'default', value: 'index_default' }, + { label: 'asc', value: 'index_asc' }, + { label: 'desc', value: 'index_desc' }, + ], + }, + }); + + sortBy.init(createInitOptions({ helper })); + sortBy.getWidgetRenderState({ helper }).refine('index_desc'); + + const renderState2 = sortBy.getRenderState( + { sortBy: {} }, + createRenderOptions({ + helper, + state: helper.state, + results: new SearchResults(helper.state, [ + createSingleSearchResponse({ + hits: [ + { brand: 'samsung', objectID: '1' }, + { brand: 'apple', objectID: '2' }, + { brand: 'sony', objectID: '3' }, + ], + hitsPerPage: 1, + }), + ]), + }) + ); + + expect(renderState2.sortBy).toEqual({ + currentRefinement: 'index_desc', + refine: expect.any(Function), + hasNoResults: false, + options: [ + { label: 'default', value: 'index_default' }, + { label: 'asc', value: 'index_asc' }, + { label: 'desc', value: 'index_desc' }, + ], + widgetParams: { + items: [ + { label: 'default', value: 'index_default' }, + { label: 'asc', value: 'index_asc' }, + { label: 'desc', value: 'index_desc' }, + ], + }, + }); + }); + }); + + describe('getWidgetRenderState', () => { + test('returns the widget render state', () => { + const renderFn = jest.fn(); + const unmountFn = jest.fn(); + const createSortBy = connectSortBy(renderFn, unmountFn); + const sortBy = createSortBy({ + items: [ + { label: 'default', value: 'index_default' }, + { label: 'asc', value: 'index_asc' }, + { label: 'desc', value: 'index_desc' }, + ], + }); + const helper = algoliasearchHelper(createSearchClient(), 'index_desc', { + index: 'index_desc', + }); + + const renderState1 = sortBy.getWidgetRenderState( + createInitOptions({ helper }) + ); + + expect(renderState1).toEqual({ + currentRefinement: 'index_desc', + refine: undefined, + hasNoResults: true, + options: [ + { label: 'default', value: 'index_default' }, + { label: 'asc', value: 'index_asc' }, + { label: 'desc', value: 'index_desc' }, + ], + widgetParams: { + items: [ + { label: 'default', value: 'index_default' }, + { label: 'asc', value: 'index_asc' }, + { label: 'desc', value: 'index_desc' }, + ], + }, + }); + + sortBy.init(createInitOptions({ helper })); + sortBy.getWidgetRenderState({ helper }).refine('index_default'); + + const renderState2 = sortBy.getWidgetRenderState( + createRenderOptions({ + helper, + state: helper.state, + results: new SearchResults(helper.state, [ + createSingleSearchResponse({ + hits: [ + { brand: 'samsung', objectID: '1' }, + { brand: 'apple', objectID: '2' }, + ], + hitsPerPage: 20, + }), + ]), + }) + ); + + expect(renderState2).toEqual({ + currentRefinement: 'index_default', + refine: expect.any(Function), + hasNoResults: false, + options: [ + { label: 'default', value: 'index_default' }, + { label: 'asc', value: 'index_asc' }, + { label: 'desc', value: 'index_desc' }, + ], + widgetParams: { + items: [ + { label: 'default', value: 'index_default' }, + { label: 'asc', value: 'index_asc' }, + { label: 'desc', value: 'index_desc' }, + ], + }, + }); + }); + }); + describe('options', () => { describe('items', () => { test('uses the helper index by default', () => { diff --git a/src/connectors/sort-by/connectSortBy.js b/src/connectors/sort-by/connectSortBy.js index 165584a2db..1789d0fa25 100644 --- a/src/connectors/sort-by/connectSortBy.js +++ b/src/connectors/sort-by/connectSortBy.js @@ -103,7 +103,8 @@ export default function connectSortBy(renderFn, unmountFn = noop) { return { $$type: 'ais.sortBy', - init({ helper, instantSearchInstance, parent }) { + init(initOptions) { + const { helper, instantSearchInstance, parent } = initOptions; const currentIndex = helper.state.index; const isCurrentIndexInItems = find( items, @@ -122,25 +123,18 @@ export default function connectSortBy(renderFn, unmountFn = noop) { renderFn( { - currentRefinement: currentIndex, - options: transformItems(items), - refine: this.setIndex, - hasNoResults: true, - widgetParams, + ...this.getWidgetRenderState(initOptions), instantSearchInstance, }, true ); }, - render({ helper, results, instantSearchInstance }) { + render(renderOptions) { + const { instantSearchInstance } = renderOptions; renderFn( { - currentRefinement: helper.state.index, - options: transformItems(items), - refine: this.setIndex, - hasNoResults: results.nbHits === 0, - widgetParams, + ...this.getWidgetRenderState(renderOptions), instantSearchInstance, }, false @@ -153,6 +147,23 @@ export default function connectSortBy(renderFn, unmountFn = noop) { return state.setIndex(this.initialIndex); }, + getRenderState(renderState, renderOptions) { + return { + ...renderState, + sortBy: this.getWidgetRenderState(renderOptions), + }; + }, + + getWidgetRenderState({ results, helper }) { + return { + currentRefinement: helper.state.index, + options: transformItems(items), + refine: this.setIndex, + hasNoResults: results ? results.nbHits === 0 : true, + widgetParams, + }; + }, + getWidgetUiState(uiState, { searchParameters }) { const currentIndex = searchParameters.index; const isInitialIndex = currentIndex === this.initialIndex;