Skip to content

Commit

Permalink
Merge pull request #164 from saseungmin/delete-own-study-review
Browse files Browse the repository at this point in the history
[Feature] Add delete my study review logic
  • Loading branch information
saseungmin authored Apr 9, 2021
2 parents 929cf3a + a449b6e commit e6601c8
Show file tree
Hide file tree
Showing 18 changed files with 18,970 additions and 72 deletions.
18,690 changes: 18,675 additions & 15 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"@babel/core": "^7.12.3",
"@babel/preset-env": "^7.12.1",
"@babel/preset-react": "^7.12.5",
"@svgr/webpack": "^5.5.0",
"@testing-library/jest-dom": "^5.11.6",
"@testing-library/react": "^11.1.2",
"@types/jest": "^26.0.15",
Expand Down
14 changes: 14 additions & 0 deletions src/__mocks__/firebase/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const firebase = jest.genMockFromModule('firebase/app');

firebase.firestore = jest.fn().mockImplementation(() => ({
collection: jest.fn().mockImplementation(() => ({
doc: jest.fn().mockImplementation(() => ({
update: jest.fn(),
delete: jest.fn(),
})),
})),
}));

firebase.auth = jest.fn().mockImplementation(() => ({}));

export default firebase;
File renamed without changes.
1 change: 1 addition & 0 deletions src/assets/icons/close.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
46 changes: 36 additions & 10 deletions src/components/introduce/Review.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import palette from '../../styles/palette';

import { changeDateToTime } from '../../util/utils';

import CloseSvg from '../../assets/icons/close.svg';

const ReviewWrapper = styled.div`
background-color: #f8f8f8;
display: flex;
Expand All @@ -33,22 +35,46 @@ const ReviewContentInfo = styled.div`
justify-content: space-between;
`;

const Review = ({ review }) => {
const ReviewHeader = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
`;

const CloseIcon = styled(CloseSvg)`
cursor: pointer;
width: 20px;
height: 20px;
fill: ${palette.gray[6]};
transition: fill .2s;
&:hover {
fill: ${palette.gray[8]};
}
`;

