diff options
| author | Wes Bos <wesbos@gmail.com> | 2018-09-10 14:29:32 -0400 |
|---|---|---|
| committer | Wes Bos <wesbos@gmail.com> | 2018-09-10 14:29:32 -0400 |
| commit | b0d25a9ad3cc1df2fcc11ddb84e4603b94520b09 (patch) | |
| tree | af1fa8c77e099f52a7fbce3a6ff3e11dec9f24df /stepped-solutions/64 | |
| parent | 093c172d16732ba8d01faa313e0af99d26902205 (diff) | |
almost done
Diffstat (limited to 'stepped-solutions/64')
4 files changed, 270 insertions, 0 deletions
diff --git a/stepped-solutions/64/frontend/__tests__/Signup.test.js b/stepped-solutions/64/frontend/__tests__/Signup.test.js new file mode 100755 index 0000000..e18bdee --- /dev/null +++ b/stepped-solutions/64/frontend/__tests__/Signup.test.js @@ -0,0 +1,80 @@ +import { mount } from 'enzyme'; +import wait from 'waait'; +import toJSON from 'enzyme-to-json'; +import { MockedProvider } from 'react-apollo/test-utils'; +import { ApolloConsumer } from 'react-apollo'; +import Signup, { SIGNUP_MUTATION } from '../components/Signup'; +import { CURRENT_USER_QUERY } from '../components/User'; +import { fakeUser } from '../lib/testUtils'; + +function type(wrapper, name, value) { + wrapper.find(`input[name="${name}"]`).simulate('change', { + target: { name, value }, + }); +} + +const me = fakeUser(); +const mocks = [ + // signup mock mutation + { + request: { + query: SIGNUP_MUTATION, + variables: { + name: me.name, + email: me.email, + password: 'wes', + }, + }, + result: { + data: { + signup: { + __typename: 'User', + id: 'abc123', + email: me.email, + name: me.name, + }, + }, + }, + }, + // current user query mock + { + request: { query: CURRENT_USER_QUERY }, + result: { data: { me } }, + }, +]; + +describe('<Signup/>', () => { + it('renders and matches snapshot', async () => { + const wrapper = mount( + <MockedProvider> + <Signup /> + </MockedProvider> + ); + expect(toJSON(wrapper.find('form'))).toMatchSnapshot(); + }); + + it('calls the mutation properly', async () => { + let apolloClient; + const wrapper = mount( + <MockedProvider mocks={mocks}> + <ApolloConsumer> + {client => { + apolloClient = client; + return <Signup />; + }} + </ApolloConsumer> + </MockedProvider> + ); + await wait(); + wrapper.update(); + type(wrapper, 'name', me.name); + type(wrapper, 'email', me.email); + type(wrapper, 'password', 'wes'); + wrapper.update(); + wrapper.find('form').simulate('submit'); + await wait(); + // query the user out of the apollo client + const user = await apolloClient.query({ query: CURRENT_USER_QUERY }); + expect(user.data.me).toMatchObject(me); + }); +}); diff --git a/stepped-solutions/64/frontend/__tests__/__snapshots__/Signup.test.js.snap b/stepped-solutions/64/frontend/__tests__/__snapshots__/Signup.test.js.snap new file mode 100755 index 0000000..14c5912 --- /dev/null +++ b/stepped-solutions/64/frontend/__tests__/__snapshots__/Signup.test.js.snap @@ -0,0 +1,62 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`<Signup/> renders and matches snapshot 1`] = ` +<form + className="Form-s1xszr8q-0 dIYPmt" + method="post" + onSubmit={[Function]} +> + <fieldset + aria-busy={false} + disabled={false} + > + <h2> + Sign Up for An Account + </h2> + <DisplayError + error={Object {}} + /> + <label + htmlFor="email" + > + Email + <input + name="email" + onChange={[Function]} + placeholder="email" + type="email" + value="" + /> + </label> + <label + htmlFor="name" + > + Name + <input + name="name" + onChange={[Function]} + placeholder="name" + type="text" + value="" + /> + </label> + <label + htmlFor="password" + > + Password + <input + name="password" + onChange={[Function]} + placeholder="password" + type="password" + value="" + /> + </label> + <button + type="submit" + > + Sign Up! + </button> + </fieldset> +</form> +`; diff --git a/stepped-solutions/64/frontend/components/Signup.js b/stepped-solutions/64/frontend/components/Signup.js new file mode 100755 index 0000000..e2f1a3f --- /dev/null +++ b/stepped-solutions/64/frontend/components/Signup.js @@ -0,0 +1,87 @@ +import React, { Component } from 'react'; +import { Mutation } from 'react-apollo'; +import gql from 'graphql-tag'; +import Form from './styles/Form'; +import Error from './ErrorMessage'; +import { CURRENT_USER_QUERY } from './User'; + +const SIGNUP_MUTATION = gql` + mutation SIGNUP_MUTATION($email: String!, $name: String!, $password: String!) { + signup(email: $email, name: $name, password: $password) { + id + email + name + } + } +`; + +class Signup extends Component { + state = { + name: '', + email: '', + password: '', + }; + saveToState = e => { + this.setState({ [e.target.name]: e.target.value }); + }; + render() { + return ( + <Mutation + mutation={SIGNUP_MUTATION} + variables={this.state} + refetchQueries={[{ query: CURRENT_USER_QUERY }]} + > + {(signup, { error, loading }) => ( + <Form + method="post" + onSubmit={async e => { + e.preventDefault(); + await signup(); + this.setState({ name: '', email: '', password: '' }); + }} + > + <fieldset disabled={loading} aria-busy={loading}> + <h2>Sign Up for An Account</h2> + <Error error={error} /> + <label htmlFor="email"> + Email + <input + type="email" + name="email" + placeholder="email" + value={this.state.email} + onChange={this.saveToState} + /> + </label> + <label htmlFor="name"> + Name + <input + type="text" + name="name" + placeholder="name" + value={this.state.name} + onChange={this.saveToState} + /> + </label> + <label htmlFor="password"> + Password + <input + type="password" + name="password" + placeholder="password" + value={this.state.password} + onChange={this.saveToState} + /> + </label> + + <button type="submit">Sign Up!</button> + </fieldset> + </Form> + )} + </Mutation> + ); + } +} + +export default Signup; +export { SIGNUP_MUTATION }; diff --git a/stepped-solutions/64/frontend/components/User.js b/stepped-solutions/64/frontend/components/User.js new file mode 100755 index 0000000..6f8a4fb --- /dev/null +++ b/stepped-solutions/64/frontend/components/User.js @@ -0,0 +1,41 @@ +import { Query } from 'react-apollo'; +import gql from 'graphql-tag'; +import PropTypes from 'prop-types'; + +const CURRENT_USER_QUERY = gql` + query { + me { + id + email + name + permissions + orders { + id + } + cart { + id + quantity + item { + id + price + image + title + description + } + } + } + } +`; + +const User = props => ( + <Query {...props} query={CURRENT_USER_QUERY}> + {payload => props.children(payload)} + </Query> +); + +User.propTypes = { + children: PropTypes.func.isRequired, +}; + +export default User; +export { CURRENT_USER_QUERY }; |
