DevKim
[ Webtooniverse ] 웹툰 상세 페이지 개발 - 리뷰 좋아요 기능 & 리뷰 수정 및 삭제 본문
[ Webtooniverse ] 웹툰 상세 페이지 개발 - 리뷰 좋아요 기능 & 리뷰 수정 및 삭제
on_doing 2021. 8. 1. 17:17[ 설계 ]
※ 현재 설계의 문제
- Review를 삭제하는 경우, 해당 웹툰에 대한 별점 정보도 삭제가된다.
이렇게 되면 webtoon의 전체 별점 수도 하나 감소해야하는 로직도 추가되어야하는 상황이다.
→ Review 내용 컬럼만 Null로 바꿀 것인지? 유저(user)의 별점 정보를 별도의 테이블로 관리해야하는지 논의 필요
( 08.02 수정 )
- Review 삭제시, 별도의 메소드를 추가하여 내용(content)만 null값으로 변경
[ 요구 사항 분석 ]
- 웹툰에 별점을 주는 순간, Review 가 NULL로 생성되기 때문에 리뷰 작성 = 수정과 동일하다.
- 리뷰를 삭제한다.
- 리뷰에 좋아요 버튼을 누른다.
API | Method | request | response |
/api/v1/reviews/{id} | PUT | { "reviewId": "리뷰 Id" "reviewContent" : 수정 할 리뷰 내용 } |
- |
/api/v1/reviews/{id} | DELETE | - | - |
/api/v1/reviews/{id}/like | POST | - | - |
[ 비즈니스 로직 ]
1. id로 해당 리뷰를 찾고, 생성한 메소드를 통해 리뷰 내용을 변경한다.
public void updateReview(Long id, ReviewContentRequestDto reviewDto) {
//해당 리뷰 찾기
Review findReview = reviewRepository.findById(id).orElseThrow(
() -> new IllegalArgumentException("해당 id를 찾을 수 없습니다.")
);
//리뷰 내용 변경
findReview.changeReviewContent(reviewDto);
}
2. 리뷰를 삭제한다. (08.02 수정)
public void deleteReview(Long id) {
//해당 리뷰 찾기
Review findReview = reviewRepository.findById(id).orElseThrow(
() -> new IllegalArgumentException("해당 id를 찾을 수 없습니다.")
);
findReview.deleteReview();
}
3. 좋아요 기능
- 좋아요 버튼을 눌렀을 때, 3가지 상황이 있다.
Case 1. 좋아요 버튼을 한번도 누르지 않은 사용자인 경우
Case 2. 취소 -> 좋아요인 경우
Case 3. 좋아요 -> 취소인 경우
#Case 1
if(reviewLike.getReviewStatus()== null)
{
//전체 카운트 +1
findReview.plusLikeCount();
//ReviewLike에 해당 유저와 리뷰 추가
ReviewLike newReviewLike = ReviewLike.builder()
.review(findReview)
.user(user)
.reviewStatus(ReviewStatus.LIKE)
.build();
reviewLikeRepository.save(newReviewLike);
}
#Case 2
else if(reviewLike.getReviewStatus() == ReviewStatus.CANCLE)
{
//전체 카운트 +1
findReview.plusLikeCount();
//좋아요 상태로 변경
reviewLike.changeStatusLike();
}
#Case 3
else if(reviewLike.getReviewStatus() == ReviewStatus.LIKE)
{
//전체 카운트 -1
findReview.minusLikeCount();
//취소 상태로 변경
reviewLike.changeStatusCancel();
}
[ 테스트 코드 ]
테스트 코드는 역시나 통합 테스트로 진행한다.
1. 리뷰 수정 (=생성)
@DisplayName("리뷰 수정 테스트")
@Test
public void updateReview() throws Exception {
//리뷰 생성
Review review1 = createReview("리뷰 내용1", 4.5F, 13);
Review review2 = createReview("리뷰 내용2", 4.3F, 15);
//웹툰
Webtoon w1 = createWebtoon("제목1", "작가1", "내용1");
em.persist(w1);
em.flush();
//임시 유저
User user = User.builder()
.userName("홍길동")
.userEmail("abc@naver.com")
.userImg(1)
.userGrade(UserGrade.FIRST)
.build();
em.persist(user);
em.flush();
review1.insertWebToonAndUser(w1, user);
review2.insertWebToonAndUser(w1, user);
em.persist(review1);
em.persist(review2);
//then
ReviewContentRequestDto reviewDto = new ReviewContentRequestDto("바뀐 리뷰 내용1");
ReviewContentRequestDto reviewDto2 = new ReviewContentRequestDto("바뀐 리뷰 내용2");
reviewService.updateReview(review1.getId(), reviewDto);
reviewService.updateReview(review2.getId(), reviewDto2);
//when
assertThat(review1.getReviewContent()).isEqualTo(reviewDto.getReviewContent());
assertThat(review2.getReviewContent()).isEqualTo(reviewDto2.getReviewContent());
}
2. 리뷰 삭제 (08.02 수정)
- review table 삭제 되지 않고, content 만 null로 변경
@DisplayName("리뷰를 삭제한다.")
@Test
public void deleteReview() throws Exception {
//given
//리뷰 생성
Review review1 = createReview("리뷰 내용1", 4.5F, 13);
Review review2 = createReview("리뷰 내용2", 4.3F, 15);
em.persist(review1);
em.persist(review2);
//when
reviewService.deleteReview(review1.getId());
//then
assertThat(reviewRepository.findAll().size()).isEqualTo(2);
assertThat(reviewRepository.findById(review1.getId()).get().getReviewContent()).isNull();
}
3. 좋아요 기능
#Case 1
-좋아요 버튼을 처음 누르는 사용자
@DisplayName("리뷰에 좋아요를 누르기 테스트_처음 누르는 사용자")
@Test
public void clickReviewLike() throws Exception{
//given
//임시 유저
User user = User.builder()
.userName("홍길동")
.userEmail("abc@naver.com")
.userImg(1)
.userGrade(UserGrade.FIRST)
.build();
em.persist(user);
em.flush();
//리뷰 생성
Review review1 = createReview("리뷰 내용1", 4.5F, 0);
em.persist(review1);
em.flush();
ReviewLike reviewLike = ReviewLike.builder()
.user(user)
.review(review1)
.reviewStatus(ReviewLikeStatus.CANCLE)
.build();
em.persist(reviewLike);
em.flush();
//when
reviewService.clickReviewLike(review1.getId(),user);
//then
assertThat(review1.getLikeCount()).isEqualTo(1);
assertThat(reviewLikeRepository.findReviewLikeByReviewAndUser(review1,user).getReviewStatus()).isEqualTo(ReviewLikeStatus.LIKE);
}
#Case 2
-좋아요->취소 버튼
@DisplayName("리뷰에 좋아요를 누르기 테스트(좋아요->취소)")
@Test
public void clickReviewLike2() throws Exception{
//given
//임시 유저
User user = User.builder()
.userName("홍길동")
.userEmail("abc@naver.com")
.userImg(1)
.userGrade(UserGrade.FIRST)
.build();
em.persist(user);
//리뷰 생성
Review review1 = createReview("리뷰 내용1", 4.5F, 0);
em.persist(review1);
ReviewLike reviewLike = ReviewLike.builder()
.user(user)
.review(review1)
.reviewStatus(ReviewLikeStatus.LIKE)
.build();
em.persist(reviewLike);
em.flush();
reviewService.clickReviewLike(review1.getId(),user);
assertThat(reviewLike.getReviewStatus()).isEqualTo(ReviewLikeStatus.CANCLE);
}
#Case 3
-취소 -> 다시 좋아요
@DisplayName("리뷰에 좋아요를 누르기 테스트(취소->좋아요)")
@Test
public void clickReviewLike3() throws Exception{
//given
//임시 유저
User user = User.builder()
.userName("홍길동")
.userEmail("abc@naver.com")
.userImg(1)
.userGrade(UserGrade.FIRST)
.build();
em.persist(user);
em.flush();
//리뷰 생성
Review review1 = createReview("리뷰 내용1", 4.5F, 0);
em.persist(review1);
ReviewLike reviewLike = ReviewLike.builder()
.user(user)
.review(review1)
.reviewStatus(ReviewLikeStatus.CANCLE)
.build();
em.persist(reviewLike);
em.flush();
reviewService.clickReviewLike(review1.getId(),user);
assertThat(reviewLike.getReviewStatus()).isEqualTo(ReviewLikeStatus.LIKE);
}
- 통합 테스트로 진행하다보니, 테스트가 조금은 느리고 테스트를 실행할 때 다른 것들에 영향을 받는다.
얼른 단위 테스트로 다시 작성해봐야겠다.
'Spring Project > Webtooniverse' 카테고리의 다른 글
[ Webtooniverse ] 웹툰 상세 페이지 개발 - 비슷한 장르 웹툰 추천 ( feat. Querydsl ) (0) | 2021.08.03 |
---|---|
[ Webtooniverse ] 웹툰 상세 페이지 개발 - 웹툰 별점 등록하기 (0) | 2021.08.02 |
[ Webtooniverse ] 웹툰 상세 페이지 개발 - 웹툰 장르, Review 리스트 (0) | 2021.07.30 |
[ Webtooniverse ] pymysql을 이용하여 Maria DB와 연동 & MySQL 쿼리문 (0) | 2021.07.28 |
[ Webtooniverse ] Maria DB 구축하기 - 네이버 웹툰 크롤링 (0) | 2021.07.28 |