Skip to content
This repository has been archived by the owner on Dec 30, 2022. It is now read-only.

Commit

Permalink
feat(voice): add additionalQueryParameters (#2366)
Browse files Browse the repository at this point in the history
* feat(voice): add additionalQueryParameters

Two new props:
- `additionalQueryParameters: () => Partial<SearchParameters>` (only applied when voice search is mounted)
- `language: string` (iso 639-1), the parameter sent to Algolia will be always the short version

known limitation: additional query parameters will stay applied as long as the Voice Search widget is mounted, meaning they can cause stale values if you switch input method without unmounting (limitation of the architecture of React InstantSearch)

This does not have additional tests yet.

The connector is written in JS instead of TS, because it's mostly copy-pasted from searchBox, and that would be needless extra work otherwise #hackathon

Co-Authored-By: Haroenv <haroen@algolia.com>

* chore(size): update bundle size (this change is +270b)

* feat(voice): handle language and additionalQueryParameters separately

* feat(voice): add tests

* feat(voice): add tests for multi index

* feat(voice): add test for additionalVoiceParameters

* chore: remove unused argument
  • Loading branch information
marieglr authored and Haroenv committed Nov 20, 2019
1 parent e3531a1 commit 3a45b2c
Show file tree
Hide file tree
Showing 8 changed files with 554 additions and 5 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@
},
{
"path": "packages/react-instantsearch-dom/dist/umd/ReactInstantSearchDOM.min.js",
"maxSize": "35.50 kB"
"maxSize": "35.75 kB"
},
{
"path": "packages/react-instantsearch-dom-maps/dist/umd/ReactInstantSearchDOMMaps.min.js",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,349 @@
import connect from '../connectVoiceSearch';
import { SearchParameters } from 'algoliasearch-helper';

jest.mock('../../core/createConnector', () => x => x);

describe('connectVoiceSearch', () => {
describe('single index', () => {
const contextValue = { mainTargetedIndex: 'index' };

describe('getProvidedProps', () => {
it('provides the correct props to the component', () => {
expect(connect.getProvidedProps({ contextValue }, {}, {})).toEqual({
currentRefinement: '',
});

expect(
connect.getProvidedProps({ contextValue }, { query: 'abc' }, {})
).toEqual({
currentRefinement: 'abc',
});
});
});

describe('refine', () => {
it('calls refine and updates the state correctly', () => {
expect(connect.refine({ contextValue }, {}, 'abc')).toEqual({
page: 1,
query: 'abc',
additionalVoiceParameters: {},
});
});

it('refines and get additionalVoiceParameters', () => {
const { additionalVoiceParameters } = connect.refine(
{ contextValue },
{},
'abc'
);
expect(additionalVoiceParameters).toEqual(expect.objectContaining({}));
});

it('refines with additionalQueryParameters', () => {
const props = {
contextValue,
additionalQueryParameters: () => ({ additional: 'param' }),
};
expect(connect.refine(props, {}, 'abc')).toEqual({
page: 1,
query: 'abc',
additionalVoiceParameters: {
additional: 'param',
ignorePlurals: true,
optionalWords: 'abc',
queryLanguages: undefined,
removeStopWords: true,
},
});
});

it('refines with language', () => {
const props = { contextValue, language: 'en-US' };
expect(connect.refine(props, {}, 'abc')).toEqual({
page: 1,
query: 'abc',
additionalVoiceParameters: {
queryLanguages: ['en'],
},
});
});

it('refines with language (2)', () => {
const props = {
contextValue,
language: 'en-US',
additionalQueryParameters: () => ({}),
};
expect(connect.refine(props, {}, 'abc')).toEqual({
page: 1,
query: 'abc',
additionalVoiceParameters: {
ignorePlurals: true,
optionalWords: 'abc',
queryLanguages: ['en'],
removeStopWords: true,
},
});
});

it('overrides with additionalQueryParameters', () => {
const props = {
contextValue,
additionalQueryParameters: () => ({
ignorePlurals: false,
optionalWords: 'something else',
removeStopWords: false,
}),
};
expect(connect.refine(props, {}, 'abc')).toEqual({
page: 1,
query: 'abc',
additionalVoiceParameters: {
ignorePlurals: false,
optionalWords: 'something else',
removeStopWords: false,
},
});
});
});

describe('cleanUp', () => {
it('should return the right searchState when clean up', () => {
expect(
connect.cleanUp(
{
contextValue,
},
{
query: 'abc',
additionalVoiceParameters: {
ignorePlurals: true,
optionalWords: 'abc',
queryLanguages: ['en'],
removeStopWords: true,
},
}
)
).toEqual({});
});
});

describe('getSearchParameters', () => {
it('returns searchParameters with query', () => {
expect(
connect.getSearchParameters(
new SearchParameters(),
{
contextValue,
},
{ query: 'foo' }
)
).toEqual(expect.objectContaining({ query: 'foo' }));
});

it('returns searchParameters with additional params', () => {
expect(
connect.getSearchParameters(
new SearchParameters(),
{
contextValue,
},
{
query: 'abc',
additionalVoiceParameters: {
ignorePlurals: true,
optionalWords: 'abc',
queryLanguages: ['en'],
removeStopWords: true,
},
}
)
).toEqual(
expect.objectContaining({
ignorePlurals: true,
optionalWords: 'abc',
queryLanguages: ['en'],
removeStopWords: true,
query: 'abc',
})
);
});
});

describe('getMetadata', () => {
it('returns correct metadata', () => {
expect(
connect.getMetadata(
{
contextValue,
},
{
ignorePlurals: true,
optionalWords: 'abc',
queryLanguages: ['en'],
removeStopWords: true,
query: 'abc',
}
)
).toEqual({
id: 'query',
index: 'index',
items: [
{
label: 'query: abc',
value: expect.any(Function),
currentRefinement: 'abc',
},
],
});
});
});
});

describe('multi index', () => {
const contextValue = { mainTargetedIndex: 'first' };
const indexContextValue = { targetedIndex: 'second' };

describe('getProvidedProps', () => {
it('provides the correct props to the component', () => {
expect(
connect.getProvidedProps({ contextValue, indexContextValue }, {}, {})
).toEqual({
currentRefinement: '',
});

expect(
connect.getProvidedProps(
{ contextValue, indexContextValue },
{ indices: { second: { query: 'yep' } } },
{}
)
).toEqual({
currentRefinement: 'yep',
});
});
});

describe('refine', () => {
it('refines with additionalQueryParameters', () => {
const props = {
contextValue,
indexContextValue,
additionalQueryParameters: () => ({ additional: 'param' }),
};
expect(connect.refine(props, {}, 'abc')).toEqual({
indices: {
second: {
page: 1,
query: 'abc',
additionalVoiceParameters: {
additional: 'param',
ignorePlurals: true,
optionalWords: 'abc',
queryLanguages: undefined,
removeStopWords: true,
},
},
},
});
});

it('refines with language', () => {
const props = { contextValue, indexContextValue, language: 'en-US' };
expect(connect.refine(props, {}, 'abc')).toEqual({
indices: {
second: {
page: 1,
query: 'abc',
additionalVoiceParameters: {
queryLanguages: ['en'],
},
},
},
});
});
});

describe('getSearchParameters', () => {
it('returns searchParameters with query', () => {
expect(
connect.getSearchParameters(
new SearchParameters(),
{
contextValue,
indexContextValue,
},
{ indices: { second: { query: 'foo' } } }
)
).toEqual(expect.objectContaining({ query: 'foo' }));
});

it('returns searchParameters with additional params', () => {
expect(
connect.getSearchParameters(
new SearchParameters(),
{
contextValue,
indexContextValue,
},
{
indices: {
second: {
query: 'abc',
additionalVoiceParameters: {
ignorePlurals: true,
optionalWords: 'abc',
queryLanguages: ['en'],
removeStopWords: true,
},
},
},
}
)
).toEqual(
expect.objectContaining({
ignorePlurals: true,
optionalWords: 'abc',
queryLanguages: ['en'],
removeStopWords: true,
query: 'abc',
})
);
});
});

describe('getMetadata', () => {
it('returns correct metadata', () => {
expect(
connect.getMetadata(
{
contextValue,
indexContextValue,
},
{
indices: {
second: {
ignorePlurals: true,
optionalWords: 'abc',
queryLanguages: ['en'],
removeStopWords: true,
query: 'abc',
},
},
}
)
).toEqual({
id: 'query',
index: 'second',
items: [
{
label: 'query: abc',
value: expect.any(Function),
currentRefinement: 'abc',
},
],
});
});
});
});
});
Loading

0 comments on commit 3a45b2c

Please sign in to comment.