diff options
| -rw-r--r-- | frontend/__tests__/EditUser.test.js | 53 | ||||
| -rw-r--r-- | frontend/__tests__/RemoveFromCart.test.js | 18 | ||||
| -rw-r--r-- | frontend/__tests__/ResetRequest.test.js | 33 | ||||
| -rw-r--r-- | frontend/__tests__/SingleItem.test.js | 23 | ||||
| -rw-r--r-- | frontend/__tests__/__snapshots__/CartList.test.js.snap | 33 | ||||
| -rw-r--r-- | frontend/__tests__/__snapshots__/EditUser.test.js.snap | 44 | ||||
| -rw-r--r-- | frontend/__tests__/__snapshots__/RemoveFromCart.test.js.snap | 10 | ||||
| -rw-r--r-- | frontend/__tests__/__snapshots__/ResetRequest.test.js.snap | 54 | ||||
| -rw-r--r-- | frontend/__tests__/__snapshots__/SingleItem.test.js.snap | 17 | ||||
| -rw-r--r-- | frontend/components/EditUser.js | 4 | ||||
| -rw-r--r-- | frontend/components/RequestReset.js | 68 | ||||
| -rw-r--r-- | frontend/components/ResetRequest.js | 52 | ||||
| -rw-r--r-- | frontend/components/SingleItem.js | 1 | ||||
| -rw-r--r-- | frontend/package.json | 2 |
14 files changed, 309 insertions, 103 deletions
diff --git a/frontend/__tests__/EditUser.test.js b/frontend/__tests__/EditUser.test.js new file mode 100644 index 0000000..08dd6f6 --- /dev/null +++ b/frontend/__tests__/EditUser.test.js @@ -0,0 +1,53 @@ +import React from 'react'; +import { shallow } from 'enzyme'; +import toJSON from 'enzyme-to-json'; +import { EditUser } from '../components/EditUser'; + +const wait = amount => new Promise(resolve => setTimeout(resolve, amount)); + +const currentUser = { + me: { + name: 'Wes Bos', + }, + refetch() {}, +}; + +describe('<EditUser/>', () => { + it('renders', () => { + const wrapper = shallow(<EditUser currentUser={currentUser} updateUser={() => {}} />); + expect(toJSON(wrapper)).toMatchSnapshot(); + }); + + it('asks you to log in when you arent logged in', () => { + const wrapper = shallow(<EditUser currentUser={{}} updateUser={() => {}} />); + expect(toJSON(wrapper)).toMatchSnapshot(); + }); + + it('displays changes', () => { + const wrapper = shallow(<EditUser currentUser={currentUser} updateUser={() => {}} />); + const nameInput = wrapper.find('[name="name"]'); + nameInput.simulate('change', { target: { name: 'name', value: 'Scott' } }); + const diff = wrapper.find('pre[data-test="change"]'); + expect(diff.text()).toBe('{"name":"Scott"}'); + }); + + it('calls update user when form is submitted', () => { + const updateUserSpy = jest.fn(); + const wrapper = shallow(<EditUser currentUser={currentUser} updateUser={updateUserSpy} />); + const nameInput = wrapper.find('[name="name"]'); + nameInput.simulate('change', { target: { name: 'name', value: 'Scott' } }); + wrapper.simulate('submit', { preventDefault() {} }); + expect(updateUserSpy).toHaveBeenCalledWith({ variables: { name: 'Scott' } }); + }); + + it('refetches the current user after an update', async () => { + const currentUserWithSpy = { + me: { name: 'wes' }, + refetch: jest.fn(), + }; + const wrapper = shallow(<EditUser currentUser={currentUserWithSpy} updateUser={() => {}} />); + wrapper.simulate('submit', { preventDefault() {} }); + await wait(0); + expect(currentUserWithSpy.refetch).toHaveBeenCalled(); + }); +}); diff --git a/frontend/__tests__/RemoveFromCart.test.js b/frontend/__tests__/RemoveFromCart.test.js new file mode 100644 index 0000000..da03f0c --- /dev/null +++ b/frontend/__tests__/RemoveFromCart.test.js @@ -0,0 +1,18 @@ +import React from 'react'; +import { shallow, mount } from 'enzyme'; +import toJSON from 'enzyme-to-json'; +import { RemoveFromCart } from '../components/RemoveFromCart'; + +describe('<RemoveFromCart/>', () => { + it('renders and matches snapshot', () => { + const wrapper = shallow(<RemoveFromCart id="abc123" removeFromCart={() => {}} />); + expect(toJSON(wrapper)).toMatchSnapshot(); + }); + + it("runs a function when it's clicked", () => { + const removeSpy = jest.fn(); + const wrapper = shallow(<RemoveFromCart id="abc123" removeFromCart={removeSpy} />); + wrapper.simulate('click'); + expect(removeSpy).toHaveBeenCalledWith({ variables: { id: 'abc123' } }); + }); +}); diff --git a/frontend/__tests__/ResetRequest.test.js b/frontend/__tests__/ResetRequest.test.js new file mode 100644 index 0000000..bd8a934 --- /dev/null +++ b/frontend/__tests__/ResetRequest.test.js @@ -0,0 +1,33 @@ +import React from 'react'; +import { shallow } from 'enzyme'; +import toJSON from 'enzyme-to-json'; +import { ResetRequest } from '../components/ResetRequest'; + +const wait = amount => new Promise(resolve => setTimeout(resolve, amount)); + +describe('<ResetRequest/>', () => { + it('renders and matches snapshot', () => { + const wrapper = shallow(<ResetRequest requestReset={() => {}} />); + expect(toJSON(wrapper)).toMatchSnapshot(); + }); + + it('handles the reset request', async () => { + const resetSpy = jest.fn(() => Promise.resolve({})); + const wrapper = shallow(<ResetRequest requestReset={resetSpy} />); + const input = wrapper.find('input[name="email"]'); + input.simulate('change', { target: { name: 'email', value: 'wesbos@gmail.com' } }); + wrapper.simulate('submit', { preventDefault() {} }); + expect(resetSpy).toHaveBeenCalledWith({ variables: { email: 'wesbos@gmail.com' } }); + }); + + it('displays errors', async () => { + const resetSpy = jest.fn(() => Promise.resolve({ errors: [{ message: 'Error!!!' }] })); + const wrapper = shallow(<ResetRequest requestReset={resetSpy} />); + const input = wrapper.find('input[name="email"]'); + input.simulate('change', { target: { name: 'email', value: 'wesbos@gmail.com' } }); + wrapper.simulate('submit', { preventDefault() {} }); + await wait(0); + wrapper.update(); + expect(toJSON(wrapper)).toMatchSnapshot(); + }); +}); diff --git a/frontend/__tests__/SingleItem.test.js b/frontend/__tests__/SingleItem.test.js new file mode 100644 index 0000000..e39431d --- /dev/null +++ b/frontend/__tests__/SingleItem.test.js @@ -0,0 +1,23 @@ +import React from 'react'; +import { shallow } from 'enzyme'; +import toJSON from 'enzyme-to-json'; +import { SingleItem } from '../components/SingleItem'; + +const wait = amount => new Promise(resolve => setTimeout(resolve, amount)); + +const findItem = { + items: [ + { + largeImage: 'dog.jpg', + title: 'Sneakers', + description: 'A cool set of shoes', + }, + ], +}; + +describe('<SingleItem/>', () => { + it('renders', () => { + const wrapper = shallow(<SingleItem findItem={findItem} />); + expect(toJSON(wrapper)).toMatchSnapshot(); + }); +}); diff --git a/frontend/__tests__/__snapshots__/CartList.test.js.snap b/frontend/__tests__/__snapshots__/CartList.test.js.snap deleted file mode 100644 index 1f3cca5..0000000 --- a/frontend/__tests__/__snapshots__/CartList.test.js.snap +++ /dev/null @@ -1,33 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`<CartItem> renders and matches snapshot 1`] = ` -<styled.li - key="abc123" -> - <img - alt="Fake Item" - src="dog.jpg" - width="100" - /> - <div - className="cart-item-details" - > - <h3> - Fake Item - </h3> - <p> - $1,000 - — - <em> - 20 - × - $50 - each - </em> - </p> - </div> - <Apollo(RemoveFromCart) - id="abc123" - /> -</styled.li> -`; diff --git a/frontend/__tests__/__snapshots__/EditUser.test.js.snap b/frontend/__tests__/__snapshots__/EditUser.test.js.snap new file mode 100644 index 0000000..de5df25 --- /dev/null +++ b/frontend/__tests__/__snapshots__/EditUser.test.js.snap @@ -0,0 +1,44 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`<EditUser/> asks you to log in when you arent logged in 1`] = ` +<p> + You must be logged in +</p> +`; + +exports[`<EditUser/> renders 1`] = ` +<Form + onSubmit={[Function]} +> + <label + htmlFor="name" + > + Name: + <input + defaultValue="Wes Bos" + name="name" + onChange={[Function]} + type="text" + /> + </label> + <button + type="submit" + > + Update + </button> + <strong> + me: + </strong> + <pre> + "Wes Bos" + </pre> + <strong> + Change: + </strong> + <pre + data-test="change" + > + {} + </pre> +</Form> +`; diff --git a/frontend/__tests__/__snapshots__/RemoveFromCart.test.js.snap b/frontend/__tests__/__snapshots__/RemoveFromCart.test.js.snap new file mode 100644 index 0000000..b25bcc9 --- /dev/null +++ b/frontend/__tests__/__snapshots__/RemoveFromCart.test.js.snap @@ -0,0 +1,10 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`<RemoveFromCart/> renders and matches snapshot 1`] = ` +<styled.button + onClick={[Function]} + title="Remove From Cart" +> + × +</styled.button> +`; diff --git a/frontend/__tests__/__snapshots__/ResetRequest.test.js.snap b/frontend/__tests__/__snapshots__/ResetRequest.test.js.snap new file mode 100644 index 0000000..ef7e9f9 --- /dev/null +++ b/frontend/__tests__/__snapshots__/ResetRequest.test.js.snap @@ -0,0 +1,54 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`<ResetRequest/> displays errors 1`] = ` +<Form + onSubmit={[Function]} +> + <p + key="0" + > + Error!!! + </p> + <label + htmlFor="email" + > + Email + <input + name="email" + onChange={[Function]} + placeholder="email" + type="text" + value="wesbos@gmail.com" + /> + </label> + <button + type="submit" + > + Request Reset! + </button> +</Form> +`; + +exports[`<ResetRequest/> renders and matches snapshot 1`] = ` +<Form + onSubmit={[Function]} +> + <label + htmlFor="email" + > + Email + <input + name="email" + onChange={[Function]} + placeholder="email" + type="text" + value="" + /> + </label> + <button + type="submit" + > + Request Reset! + </button> +</Form> +`; diff --git a/frontend/__tests__/__snapshots__/SingleItem.test.js.snap b/frontend/__tests__/__snapshots__/SingleItem.test.js.snap new file mode 100644 index 0000000..173fb95 --- /dev/null +++ b/frontend/__tests__/__snapshots__/SingleItem.test.js.snap @@ -0,0 +1,17 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`<SingleItem/> renders 1`] = ` +<div> + <img + alt="Sneakers" + src="dog.jpg" + /> + <h2> + Viewing + Sneakers + </h2> + <p> + A cool set of shoes + </p> +</div> +`; diff --git a/frontend/components/EditUser.js b/frontend/components/EditUser.js index 5259d54..b885fe6 100644 --- a/frontend/components/EditUser.js +++ b/frontend/components/EditUser.js @@ -13,6 +13,7 @@ class EditUser extends React.Component { state = { changes: {}, }; + handleChange = e => { const { name, value } = e.target; const { me } = this.props.currentUser; @@ -48,10 +49,11 @@ class EditUser extends React.Component { <strong>me:</strong> <pre>{JSON.stringify(me.name)}</pre> <strong>Change:</strong> - <pre>{JSON.stringify(this.state.changes)}</pre> + <pre data-test="change">{JSON.stringify(this.state.changes)}</pre> </Form> ); } } export default compose(userEnhancer, updateUserEnhancer)(EditUser); +export { EditUser }; diff --git a/frontend/components/RequestReset.js b/frontend/components/RequestReset.js deleted file mode 100644 index 974924f..0000000 --- a/frontend/components/RequestReset.js +++ /dev/null @@ -1,68 +0,0 @@ -import React, { Component } from 'react'; -import { graphql, compose } from 'react-apollo'; -import { REQUEST_RESET_MUTATION } from '../queries'; -import Form from './styles/Form'; - -class ResetRequest extends Component { - state = { - email: `wesbos@gmail.com`, - password: 'abc123', - errors: [], - }; - - requestReset = async e => { - e.preventDefault(); - console.log(this.state.email); - const res = await this.props.requestReset({ - variables: { - email: this.state.email, - }, - }); - if (res.errors) { - this.setState({ errors: res.errors }); - } - console.log(res); - // // pull the values from state - // const { email, password } = this.state; - // this.setState({ loading: true, errors: [] }); - // const res = await this.props.signin({ - // // pass in those variables from state - // variables: { name, email, password }, - // }); - // if (res.errors) { - // this.setState({ errors: res.errors }); - // return; - // } - // localStorage.setItem('token', res.data.signin.token); - // // TODO refetch current user query - // this.props.currentUser.refetch(); - // this.setState({ loading: false }); - }; - - saveToState = e => { - const { name, value } = e.target; - this.setState({ [name]: value }); - }; - - render() { - return ( - <Form onSubmit={this.requestReset}> - {this.state.loading ? 'LOADING...' : null} - {this.state.errors ? this.state.errors.map(err => <p>{err.message}</p>) : null} - <label htmlFor="email"> - Email - <input value={this.state.email} onChange={this.saveToState} name="email" type="text" placeholder="email" /> - </label> - - <button type="submit">Request Reset!</button> - </Form> - ); - } -} - -// When we submit this mutation, we need to update our store - we have a few ways to do that: -// One - we can go nucular and run refetchQueries() which will just go get everything - this is easy, but at the cost of efficiency. - -const requestResetEnhancer = graphql(REQUEST_RESET_MUTATION, { name: 'requestReset' }); - -export default compose(requestResetEnhancer)(ResetRequest); diff --git a/frontend/components/ResetRequest.js b/frontend/components/ResetRequest.js new file mode 100644 index 0000000..0910e5f --- /dev/null +++ b/frontend/components/ResetRequest.js @@ -0,0 +1,52 @@ +import React, { Component } from 'react'; +import { graphql, compose } from 'react-apollo'; +import PropTypes from 'prop-types'; +import { REQUEST_RESET_MUTATION } from '../queries'; +import Form from './styles/Form'; + +class ResetRequest extends Component { + static propTypes = { + requestReset: PropTypes.func.isRequired, + }; + + state = { + email: '', + errors: [], + }; + + requestReset = async e => { + e.preventDefault(); + const res = await this.props.requestReset({ + variables: { + email: this.state.email, + }, + }); + if (res.errors) { + this.setState({ errors: res.errors }); + } + }; + + saveToState = e => { + const { name, value } = e.target; + this.setState({ [name]: value }); + }; + + render() { + return ( + <Form onSubmit={this.requestReset}> + {this.state.errors ? this.state.errors.map((err, i) => <p key={i}>{err.message}</p>) : null} + <label htmlFor="email"> + Email + <input value={this.state.email} onChange={this.saveToState} name="email" type="text" placeholder="email" /> + </label> + + <button type="submit">Request Reset!</button> + </Form> + ); + } +} + +const requestResetEnhancer = graphql(REQUEST_RESET_MUTATION, { name: 'requestReset' }); + +export default compose(requestResetEnhancer)(ResetRequest); +export { ResetRequest }; diff --git a/frontend/components/SingleItem.js b/frontend/components/SingleItem.js index f591f55..437fff1 100644 --- a/frontend/components/SingleItem.js +++ b/frontend/components/SingleItem.js @@ -16,3 +16,4 @@ const SingleItem = ({ findItem: { error, loading, items } }) => { }; export default compose(singleItemEnhancer)(SingleItem); +export { SingleItem }; diff --git a/frontend/package.json b/frontend/package.json index f032a04..e43e630 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -9,7 +9,7 @@ "start": "next start", "micro": "micro", "micro-dev": "micro-dev ./functions", - "test": "NODE_ENV=test jest" + "test": "NODE_ENV=test jest --watch" }, "author": "", "license": "ISC", |