const Review = ({ user, review, onClick }) => {
const {
id, rating, content, createDate,
} = review;

return (
<ReviewWrapper>
<StarRatings
rating={rating}
starRatedColor="#ffc816"
numberOfStars={5}
starDimension="20px"
starSpacing="0"
starHoverColor="#ffc816"
name="rating"
/>
<ReviewHeader>
<StarRatings
rating={rating}
starRatedColor="#ffc816"
numberOfStars={5}
starDimension="20px"
starSpacing="0"
/>
{user === id && (
<CloseIcon
data-testid="close-icon"
onClick={() => onClick(id)}
/>
)}
</ReviewHeader>
<ReviewContent>
{content}
</ReviewContent>
Expand Down
38 changes: 33 additions & 5 deletions src/components/introduce/Review.test.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';

import { render } from '@testing-library/react';
import { render, fireEvent } from '@testing-library/react';

import Review from './Review';

Expand All @@ -12,16 +12,44 @@ describe('Review', () => {
createDate: new Date(),
};

const handleClick = jest.fn();

const renderReview = (review) => render((
<Review
user={given.user}
review={review}
onClick={handleClick}
/>
));

it('Render review contents', () => {
const { container } = renderReview(mockReview);
context("When it's my review", () => {
given('user', () => ('test@test.com'));

it('Render review contents', () => {
const { container, getByTestId } = renderReview(mockReview);

expect(container).toHaveTextContent('review');
expect(container).toHaveTextContent('test@test.com');
expect(getByTestId('close-icon')).not.toBeNull();
});

it('Listen delete click events', () => {
const { getByTestId } = renderReview(mockReview);

fireEvent.click(getByTestId('close-icon'));

expect(handleClick).toBeCalledTimes(1);
});
});

context("When it's my review", () => {
given('user', () => ('test'));

it('Render review contents', () => {
const { container } = renderReview(mockReview);

expect(container).toHaveTextContent('review');
expect(container).toHaveTextContent('test@test.com');
expect(container).toHaveTextContent('review');
expect(container).toHaveTextContent('test@test.com');
});
});
});
4 changes: 3 additions & 1 deletion src/components/introduce/ReviewList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const EmptyReviewWrapper = styled.div`
border-radius: 5px;
`;

const ReviewList = ({ reviews }) => {
const ReviewList = ({ user, reviews, onDelete }) => {
if (_.isEmpty(reviews)) {
return (
<EmptyReviewWrapper>
Expand All @@ -44,7 +44,9 @@ const ReviewList = ({ reviews }) => {
{reviews.map((review) => (
<Review
key={review.id}
user={user}
review={review}
onClick={onDelete}
/>
))}
</ReviewWrapper>
Expand Down
14 changes: 13 additions & 1 deletion src/components/introduce/ReviewList.test.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';

import { render } from '@testing-library/react';
import { render, fireEvent } from '@testing-library/react';

import ReviewList from './ReviewList';

Expand All @@ -12,9 +12,13 @@ describe('ReviewList', () => {
createdDate: new Date(),
}];

const handleClick = jest.fn();

const renderReviewList = (reviews) => render((
<ReviewList
user="test@test.com"
reviews={reviews}
onDelete={handleClick}
/>
));

Expand All @@ -27,6 +31,14 @@ describe('ReviewList', () => {
expect(container).toHaveTextContent('review');
expect(container).toHaveTextContent('test@test.com');
});

it('Listen delete click events', () => {
const { getByTestId } = renderReviewList(mockReviews);

fireEvent.click(getByTestId('close-icon'));

expect(handleClick).toBeCalledTimes(1);
});
});

context('Without reviews', () => {
Expand Down
8 changes: 7 additions & 1 deletion src/containers/introduce/ReviewContainer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useSelector, useDispatch } from 'react-redux';
import {
getAuth, getGroup, isCheckedTimeStatus, changeDateToTime,
} from '../../util/utils';
import { changeStudyReviewFields, setStudyReview } from '../../reducers/groupSlice';
import { changeStudyReviewFields, setStudyReview, deleteStudyReview } from '../../reducers/groupSlice';

import SubTitle from '../../styles/SubTitle';

Expand Down Expand Up @@ -35,6 +35,10 @@ const ReviewFormContainer = () => {
}));
}, [dispatch, user, studyReviewFields]);

const onDeleteReview = useCallback((reviewId) => {
dispatch(deleteStudyReview(reviewId));
}, [dispatch]);

if (!group) {
return null;
}
Expand Down Expand Up @@ -63,7 +67,9 @@ const ReviewFormContainer = () => {
onSubmit={onSubmitReview}
/>
<ReviewList
user={user}
reviews={group.reviews ? group.reviews : []}
onDelete={onDeleteReview}
/>
</>
);
Expand Down
107 changes: 74 additions & 33 deletions src/containers/introduce/ReviewContainer.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,53 +93,94 @@ describe('ReviewContainer', () => {
});

context('when apply end date is DeadLine', () => {
given('group', () => ({
...STUDY_GROUP,
personnel: 3,
participants: [
{ id: 'user2' },
{
context('When my review exists', () => {
given('group', () => ({
...STUDY_GROUP,
personnel: 3,
participants: [
{ id: 'user2' },
{
id: 'user1',
confirm: true,
},
],
applyEndDate: yesterday,
reviews: [{
id: 'user1',
confirm: true,
},
],
applyEndDate: yesterday,
reviews: [],
}));
content: 'review',
rating: 3,
createDate: new Date(),
}],
}));

it('Renders review contents', () => {
const { container, getByTestId } = renderReviewContainer();

expect(container).toHaveTextContent('review');
expect(container).toHaveTextContent('스터디를 참여한 1명의 회원 평균평점');
expect(getByTestId('close-icon')).not.toBeNull();
});

describe('When Click delete review button', () => {
it('dispatch deleteStudyReview calls', () => {
const { getByTestId } = renderReviewContainer();

describe('When you are an approved applicant', () => {
it('renders study review form', () => {
const { container } = renderReviewContainer();
fireEvent.click(getByTestId('close-icon'));

expect(container).toHaveTextContent('스터디 후기를 작성해주세요!');
expect(dispatch).toBeCalledTimes(1);
});
});
});

it('dispatch actions call changeStudyReviewFields', () => {
const form = {
name: 'review',
value: '후기입니다.',
};
context("When my review isn't exists", () => {
given('group', () => ({
...STUDY_GROUP,
personnel: 3,
participants: [
{ id: 'user2' },
{
id: 'user1',
confirm: true,
},
],
applyEndDate: yesterday,
reviews: [],
}));

describe('When you are an approved applicant', () => {
it('renders study review form', () => {
const { container } = renderReviewContainer();

expect(container).toHaveTextContent('스터디 후기를 작성해주세요!');
});
});

it('dispatch actions call changeStudyReviewFields', () => {
const form = {
name: 'review',
value: '후기입니다.',
};

const { getByPlaceholderText } = renderReviewContainer();
const { getByPlaceholderText } = renderReviewContainer();

const textarea = getByPlaceholderText('후기를 입력해주세요!');
const textarea = getByPlaceholderText('후기를 입력해주세요!');

fireEvent.change(textarea, { target: form });
fireEvent.change(textarea, { target: form });

expect(dispatch).toBeCalledWith({
type: 'group/changeStudyReviewFields',
payload: form,
expect(dispatch).toBeCalledWith({
type: 'group/changeStudyReviewFields',
payload: form,
});
});
});

describe('Click the button to submit for study review', () => {
it('dispatch actions call setStudyReview', () => {
const { getByText } = renderReviewContainer();
describe('Click the button to submit for study review', () => {
it('dispatch actions call setStudyReview', () => {
const { getByText } = renderReviewContainer();

fireEvent.click(getByText('후기 등록하기'));
fireEvent.click(getByText('후기 등록하기'));

expect(dispatch).toBeCalledTimes(1);
expect(dispatch).toBeCalledTimes(1);
});
});
});
});
Expand Down
2 changes: 1 addition & 1 deletion src/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import App from './App';

import store from './reducers/store';

import '../assets/global.css';
import './assets/css/global.css';

ReactDOM.render(
(
Expand Down
Loading

0 comments on commit e6601c8

Please sign in to comment.