Skip to content

Commit

Permalink
feat(stats): apply nbSortedHits (#4649)
Browse files Browse the repository at this point in the history
* fix(stats): apply nbSortedHits

* update default template for singular/plurial expressions

* move the logic calculating isSmartSorted to the connector

* clean up the condition for isSmartSorted

* Revert "clean up the condition for isSmartSorted"

This reverts commit a3b6761.

* remove test code

* rename isSmartSort to areHitsSorted and add more condition to it to compare nbHits !== nbSortedHits
  • Loading branch information
Eunjae Lee authored Feb 22, 2021
1 parent 89c6e86 commit 34478c1
Show file tree
Hide file tree
Showing 9 changed files with 286 additions and 26 deletions.
9 changes: 9 additions & 0 deletions src/components/Stats/Stats.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import Template from '../Template/Template';

const Stats = ({
nbHits,
nbSortedHits,
areHitsSorted,
hitsPerPage,
nbPages,
page,
Expand All @@ -21,11 +23,16 @@ const Stats = ({
rootTagName="span"
rootProps={{ className: cssClasses.text }}
data={{
hasManySortedResults: nbSortedHits > 1,
hasNoSortedResults: nbSortedHits === 0,
hasOneSortedResults: nbSortedHits === 1,
hasManyResults: nbHits > 1,
hasNoResults: nbHits === 0,
hasOneResult: nbHits === 1,
areHitsSorted,
hitsPerPage,
nbHits,
nbSortedHits,
nbPages,
page,
processingTimeMS,
Expand All @@ -43,6 +50,8 @@ Stats.propTypes = {
}).isRequired,
hitsPerPage: PropTypes.number,
nbHits: PropTypes.number,
nbSortedHits: PropTypes.number,
areHitsSorted: PropTypes.bool,
nbPages: PropTypes.number,
page: PropTypes.number,
processingTimeMS: PropTypes.number,
Expand Down
73 changes: 73 additions & 0 deletions src/components/Stats/__tests__/Stats-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { h } from 'preact';
import { mount } from 'enzyme';
import Stats from '../Stats';
import defaultTemplates from '../../../widgets/stats/defaultTemplates';
import createHelpers from '../../../lib/createHelpers';

describe('Stats', () => {
const cssClasses = {
Expand Down Expand Up @@ -41,6 +42,78 @@ describe('Stats', () => {
expect(wrapper).toMatchSnapshot();
});

it('should render sorted hits', () => {
const wrapper = mount(
<Stats
{...getProps({ nbSortedHits: 150, areHitsSorted: true })}
templateProps={{
templates: defaultTemplates,
templatesConfig: {
helpers: createHelpers({}),
},
}}
/>
);
expect(wrapper.find('.text')).toMatchInlineSnapshot(`
<span
className="text"
dangerouslySetInnerHTML={
Object {
"__html": "150 relevant results sorted out of 1,234 found in 42ms",
}
}
/>
`);
});

it('should render 1 sorted hit', () => {
const wrapper = mount(
<Stats
{...getProps({ nbSortedHits: 1, areHitsSorted: true })}
templateProps={{
templates: defaultTemplates,
templatesConfig: {
helpers: createHelpers({}),
},
}}
/>
);
expect(wrapper.find('.text')).toMatchInlineSnapshot(`
<span
className="text"
dangerouslySetInnerHTML={
Object {
"__html": "1 relevant result sorted out of 1,234 found in 42ms",
}
}
/>
`);
});

it('should render 0 sorted hit', () => {
const wrapper = mount(
<Stats
{...getProps({ nbSortedHits: 0, areHitsSorted: true })}
templateProps={{
templates: defaultTemplates,
templatesConfig: {
helpers: createHelpers({}),
},
}}
/>
);
expect(wrapper.find('.text')).toMatchInlineSnapshot(`
<span
className="text"
dangerouslySetInnerHTML={
Object {
"__html": "No relevant results sorted out of 1,234 found in 42ms",
}
}
/>
`);
});

function getProps(extraProps = {}) {
return {
cssClasses,
Expand Down
91 changes: 91 additions & 0 deletions src/connectors/stats/__tests__/connectStats-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,10 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/stats/js/#c

expect(renderState.stats).toEqual({
hitsPerPage: undefined,
areHitsSorted: false,
nbHits: 0,
nbPages: 0,
nbSortedHits: undefined,
page: 0,
processingTimeMS: -1,
query: '',
Expand All @@ -102,8 +104,10 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/stats/js/#c

expect(renderState.stats).toEqual({
hitsPerPage: 20,
areHitsSorted: false,
nbHits: 0,
nbPages: 0,
nbSortedHits: undefined,
page: 0,
processingTimeMS: 0,
query: '',
Expand Down Expand Up @@ -137,8 +141,10 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/stats/js/#c

expect(renderState.stats).toEqual({
hitsPerPage: 3,
areHitsSorted: false,
nbHits: 5,
nbPages: 2,
nbSortedHits: undefined,
page: 0,
processingTimeMS: 0,
query: 'apple',
Expand All @@ -163,8 +169,10 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/stats/js/#c

expect(renderState).toEqual({
hitsPerPage: undefined,
areHitsSorted: false,
nbHits: 0,
nbPages: 0,
nbSortedHits: undefined,
page: 0,
processingTimeMS: -1,
query: '',
Expand All @@ -187,8 +195,10 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/stats/js/#c

expect(renderState).toEqual({
hitsPerPage: 20,
areHitsSorted: false,
nbHits: 0,
nbPages: 0,
nbSortedHits: undefined,
page: 0,
processingTimeMS: 0,
query: '',
Expand Down Expand Up @@ -221,8 +231,89 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/stats/js/#c

expect(renderState).toEqual({
hitsPerPage: 3,
areHitsSorted: false,
nbHits: 5,
nbPages: 2,
nbSortedHits: undefined,
page: 0,
processingTimeMS: 0,
query: 'apple',
widgetParams: {},
});
});

test('returns areHitsSorted as true', () => {
const [stats, helper] = getInitializedWidget();

const renderState = stats.getWidgetRenderState(
createRenderOptions({
helper,
state: helper.state,
results: new SearchResults(helper.state, [
createSingleSearchResponse({
hits: [
{ brand: 'samsung', objectID: '1' },
{ brand: 'apple', objectID: '2' },
{ brand: 'sony', objectID: '3' },
{ brand: 'benq', objectID: '4' },
{ brand: 'dyson', objectID: '5' },
],
hitsPerPage: 3,
query: 'apple',
appliedRelevancyStrictness: 20,
nbHits: 20,
nbPages: 2,
nbSortedHits: 5,
}),
]),
})
);

expect(renderState).toEqual({
hitsPerPage: 3,
areHitsSorted: true,
nbHits: 20,
nbPages: 2,
nbSortedHits: 5,
page: 0,
processingTimeMS: 0,
query: 'apple',
widgetParams: {},
});
});

test('returns areHitsSorted as false when nbSortedHits === nbHits', () => {
const [stats, helper] = getInitializedWidget();

const renderState = stats.getWidgetRenderState(
createRenderOptions({
helper,
state: helper.state,
results: new SearchResults(helper.state, [
createSingleSearchResponse({
hits: [
{ brand: 'samsung', objectID: '1' },
{ brand: 'apple', objectID: '2' },
{ brand: 'sony', objectID: '3' },
{ brand: 'benq', objectID: '4' },
{ brand: 'dyson', objectID: '5' },
],
hitsPerPage: 3,
query: 'apple',
appliedRelevancyStrictness: 20,
nbHits: 5,
nbSortedHits: 5,
}),
]),
})
);

expect(renderState).toEqual({
hitsPerPage: 3,
areHitsSorted: false,
nbHits: 5,
nbPages: 2,
nbSortedHits: 5,
page: 0,
processingTimeMS: 0,
query: 'apple',
Expand Down
7 changes: 7 additions & 0 deletions src/connectors/stats/connectStats.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ export default function connectStats(renderFn, unmountFn = noop) {
return {
hitsPerPage: helper.state.hitsPerPage,
nbHits: 0,
nbSortedHits: undefined,
areHitsSorted: false,
nbPages: 0,
page: helper.state.page || 0,
processingTimeMS: -1,
Expand All @@ -108,6 +110,11 @@ export default function connectStats(renderFn, unmountFn = noop) {
return {
hitsPerPage: results.hitsPerPage,
nbHits: results.nbHits,
nbSortedHits: results.nbSortedHits,
areHitsSorted:
typeof results.appliedRelevancyStrictness !== 'undefined' &&
results.appliedRelevancyStrictness > 0 &&
results.nbSortedHits !== results.nbHits,
nbPages: results.nbPages,
page: results.page,
processingTimeMS: results.processingTimeMS,
Expand Down
36 changes: 30 additions & 6 deletions src/widgets/stats/__tests__/__snapshots__/stats-test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,33 @@

exports[`stats() calls twice render(<Stats props />, container) 1`] = `
Object {
"areHitsSorted": false,
"cssClasses": Object {
"root": "ais-Stats",
"text": "ais-Stats-text text cx",
},
"hitsPerPage": 2,
"nbHits": 20,
"nbPages": 10,
"nbSortedHits": undefined,
"page": 0,
"processingTimeMS": 42,
"query": "a query",
"templateProps": Object {
"templates": Object {
"text": "{{#hasNoResults}}No results{{/hasNoResults}}
{{#hasOneResult}}1 result{{/hasOneResult}}
{{#hasManyResults}}{{#helpers.formatNumber}}{{nbHits}}{{/helpers.formatNumber}} results{{/hasManyResults}} found in {{processingTimeMS}}ms",
"text": "
{{#areHitsSorted}}
{{#hasNoSortedResults}}No relevant results{{/hasNoSortedResults}}
{{#hasOneSortedResults}}1 relevant result{{/hasOneSortedResults}}
{{#hasManySortedResults}}{{#helpers.formatNumber}}{{nbSortedHits}}{{/helpers.formatNumber}} relevant results{{/hasManySortedResults}}
sorted out of {{#helpers.formatNumber}}{{nbHits}}{{/helpers.formatNumber}}
{{/areHitsSorted}}
{{^areHitsSorted}}
{{#hasNoResults}}No results{{/hasNoResults}}
{{#hasOneResult}}1 result{{/hasOneResult}}
{{#hasManyResults}}{{#helpers.formatNumber}}{{nbHits}}{{/helpers.formatNumber}} results{{/hasManyResults}}
{{/areHitsSorted}}
found in {{processingTimeMS}}ms",
},
"templatesConfig": undefined,
"useCustomCompileOptions": Object {
Expand All @@ -28,21 +40,33 @@ Object {

exports[`stats() calls twice render(<Stats props />, container) 2`] = `
Object {
"areHitsSorted": false,
"cssClasses": Object {
"root": "ais-Stats",
"text": "ais-Stats-text text cx",
},
"hitsPerPage": 2,
"nbHits": 20,
"nbPages": 10,
"nbSortedHits": undefined,
"page": 0,
"processingTimeMS": 42,
"query": "a query",
"templateProps": Object {
"templates": Object {
"text": "{{#hasNoResults}}No results{{/hasNoResults}}
{{#hasOneResult}}1 result{{/hasOneResult}}
{{#hasManyResults}}{{#helpers.formatNumber}}{{nbHits}}{{/helpers.formatNumber}} results{{/hasManyResults}} found in {{processingTimeMS}}ms",
"text": "
{{#areHitsSorted}}
{{#hasNoSortedResults}}No relevant results{{/hasNoSortedResults}}
{{#hasOneSortedResults}}1 relevant result{{/hasOneSortedResults}}
{{#hasManySortedResults}}{{#helpers.formatNumber}}{{nbSortedHits}}{{/helpers.formatNumber}} relevant results{{/hasManySortedResults}}
sorted out of {{#helpers.formatNumber}}{{nbHits}}{{/helpers.formatNumber}}
{{/areHitsSorted}}
{{^areHitsSorted}}
{{#hasNoResults}}No results{{/hasNoResults}}
{{#hasOneResult}}1 result{{/hasOneResult}}
{{#hasManyResults}}{{#helpers.formatNumber}}{{nbHits}}{{/helpers.formatNumber}} results{{/hasManyResults}}
{{/areHitsSorted}}
found in {{processingTimeMS}}ms",
},
"templatesConfig": undefined,
"useCustomCompileOptions": Object {
Expand Down
Loading

0 comments on commit 34478c1

Please sign in to comment.