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

Commit

Permalink
feat(indexId): avoid to rely on the results.index [PART-1] (#1833)
Browse files Browse the repository at this point in the history
* feat(indexId): rely on indexId rather than indexName [PART-2] (#1835)

* feat(indexId): refactor createInstantSearchManager [PART-3] (#1840)

* feat(indexId): rely on indexId rather than indexName in SSR [PART-4] (#1842)

* feat(indexId): refactor createInstantSearchServer [PART-5] (#1843)

* feat(indexId): rename getIndex -> getIndexId [PART-6] (#1851)
  • Loading branch information
samouss authored Jan 4, 2019
1 parent 79ff7ba commit ec9e0fb
Show file tree
Hide file tree
Showing 25 changed files with 1,285 additions and 461 deletions.
2 changes: 2 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ module.exports = {
extends: ['algolia/react', 'algolia/jest'],
rules: {
'no-param-reassign': 'off',
// @TODO: to remove once `eslint-config-algolia` ships the change
'valid-jsdoc': 'off',
},
settings: {
react: {
Expand Down
15 changes: 7 additions & 8 deletions packages/react-instantsearch-core/src/components/Index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React, { Component, Children } from 'react';
import PropTypes from 'prop-types';

/* eslint valid-jsdoc: 0 */
/**
* @description
* `<Index>` is the component that allows you to apply widgets to a dedicated index. It's
Expand Down Expand Up @@ -32,18 +31,17 @@ import PropTypes from 'prop-types';
* );
*/
class Index extends Component {
constructor(props, context) {
super(props);
const {
ais: { widgetsManager },
} = context;
constructor(...args) {
super(...args);

/*
we want <Index> to be seen as a regular widget.
It means that with only <Index> present a new query will be sent to Algolia.
That way you don't need a virtual hits widget to use the connectAutoComplete.
*/
this.unregisterWidget = widgetsManager.registerWidget(this);
this.unregisterWidget = this.context.ais.widgetsManager.registerWidget(
this
);
}

componentWillMount() {
Expand All @@ -67,7 +65,7 @@ class Index extends Component {
getChildContext() {
return {
multiIndexContext: {
targetedIndex: this.props.indexName,
targetedIndex: this.props.indexId,
},
};
}
Expand All @@ -89,6 +87,7 @@ class Index extends Component {
Index.propTypes = {
// @TODO: These props are currently constant.
indexName: PropTypes.string.isRequired,
indexId: PropTypes.string.isRequired,
children: PropTypes.node,
root: PropTypes.shape({
Root: PropTypes.oneOfType([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ function validateNextProps(props, nextProps) {
}
}

/* eslint valid-jsdoc: 0 */
/**
* @description
* `<InstantSearch>` is the root component of all React InstantSearch implementations.
Expand Down
184 changes: 122 additions & 62 deletions packages/react-instantsearch-core/src/components/__tests__/Index.js
Original file line number Diff line number Diff line change
@@ -1,100 +1,160 @@
import React from 'react';
import Enzyme, { mount } from 'enzyme';
import Enzyme, { shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import { SearchParameters } from 'algoliasearch-helper';
import Index from '../Index';

Enzyme.configure({ adapter: new Adapter() });

describe('Index', () => {
const DEFAULT_PROPS = {
indexName: 'foobar',
const createContext = () => ({
ais: {
onSearchParameters: jest.fn(),
widgetsManager: {
registerWidget: jest.fn(),
update: jest.fn(),
},
},
});

const requiredProps = {
indexName: 'indexName',
indexId: 'indexId',
root: {
Root: 'div',
},
};

const registerWidget = jest.fn();
const update = jest.fn();
const widgetsManager = { registerWidget, update };
it('registers itself on mount', () => {
const context = createContext();

let context = {
ais: {
widgetsManager,
onSearchParameters: () => {},
update,
},
};
const wrapper = shallow(
<Index {...requiredProps}>
<div />
</Index>,
{
context,
}
);

expect(context.ais.widgetsManager.registerWidget).toHaveBeenCalledTimes(1);
expect(context.ais.widgetsManager.registerWidget).toHaveBeenCalledWith(
wrapper.instance()
);
});

it('calls onSearchParameters on mount', () => {
const context = createContext();

shallow(
<Index {...requiredProps}>
<div />
</Index>,
{
context,
}
);

it('validates its props', () => {
expect(() => {
mount(
<Index {...DEFAULT_PROPS}>
<div />
</Index>,
{ context }
);
}).not.toThrow();

expect(() => {
mount(<Index {...DEFAULT_PROPS} />, { context });
}).not.toThrow();

expect(() => {
mount(
<Index {...DEFAULT_PROPS}>
<div />
<div />
</Index>,
{ context }
);
}).not.toThrow();

expect(registerWidget.mock.calls).toHaveLength(3);
expect(context.ais.onSearchParameters).toHaveBeenCalledTimes(1);
});

it('calls update if indexName prop changes', () => {
const context = createContext();

const wrapper = shallow(
<Index {...requiredProps}>
<div />
</Index>,
{
context,
}
);

expect(context.ais.widgetsManager.update).toHaveBeenCalledTimes(0);

wrapper.setProps({ indexName: 'newIndexName' });

expect(context.ais.widgetsManager.update).toHaveBeenCalledTimes(1);
});

it('unregisters itself on unmount', () => {
const unregister = jest.fn();
const context = createContext();

context.ais.widgetsManager.registerWidget.mockImplementation(
() => unregister
);

const wrapper = shallow(
<Index {...requiredProps}>
<div />
</Index>,
{
context,
}
);

expect(unregister).toHaveBeenCalledTimes(0);

wrapper.unmount();

expect(unregister).toHaveBeenCalledTimes(1);
});

it('exposes multi index context', () => {
const wrapper = mount(
<Index {...DEFAULT_PROPS}>
const context = createContext();

const wrapper = shallow(
<Index {...requiredProps}>
<div />
</Index>,
{ context }
{
context,
}
);

const childContext = wrapper.instance().getChildContext();
expect(childContext.multiIndexContext.targetedIndex).toBe(
DEFAULT_PROPS.indexName
);

expect(childContext.multiIndexContext.targetedIndex).toBe('indexId');
});

it('update search if indexName prop change', () => {
const wrapper = mount(
<Index {...DEFAULT_PROPS}>
it('provides search parameters from instance props', () => {
const context = createContext();

const wrapper = shallow(
<Index {...requiredProps}>
<div />
</Index>,
{ context }
{
context,
}
);

wrapper.setProps({ indexName: 'newIndexName' });
const parameters = wrapper
.instance()
.getSearchParameters(new SearchParameters());

expect(update.mock.calls).toHaveLength(1);
expect(parameters.index).toBe('indexName');
});

it('calls onSearchParameters when mounted', () => {
const onSearchParameters = jest.fn();
context = {
ais: {
widgetsManager,
onSearchParameters,
},
};
it('provides search parameters from argument props when instance props are not available', () => {
const context = createContext();

mount(
<Index {...DEFAULT_PROPS}>
const wrapper = shallow(
<Index {...requiredProps}>
<div />
</Index>,
{ context }
{
context,
}
);

expect(onSearchParameters.mock.calls).toHaveLength(1);
const parameters = wrapper
.instance()
.getSearchParameters.call({}, new SearchParameters(), {
indexName: 'otherIndexName',
});

expect(parameters.index).toBe('otherIndexName');
});
});
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { omit, difference, keys } from 'lodash';
import createConnector from '../core/createConnector';
import { hasMultipleIndex, getIndex, refineValue } from '../core/indexUtils';
import {
refineValue,
getIndexId,
hasMultipleIndices,
} from '../core/indexUtils';

function getId() {
return 'configure';
Expand Down Expand Up @@ -29,10 +33,10 @@ export default createConnector({
},
cleanUp(props, searchState) {
const id = getId();
const index = getIndex(this.context);
const indexId = getIndexId(this.context);
const subState =
hasMultipleIndex(this.context) && searchState.indices
? searchState.indices[index]
hasMultipleIndices(this.context) && searchState.indices
? searchState.indices[indexId]
: searchState;
const configureKeys =
subState && subState[id] ? Object.keys(subState[id]) : [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import createConnector from '../core/createConnector';
import {
getResults,
getCurrentRefinementValue,
getIndex,
getIndexId,
refineValue,
cleanUpValue,
} from '../core/indexUtils';
Expand Down Expand Up @@ -205,7 +205,7 @@ export default createConnector({
getMetadata(props, searchState) {
const items = [];
const id = getBoundingBoxId();
const index = getIndex(this.context);
const index = getIndexId(this.context);
const nextRefinement = {};
const currentRefinement = getCurrentRefinement(
props,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { SearchParameters } from 'algoliasearch-helper';
import createConnector from '../core/createConnector';
import {
cleanUpValue,
getIndex,
getIndexId,
refineValue,
getCurrentRefinementValue,
getResults,
Expand Down Expand Up @@ -270,7 +270,7 @@ export default createConnector({

return {
id,
index: getIndex(this.context),
index: getIndexId(this.context),
items: !currentRefinement
? []
: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { orderBy } from 'lodash';
import PropTypes from 'prop-types';
import createConnector from '../core/createConnector';
import {
getIndex,
getIndexId,
cleanUpValue,
refineValue,
getCurrentRefinementValue,
Expand Down Expand Up @@ -222,7 +222,7 @@ export default createConnector({
);
return {
id,
index: getIndex(this.context),
index: getIndexId(this.context),
items:
currentRefinement === null
? []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
refineValue,
getCurrentRefinementValue,
getResults,
getIndex,
getIndexId,
} from '../core/indexUtils';

function stringifyItem(item) {
Expand Down Expand Up @@ -209,7 +209,7 @@ export default createConnector({
const id = getId(props);
const value = getCurrentRefinement(props, searchState, this.context);
const items = [];
const index = getIndex(this.context);
const index = getIndexId(this.context);
if (value !== '') {
const { label } = find(
props.items,
Expand Down
Loading

0 comments on commit ec9e0fb

Please sign in to comment.