diff options
| author | Wes Bos <wesbos@gmail.com> | 2018-06-14 16:44:21 -0400 |
|---|---|---|
| committer | Wes Bos <wesbos@gmail.com> | 2018-06-14 16:44:21 -0400 |
| commit | b1600adec47a04f60e1da07d94a3ed3906ff5aee (patch) | |
| tree | 828f786da6806d7237ee5cbc5df61e552353b85b /finished-application/frontend/__tests__ | |
| parent | a95e08cd2dd5d7ec0a0412adae02515a5f9cec4f (diff) | |
starter files
Diffstat (limited to 'finished-application/frontend/__tests__')
32 files changed, 2022 insertions, 0 deletions
diff --git a/finished-application/frontend/__tests__/AddToCart.test.js b/finished-application/frontend/__tests__/AddToCart.test.js new file mode 100644 index 0000000..fe15f3f --- /dev/null +++ b/finished-application/frontend/__tests__/AddToCart.test.js @@ -0,0 +1,92 @@ +import React from 'react'; +import { mount } from 'enzyme'; +import toJSON from 'enzyme-to-json'; +import { ApolloConsumer } from 'react-apollo'; +import { MockedProvider } from 'react-apollo/test-utils'; +import wait from 'waait'; +import AddToCart, { ADD_TO_CART_MUTATION } from '../components/AddToCart'; +import { fakeCartItem, fakeUser } from '../lib/testUtils'; +import { CURRENT_USER_QUERY } from '../components/User'; + +const mocks = [ + { + request: { query: CURRENT_USER_QUERY }, + result: { + data: { + me: { + ...fakeUser(), + cart: [], + }, + }, + }, + }, + { + request: { query: ADD_TO_CART_MUTATION, variables: { id: 'abc123' } }, + result: { + data: { + addToCart: { + ...fakeCartItem(), + quantity: 1, + }, + }, + }, + }, +]; + +describe('<AddtoCart/>', () => { + it('renders and matches snapshot', async () => { + const wrapper = mount( + <MockedProvider mocks={mocks}> + <AddToCart id="abc123" /> + </MockedProvider> + ); + await wait(); + wrapper.update(); + + expect(toJSON(wrapper.find('button'))).toMatchSnapshot(); + }); + + it('adds an item to the cart when clicked', async () => { + // 1. Grab a copy of the current client + let apolloClient; + // const wrapper = mountWithApollo(<RemoveFromCart id="abc123" />); + const wrapper = mount( + <MockedProvider mocks={mocks}> + <ApolloConsumer> + {client => { + apolloClient = client; + return <AddToCart id="abc123" />; + }} + </ApolloConsumer> + </MockedProvider> + ); + await wait(); + wrapper.update(); + + const { me } = apolloClient.readQuery({ query: CURRENT_USER_QUERY }); + expect(me.cart).toHaveLength(0); + + // add to cart + wrapper.find('button').simulate('click'); + await wait(); + // check if the item is in the cart + const { me: me2 } = apolloClient.readQuery({ query: CURRENT_USER_QUERY }); + + expect(me2.cart).toHaveLength(1); + expect(me2.cart[0].id).toBe('omg123'); + expect(me2.cart[0].quantity).toBe(1); + }); + + it('changes to adding when clicked', async () => { + const wrapper = mount( + <MockedProvider mocks={mocks}> + <AddToCart id="abc123" /> + </MockedProvider> + ); + await wait(); + wrapper.update(); + expect(wrapper.text()).toContain('π Add To Cart'); + wrapper.find('button').simulate('click'); + expect(wrapper.text()).toContain('π Adding To Cart'); + }); +}); diff --git a/finished-application/frontend/__tests__/Cart.test.js b/finished-application/frontend/__tests__/Cart.test.js new file mode 100644 index 0000000..255183e --- /dev/null +++ b/finished-application/frontend/__tests__/Cart.test.js @@ -0,0 +1,46 @@ +import React from 'react'; +import { shallow, mount } from 'enzyme'; +import toJSON from 'enzyme-to-json'; +import mountOptions from '../lib/testUtils'; +import wait from 'waait'; +import Cart from '../components/Cart'; +import { MockedProvider } from 'react-apollo/test-utils'; +import { fakeCartItem, fakeUser } from '../lib/testUtils'; +import { CURRENT_USER_QUERY } from '../components/User'; +import { LOCAL_STATE_QUERY } from '../components/Cart'; + +const mocks = [ + { + request: { query: CURRENT_USER_QUERY }, + result: { + data: { + me: { + ...fakeUser(), + cart: [fakeCartItem()], + }, + }, + }, + }, + { + request: { query: LOCAL_STATE_QUERY }, + result: { + data: { + cartOpen: true, + }, + }, + }, +]; + +describe('<Cart/>', () => { + it('renders', async () => { + const wrapper = mount( + <MockedProvider mocks={mocks}> + <Cart /> + </MockedProvider> + ); + await wait(); + wrapper.update(); + expect(toJSON(wrapper.find('header'))).toMatchSnapshot(); + expect(wrapper.find('CartItem')).toHaveLength(1); + }); +}); diff --git a/finished-application/frontend/__tests__/CartCount.test.js b/finished-application/frontend/__tests__/CartCount.test.js new file mode 100644 index 0000000..dcb9ca8 --- /dev/null +++ b/finished-application/frontend/__tests__/CartCount.test.js @@ -0,0 +1,21 @@ +import React from 'react'; +import { shallow, mount } from 'enzyme'; +import toJSON from 'enzyme-to-json'; +import CartCount from '../components/CartCount'; + +describe('<CartCount></CartCount>', () => { + it('renders okay', () => { + shallow(<CartCount count={10} />); + }); + + it('matches snapshot', () => { + const wrapper = shallow(<CartCount count={10} />); + expect(toJSON(wrapper)).toMatchSnapshot(); + }); + it('updates via props', () => { + const wrapper = mount(<CartCount count={50} />); + expect(toJSON(wrapper)).toMatchSnapshot(); + wrapper.setProps({ count: 10 }); + expect(toJSON(wrapper)).toMatchSnapshot(); + }); +}); diff --git a/finished-application/frontend/__tests__/CartItem.test.js b/finished-application/frontend/__tests__/CartItem.test.js new file mode 100644 index 0000000..42dd39b --- /dev/null +++ b/finished-application/frontend/__tests__/CartItem.test.js @@ -0,0 +1,33 @@ +import React from 'react'; +import { shallow, mount } from 'enzyme'; +import toJSON from 'enzyme-to-json'; +import CartItem from '../components/CartItem'; + +const cartItem = { + item: { + price: 5000, + image: 'dog.jpg', + title: 'Fake Item', + }, + id: 'abc123', + quantity: 20, +}; + +describe('<CartItem>', () => { + it('renders and matches snapshot', () => { + const wrapper = shallow(<CartItem cartItem={cartItem} />); + expect(toJSON(wrapper)).toMatchSnapshot(); + }); + + it('renders a single quantity', () => { + const wrapper = shallow(<CartItem cartItem={{ ...cartItem, quantity: 1 }} />); + const p = wrapper.find('p'); + expect(p.text()).toBe('$50 β 1 Γ $50 each'); + }); + + it('renders multiples', () => { + const wrapper = shallow(<CartItem cartItem={{ ...cartItem, quantity: 23423 }} />); + const p = wrapper.find('p'); + expect(p.text()).toBe('$1,171,150 β 23423 Γ $50 each'); + }); +}); diff --git a/finished-application/frontend/__tests__/CreateItem.test.js b/finished-application/frontend/__tests__/CreateItem.test.js new file mode 100644 index 0000000..56c3f10 --- /dev/null +++ b/finished-application/frontend/__tests__/CreateItem.test.js @@ -0,0 +1,132 @@ +import React from 'react'; +import { mount } from 'enzyme'; +import toJSON from 'enzyme-to-json'; +import Router from 'next/router'; +import { MockedProvider } from 'react-apollo/test-utils'; +import CreateItem, { CREATE_ITEM_MUTATION } from '../components/CreateItem'; +import wait from 'waait'; +import { fakeItem } from '../lib/testUtils'; + +const dogImage = 'https://dog.com/dog.jpg'; + +// Mock fetch to resolve data +global.fetch = jest.fn().mockResolvedValue({ + json: () => ({ + secure_url: dogImage, + eager: [{ secure_url: dogImage }], + }), +}); + +describe('<Createitem/>', () => { + it('renders and matches snapshot', () => { + const wrapper = mount( + <MockedProvider> + <CreateItem /> + </MockedProvider> + ); + const form = wrapper.find('form[data-test]'); + expect(toJSON(form)).toMatchSnapshot(); + }); + + it('uploads a file when changed', async () => { + const wrapper = mount( + <MockedProvider> + <CreateItem /> + </MockedProvider> + ); + const component = wrapper.find('CreateItem').instance(); + + const input = wrapper.find('input[type="file"]'); + // internally this does some setState() calls + input.simulate('change', { currentTarget: { files: ['fakedog.jpg'] } }); + await wait(0); + expect(component.state.image).toEqual(dogImage); + expect(component.state.largeImage).toEqual(dogImage); + }); + + it('handles state updating', async () => { + const wrapper = mount( + <MockedProvider> + <CreateItem /> + </MockedProvider> + ); + + wrapper.find('#title').simulate('change', { target: { value: 'Testing', name: 'title' } }); + wrapper.find('#price').simulate('change', { + target: { + value: 50000, + name: 'price', + type: 'number', + }, + }); + wrapper.find('#description').simulate('change', { + target: { + value: 'This is a really nice item', + name: 'description', + }, + }); + const component = wrapper.find('CreateItem').instance(); + expect(component.state).toMatchObject({ + title: 'Testing', + description: 'This is a really nice item', + image: '', + largeImage: '', + price: 50000, + }); + }); + + it('creates an item when form is submitted', async () => { + const item = fakeItem(); + const mocks = [ + { + request: { + query: CREATE_ITEM_MUTATION, + variables: { + title: item.title, + description: item.description, + image: '', + largeImage: '', + price: item.price, + }, + }, + result: { + data: { + createItem: { + ...fakeItem(), + __typeName: 'Item', + }, + }, + }, + }, + ]; + + const wrapper = mount( + <MockedProvider mocks={mocks}> + <CreateItem /> + </MockedProvider> + ); + + wrapper.find('#title').simulate('change', { target: { value: item.title, name: 'title' } }); + wrapper.find('#price').simulate('change', { + target: { + value: item.price, + name: 'price', + type: 'number', + }, + }); + wrapper.find('#description').simulate('change', { + target: { + value: item.description, + name: 'description', + }, + }); + + Router.router = { push: jest.fn() }; + // it submits and matches the mocks + wrapper.find('form').simulate('submit'); + // it routes to the item page + await wait(50); + expect(Router.router.push).toHaveBeenCalled(); + expect(Router.router.push).toHaveBeenCalledWith({ pathname: '/item', query: { id: '123' } }); + }); +}); diff --git a/finished-application/frontend/__tests__/EditUser.test.js b/finished-application/frontend/__tests__/EditUser.test.js new file mode 100644 index 0000000..a98cbb5 --- /dev/null +++ b/finished-application/frontend/__tests__/EditUser.test.js @@ -0,0 +1,75 @@ +import React from 'react'; +import { mount } from 'enzyme'; +import toJSON from 'enzyme-to-json'; +import { MockedProvider } from 'react-apollo/test-utils'; +import wait from 'waait'; +import EditUser, { UPDATE_USER_MUTATION } from '../components/EditUser'; +import { fakeUser } from '../lib/testUtils'; +import { CURRENT_USER_QUERY } from '../components/User'; + +const mocks = [ + { + request: { query: CURRENT_USER_QUERY }, + result: { + data: { + me: fakeUser(), + }, + }, + }, + { + request: { + query: UPDATE_USER_MUTATION, + variables: { + name: 'Westopher', + }, + }, + result: { + updateUser: { + name: 'Westopher', + __typename: 'User', + }, + }, + }, +]; + +describe('<EditUser/>', () => { + it('renders', async () => { + const wrapper = mount( + <MockedProvider mocks={mocks}> + <EditUser /> + </MockedProvider> + ); + await wait(); + wrapper.update(); + expect(toJSON(wrapper.find('form'))).toMatchSnapshot(); + }); + + it('displays changes', async () => { + const wrapper = mount( + <MockedProvider mocks={mocks}> + <EditUser /> + </MockedProvider> + ); + await wait(); + wrapper.update(); + 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', async () => { + const wrapper = mount( + <MockedProvider mocks={mocks}> + <EditUser /> + </MockedProvider> + ); + await wait(); + wrapper.update(); + const nameInput = wrapper.find('[name="name"]'); + nameInput.simulate('change', { target: { name: 'name', value: 'Westopher' } }); + wrapper.find('form').simulate('submit'); + wrapper.update(); + expect(wrapper.find('[data-test="updated"]').text()).toBe('Updated!'); + }); +}); diff --git a/finished-application/frontend/__tests__/Item.test.js b/finished-application/frontend/__tests__/Item.test.js new file mode 100644 index 0000000..129efa9 --- /dev/null +++ b/finished-application/frontend/__tests__/Item.test.js @@ -0,0 +1,22 @@ +/* eslint-env jest */ + +import React from 'react'; +import Enzyme, { shallow, mount } from 'enzyme'; +import toJSON from 'enzyme-to-json'; +import ItemComponent from '../components/Item'; + +const fakeItem = { + id: 'ABC123', + title: 'A Cool Item', + price: 5000, + description: 'This item is really cool!', + image: 'dog.jpg', + largeImage: 'largedog.jpg', +}; + +describe('<Item/>', () => { + it('Renders and matches snapshot', () => { + const wrapper = shallow(<ItemComponent item={fakeItem} />); + expect(toJSON(wrapper)).toMatchSnapshot(); + }); +}); diff --git a/finished-application/frontend/__tests__/Nav.test.js b/finished-application/frontend/__tests__/Nav.test.js new file mode 100644 index 0000000..5c61c56 --- /dev/null +++ b/finished-application/frontend/__tests__/Nav.test.js @@ -0,0 +1,66 @@ +import React from 'react'; +import { mount } from 'enzyme'; +import toJSON from 'enzyme-to-json'; +import wait from 'waait'; +import Router from 'next/router'; +import Nav from '../components/Nav'; +import { MockedProvider } from 'react-apollo/test-utils'; +import { fakeUser } from '../lib/testUtils'; +import { CURRENT_USER_QUERY } from '../components/User'; + +// Mock the router +Router.router = { push() {} }; + +const loggedOutMocks = [ + { + request: { query: CURRENT_USER_QUERY }, + delay: 0, + result: { + data: { + me: null, + }, + }, + }, +]; + +const loggedInMocks = [ + { + request: { query: CURRENT_USER_QUERY }, + result: { + data: { + what: 'yah', + me: { + ...fakeUser(), + orders: [], + cart: [], + }, + }, + }, + }, +]; + +describe('<Nav></Nav>', () => { + it('Renders minimal nav when logged out', () => { + const wrapper = mount( + <MockedProvider mocks={loggedOutMocks}> + <Nav /> + </MockedProvider> + ); + const nav = wrapper.find('ul[data-test="nav"]'); + expect(toJSON(nav)).toMatchSnapshot(); + }); + + it('renders full nav when logged in', async () => { + const wrapper = mount( + <MockedProvider mocks={loggedInMocks}> + <Nav /> + </MockedProvider> + ); + await wait(); + wrapper.update(); + const nav = wrapper.find('ul[data-test="nav"]'); + // account link + const accountLink = wrapper.find('a[href="/me"]'); + expect(accountLink.length).toBe(1); + }); +}); diff --git a/finished-application/frontend/__tests__/Order.test.js b/finished-application/frontend/__tests__/Order.test.js new file mode 100644 index 0000000..f3a4f06 --- /dev/null +++ b/finished-application/frontend/__tests__/Order.test.js @@ -0,0 +1,41 @@ +import React from 'react'; +import { mount } from 'enzyme'; +import toJSON from 'enzyme-to-json'; +import wait from 'waait'; +import { MockedProvider } from 'react-apollo/test-utils'; +import Order, { SINGLE_ORDER_QUERY } from '../components/Order'; +import { fakeOrder } from '../lib/testUtils'; + +const mocks = [ + { + request: { query: SINGLE_ORDER_QUERY, variables: { id: '123' } }, + result: { + data: { + order: fakeOrder(), + }, + }, + }, +]; + +describe('<Order/>', () => { + it('Renders loading state', async () => { + const wrapper = mount( + <MockedProvider mocks={mocks}> + <Order id="123" /> + </MockedProvider> + ); + expect(wrapper.text()).toContain('Loading...'); + }); + + it('Renders the order', async () => { + const wrapper = mount( + <MockedProvider mocks={mocks}> + <Order id="123" /> + </MockedProvider> + ); + await wait(50); + wrapper.update(); + const order = wrapper.find('div[data-test="order"]'); + expect(toJSON(order)).toMatchSnapshot(); + }); +}); diff --git a/finished-application/frontend/__tests__/Pagination.test.js b/finished-application/frontend/__tests__/Pagination.test.js new file mode 100644 index 0000000..29a57f9 --- /dev/null +++ b/finished-application/frontend/__tests__/Pagination.test.js @@ -0,0 +1,94 @@ +import React from 'react'; +import { shallow, mount } from 'enzyme'; +import toJSON from 'enzyme-to-json'; +import Pagination, { PAGINATION_QUERY } from '../components/Pagination'; +import { MockedProvider } from 'react-apollo/test-utils'; +import wait from 'waait'; +import { fakeItem } from '../lib/testUtils'; + +import Router from 'next/router'; + +// mock the router because there isn't really a router instance +Router.router = { push() {}, prefetch() {} }; + +function makeMocksFor(length) { + return [ + { + request: { query: PAGINATION_QUERY, variables: { skip: 0, first: 4 } }, + result: { + data: { + itemsConnection: { + __typename: 'aggregate', + aggregate: { + count: length, + __typename: 'count', + }, + }, + }, + }, + }, + ]; +} + +describe('<Pagination/>', () => { + it('displays loading message', async () => { + const wrapper = mount( + <MockedProvider mocks={makeMocksFor(1)}> + <Pagination page={1} /> + </MockedProvider> + ); + await wait(); + wrapper.update(); + expect(toJSON(wrapper.find('div[data-test="pagination"]'))).toMatchSnapshot(); + }); + + it('renders pagination for 18 items', async () => { + const wrapper = mount( + <MockedProvider mocks={makeMocksFor(18)}> + <Pagination page={1} /> + </MockedProvider> + ); + await wait(); + wrapper.update(); + expect(wrapper.find('.totalPages').text()).toEqual('5'); + }); + + it('disables prev button on first page', async () => { + const wrapper = mount( + <MockedProvider mocks={makeMocksFor(18)}> + <Pagination page={1} /> + </MockedProvider> + ); + await wait(); + wrapper.update(); + // first page + expect(wrapper.find('a.prev').prop('aria-disabled')).toEqual(true); + expect(wrapper.find('a.next').prop('aria-disabled')).toEqual(false); + }); + + it('disables next button on last page', async () => { + const wrapper = mount( + <MockedProvider mocks={makeMocksFor(18)}> + <Pagination page={5} /> + </MockedProvider> + ); + await wait(); + wrapper.update(); + // first page + expect(wrapper.find('a.prev').prop('aria-disabled')).toEqual(false); + expect(wrapper.find('a.next').prop('aria-disabled')).toEqual(true); + }); + + it('enables all buttons on a middle page', async () => { + const wrapper = mount( + <MockedProvider mocks={makeMocksFor(18)}> + <Pagination page={2} /> + </MockedProvider> + ); + await wait(); + wrapper.update(); + // first page + expect(wrapper.find('a.prev').prop('aria-disabled')).toEqual(false); + expect(wrapper.find('a.next').prop('aria-disabled')).toEqual(false); + }); +}); diff --git a/finished-application/frontend/__tests__/PleaseSignIn.test.js b/finished-application/frontend/__tests__/PleaseSignIn.test.js new file mode 100644 index 0000000..f516ea3 --- /dev/null +++ b/finished-application/frontend/__tests__/PleaseSignIn.test.js @@ -0,0 +1,80 @@ +import React from 'react'; +import { mount } from 'enzyme'; +import wait from 'waait'; +import PleaseSignIn from '../components/PleaseSignIn'; +import { MockedProvider } from 'react-apollo/test-utils'; +import { fakeUser } from '../lib/testUtils'; +import { CURRENT_USER_QUERY } from '../components/User'; + +const notSignedInMocks = [ + { + request: { query: CURRENT_USER_QUERY }, + result: { + data: { + me: null, + }, + }, + }, +]; + +const signedInMocks = [ + { + request: { query: CURRENT_USER_QUERY }, + result: { + data: { + me: { + ...fakeUser(), + permissions: ['VIEW_HEY'], + }, + }, + }, + }, +]; +// some dummy child component +const Hey = () => <p>Hey!</p>; + +describe('<PleaseSignIn />', () => { + it('renders sign in dialog to logged out users', async () => { + const wrapper = mount( + <MockedProvider mocks={notSignedInMocks}> + <PleaseSignIn allowedPermissions={[]}> + <Hey /> + </PleaseSignIn> + </MockedProvider> + ); + await wait(); + wrapper.update(); + // find the error message + expect(wrapper.text()).toContain('Please sign in before continuing!'); + // show the sign in dialog + expect(wrapper.find('Signin').exists()).toBeTruthy(); + }); + + it('renders child for correct permissions', async () => { + const wrapper = mount( + <MockedProvider mocks={signedInMocks}> + <PleaseSignIn allowedPermissions={['ADMIN', 'VIEW_HEY']}> + <Hey /> + </PleaseSignIn> + </MockedProvider> + ); + await wait(); + wrapper.update(); + expect(wrapper.find('Hey').exists()).toBeTruthy(); + }); + it("renders error when permissions aren't met", async () => { + const wrapper = mount( + <MockedProvider mocks={signedInMocks}> + <PleaseSignIn allowedPermissions={['ADMIN']}> + <Hey /> + </PleaseSignIn> + </MockedProvider> + ); + await wait(); + wrapper.update(); + // should tell you you can't access it + expect(wrapper.text()).toContain('Insufficient Permissions'); + // it should not render the child component + expect(wrapper.find('Hey').exists()).toBeFalsy(); + }); +}); diff --git a/finished-application/frontend/__tests__/RemoveFromCart.test.js b/finished-application/frontend/__tests__/RemoveFromCart.test.js new file mode 100644 index 0000000..34229a5 --- /dev/null +++ b/finished-application/frontend/__tests__/RemoveFromCart.test.js @@ -0,0 +1,78 @@ +import React from 'react'; +import { mount } from 'enzyme'; +import toJSON from 'enzyme-to-json'; +import { ApolloConsumer } from 'react-apollo'; +import { MockedProvider } from 'react-apollo/test-utils'; +import wait from 'waait'; +import RemoveFromCart, { REMOVE_FROM_CART_MUTATION } from '../components/RemoveFromCart'; +import { fakeCartItem, fakeUser } from '../lib/testUtils'; +import { CURRENT_USER_QUERY } from '../components/User'; + +const mocks = [ + { + request: { query: CURRENT_USER_QUERY }, + result: { + data: { + me: { + ...fakeUser(), + cart: [fakeCartItem({ id: 'abc123' })], + orders: [], + }, + }, + }, + }, + { + request: { + // This is the mutation + query: REMOVE_FROM_CART_MUTATION, + variables: { id: 'abc123' }, + }, + result: { + data: { + removeFromCart: { + __typename: 'CartItem', + id: 'abc123', + }, + }, + }, + }, +]; + +describe('<RemoveFromCart/>', () => { + it('renders and matches snapshot', () => { + const wrapper = mount( + <MockedProvider mocks={mocks}> + <RemoveFromCart id="abc123" /> + </MockedProvider> + ); + expect(toJSON(wrapper.find('button'))).toMatchSnapshot(); + }); + + it('removes an item from the cart', async () => { + // 1. Grab a copy of the current client + let apolloClient; + // const wrapper = mountWithApollo(<RemoveFromCart id="abc123" />); + const wrapper = mount( + <MockedProvider mocks={mocks}> + <ApolloConsumer> + {client => { + apolloClient = client; + return <RemoveFromCart id="abc123" />; + }} + </ApolloConsumer> + </MockedProvider> + ); + // Fire Off that first mock + await apolloClient.query({ query: CURRENT_USER_QUERY }); + // check if it worked + const { me } = apolloClient.readQuery({ query: CURRENT_USER_QUERY }); + expect(me.cart).toHaveLength(1); + expect(me.cart[0].item.price).toBe(5000); + + // simulate a click, which will fire REMOVE_FROM_CART mock + wrapper.find('button').simulate('click'); + await wait(); + const { me: me2 } = apolloClient.readQuery({ query: CURRENT_USER_QUERY }); + expect(me2.cart).toHaveLength(0); + }); +}); diff --git a/finished-application/frontend/__tests__/ResetRequest.test.js b/finished-application/frontend/__tests__/ResetRequest.test.js new file mode 100644 index 0000000..22a9508 --- /dev/null +++ b/finished-application/frontend/__tests__/ResetRequest.test.js @@ -0,0 +1,54 @@ +import { mount } from 'enzyme'; +import toJSON from 'enzyme-to-json'; +import { MockedProvider } from 'react-apollo/test-utils'; +import wait from 'waait'; +import ResetRequest, { REQUEST_RESET_MUTATION } from '../components/ResetRequest'; + +const mocks = [ + { + request: { + query: REQUEST_RESET_MUTATION, + variables: { + email: 'wesbos@gmail.com', + }, + }, + result: { + data: { + requestReset: { id: 'abc123', __typename: 'User' }, + }, + }, + }, +]; + +describe('<ResetRequest/>', () => { + it('renders and matches snapshot', async () => { + const wrapper = mount( + <MockedProvider> + <ResetRequest /> + </MockedProvider> + ); + const form = wrapper.find("form[data-test='ResetRequest']"); + expect(toJSON(form)).toMatchSnapshot(); + }); + + it('calls the mutation', async () => { + const wrapper = mount( + <MockedProvider mocks={mocks}> + <ResetRequest /> + </MockedProvider> + ); + + wrapper.find('input').simulate('change', { + target: { value: 'wesbos@gmail.com' }, + }); + + // submit the form + const form = wrapper.find('form'); + console.log(form); + form.simulate('submit'); + + await wait(); + wrapper.update(); + expect(wrapper.find('p').text()).toContain('Success! Check Your Email!'); + }); +}); diff --git a/finished-application/frontend/__tests__/Signup.test.js b/finished-application/frontend/__tests__/Signup.test.js new file mode 100644 index 0000000..2a668a6 --- /dev/null +++ b/finished-application/frontend/__tests__/Signup.test.js @@ -0,0 +1,91 @@ +import React from 'react'; +import { mount } from 'enzyme'; +import toJSON from 'enzyme-to-json'; +import wait from 'waait'; +import { ApolloConsumer } from 'react-apollo'; +import { MockedProvider } from 'react-apollo/test-utils'; +import Signup, { SIGNUP_MUTATION } from '../components/Signup'; +import { fakeUser } from '../lib/testUtils'; +import { CURRENT_USER_QUERY } from '../components/User'; + +function type(wrapper, name, value) { + wrapper.find(`input[name="${name}"]`).simulate('change', { + target: { + name, + value, + }, + }); +} +const me = fakeUser(); +const mocks = [ + { + request: { + query: SIGNUP_MUTATION, + variables: { + email: me.email, + name: me.name, + password: 'wes', + }, + }, + result: { + data: { + signup: { + __typename: 'User', + id: 'abc123', + email: me.email, + name: me.name, + }, + }, + }, + }, + { + request: { query: CURRENT_USER_QUERY }, + result: { + data: { + me: { + __typename: 'User', + ...me, + cart: [], + }, + }, + }, + }, +]; + +describe('<Signup/>', () => { + it('renders and matches snapshot', () => { + const wrapper = mount( + <MockedProvider> + <Signup /> + </MockedProvider> + ); + expect(toJSON(wrapper.find('form'))).toMatchSnapshot(); + }); + + it('calls mutation with correct data', 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'); + + const user = await apolloClient.query({ query: CURRENT_USER_QUERY }); + expect(user.data.me).toMatchObject(me); + }); +}); diff --git a/finished-application/frontend/__tests__/SingleItem.test.js b/finished-application/frontend/__tests__/SingleItem.test.js new file mode 100644 index 0000000..aeb8554 --- /dev/null +++ b/finished-application/frontend/__tests__/SingleItem.test.js @@ -0,0 +1,67 @@ +import React from 'react'; +import { mount } from 'enzyme'; +import wait from 'waait'; +import toJSON from 'enzyme-to-json'; +import SingleItem, { SINGLE_ITEM_QUERY } from '../components/SingleItem'; +import { MockedProvider } from 'react-apollo/test-utils'; +import { fakeItem, fakeUser } from '../lib/testUtils'; +import { CURRENT_USER_QUERY } from '../components/User'; + +const data = { + items: [fakeItem()], +}; + +describe('<SingleItem/>', () => { + it('Renders with Proper Data', async () => { + const mocks = [ + { + request: { query: SINGLE_ITEM_QUERY, variables: { id: '123' } }, + result: { data }, + }, + { + request: { query: CURRENT_USER_QUERY }, + result: { data: { me: fakeUser() } }, + }, + ]; + const wrapper = mount( + <MockedProvider mocks={mocks}> + <SingleItem id="123" /> + </MockedProvider> + ); + // Check for loading state + expect(wrapper.text()).toContain('Loading...'); + + // wait for response and refresh + await wait(55); + wrapper.update(); + // Grab the piece we want + expect(toJSON(wrapper.find('h2'))).toMatchSnapshot(); + expect(toJSON(wrapper.find('img'))).toMatchSnapshot(); + expect(toJSON(wrapper.find('p'))).toMatchSnapshot(); + }); + + it('Errors with a not found Item', async () => { + const mocks = [ + { + request: { query: SINGLE_ITEM_QUERY, variables: { id: '123' } }, + delay: 50, + // we can return data and an error + result: { data, errors: [{ message: 'Item not found!' }] }, + // or just an error! + // error: new Error('offline!'), + }, + ]; + const wrapper = mount( + <MockedProvider mocks={mocks}> + <SingleItem id="123" /> + </MockedProvider> + ); + + // wait for response + await wait(55); + wrapper.update(); + + const Item = wrapper.find('[data-test="graphql-error"]'); + expect(toJSON(Item)).toMatchSnapshot(); + }); +}); diff --git a/finished-application/frontend/__tests__/TakeMyMoney.test.js b/finished-application/frontend/__tests__/TakeMyMoney.test.js new file mode 100644 index 0000000..1c41410 --- /dev/null +++ b/finished-application/frontend/__tests__/TakeMyMoney.test.js @@ -0,0 +1,98 @@ +import { mount } from 'enzyme'; +import toJSON from 'enzyme-to-json'; +import NProgress from 'nprogress'; +import Router from 'next/router'; +import wait from 'waait'; +import { MockedProvider } from 'react-apollo/test-utils'; +import TakeMyMoney from '../components/TakeMyMoney'; +import { fakeUser, fakeCartItem } from '../lib/testUtils'; +import { CURRENT_USER_QUERY } from '../components/User'; + +Router.router = { push() {} }; + +const mocks = [ + { + request: { query: CURRENT_USER_QUERY }, + result: { + data: { + me: { + ...fakeUser(), + cart: [fakeCartItem()], + }, + }, + }, + }, +]; +describe('<TakeMyMoney />', () => { + it('renders', async () => { + const wrapper = mount( + <MockedProvider mocks={mocks}> + <TakeMyMoney /> + </MockedProvider> + ); + // wait for it to load + await wait(); + wrapper.update(); + // find the button + const checkoutButton = wrapper.find('ReactStripeCheckout'); + expect(toJSON(checkoutButton)).toMatchSnapshot(); + }); + + it('creates an order onToken', async () => { + const createOrderSpy = jest.fn().mockResolvedValue({ data: { createOrder: { id: 'xyz789' } } }); + + const wrapper = mount( + <MockedProvider mocks={mocks}> + <TakeMyMoney /> + </MockedProvider> + ); + const component = wrapper.find('TakeMyMoney'); + component.instance().onToken({ id: 'abc123' }, createOrderSpy); + // check it + expect(createOrderSpy).toBeCalled(); + expect(createOrderSpy).toBeCalledWith({ variables: { token: 'abc123' } }); + }); + + it('turns the progress bar on', async () => { + const wrapper = mount( + <MockedProvider mocks={mocks}> + <TakeMyMoney /> + </MockedProvider> + ); + await wait(); + wrapper.update(); + NProgress.start = jest.fn(); + + const createOrderSpy = jest.fn().mockResolvedValue({ data: { createOrder: { id: 'xyz789' } } }); + const component = wrapper.find('TakeMyMoney'); + component.instance().onToken({ id: 'abc123' }, createOrderSpy); + wrapper.find('button').simulate('click'); + expect(NProgress.start).toHaveBeenCalled(); + }); + + it('routes to the order page when completed', async () => { + // Mount the wrapper + const wrapper = mount( + <MockedProvider mocks={mocks}> + <TakeMyMoney /> + </MockedProvider> + ); + await wait(); + wrapper.update(); + + // Spy on Router Push + Router.router.push = jest.fn(); + const createOrderSpy = jest.fn().mockResolvedValue({ data: { createOrder: { id: 'xyz789' } } }); + + const component = wrapper.find('TakeMyMoney'); + component.instance().onToken({ id: 'abc123' }, createOrderSpy); + + // submit the form + wrapper.find('button').simulate('click'); + await wait(); + expect(Router.router.push).toHaveBeenCalledWith({ + pathname: '/order', + query: { id: 'xyz789' }, + }); + }); +}); diff --git a/finished-application/frontend/__tests__/__snapshots__/AddToCart.test.js.snap b/finished-application/frontend/__tests__/__snapshots__/AddToCart.test.js.snap new file mode 100644 index 0000000..e3f8229 --- /dev/null +++ b/finished-application/frontend/__tests__/__snapshots__/AddToCart.test.js.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`<AddtoCart/> renders and matches snapshot 1`] = ` +<button + disabled={false} + onClick={[Function]} +> + π Add + To Cart +</button> +`; diff --git a/finished-application/frontend/__tests__/__snapshots__/Cart.test.js.snap b/finished-application/frontend/__tests__/__snapshots__/Cart.test.js.snap new file mode 100644 index 0000000..9aeedfd --- /dev/null +++ b/finished-application/frontend/__tests__/__snapshots__/Cart.test.js.snap @@ -0,0 +1,32 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`<Cart/> renders 1`] = ` +<header> + <styled.button + onClick={[Function]} + title="close" + > + <button + className="sc-EHOje jytiuo" + onClick={[Function]} + title="close" + > + Γ + </button> + </styled.button> + <styled.h3> + <h3 + className="sc-ifAKCX imryuh" + > + Miss Coleman Berge + 's Cart. + </h3> + </styled.h3> + <p> + You have + 1 + item + in your cart. + </p> +</header> +`; diff --git a/finished-application/frontend/__tests__/__snapshots__/CartCount.test.js.snap b/finished-application/frontend/__tests__/__snapshots__/CartCount.test.js.snap new file mode 100644 index 0000000..224141b --- /dev/null +++ b/finished-application/frontend/__tests__/__snapshots__/CartCount.test.js.snap @@ -0,0 +1,205 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`<CartCount></CartCount> matches snapshot 1`] = ` +<styled.span> + <TransitionGroup + childFactory={[Function]} + component="div" + > + <CSSTransition + className="count" + classNames="count" + key="10" + timeout={ + Object { + "enter": 400, + "exit": 400, + } + } + unmountOnExit={true} + > + <styled.div> + 10 + </styled.div> + </CSSTransition> + </TransitionGroup> +</styled.span> +`; + +exports[`<CartCount></CartCount> updates via props 1`] = ` +<CartCount + count={50} +> + <styled.span> + <span + className="sc-bwzfXH fWZfOZ" + > + <TransitionGroup + childFactory={[Function]} + component="div" + > + <div> + <CSSTransition + className="count" + classNames="count" + in={true} + key=".$50" + onExited={[Function]} + timeout={ + Object { + "enter": 400, + "exit": 400, + } + } + unmountOnExit={true} + > + <Transition + appear={false} + className="count" + enter={true} + exit={true} + in={true} + mountOnEnter={false} + onEnter={[Function]} + onEntered={[Function]} + onEntering={[Function]} + onExit={[Function]} + onExited={[Function]} + onExiting={[Function]} + timeout={ + Object { + "enter": 400, + "exit": 400, + } + } + unmountOnExit={true} + > + <styled.div + className="count" + > + <div + className="count sc-bdVaJa ldHGxH" + > + 50 + </div> + </styled.div> + </Transition> + </CSSTransition> + </div> + </TransitionGroup> + </span> + </styled.span> +</CartCount> +`; + +exports[`<CartCount></CartCount> updates via props 2`] = ` +<CartCount + count={10} +> + <styled.span> + <span + className="sc-bwzfXH fWZfOZ" + > + <TransitionGroup + childFactory={[Function]} + component="div" + > + <div> + <CSSTransition + className="count" + classNames="count" + in={true} + key=".$10" + onExited={[Function]} + timeout={ + Object { + "enter": 400, + "exit": 400, + } + } + unmountOnExit={true} + > + <Transition + appear={false} + className="count" + enter={true} + exit={true} + in={true} + mountOnEnter={false} + onEnter={[Function]} + onEntered={[Function]} + onEntering={[Function]} + onExit={[Function]} + onExited={[Function]} + onExiting={[Function]} + timeout={ + Object { + "enter": 400, + "exit": 400, + } + } + unmountOnExit={true} + > + <styled.div + className="count" + > + <div + className="count sc-bdVaJa ldHGxH" + > + 10 + </div> + </styled.div> + </Transition> + </CSSTransition> + <CSSTransition + className="count" + classNames="count" + in={false} + key=".$50" + onExited={[Function]} + timeout={ + Object { + "enter": 400, + "exit": 400, + } + } + unmountOnExit={true} + > + <Transition + appear={false} + className="count" + enter={true} + exit={true} + in={false} + mountOnEnter={false} + onEnter={[Function]} + onEntered={[Function]} + onEntering={[Function]} + onExit={[Function]} + onExited={[Function]} + onExiting={[Function]} + timeout={ + Object { + "enter": 400, + "exit": 400, + } + } + unmountOnExit={true} + > + <styled.div + className="count" + > + <div + className="count sc-bdVaJa ldHGxH" + > + 50 + </div> + </styled.div> + </Transition> + </CSSTransition> + </div> + </TransitionGroup> + </span> + </styled.span> +</CartCount> +`; diff --git a/finished-application/frontend/__tests__/__snapshots__/CartItem.test.js.snap b/finished-application/frontend/__tests__/__snapshots__/CartItem.test.js.snap new file mode 100644 index 0000000..b8f5ad3 --- /dev/null +++ b/finished-application/frontend/__tests__/__snapshots__/CartItem.test.js.snap @@ -0,0 +1,33 @@ +// 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> + <RemoveFromCart + id="abc123" + /> +</styled.li> +`; diff --git a/finished-application/frontend/__tests__/__snapshots__/CreateItem.test.js.snap b/finished-application/frontend/__tests__/__snapshots__/CreateItem.test.js.snap new file mode 100644 index 0000000..89dbcd2 --- /dev/null +++ b/finished-application/frontend/__tests__/__snapshots__/CreateItem.test.js.snap @@ -0,0 +1,75 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`<Createitem/> renders and matches snapshot 1`] = ` +<form + className="sc-bwzfXH ikCwBB" + data-test={true} + onSubmit={[Function]} +> + <h2> + Sell an Item. + </h2> + <DisplayError + error={Object {}} + /> + <fieldset + aria-busy={false} + disabled={false} + > + <label + htmlFor="file" + > + Image + <input + accept=".png, .jpg, .jpeg" + id="file" + onChange={[Function]} + required={true} + type="file" + /> + </label> + <label + htmlFor="title" + > + Title + <input + id="title" + name="title" + onChange={[Function]} + placeholder="Title" + required={true} + type="text" + value="" + /> + </label> + <label + htmlFor="price" + > + Price + 0 + <input + id="price" + min="0" + name="price" + onChange={[Function]} + required={true} + type="number" + value={0} + /> + </label> + <textarea + id="description" + name="description" + onChange={[Function]} + placeholder="The desc for this item" + required={true} + value="" + /> + <button + type="submit" + > + Submit + </button> + </fieldset> +</form> +`; diff --git a/finished-application/frontend/__tests__/__snapshots__/EditUser.test.js.snap b/finished-application/frontend/__tests__/__snapshots__/EditUser.test.js.snap new file mode 100644 index 0000000..bbb672d --- /dev/null +++ b/finished-application/frontend/__tests__/__snapshots__/EditUser.test.js.snap @@ -0,0 +1,47 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`<EditUser/> renders 1`] = ` +<form + className="sc-bdVaJa LHejR" + onSubmit={[Function]} +> + <DisplayError + error={Object {}} + /> + <fieldset + aria-busy={false} + disabled={false} + > + <label + htmlFor="name" + > + Name: + <input + defaultValue="Miss Coleman Berge" + name="name" + onChange={[Function]} + type="text" + /> + </label> + <button + type="submit" + > + Update + </button> + <strong> + me: + </strong> + <pre> + "Miss Coleman Berge" + </pre> + <strong> + Change: + </strong> + <pre + data-test="change" + > + {} + </pre> + </fieldset> +</form> +`; diff --git a/finished-application/frontend/__tests__/__snapshots__/Item.test.js.snap b/finished-application/frontend/__tests__/__snapshots__/Item.test.js.snap new file mode 100644 index 0000000..930c7a9 --- /dev/null +++ b/finished-application/frontend/__tests__/__snapshots__/Item.test.js.snap @@ -0,0 +1,58 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`<Item/> Renders and matches snapshot 1`] = ` +<styled.div + key="ABC123" +> + <img + alt="A Cool Item" + src="dog.jpg" + /> + <styled.h3> + <Link + href={ + Object { + "pathname": "/item", + "query": Object { + "id": "ABC123", + }, + } + } + > + <a> + A Cool Item + </a> + </Link> + </styled.h3> + <styled.span> + $50 + </styled.span> + <p> + This item is really cool! + </p> + <div + className="buttonList" + > + <Link + href={ + Object { + "pathname": "/update", + "query": Object { + "id": "ABC123", + }, + } + } + > + <a> + Edit βοΈ + </a> + </Link> + <AddToCart + id="ABC123" + /> + <DeleteItem + id="ABC123" + /> + </div> +</styled.div> +`; diff --git a/finished-application/frontend/__tests__/__snapshots__/Nav.test.js.snap b/finished-application/frontend/__tests__/__snapshots__/Nav.test.js.snap new file mode 100644 index 0000000..354fbc1 --- /dev/null +++ b/finished-application/frontend/__tests__/__snapshots__/Nav.test.js.snap @@ -0,0 +1,39 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`<Nav></Nav> Renders minimal nav when logged out 1`] = ` +<ul + className="sc-dnqmqq kxZizK" + data-test="nav" +> + <Link + href="/items" + > + <a + href="/items" + onClick={[Function]} + > + Shop + </a> + </Link> + <Link + href="/sell" + > + <a + href="/sell" + onClick={[Function]} + > + Sell + </a> + </Link> + <Link + href="/signup" + > + <a + href="/signup" + onClick={[Function]} + > + Sign In + </a> + </Link> +</ul> +`; diff --git a/finished-application/frontend/__tests__/__snapshots__/Order.test.js.snap b/finished-application/frontend/__tests__/__snapshots__/Order.test.js.snap new file mode 100644 index 0000000..8e76546 --- /dev/null +++ b/finished-application/frontend/__tests__/__snapshots__/Order.test.js.snap @@ -0,0 +1,130 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`<Order/> Renders the order 1`] = ` +<div + className="sc-bwzfXH wJijb" + data-test="order" +> + <SideEffect(Head)> + <Head /> + </SideEffect(Head)> + <p> + <span> + Order Id: + </span> + <span> + ord123 + </span> + </p> + <p> + <span> + Charge + </span> + <span> + ch_123 + </span> + </p> + <p> + <span> + Date + </span> + <span> + March 90, 2018 8:00 A + </span> + </p> + <p> + <span> + Order Total + </span> + <span> + $400 + </span> + </p> + <p> + <span> + Item Count + </span> + <span> + 2 + </span> + </p> + <div + className="items" + > + <div + className="order-item" + key="3a430a73-c9e9-4bcc-b46a-41618965ffea" + > + <img + alt="soluta non omnis consequatur enim quia autem" + src="reprehenderit.jpg" + /> + <div + className="item-details" + > + <h2> + + soluta non omnis consequatur enim quia autem + + </h2> + <p> + Qty: + 1 + </p> + <p> + Each: + $42.34 + </p> + <p> + Subtotal: + $42.34 + </p> + <p> + SubTotal: + et modi tenetur amet modi reprehenderit omnis + </p> + <p> + et modi tenetur amet modi reprehenderit omnis + </p> + </div> + </div> + <div + className="order-item" + key="2393e090-592f-4d03-b808-c9d81098deec" + > + <img + alt="quia sed exercitationem omnis laborum exercitationem est" + src="sint.jpg" + /> + <div + className="item-details" + > + <h2> + + quia sed exercitationem omnis laborum exercitationem est + + </h2> + <p> + Qty: + 1 + </p> + <p> + Each: + $42.34 + </p> + <p> + Subtotal: + $42.34 + </p> + <p> + SubTotal: + sapiente laudantium molestias assumenda quasi adipisci mollitia + </p> + <p> + sapiente laudantium molestias assumenda quasi adipisci mollitia + </p> + </div> + </div> + </div> +</div> +`; diff --git a/finished-application/frontend/__tests__/__snapshots__/Pagination.test.js.snap b/finished-application/frontend/__tests__/__snapshots__/Pagination.test.js.snap new file mode 100644 index 0000000..c757968 --- /dev/null +++ b/finished-application/frontend/__tests__/__snapshots__/Pagination.test.js.snap @@ -0,0 +1,71 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`<Pagination/> displays loading message 1`] = ` +<div + className="sc-bdVaJa ijYKGd" + data-test="pagination" +> + <SideEffect(Head)> + <Head /> + </SideEffect(Head)> + <Link + href={ + Object { + "pathname": "items", + "query": Object { + "page": 0, + }, + } + } + prefetch={true} + > + <a + aria-disabled={true} + className="prev" + href="items?page=0" + onClick={[Function]} + > + βPrev + </a> + </Link> + <p> + Page + <strong> + 1 + + </strong> + of + <strong + className="totalPages" + > + 1 + </strong> + </p> + <p> + <strong> + 1 + </strong> + Items Total + </p> + <Link + href={ + Object { + "pathname": "items", + "query": Object { + "page": 2, + }, + } + } + prefetch={true} + > + <a + aria-disabled={true} + className="next" + href="items?page=2" + onClick={[Function]} + > + Next β + </a> + </Link> +</div> +`; diff --git a/finished-application/frontend/__tests__/__snapshots__/RemoveFromCart.test.js.snap b/finished-application/frontend/__tests__/__snapshots__/RemoveFromCart.test.js.snap new file mode 100644 index 0000000..a80b678 --- /dev/null +++ b/finished-application/frontend/__tests__/__snapshots__/RemoveFromCart.test.js.snap @@ -0,0 +1,12 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`<RemoveFromCart/> renders and matches snapshot 1`] = ` +<button + className="sc-bdVaJa fXnNqM" + disabled={false} + onClick={[Function]} + title="Remove From Cart" +> + Γ +</button> +`; diff --git a/finished-application/frontend/__tests__/__snapshots__/ResetRequest.test.js.snap b/finished-application/frontend/__tests__/__snapshots__/ResetRequest.test.js.snap new file mode 100644 index 0000000..a6a0375 --- /dev/null +++ b/finished-application/frontend/__tests__/__snapshots__/ResetRequest.test.js.snap @@ -0,0 +1,35 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`<ResetRequest/> renders and matches snapshot 1`] = ` +<form + className="sc-bdVaJa LHejR" + data-test="ResetRequest" + onSubmit={[Function]} +> + <DisplayError + error={Object {}} + /> + <fieldset + aria-busy={false} + disabled={false} + > + <label + htmlFor="email" + > + Email + <input + name="email" + onChange={[Function]} + placeholder="email" + type="text" + value="" + /> + </label> + <button + type="submit" + > + Request Reset! + </button> + </fieldset> +</form> +`; diff --git a/finished-application/frontend/__tests__/__snapshots__/Signup.test.js.snap b/finished-application/frontend/__tests__/__snapshots__/Signup.test.js.snap new file mode 100644 index 0000000..b3c057e --- /dev/null +++ b/finished-application/frontend/__tests__/__snapshots__/Signup.test.js.snap @@ -0,0 +1,64 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`<Signup/> renders and matches snapshot 1`] = ` +<form + className="sc-bdVaJa LHejR" + method="post" + onSubmit={[Function]} +> + <fieldset + aria-busy={false} + disabled={false} + > + <DisplayError + error={Object {}} + /> + <h2> + Sign Up for an Account + </h2> + <label + htmlFor="email" + > + Email + <input + name="email" + onChange={[Function]} + placeholder="email" + type="text" + value="" + /> + </label> + <label + htmlFor="name" + > + Name + <input + name="name" + onChange={[Function]} + placeholder="name" + type="text" + value="" + /> + </label> + <label + htmlFor="signupPassword" + > + Password + <input + className="password" + id="signupPassword" + name="password" + onChange={[Function]} + placeholder="password" + type="password" + value="" + /> + </label> + <button + type="submit" + > + Submit + </button> + </fieldset> +</form> +`; diff --git a/finished-application/frontend/__tests__/__snapshots__/SingleItem.test.js.snap b/finished-application/frontend/__tests__/__snapshots__/SingleItem.test.js.snap new file mode 100644 index 0000000..28e9174 --- /dev/null +++ b/finished-application/frontend/__tests__/__snapshots__/SingleItem.test.js.snap @@ -0,0 +1,32 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`<SingleItem/> Errors with a not found Item 1`] = ` +<p + data-test="graphql-error" +> + <strong> + Shoot! + </strong> + Item not found! +</p> +`; + +exports[`<SingleItem/> Renders with Proper Data 1`] = ` +<h2> + Viewing + dogs are best +</h2> +`; + +exports[`<SingleItem/> Renders with Proper Data 2`] = ` +<img + alt="dogs are best" + src="dog.jpg" +/> +`; + +exports[`<SingleItem/> Renders with Proper Data 3`] = ` +<p> + dogs +</p> +`; diff --git a/finished-application/frontend/__tests__/__snapshots__/TakeMyMoney.test.js.snap b/finished-application/frontend/__tests__/__snapshots__/TakeMyMoney.test.js.snap new file mode 100644 index 0000000..00863d3 --- /dev/null +++ b/finished-application/frontend/__tests__/__snapshots__/TakeMyMoney.test.js.snap @@ -0,0 +1,67 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`<TakeMyMoney /> renders 1`] = ` +<ReactStripeCheckout + ComponentClass="span" + amount={15000} + className="StripeCheckout" + currency="USD" + description="Order of 3 Items From Sick Fits" + email="Delmer.Smith@yahoo.com" + image="dog-small.jpg" + label="Pay With Card" + locale="auto" + name="Sick Fits Haul" + reconfigureOnUpdate={false} + stripeKey="pk_lclTtThFp8CnO3QtEZSd8HA9mFUps" + token={[Function]} + triggerEvent="onClick" +> + <button + className="StripeCheckout" + onBlur={[Function]} + onClick={[Function]} + onFocus={[Function]} + onMouseDown={[Function]} + onMouseOut={[Function]} + onMouseUp={[Function]} + style={ + Object { + "background": "linear-gradient(#28a0e5,#015e94)", + "border": 0, + "borderRadius": 5, + "boxShadow": "0 1px 0 rgba(0,0,0,0.2)", + "cursor": "pointer", + "display": "inline-block", + "overflow": "hidden", + "padding": 1, + "textDecoration": "none", + "userSelect": "none", + "visibility": "visible", + } + } + > + <span + style={ + Object { + "backgroundImage": "linear-gradient(#7dc5ee,#008cdd 85%,#30a2e4)", + "borderRadius": 4, + "boxShadow": "inset 0 1px 0 rgba(255,255,255,0.25)", + "color": "#fff", + "display": "block", + "fontFamily": "\\"Helvetica Neue\\",Helvetica,Arial,sans-serif", + "fontSize": 14, + "fontWeight": "bold", + "height": 30, + "lineHeight": "30px", + "padding": "0 12px", + "position": "relative", + "textShadow": "0 -1px 0 rgba(0,0,0,0.25)", + } + } + > + Pay With Card + </span> + </button> +</ReactStripeCheckout> +`; diff --git a/finished-application/frontend/__tests__/formatMoney.test.js b/finished-application/frontend/__tests__/formatMoney.test.js new file mode 100644 index 0000000..c5c79b6 --- /dev/null +++ b/finished-application/frontend/__tests__/formatMoney.test.js @@ -0,0 +1,21 @@ +import formatMoney from '../lib/formatMoney'; + +describe('formatMoney', () => { + it('works with fractional dollars', () => { + expect(formatMoney(1)).toEqual('$0.01'); + expect(formatMoney(10)).toEqual('$0.10'); + }); + + it('leaves cents off for whole dollars', () => { + expect(formatMoney(5000)).toEqual('$50'); + expect(formatMoney(100)).toEqual('$1'); + expect(formatMoney(50000000)).toEqual('$500,000'); + }); + + it('works with whole and fractional dollars', () => { + expect(formatMoney(5012)).toEqual('$50.12'); + expect(formatMoney(101)).toEqual('$1.01'); + expect(formatMoney(110)).toEqual('$1.10'); + expect(formatMoney(54345345)).toEqual('$543,453.45'); + }); +}); |
