Skip to content
This repository was archived by the owner on Aug 5, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
a4ce3ca
Create basic redux actions unit tests
developer239 Apr 21, 2019
054c627
Update jest collect coverage settings
developer239 Apr 21, 2019
ecb3da2
Write basic reducer integration test
developer239 Apr 21, 2019
283478e
Remove redux actions unit tests
developer239 Apr 21, 2019
d695e9f
Add react-testing-library and jest-styled-components dependencies
developer239 Apr 21, 2019
96a137b
Create basic button component unit test
developer239 Apr 21, 2019
6215985
Create basic button component snapshot
developer239 Apr 21, 2019
592604b
Create test case for disabled button
developer239 Apr 21, 2019
67fe678
Create failing test for not found page
developer239 Apr 21, 2019
95b8e31
Create successful test for not found page
developer239 Apr 21, 2019
c61a349
Create basic products list snapshot test
developer239 Apr 21, 2019
1cc2c59
Create basic products list snapshot test when products loaded
developer239 Apr 21, 2019
02bed15
Fix react-testing-library react-hooks errors
developer239 Apr 21, 2019
016098f
Add jest-mock dependency
developer239 Apr 21, 2019
08e4cea
Added CartItem product id into array
arnostpleskot Apr 21, 2019
c4bd7cd
Getting rid of classes
arnostpleskot Apr 21, 2019
5e1aaa8
Adding number of products per size selector
arnostpleskot Apr 21, 2019
21635ee
Refactored getting url params in product list
arnostpleskot Apr 21, 2019
5fdc5dd
Mock Fetch requests
developer239 Apr 21, 2019
b3f09d2
ramdify
varholak-peter Apr 21, 2019
dcf549c
Create basic tests for product detail page
developer239 Apr 21, 2019
91a2813
Create basic tests for cart page
developer239 Apr 21, 2019
6831962
Use routes constants instead of hard-coded routes
developer239 Apr 21, 2019
e601196
Create basic test for not-logged-in user on account page
developer239 Apr 21, 2019
3642e2e
Create basic test user account page
developer239 Apr 21, 2019
6c5c135
Create basic signup page test
developer239 Apr 21, 2019
21ed32b
Write advanced tests for signup page
developer239 Apr 21, 2019
7b0e673
Replace hard-coded user data with constant mock user data
developer239 Apr 21, 2019
8104b90
Write tests for sign in page
developer239 Apr 21, 2019
5687627
Merge branch 'week5-homework' of https://github.com/strvcom/react-nig…
developer239 Apr 21, 2019
026e2fe
Update products list snapshot
developer239 Apr 21, 2019
365a1d1
Fix typo
developer239 Apr 21, 2019
3fe0468
Polish source code
developer239 Apr 21, 2019
741a015
Make store mock nicer
developer239 Apr 23, 2019
ac821ce
Detect account page by page-id
developer239 Apr 23, 2019
8fcb048
Fix snapshot tests
developer239 Apr 23, 2019
584b989
Install cypress
developer239 Apr 23, 2019
529852b
Initialize cypress
developer239 Apr 23, 2019
03f45e1
Add eslint-plugin-cypress
developer239 Apr 23, 2019
e58c97c
Fix cypress base url
developer239 Apr 23, 2019
4dc68aa
Write basic cypress test
developer239 Apr 23, 2019
1fb47c2
Fix cypress test
developer239 Apr 24, 2019
ba0a6ed
Resolve tasks from code review
developer239 Apr 24, 2019
fa13c9e
Merge branch 'master' of https://github.com/strvcom/react-nights-2018…
developer239 Apr 24, 2019
c6635c0
Run tests before every commit
developer239 Apr 24, 2019
0ceeb98
Add cross-env
developer239 Apr 24, 2019
02e2c23
Revert "Add cross-env"
developer239 Apr 24, 2019
daffaa2
Revert "Run tests before every commit"
developer239 Apr 24, 2019
15e7a9a
Recover README files 💣
developer239 Apr 24, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@
"lint:js": "eslint . --ignore-path .gitignore --fix",
"lint:css": "stylelint 'src/**/*.js'"
},
"jest": {
"collectCoverageFrom": [
"src/**/*.{js,jsx}",
"!/node_modules/",
"!src/index.js",
"!src/serviceWorker.js",
"!src/store/index.js"
Comment thread
developer239 marked this conversation as resolved.
]
},
"lint-staged": {
"*.js": [
"eslint --fix",
Expand Down Expand Up @@ -55,9 +64,12 @@
"@strv/stylelint-config-styled-components": "^1.0.0",
"eslint-config-prettier": "^4.1.0",
"eslint-plugin-react-hooks": "^1.6.0",
"fetch-mock": "^7.3.1",
"husky": "^1.3.1",
"jest-styled-components": "^6.3.1",
"lint-staged": "^8.1.5",
"prettier": "^1.16.4",
"react-testing-library": "^6.1.2",
"stylelint": "^9.10.1",
"stylelint-config-prettier": "^5.0.0"
}
Expand Down
4 changes: 2 additions & 2 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ const store = configureStore({
customer: getCustomer(),
})

const App = () => (
<Provider store={store}>
const App = ({ customStore }) => (
Comment thread
developer239 marked this conversation as resolved.
Outdated
<Provider store={customStore || store}>
<React.Fragment>
<GlobalStyles />
<Switch>
Expand Down
53 changes: 53 additions & 0 deletions src/components/Button/test/__snapshots__/index.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`[components] Button should render correctly 1`] = `
.c0 {
background: #ef0d33;
cursor: pointer;
padding: 1rem;
margin-top: 0.5rem;
border: none;
border-radius: 5px;
color: #fff;
}

<body>
<div>
<button
class="c0"
>
My Button
</button>
</div>
</body>
`;

exports[`[components] Button when disabled should render correctly 1`] = `
<body>
<div>
<button
class="Button-sc-2y5gim-0 iFNPkt"
>
My Button
</button>
</div>
.c0 {
background: #e5e5e5;
cursor: default;
padding: 1rem;
margin-top: 0.5rem;
border: none;
border-radius: 5px;
color: #fff;
}

<div>
<button
class="c0"
disabled=""
>
My Button
</button>
</div>
</body>
`;
20 changes: 20 additions & 0 deletions src/components/Button/test/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react'
import { render } from 'react-testing-library'
import 'jest-styled-components'

import Button from '../index'

// This is just an example how to test components
describe('[components] Button', () => {
it('should render correctly', () => {
const renderer = render(<Button>My Button</Button>)
expect(renderer.baseElement).toMatchSnapshot()
})

describe('when disabled', () => {
it('should render correctly', () => {
const renderer = render(<Button disabled>My Button</Button>)
expect(renderer.baseElement).toMatchSnapshot()
})
})
})
66 changes: 31 additions & 35 deletions src/components/Layout/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { Component, Fragment } from 'react'
import React, { Fragment } from 'react'
import { withRouter } from 'react-router-dom'
import { connect } from 'react-redux'

Expand All @@ -9,44 +9,40 @@ import { removeToken } from '../../utils/token'
import { removeCustomer } from '../../utils/customer'
import { Wrapper, Header, HeaderSection, HeaderLink } from './styled'

class Layout extends Component {
handleLogout = () => {
this.props.logout()
const Layout = ({ logout, isAuthenticated, history, children, dataTestId }) => {
const handleLogout = () => {
logout()
removeToken()
removeCustomer()
this.props.history.push(routes.HOMEPAGE)
history.push(routes.HOMEPAGE)
}

render() {
const { isAuthenticated } = this.props

return (
<Fragment>
<Header>
<HeaderSection>
<HeaderLink to={routes.PRODUCT_LIST}>All Products</HeaderLink>
</HeaderSection>
<HeaderSection>
<HeaderLink to={routes.CART}>My Cart</HeaderLink>|
{isAuthenticated ? (
<>
<HeaderLink to={routes.ACCOUNT}>My Account</HeaderLink>|
<HeaderLink as="button" onClick={this.handleLogout}>
Logout
</HeaderLink>
</>
) : (
<>
<HeaderLink to={routes.LOGIN}>Log In</HeaderLink> |
<HeaderLink to={routes.SIGN_UP}>Sign Up</HeaderLink>
</>
)}
</HeaderSection>
</Header>
<Wrapper>{this.props.children}</Wrapper>
</Fragment>
)
}
return (
<Fragment>
<Header>
<HeaderSection>
<HeaderLink to={routes.PRODUCT_LIST}>All Products</HeaderLink>
</HeaderSection>
<HeaderSection>
<HeaderLink to={routes.CART}>My Cart</HeaderLink>|
{isAuthenticated ? (
<>
<HeaderLink to={routes.ACCOUNT}>My Account</HeaderLink>|
<HeaderLink as="button" onClick={handleLogout}>
Logout
</HeaderLink>
</>
) : (
<>
<HeaderLink to={routes.LOGIN}>Log In</HeaderLink> |
<HeaderLink to={routes.SIGN_UP}>Sign Up</HeaderLink>
</>
)}
</HeaderSection>
</Header>
<Wrapper data-testid={dataTestId}>{children}</Wrapper>
</Fragment>
)
}

const mapStateToProps = state => ({
Expand Down
2 changes: 1 addition & 1 deletion src/components/Loader/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react'
import { LoaderWrap, StyledLoader, Circular, Path } from './styled'

const Loader = props => (
<LoaderWrap {...props}>
<LoaderWrap data-testid="loader" {...props}>
<StyledLoader>
<Circular viewBox="25 25 50 50">
<Path
Expand Down
16 changes: 16 additions & 0 deletions src/components/Pagination/SizeSelect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react'

const options = [10, 25, 50, 100]

const SizeSelect = ({ onChange, value }) => (
// eslint-disable-next-line jsx-a11y/no-onchange
<select onChange={onChange} value={value}>
{options.map(number => (
<option value={number} key={number}>
{number}
</option>
))}
</select>
)

export { SizeSelect }
14 changes: 10 additions & 4 deletions src/components/Pagination/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,22 @@ import { Link } from 'react-router-dom'

import * as routes from '../../routes'

import { SizeSelect } from './SizeSelect'
import { List, ListItem } from './styled'

const renderPaginationItem = number => (
const renderPaginationItem = size => number => (
<ListItem key={number}>
<Link to={`${routes.PRODUCT_LIST}?page=${number}`}>{number}</Link>
<Link to={`${routes.PRODUCT_LIST}?page=${number}&size=${size}`}>
{number}
</Link>
</ListItem>
)

const Pagination = ({ pages }) => (
<List>{map(renderPaginationItem, range(1, pages + 1))}</List>
const Pagination = ({ pages, size, onSizeChange }) => (
<>
<List>{map(renderPaginationItem(size), range(1, pages + 1))}</List>
<SizeSelect onChange={onSizeChange} value={size} />
</>
)

export { Pagination }
3 changes: 2 additions & 1 deletion src/components/PrivateRoute/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react'
import { Route, Redirect } from 'react-router-dom'
import { connect } from 'react-redux'
import isEmpty from 'ramda/src/isEmpty'

import * as routes from '../../routes'

Expand Down Expand Up @@ -32,7 +33,7 @@ const PrivateRouteComponent = ({
}

const mapStateToProps = state => ({
isAuthenticated: Object.keys(state.customer).length !== 0,
isAuthenticated: !isEmpty(state.customer),
})

export const PrivateRoute = connect(mapStateToProps)(PrivateRouteComponent)
2 changes: 1 addition & 1 deletion src/pages/Account/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Layout from '../../components/Layout'
import { H1 } from '../../components/Typography'

const AccountPage = ({ customer }) => (
<Layout>
<Layout dataTestId="account-page">
<H1>Welcome {customer.attributes.metadata.firstName}</H1>
</Layout>
)
Expand Down
39 changes: 39 additions & 0 deletions src/pages/Account/test/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from 'react'
import 'jest-styled-components'

import { App } from '../../../App'
import * as routes from '../../../routes'
import { renderWithRouter } from '../../../utilsTest/render'
import { configureStore } from '../../../store'
import { USER } from '../../../utilsTest/mockData'

describe('[pages] Account', () => {
describe('when not logged in', () => {
it('should redirect to login page', () => {
const renderer = renderWithRouter(<App />, routes.ACCOUNT)
const HTMLDivElement = renderer.getByTestId('login-page')
expect(HTMLDivElement).toBeTruthy()
})
})

describe('when logged in', () => {
it('should render private user account page', async () => {
const store = configureStore({
customer: {
attributes: {
metadata: {
firstName: USER.firstName,
},
},
},
})

const renderer = renderWithRouter(
<App customStore={store} />,
routes.ACCOUNT
)
const H1HtmlElement = renderer.getByText(`Welcome ${USER.firstName}`)
Comment thread
developer239 marked this conversation as resolved.
Outdated
expect(H1HtmlElement).toBeTruthy()
})
})
})
29 changes: 19 additions & 10 deletions src/pages/Cart/CartItem.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,35 @@
import * as React from 'react'
import flip from 'ramda/src/flip'
import propOr from 'ramda/src/propOr'

import { getProductById } from '../../api/products/get-product'
import { useApi } from '../../api/use-api'

import Loader from '../../components/Loader'
import Button from '../../components/Button'

const getNameFallback = flip(propOr)('name')

const CartItem = ({ productId, quantity, removeProduct }) => {
const { data: product, isLoading } = useApi(
() => getProductById(productId),
productId
)
const { data: product, isLoading } = useApi(() => getProductById(productId), [
productId,
])

const getName = getNameFallback(productId)

return (
<li key={productId}>
{isLoading && <Loader small />}
<p>
{product ? product.name : productId} - {quantity}
</p>
<Button type="button" onClick={() => removeProduct(productId)}>
Remove
</Button>
{!isLoading && (
<React.Fragment>
<p>
{getName(product)} - {quantity}
</p>
<Button type="button" onClick={() => removeProduct(productId)}>
Remove
</Button>
</React.Fragment>
)}
</li>
)
}
Expand Down
5 changes: 3 additions & 2 deletions src/pages/Cart/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react'
import { connect } from 'react-redux'
import toPairs from 'ramda/src/toPairs'

import Layout from '../../components/Layout'
import { H1 } from '../../components/Typography'
Expand All @@ -25,8 +26,8 @@ const CartView = ({ items, removeProduct }) => {
}

const mapStateToProps = state => ({
items: Object.keys(state.cart).map(productId => ({
quantity: state.cart[productId],
items: toPairs(state.cart).map(([productId, quantity]) => ({
quantity,
product: { id: productId },
})),
})
Expand Down
Loading