Skip to content

Commit

Permalink
Merge pull request #1490 from fshowalter/add_component_tests_to_shopp…
Browse files Browse the repository at this point in the history
…ing_cart_example

add shopping cart example tests (for #1481)
  • Loading branch information
timdorr committed Mar 8, 2016
2 parents 0bbabe8 + 9353e1e commit 705704b
Show file tree
Hide file tree
Showing 9 changed files with 402 additions and 1 deletion.
9 changes: 8 additions & 1 deletion examples/shopping-cart/package.json
Expand Up @@ -3,7 +3,9 @@
"version": "0.0.0",
"description": "Redux shopping-cart example",
"scripts": {
"start": "node server.js"
"start": "node server.js",
"test": "cross-env NODE_ENV=test mocha --recursive --compilers js:babel-register",
"test:watch": "npm test -- --watch"
},
"repository": {
"type": "git",
Expand All @@ -28,9 +30,14 @@
"babel-preset-es2015": "^6.3.13",
"babel-preset-react": "^6.3.13",
"babel-preset-react-hmre": "^1.1.1",
"cross-env": "^1.0.7",
"enzyme": "^2.0.0",
"express": "^4.13.3",
"json-loader": "^0.5.3",
"react-addons-test-utils": "^0.14.7",
"redux-logger": "^2.0.1",
"mocha": "^2.2.5",
"node-libs-browser": "^0.5.2",
"webpack": "^1.9.11",
"webpack-dev-middleware": "^1.2.0",
"webpack-hot-middleware": "^2.9.1"
Expand Down
5 changes: 5 additions & 0 deletions examples/shopping-cart/test/.eslintrc
@@ -0,0 +1,5 @@
{
"env": {
"mocha": true
}
}
74 changes: 74 additions & 0 deletions examples/shopping-cart/test/components/Cart.spec.js
@@ -0,0 +1,74 @@
import expect from 'expect'
import React from 'react'
import { shallow } from 'enzyme'
import Cart from '../../components/Cart'
import Product from '../../components/Product'

function setup(total, products = []) {
const actions = {
onCheckoutClicked: expect.createSpy()
}

const component = shallow(
<Cart products={products} total={total} {...actions} />
)

return {
component: component,
actions: actions,
button: component.find('button'),
products: component.find(Product),
em: component.find('em'),
p: component.find('p')
}
}

describe('Cart component', () => {
it('should display total', () => {
const { p } = setup('76')
expect(p.text()).toMatch(/^Total: \$76/)
})

it('should display add some products message', () => {
const { em } = setup()
expect(em.text()).toMatch(/^Please add some products to cart/)
})

it('should disable button', () => {
const { button } = setup()
expect(button.prop('disabled')).toEqual('disabled')
})

describe('when given product', () => {
const product = [
{
id: 1,
title: 'Product 1',
price: 9.99,
quantity: 1
}
]

it('should render products', () => {
const { products } = setup('9.99', product)
const props = {
title: product[0].title,
price: product[0].price,
quantity: product[0].quantity
}

expect(products.at(0).props()).toEqual(props)
})

it('should not disable button', () => {
const { button } = setup('9.99', product)
expect(button.prop('disabled')).toEqual('')
})

it('should call action on button click', () => {
const { button, actions } = setup('9.99', product)
button.simulate('click')
expect(actions.onCheckoutClicked).toHaveBeenCalled()
})
})
})
28 changes: 28 additions & 0 deletions examples/shopping-cart/test/components/Product.spec.js
@@ -0,0 +1,28 @@
import expect from 'expect'
import React from 'react'
import { shallow } from 'enzyme'
import Product from '../../components/Product'

function setup(props) {
const component = shallow(
<Product {...props} />
)

return {
component: component
}
}

describe('Product component', () => {
it('should render title and price', () => {
const { component } = setup({ title: 'Test Product', price: 9.99 })
expect(component.text()).toMatch(/^ Test Product - \$9.99 {2}$/)
})

describe('when given quantity', () => {
it('should render title, price, and quantity', () => {
const { component } = setup({ title: 'Test Product', price: 9.99, quantity: 6 })
expect(component.text()).toMatch(/^ Test Product - \$9.99 x 6 $/)
})
})
})
71 changes: 71 additions & 0 deletions examples/shopping-cart/test/components/ProductItem.spec.js
@@ -0,0 +1,71 @@
import expect from 'expect'
import React from 'react'
import { shallow } from 'enzyme'
import Product from '../../components/Product'
import ProductItem from '../../components/ProductItem'

function setup(product) {
const actions = {
onAddToCartClicked: expect.createSpy()
}

const component = shallow(
<ProductItem product={product} {...actions} />
)

return {
component: component,
actions: actions,
button: component.find('button'),
product: component.find(Product)
}
}

let productProps

describe('ProductItem component', () => {
beforeEach(() => {
productProps = {
title: 'Product 1',
price: 9.99,
inventory: 6
}
})

it('should render product', () => {
const { product } = setup(productProps)
expect(product.props()).toEqual({ title: 'Product 1', price: 9.99 })
})

it('should render Add To Cart message', () => {
const { button } = setup(productProps)
expect(button.text()).toMatch(/^Add to cart/)
})

it('should not disable button', () => {
const { button } = setup(productProps)
expect(button.prop('disabled')).toEqual('')
})

it('should call action on button click', () => {
const { button, actions } = setup(productProps)
button.simulate('click')
expect(actions.onAddToCartClicked).toHaveBeenCalled()
})

describe('when product inventory is 0', () => {
beforeEach(() => {
productProps.inventory = 0
})

it('should render Sold Out message', () => {
const { button } = setup(productProps)
expect(button.text()).toMatch(/^Sold Out/)
})

it('should disable button', () => {
const { button } = setup(productProps)
expect(button.prop('disabled')).toEqual('disabled')
})
})
})
28 changes: 28 additions & 0 deletions examples/shopping-cart/test/components/ProductsList.spec.js
@@ -0,0 +1,28 @@
import expect from 'expect'
import React from 'react'
import { shallow } from 'enzyme'
import ProductsList from '../../components/ProductsList'

function setup(props) {
const component = shallow(
<ProductsList title={props.title}>{props.children}</ProductsList>
)

return {
component: component,
children: component.children().at(1),
h3: component.find('h3')
}
}

describe('ProductsList component', () => {
it('should render title', () => {
const { h3 } = setup({ title: 'Test Products' })
expect(h3.text()).toMatch(/^Test Products$/)
})

it('should render children', () => {
const { children } = setup({ title: 'Test Products', children: 'Test Children' })
expect(children.text()).toMatch(/^Test Children$/)
})
})
44 changes: 44 additions & 0 deletions examples/shopping-cart/test/reducers/cart.spec.js
@@ -0,0 +1,44 @@
import expect from 'expect'
import cart from '../../reducers/cart'

describe('reducers', () => {
describe('cart', () => {
const initialState = {
addedIds: [],
quantityById: {}
}

it('should provide the initial state', () => {
expect(cart(undefined, {})).toEqual(initialState)
})

it('should handle CHECKOUT_REQUEST action', () => {
expect(cart({}, { type: 'CHECKOUT_REQUEST' })).toEqual(initialState)
})

it('should handle CHECKOUT_FAILURE action', () => {
expect(cart({}, { type: 'CHECKOUT_FAILURE', cart: 'cart state' })).toEqual('cart state')
})

it('should handle ADD_TO_CART action', () => {
expect(cart(initialState, { type: 'ADD_TO_CART', productId: 1 })).toEqual({
addedIds: [ 1 ],
quantityById: { 1: 1 }
})
})

describe('when product is already in cart', () => {
it('should handle ADD_TO_CART action', () => {
const state = {
addedIds: [ 1, 2 ],
quantityById: { 1: 1, 2: 1 }
}

expect(cart(state, { type: 'ADD_TO_CART', productId: 2 })).toEqual({
addedIds: [ 1, 2 ],
quantityById: { 1: 1, 2: 2 }
})
})
})
})
})
59 changes: 59 additions & 0 deletions examples/shopping-cart/test/reducers/products.spec.js
@@ -0,0 +1,59 @@
import expect from 'expect'
import products from '../../reducers/products'

describe('reducers', () => {
describe('products', () => {
it('should handle RECEIVE_PRODUCTS action', () => {
const action = {
type: 'RECEIVE_PRODUCTS',
products: [
{
id: 1,
title: 'Product 1'
},
{
id: 2,
title: 'Product 2'
}
]
}

expect(products({}, action)).toEqual({
byId: {
1: {
id: 1,
title: 'Product 1'
},
2: {
id: 2,
title: 'Product 2'
}
},
visibleIds: [ 1, 2 ]
})
})

it('should handle ADD_TO_CART action', () => {
const state = {
byId: {
1: {
id: 1,
title: 'Product 1',
inventory: 1
}
}
}

expect(products(state, { type: 'ADD_TO_CART', productId: 1 })).toEqual({
byId: {
1: {
id: 1,
title: 'Product 1',
inventory: 0
}
},
visibleIds: []
})
})
})
})

0 comments on commit 705704b

Please sign in to comment.