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

Commit

Permalink
chore(context): migrate Panel (#2203)
Browse files Browse the repository at this point in the history
* chore(context): migrate Panel

This migration is fairly straightforward, and has no impact on how the PanelCallbackHandler is used, although it adds a new component in that tree so it can read the context

IFW-485
  • Loading branch information
Haroenv authored and samouss committed Apr 19, 2019
1 parent beb0ce4 commit c0e150b
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 152 deletions.
21 changes: 9 additions & 12 deletions packages/react-instantsearch-dom/src/components/Panel.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import React, { Component } from 'react';
import React, { Component, createContext } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { createClassNames } from '../core/utils';

const cx = createClassNames('Panel');

export const {
Consumer: PanelConsumer,
Provider: PanelProvider,
} = createContext(function setCanRefine() {});

class Panel extends Component {
static propTypes = {
children: PropTypes.node.isRequired,
Expand All @@ -13,10 +18,6 @@ class Panel extends Component {
footer: PropTypes.node,
};

static childContextTypes = {
setCanRefine: PropTypes.func.isRequired,
};

static defaultProps = {
className: '',
header: null,
Expand All @@ -27,12 +28,6 @@ class Panel extends Component {
canRefine: true,
};

getChildContext() {
return {
setCanRefine: this.setCanRefine,
};
}

setCanRefine = nextCanRefine => {
this.setState({ canRefine: nextCanRefine });
};
Expand All @@ -47,7 +42,9 @@ class Panel extends Component {
>
{header && <div className={cx('header')}>{header}</div>}

<div className={cx('body')}>{children}</div>
<div className={cx('body')}>
<PanelProvider value={this.setCanRefine}>{children}</PanelProvider>
</div>

{footer && <div className={cx('footer')}>{footer}</div>}
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,21 @@
import { Component } from 'react';
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { PanelConsumer } from './Panel';

class PanelCallbackHandler extends Component {
static propTypes = {
children: PropTypes.node.isRequired,
canRefine: PropTypes.bool.isRequired,
setCanRefine: PropTypes.func.isRequired,
};

static contextTypes = {
setCanRefine: PropTypes.func,
};

componentWillMount() {
if (this.context.setCanRefine) {
this.context.setCanRefine(this.props.canRefine);
}
componentDidMount() {
this.props.setCanRefine(this.props.canRefine);
}

componentWillReceiveProps(nextProps) {
if (
this.context.setCanRefine &&
this.props.canRefine !== nextProps.canRefine
) {
this.context.setCanRefine(nextProps.canRefine);
componentDidUpdate(prevProps) {
if (prevProps.canRefine !== this.props.canRefine) {
this.props.setCanRefine(this.props.canRefine);
}
}

Expand All @@ -31,4 +24,19 @@ class PanelCallbackHandler extends Component {
}
}

export default PanelCallbackHandler;
const PanelWrapper = ({ canRefine, children }) => (
<PanelConsumer>
{setCanRefine => (
<PanelCallbackHandler setCanRefine={setCanRefine} canRefine={canRefine}>
{children}
</PanelCallbackHandler>
)}
</PanelConsumer>
);

PanelWrapper.propTypes = {
canRefine: PropTypes.bool.isRequired,
children: PropTypes.node.isRequired,
};

export default PanelWrapper;
37 changes: 21 additions & 16 deletions packages/react-instantsearch-dom/src/components/__tests__/Panel.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import Enzyme, { shallow } from 'enzyme';
import Enzyme, { shallow, mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import Panel from '../Panel';
import Panel, { PanelConsumer } from '../Panel';

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

Expand Down Expand Up @@ -70,35 +70,40 @@ describe('Panel', () => {
expect(wrapper).toMatchSnapshot();
});

it('expect to expose context to his children', () => {
const wrapper = shallow(
it('expect to expose context to its children', () => {
let provided;
const wrapper = mount(
<Panel>
<div>Hello content</div>
<PanelConsumer>
{setCanRefine => {
provided = setCanRefine;
return null;
}}
</PanelConsumer>
</Panel>
);

expect(wrapper.instance().getChildContext()).toEqual({
setCanRefine: wrapper.instance().setCanRefine,
});
expect(provided).toEqual(wrapper.instance().setCanRefine);
});

it('expect to render when setCanRefine is called', () => {
const wrapper = shallow(
const wrapper = mount(
<Panel>
<div>Hello content</div>
<PanelConsumer>
{setCanRefine => (
<button onClick={() => setCanRefine(false)}>
call setCanRefine
</button>
)}
</PanelConsumer>
</Panel>
);

expect(wrapper.state('canRefine')).toBe(true);
expect(wrapper).toMatchSnapshot();

// Simulate context call
wrapper
.instance()
.getChildContext()
.setCanRefine(false);

wrapper.update();
wrapper.find('button').simulate('click');

expect(wrapper.state('canRefine')).toBe(false);
expect(wrapper).toMatchSnapshot();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,122 +1,118 @@
import React from 'react';
import Enzyme, { shallow } from 'enzyme';
import Enzyme, { shallow, mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import PanelCallbackHandler from '../PanelCallbackHandler';
import { PanelProvider } from '../Panel';

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

describe('PanelCallbackHandler', () => {
it('expect to render', () => {
const props = {
canRefine: true,
};

const wrapper = shallow(
<PanelCallbackHandler {...props}>
const wrapper = mount(
<PanelCallbackHandler canRefine>
<div>Hello content</div>
</PanelCallbackHandler>
);

expect(wrapper).toMatchSnapshot();
expect(wrapper).toMatchInlineSnapshot(`
<PanelWrapper
canRefine={true}
>
<PanelCallbackHandler
canRefine={true}
setCanRefine={[Function]}
>
<div>
Hello content
</div>
</PanelCallbackHandler>
</PanelWrapper>
`);
});

describe('willMount', () => {
describe('didMount', () => {
it('expect to call setCanRefine when the context is given', () => {
const props = {
canRefine: true,
};

const context = {
setCanRefine: jest.fn(),
};

shallow(
<PanelCallbackHandler {...props}>
<div>Hello content</div>
</PanelCallbackHandler>,
{ context }
const setCanRefine = jest.fn();

mount(
<PanelProvider value={setCanRefine}>
<PanelCallbackHandler canRefine>
<div>Hello content</div>
</PanelCallbackHandler>
</PanelProvider>
);

expect(context.setCanRefine).toHaveBeenCalledTimes(1);
expect(context.setCanRefine).toHaveBeenCalledWith(true);
expect(setCanRefine).toHaveBeenCalledTimes(1);
expect(setCanRefine).toHaveBeenCalledWith(true);
});

it('expect to not throw when the context is not given', () => {
const props = {
canRefine: true,
};

const trigger = () =>
expect(() =>
shallow(
<PanelCallbackHandler {...props}>
<PanelCallbackHandler canRefine>
<div>Hello content</div>
</PanelCallbackHandler>
);

expect(() => trigger()).not.toThrow();
)
).not.toThrow();
});
});

describe('willReceiveProps', () => {
describe('didUpdate', () => {
it('expect to call setCanRefine when the context is given', () => {
const props = {
canRefine: true,
};

const context = {
setCanRefine: jest.fn(),
};

const wrapper = shallow(
<PanelCallbackHandler {...props}>
<div>Hello content</div>
</PanelCallbackHandler>,
{ context }
const setCanRefine = jest.fn();

const wrapper = mount(
<PanelProvider value={setCanRefine}>
<PanelCallbackHandler canRefine>
<div>Hello content</div>
</PanelCallbackHandler>
</PanelProvider>
);

wrapper.setProps({ canRefine: false });
wrapper.setProps({
children: (
<PanelCallbackHandler canRefine={false}>
<div>Hello content</div>
</PanelCallbackHandler>
),
});

expect(context.setCanRefine).toHaveBeenCalledTimes(2);
expect(context.setCanRefine).toHaveBeenLastCalledWith(false);
expect(setCanRefine).toHaveBeenCalledTimes(2);
expect(setCanRefine).toHaveBeenLastCalledWith(false);
});

it('expect to not call setCanRefine when the nextProps is the same', () => {
const props = {
canRefine: true,
};

const context = {
setCanRefine: jest.fn(),
};

const wrapper = shallow(
<PanelCallbackHandler {...props}>
<div>Hello content</div>
</PanelCallbackHandler>,
{ context }
const setCanRefine = jest.fn();

const wrapper = mount(
<PanelProvider value={setCanRefine}>
<PanelCallbackHandler canRefine>
<div>Hello content</div>
</PanelCallbackHandler>
</PanelProvider>
);

wrapper.setProps({ canRefine: true });
wrapper.setProps({
children: (
<PanelCallbackHandler canRefine>
<div>Hello content</div>
</PanelCallbackHandler>
),
});

expect(context.setCanRefine).toHaveBeenCalledTimes(1);
expect(setCanRefine).toHaveBeenCalledTimes(1);
});

it('expect to not throw when the context is not given', () => {
const props = {
canRefine: true,
};

const trigger = () => {
expect(() => {
const wrapper = shallow(
<PanelCallbackHandler {...props}>
<PanelCallbackHandler canRefine>
<div>Hello content</div>
</PanelCallbackHandler>
);

wrapper.setProps({ canRefine: false });
};

expect(() => trigger()).not.toThrow();
}).not.toThrow();
});
});
});

0 comments on commit c0e150b

Please sign in to comment.