Skip to content
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

prop types, tests #37

Open
wants to merge 2 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: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

83 changes: 83 additions & 0 deletions .idea/workspace.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions src/components/banner/banner.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import styles from './banner.module.css';
import PropTypes from 'prop-types';

import banner from './banner.jpg';

Expand All @@ -12,4 +13,9 @@ const Banner = ({ heading, children }) => (
</div>
);

Banner.propTypes = {
heading: PropTypes.string.isRequired,
children: PropTypes.element.isRequired
};

export default Banner;
5 changes: 5 additions & 0 deletions src/components/button/button.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import styles from './button.module.css';
import PropTypes from 'prop-types';

import { ReactComponent as PlusIcon } from '../../icons/plus.svg';
import { ReactComponent as MinusIcon } from '../../icons/minus.svg';
Expand All @@ -17,4 +18,8 @@ const Button = ({ icon, ...props }) => {
);
};

Button.propTypes = {
icon: PropTypes.string.isRequired
};

export default Button;
2 changes: 1 addition & 1 deletion src/components/product/product.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ function Product({ product, amount, decrement, increment, fetchData }) {
{amount}
</div>
<div className={styles.buttons}>
<Button onClick={decrement} icon="minus" />
<Button onClick={decrement} data-id="product-decrement" icon="minus" />
<Button
onClick={increment}
data-id="product-increment"
Expand Down
6 changes: 6 additions & 0 deletions src/components/product/product.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ describe('Product', () => {
expect(wrapper.find('[data-id="product-amount"]').text()).toBe('1');
});

it('should decrement amount', () => {
const wrapper = mount(<Product product={product} />);
wrapper.find('button[data-id="product-decrement"]').simulate('click');
expect(wrapper.find('[data-id="product-amount"]').text()).toBe('0');
Copy link
Owner

Choose a reason for hiding this comment

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

это тест не на decrement, а на то, что у нас кол-во не уходит в минус

});

it('should fetch data', () => {
const fn = jest.fn();
mount(<Product product={product} fetchData={fn} />);
Expand Down
8 changes: 7 additions & 1 deletion src/components/rate/rate.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
import cn from 'classnames';
import PropTypes from 'prop-types';

import { ReactComponent as Star } from '../../icons/star.svg';

import styles from './rate.module.css';

const Rate = ({ value }) => (
<div>
<div >
{[...Array(5)].map((_, i) => (
<Star
data-id="review-rating"
key={i}
className={cn(styles.star, { [styles.checked]: i <= value - 1 })}
/>
))}
</div>
);

Rate.propTypes = {
value: PropTypes.number.isRequired
};

export default Rate;
24 changes: 24 additions & 0 deletions src/components/restaurant/restaurant.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { useMemo } from 'react';
import PropTypes from 'prop-types';

import Menu from '../menu';
import Reviews from '../reviews';
import Banner from '../banner';
Expand Down Expand Up @@ -26,4 +28,26 @@ const Restaurant = ({ restaurant }) => {
);
};

Restaurant.propTypes = {
restaurant:
PropTypes.shape({
id: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
menu: PropTypes.arrayOf(
Copy link
Owner

Choose a reason for hiding this comment

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

слишком глубоко описаны propTypes, нем тут не нужна детализация по menu и reviews

PropTypes.shape({
id: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
price: PropTypes.number.isRequired,
ingredients: PropTypes.arrayOf(PropTypes.string).isRequired,
})).isRequired,
reviews: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.string.isRequired,
user: PropTypes.string.isRequired,
rating: PropTypes.number.isRequired,
text: PropTypes.string.isRequired,
})).isRequired,
}).isRequired
};

export default Restaurant;
10 changes: 10 additions & 0 deletions src/components/restaurants/restaurants.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useState, useMemo } from 'react';
import PropTypes from 'prop-types';

import Restaurant from '../restaurant';
import Tabs from '../tabs';
Expand All @@ -23,3 +24,12 @@ export default function Restaurants({ restaurants }) {
</div>
);
}

Restaurants.propTypes = {
restaurants: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
}).isRequired
).isRequired,
};
12 changes: 10 additions & 2 deletions src/components/reviews/review/review.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import Rate from '../../rate';
import styles from './review.module.css';

