DevKim

[ Webtooniverse ] 웹툰 상세 페이지 개발 - 리뷰 좋아요 기능 & 리뷰 수정 및 삭제 본문

Spring Project/Webtooniverse

[ Webtooniverse ] 웹툰 상세 페이지 개발 - 리뷰 좋아요 기능 & 리뷰 수정 및 삭제

on_doing 2021. 8. 1. 17:17
728x90

[ 설계 ]

※ 현재 설계의 문제

- 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);

    }

 

- 통합 테스트로 진행하다보니, 테스트가 조금은 느리고 테스트를 실행할 때 다른 것들에 영향을 받는다.

얼른 단위 테스트로 다시 작성해봐야겠다.

728x90
Comments