Skip to content
This repository was archived by the owner on Apr 13, 2023. It is now read-only.

Commit

Permalink
Requested PR changes
Browse files Browse the repository at this point in the history
* Requested ApolloProvider changes
* Add tests
  • Loading branch information
Wyatt McBain committed Feb 24, 2017
1 parent d08dc9d commit 0a36251
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 26 deletions.
2 changes: 1 addition & 1 deletion Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Expect active development and potentially significant breaking changes in the `0.x` track. We'll try to be diligent about releasing a `1.0` version in a timely fashion (ideally within 1 or 2 months), so that we can take advantage of SemVer to signify breaking changes from that point on.

### vNext
- ApolloProvider now changes it's client and store when those props change. [PR #479](https://github.com/apollographql/react-apollo/pull/479)
- ApolloProvider now changes its client and store when those props change. [PR #479](https://github.com/apollographql/react-apollo/pull/479)

### 0.11.2
- Remove `@types/chai` dev dependency which called a reference to the `chai` types in the production build. [PR #471](https://github.com/apollographql/react-apollo/pull/471)
Expand Down
38 changes: 14 additions & 24 deletions src/ApolloProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import {
Store,
} from 'redux';

import ApolloClient from 'apollo-client';
/* tslint:disable:no-unused-variable */
import ApolloClient, { ApolloStore } from 'apollo-client';
/* tslint:enable:no-unused-variable */

import invariant = require('invariant');

Expand All @@ -37,44 +39,32 @@ export default class ApolloProvider extends Component<ProviderProps, any> {
client: PropTypes.object.isRequired,
};

public store: Store<any>;
public client: ApolloClient;

constructor(props, context) {
super(props, context);

this._init(props);
}

componentWillReceiveProps(nextProps) {
this._init(nextProps);
}

_init(props) {
invariant(
props.client,
'ApolloClient was not passed a client instance. Make ' +
'sure you pass in your client via the "client" prop.'
);

this.client = props.client;
if (!props.store) { props.client.initStore(); }
}

if (props.store) {
this.store = props.store;
// support an immutable store alongside apollo store
if (props.immutable) props.client.initStore();
return;
}
shouldComponentUpdate(nextProps) {
return this.props.client !== nextProps.client ||
this.props.store !== nextProps.store ||
this.props.children !== nextProps.children;
}

// intialize the built in store if none is passed in
props.client.initStore();
this.store = props.client.store;
componentDidUpdate() {
if (!this.props.store) { this.props.client.initStore(); }
}

getChildContext() {
return {
store: this.store,
client: this.client,
store: this.props.store || this.props.client.store,
client: this.props.client,
};
}

Expand Down
95 changes: 94 additions & 1 deletion test/react-web/client/ApolloProvider.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,39 @@ describe('<ApolloProvider /> Component', () => {
return <div />;
}
}
class Container extends React.Component<any, any> {
constructor(props) {
super(props)
this.state = {}
}

componentDidMount() {
this.setState({
store: this.props.store,
client: this.props.client
})
}

render() {
if (this.state.store || this.props.store) {
return (
<ApolloProvider client={this.state.client || this.props.client}
store={this.state.store || this.props.store}>
<Child />
</ApolloProvider>
)
} else {
return (
<ApolloProvider client={this.state.client || this.props.client}>
<Child />
</ApolloProvider>
)
}
}
};
const client = new ApolloClient();
const store = createStore(() => ({}));


it('should render children components', () => {
const wrapper = shallow(
<ApolloProvider store={store} client={client}>
Expand Down Expand Up @@ -103,4 +132,68 @@ describe('<ApolloProvider /> Component', () => {
expect(child.context.store).toEqual(store);

});

it('should update props when the client changes', () => {
const container = shallow(<Container client={client} />);
expect(container.find(ApolloProvider).props().client).toEqual(client);

const newClient = new ApolloClient();
container.setState({ client: newClient });
expect(container.find(ApolloProvider).props().client).toEqual(newClient);
expect(container.find(ApolloProvider).props().client).not.toEqual(client);
});

it('should update props when the store changes', () => {
const container = shallow(<Container client={client} store={store} />);
expect(container.find(ApolloProvider).props().store).toEqual(store);

const newStore = createStore(() => ({}));
container.setState({ store: newStore });
expect(container.find(ApolloProvider).props().store).toEqual(newStore);
expect(container.find(ApolloProvider).props().store).not.toEqual(store);
});

it('should call clients init store when a store is not passed', () => {
const testClient = new ApolloClient();
testClient.store = store;

const initStoreMock = jest.fn();
testClient.initStore = initStoreMock;

const container = TestUtils.renderIntoDocument(
<Container client={testClient} />
) as React.Component<any, any>;
expect(initStoreMock).toHaveBeenCalled();

initStoreMock.mockClear();
const newClient = new ApolloClient();
newClient.store = store;
newClient.initStore = initStoreMock;
container.setState({ client: newClient });

expect(initStoreMock).toHaveBeenCalled();
})

it('should not call clients init store when a store is passed', () => {
const testClient = new ApolloClient();

const initStoreMock = jest.fn();
testClient.initStore = initStoreMock;

const container = TestUtils.renderIntoDocument(
<Container client={testClient} store={store} />
) as React.Component<any, any>;

expect(initStoreMock).not.toHaveBeenCalled();

initStoreMock.mockClear();
const newClient = new ApolloClient();
container.setState({ client: newClient });

expect(initStoreMock).not.toHaveBeenCalled();

const newStore = createStore(() => ({}));
container.setState({ store: store });
expect(initStoreMock).not.toHaveBeenCalled();
})
});

0 comments on commit 0a36251

Please sign in to comment.