import PropTypes from 'prop-types';

const Review = ({ user, text, rating }) => (
<div className={styles.review}>
<div className={styles.content}>
<div>
<h4 className={styles.name}>{user}</h4>
<p className={styles.comment}>{text}</p>
<h4 data-id="review-name" className={styles.name}>{user}</h4>
<p data-id="review-text" className={styles.comment}>{text}</p>
</div>
<div className={styles.rate}>
<Rate value={rating} />
Expand All @@ -19,4 +21,10 @@ Review.defaultProps = {
user: 'Anonymous',
};

Review.propTypes = {
user: PropTypes.string.isRequired,
text: PropTypes.string.isRequired,
rating: PropTypes.number.isRequired,
};

export default Review;
13 changes: 11 additions & 2 deletions src/components/reviews/reviews.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
import Review from './review';
import styles from './reviews.module.css';

import PropTypes from 'prop-types';

const Reviews = ({ reviews }) => {
return (
<div className={styles.reviews}>
{reviews.map((review) => (
<div className={styles.reviews} data-id="reviews">
{reviews && reviews.map((review) => (
<Review key={review.id} {...review} />
))}
</div>
);
};

Reviews.propTypes = {
reviews: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.string.isRequired,
})).isRequired
};
Copy link
Owner

Choose a reason for hiding this comment

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

тут arrayOf тоже должен быть isRequired


export default Reviews;
58 changes: 58 additions & 0 deletions src/components/reviews/reviews.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import Enzyme, { mount } from 'enzyme';
import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
import Reviews from './reviews';

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

const reviews = [{
id: '5db6247b-ab1c-49db-be1f-8dd27fd38b81',
text: 'Finally! This place is amazing place for breakfast, lunch, dinner and supper',
rating: 5,
}];

describe('Reviews', () => {
it(' should render Reviews', () => {
const wrapper = mount(<Reviews reviews={reviews}/>);
expect(wrapper.find('[data-id="reviews"]').length).toBe(1);
});

it('should render Rate', () => {
const wrapper = mount(<Reviews reviews={reviews}/>);
expect(wrapper.find('svg[data-id="review-rating"]').length).toBe(5);
});

it('should render default name', () => {
const wrapper = mount(<Reviews reviews={reviews}/>);
expect(wrapper.find('h4[data-id="review-name"]').text()).toEqual('Anonymous')
});

it('should render text', () => {
const wrapper = mount(<Reviews reviews={reviews}/>);
expect(wrapper.find('p[data-id="review-text"]').text()).toEqual('Finally! This place is amazing place for breakfast, lunch, dinner and supper')
});

it('allows us to set props', () => {
const wrapper = mount(<Reviews reviews={reviews} />);
expect(wrapper.props().reviews[0].rating).toEqual(5);
Copy link
Owner

Choose a reason for hiding this comment

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

не нужно проверять props, тем более те, которых не должно быть

wrapper.setProps({ bar: 'foo' });
expect(wrapper.props().bar).toEqual('foo');
});

it('reviews is an array of objects', () => {
const wrapper = mount(<Reviews reviews={reviews} />);
expect(reviews).toHaveLength(1);
});

it('review has properties', () => {
const wrapper = mount(<Reviews reviews={reviews} />);
expect(reviews[0]).toHaveProperty('id');
expect(reviews[0]).toHaveProperty('text');
expect(reviews[0]).toHaveProperty('rating');
});

it('reviews rating is a number', () => {
const wrapper = mount(<Reviews reviews={reviews} />);
expect(typeof reviews[0].rating).toEqual("number");
});
});

12 changes: 12 additions & 0 deletions src/components/tabs/tabs.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import PropTypes from 'prop-types';
import cn from 'classnames';

import styles from './tabs.module.css';
Expand All @@ -17,3 +18,14 @@ export default function Tabs({ tabs, activeId, onChange }) {
</div>
);
}

Tabs.propTypes = {
tabs: PropTypes.arrayOf(PropTypes.shape({
id: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
})).isRequired,
activeId: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired,
};