Skip to content

HT #2 #24

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 5 additions & 1 deletion src/components/article-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,12 @@ class ArticleList extends Component {
return <ul className="test--article-list__container">{articleItems}</ul>
}
}

ArticleList.propTypes = {
articles: PropTypes.array.isRequired
articles: PropTypes.arrayOf(PropTypes.object).isRequired,
toggleOpenItem: PropTypes.func,
fetchAll: PropTypes.func,
openItemId: PropTypes.string
}

export default accordion(ArticleList)
12 changes: 12 additions & 0 deletions src/components/article.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { findDOMNode } from 'react-dom'
import CommentList from './comment-list'
import CommentForm from './comment-form/comment-form'

class Article extends Component {
static propTypes = {
article: PropTypes.shape({
title: PropTypes.string,
text: PropTypes.string,
comments: PropTypes.arrayOf(PropTypes.object)
}).isRequired,
isOpen: PropTypes.bool,
onBtnClick: PropTypes.func
}

/*
componentDidCatch(error) {
console.log('---', error)
Expand Down
32 changes: 32 additions & 0 deletions src/components/article.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from 'react'
import Enzyme, { mount } from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
import Article from './article'

import articles from '../fixtures'

const article = articles[0]

Enzyme.configure({ adapter: new Adapter() })
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Это можно один раз в setup.tests сдалать


describe('Article', () => {
it('should hide body when isOpen=false', () => {
const container = mount(<Article article={article} isOpen={false} />)
expect(container.find('.test--article__body').length).toBe(0)
})

it('should show body when isOpen=true', () => {
const container = mount(<Article article={article} isOpen={true} />)
expect(container.find('.test--article__body').length).toBe(1)
})

it('check button label when isOpen=true', () => {
const container = mount(<Article article={article} isOpen={true} />)
expect(container.find('.test--article__btn').text()).toBe('close')
})

it('check button label when isOpen=false', () => {
const container = mount(<Article article={article} isOpen={false} />)
expect(container.find('.test--article__btn').text()).toBe('open')
})
})
83 changes: 83 additions & 0 deletions src/components/comment-form/comment-form.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import React, { Component } from 'react'

class CommentForm extends Component {
state = {
username: '',
text: '',
usernameError: null,
textError: null
}

render() {
const { username, text, usernameError, textError } = this.state

return (
<form onSubmit={this.handleSubmit}>
<h3>New comment</h3>
<div>
<label htmlFor="username">Username: </label>
<input type="text" id="username" value={username} onChange={this.handleChangeUsername} />
{usernameError ? <span>{usernameError}</span> : null}
</div>
<div>
<label htmlFor="text">Text: </label>
<textarea id="text" value={text} onChange={this.handleChangeText} />
{textError ? <span>{textError}</span> : null}
</div>
<div>
<button>Submit</button>
</div>
</form>
)
}

handleChangeUsername = (e) => {
this.setState({
username: e.target.value
})
}

handleChangeText = (e) => {
this.setState({
text: e.target.value
})
}

handleSubmit = (e) => {
e.preventDefault()

let hasError = false

if (this.state.username.trim().length === 0) {
this.setState({
usernameError: 'Invalid name'
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Лучше хранить минимальное состояние, а есть ошибка, или нет - ты можешь всегда при неодходимости посчитать

})
hasError = true
} else {
this.setState({
usernameError: null
})
}

if (this.state.text.trim().length === 0) {
this.setState({
textError: 'Invalid text'
})
hasError = true
} else {
this.setState({
textError: null
})
}

if (hasError === false) {
this.setState({
username: '',
text: ''
})
alert('Submit success')
}
}
}

export default CommentForm
6 changes: 6 additions & 0 deletions src/components/comment-list-hooks.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react'
import PropTypes from 'prop-types'
import Comment from './comment'
import useToggler from '../custom-hooks/toggle-open'

Expand Down Expand Up @@ -31,4 +32,9 @@ function getBody({ comments, isOpen }) {
return <div>{body}</div>
}

CommentList.propTypes = {
comments: PropTypes.arrayOf(PropTypes.object),
isOpen: PropTypes.bool
}

export default CommentList
38 changes: 24 additions & 14 deletions src/components/comment-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import React, { Component } from 'react'
import PropTypes from 'prop-types'
import Comment from './comment'
import toggleOpen from '../decorators/toggle-open'
import CommentForm from './comment-form/comment-form'

class CommentList extends Component {
static propTypes = {
comments: PropTypes.array,
comments: PropTypes.arrayOf(PropTypes.object),
isOpen: PropTypes.bool,
toggleOpen: PropTypes.func
}
Expand All @@ -21,7 +22,9 @@ class CommentList extends Component {
const text = isOpen ? 'hide comments' : 'show comments'
return (
<div>
<button onClick={toggleOpen}>{text}</button>
<button className="test--toggle_comments__btn" onClick={toggleOpen}>
{text}
</button>
{this.getBody()}
</div>
)
Expand All @@ -31,25 +34,32 @@ class CommentList extends Component {
const { comments, isOpen } = this.props
if (!isOpen) return null

const body = comments.length ? (
<ul ref={this.setListRef}>
{comments.map((comment) => (
<li key={comment.id}>
<Comment comment={comment} />
</li>
))}
</ul>
) : (
<h3>No comments yet</h3>
)
const body =
comments && comments.length ? (
<ul ref={this.setListRef} className="test--comments_list">
{comments.map((comment) => (
<li key={comment.id} className="test--comments_item">
<Comment comment={comment} />
</li>
))}
</ul>
) : (
<h3 className="test--comments_empty-label">No comments yet</h3>
)

return <div>{body}</div>
return (
<div>
{body}
<CommentForm />
</div>
)
}

setListRef = (ref) => {
this.list = ref
}
}

/*

CommentList.propTypes = {
Expand Down
64 changes: 64 additions & 0 deletions src/components/comment-list.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import React from 'react'
import Enzyme, { mount } from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'

import articles from '../fixtures'
import CommentList from './comment-list'

const comments = articles[0].comments

Enzyme.configure({ adapter: new Adapter() })

describe('CommentList', () => {
it('check button label when isOpen=true', () => {
const container = mount(<CommentList comments={comments} isOpen={true} />)
expect(container.find('.test--toggle_comments__btn').text()).toBe('hide comments')
})

it('check button label when isOpen=false', () => {
const container = mount(<CommentList comments={comments} isOpen={false} />)
expect(container.find('.test--toggle_comments__btn').text()).toBe('show comments')
})

it('check no comments when comments are not pass to component', () => {
const container = mount(<CommentList isOpen={true} />)
expect(container.find('.test--comments_list').length).toBe(0)
})

it('check "no comments" label exists when comments are empty', () => {
const container = mount(<CommentList isOpen={true} />)
expect(container.find('.test--comments_empty-label').length).toBe(1)
})

it('check "no comments" label does not exist when comments are not empty', () => {
const container = mount(<CommentList isOpen={true} comments={comments} />)
expect(container.find('.test--comments_empty-label').length).toBe(0)
})

it('check comments list', () => {
const container = mount(<CommentList comments={comments} isOpen={true} />)
expect(container.find('.test--comments_item').length).toBe(comments.length)
})

it('should toggle comments on clicks on toggle button', () => {
const container = mount(<CommentList comments={comments} />)
expect(container.find('.test--comments_list').length).toBe(0)

container
.find('.test--toggle_comments__btn')
.at(0)
.simulate('click')

expect(container.find('.test--toggle_comments__btn').text()).toBe('hide comments')
expect(container.find('.test--comments_list').length).toBe(1)
expect(container.find('.test--comments_item').length).toBe(comments.length)

container
.find('.test--toggle_comments__btn')
.at(0)
.simulate('click')

expect(container.find('.test--toggle_comments__btn').text()).toBe('show comments')
expect(container.find('.test--comments_list').length).toBe(0)
})
})
5 changes: 4 additions & 1 deletion src/components/filters/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import DateRange from './date-range'
import SelectFilter from './select'

class Filters extends Component {
static propTypes = {}
static propTypes = {
articles: PropTypes.array
}

render() {
return (
Expand Down
5 changes: 3 additions & 2 deletions src/decorators/toggle-open.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ export default (OriginalComponent) =>
isOpen: false
}

toggleOpen = () =>
toggleOpen = () => {
this.setState((state) => ({
isOpen: !state.isOpen
}))
}

render() {
return <OriginalComponent {...this.props} {...this.state} toggleOpen={this.toggleOpen} />
return <OriginalComponent {...this.state} {...this.props} toggleOpen={this.toggleOpen} />
}
}