diff --git a/src/main/java/com/example/betteriter/fo_domain/follow/repository/FollowReadRepository.java b/src/main/java/com/example/betteriter/fo_domain/follow/repository/FollowReadRepository.java index d39486e..dd2b832 100644 --- a/src/main/java/com/example/betteriter/fo_domain/follow/repository/FollowReadRepository.java +++ b/src/main/java/com/example/betteriter/fo_domain/follow/repository/FollowReadRepository.java @@ -1,6 +1,7 @@ package com.example.betteriter.fo_domain.follow.repository; import com.example.betteriter.fo_domain.follow.domain.Follow; +import com.example.betteriter.fo_domain.user.domain.Users; import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; @@ -12,4 +13,6 @@ public interface FollowReadRepository extends JpaRepository { List findByFolloweeId(Long followeeId); // 팔로위(나를 팔로우하는 사람) 목록 조회 List findByFollowerId(Long followerId); // 팔로워(내가 팔로우하는 사람) 목록 조회 + + boolean existsByFollowerAndFollowee(Users follower, Users followee); } diff --git a/src/main/java/com/example/betteriter/fo_domain/follow/service/FollowService.java b/src/main/java/com/example/betteriter/fo_domain/follow/service/FollowService.java index b93dbf7..e0dc746 100644 --- a/src/main/java/com/example/betteriter/fo_domain/follow/service/FollowService.java +++ b/src/main/java/com/example/betteriter/fo_domain/follow/service/FollowService.java @@ -44,14 +44,6 @@ public void unfollowing(FollowRequest.UnfollowingDto unfollowingRequestDto) { followWriteRepository.delete(follow); } - - private Follow findFollowData(Users user, Users targetUser) { - Follow follow = followReadRepository.findByFolloweeIdAndFollowerId(user.getId(), targetUser.getId()); - if (follow == null) throw new FollowHandler(ErrorStatus._FOLLOW_NOT_FOUND); - - return follow; - } - @Transactional(readOnly = true) public List getFollowerList(Users user) { List followers = followReadRepository.findByFollowerId(user.getId()); @@ -69,4 +61,17 @@ public List getFolloweeList(Users user) { .map(Follow::getFollower) .collect(Collectors.toList()); } + /** + * - 팔로우 여부 체크 메소드 + **/ + public boolean isFollow(Users follower, Users followee) { + return this.followReadRepository.existsByFollowerAndFollowee(follower,followee); + } + + private Follow findFollowData(Users user, Users targetUser) { + Follow follow = followReadRepository.findByFolloweeIdAndFollowerId(user.getId(), targetUser.getId()); + if (follow == null) throw new FollowHandler(ErrorStatus._FOLLOW_NOT_FOUND); + + return follow; + } } diff --git a/src/main/java/com/example/betteriter/fo_domain/mypage/controller/MypageController.java b/src/main/java/com/example/betteriter/fo_domain/mypage/controller/MypageController.java index 8534f2e..875b71c 100644 --- a/src/main/java/com/example/betteriter/fo_domain/mypage/controller/MypageController.java +++ b/src/main/java/com/example/betteriter/fo_domain/mypage/controller/MypageController.java @@ -44,7 +44,7 @@ public ResponseDto> getReview( } /** - * 내가 쓴 리뷰 조회 + * 내가 스크랩한 리뷰 조회 * * @param id 사용자 id * @return List @@ -58,7 +58,7 @@ public ResponseDto> getScrapReview( } /** - * 내가 쓴 리뷰 조회 + * 내가 좋아요 한 리뷰 조회 * * @param id 사용자 id * @return List @@ -72,7 +72,7 @@ public ResponseDto> getLikeReview( } /** - * 팔로워 조회 (내가 팔로우한 사람) + * 팔로워 조회 (나를 팔로우 하는 사람) * * @param id 사용자 id * @return List @@ -86,7 +86,7 @@ public ResponseDto> getFollower( } /** - * 팔로잉 조회 (나를 팔로우한 사람) + * 팔로잉 조회 (내가 팔로잉 하는 사람) * * @param id 사용자 id * @return List diff --git a/src/main/java/com/example/betteriter/fo_domain/review/controller/ReviewController.java b/src/main/java/com/example/betteriter/fo_domain/review/controller/ReviewController.java index 3d18773..1f46ae4 100644 --- a/src/main/java/com/example/betteriter/fo_domain/review/controller/ReviewController.java +++ b/src/main/java/com/example/betteriter/fo_domain/review/controller/ReviewController.java @@ -1,9 +1,6 @@ package com.example.betteriter.fo_domain.review.controller; -import com.example.betteriter.fo_domain.review.dto.CreateReviewRequestDto; -import com.example.betteriter.fo_domain.review.dto.GetReviewSpecResponseDto; -import com.example.betteriter.fo_domain.review.dto.ReviewDetailResponse; -import com.example.betteriter.fo_domain.review.dto.ReviewResponse; +import com.example.betteriter.fo_domain.review.dto.*; import com.example.betteriter.fo_domain.review.exception.ReviewHandler; import com.example.betteriter.fo_domain.review.service.ReviewService; import com.example.betteriter.global.common.response.ResponseDto; @@ -16,6 +13,7 @@ import org.springframework.web.bind.annotation.*; import javax.validation.Valid; +import java.util.List; import static com.example.betteriter.global.common.code.status.ErrorStatus._METHOD_ARGUMENT_ERROR; @@ -65,13 +63,29 @@ public ResponseDto getReviewsBySearch( } /* 리뷰 상세 조회 */ - @GetMapping("/detail/{reviewId}") + @GetMapping("{reviewId}/detail") public ResponseDto getReviewDetail( @PathVariable Long reviewId ) { return ResponseDto.onSuccess(this.reviewService.getReviewDetail(reviewId)); } + /* 리뷰 상세 좋아요 정보 조회 */ + @GetMapping("/{reviewId}/detail/likes") + public ResponseDto> getReviewDetailLikes( + @PathVariable Long reviewId + ) { + return ResponseDto.onSuccess(this.reviewService.getReviewDetailLikes(reviewId)); + } + + /* 리뷰 상세 댓글 정보 조회 */ + @GetMapping("/{reviewId}/detail/comments") + public ResponseDto> getReviewDetailComments( + @PathVariable Long reviewId + ) { + return ResponseDto.onSuccess(this.reviewService.getReviewDetailComments(reviewId)); + } + /* 리뷰 좋아요 */ @PostMapping("/like/{reviewId}") public ResponseDto reviewLike( diff --git a/src/main/java/com/example/betteriter/fo_domain/review/domain/Review.java b/src/main/java/com/example/betteriter/fo_domain/review/domain/Review.java index 3fa288e..2836fd0 100644 --- a/src/main/java/com/example/betteriter/fo_domain/review/domain/Review.java +++ b/src/main/java/com/example/betteriter/fo_domain/review/domain/Review.java @@ -120,10 +120,21 @@ public void countReviewLikedCount() { this.likedCount += 1; } + // TODO : 제거 public void setReviewImage(ReviewImage reviewImage) { this.reviewImages.add(reviewImage); } + // TODO : 제거 + public void setReviewLikes(List reviewLikes) { + this.reviewLiked = reviewLikes; + } + + // TODO : 제거 + public void setReviewsComment(List comments) { + this.reviewComment = comments; + } + // 매주 월요일 자정 실행 @Scheduled(cron = "0 0 0 ? * MON") public void resetClickCountsScheduler() { diff --git a/src/main/java/com/example/betteriter/fo_domain/review/dto/GetReviewDetailResponseDto.java b/src/main/java/com/example/betteriter/fo_domain/review/dto/GetReviewDetailResponseDto.java index 471d6ce..8373542 100644 --- a/src/main/java/com/example/betteriter/fo_domain/review/dto/GetReviewDetailResponseDto.java +++ b/src/main/java/com/example/betteriter/fo_domain/review/dto/GetReviewDetailResponseDto.java @@ -1,7 +1,6 @@ package com.example.betteriter.fo_domain.review.dto; import com.example.betteriter.fo_domain.review.domain.Review; -import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -13,7 +12,7 @@ @Getter @NoArgsConstructor public class GetReviewDetailResponseDto { - private Long id; // 리뷰 아이디 + private Long reviewId; // 리뷰 아이디 private String productName; // 리뷰 상품명 private List reviewSpecData; // 리뷰 스펙 데이터 private double starPoint; // 리뷰 별점 @@ -25,18 +24,24 @@ public class GetReviewDetailResponseDto { private LocalDate boughtAt; // 구매 일 private LocalDate createdAt; // 작성일 private List reviewImages; // 리뷰 이미지 + private long scrapedCount; // 리뷰 스크랩 갯수 + private long likedCount; // 리뷰 좋아요 갯수 + private long commentCount; // 리뷰 댓글 갯수 private boolean isScrap; // 리뷰 스크랩 여부 private boolean isLike; // 리뷰 좋아요 여부 + private boolean isFollow; // 리뷰 팔로우 여부 + private boolean isMine; // 로그인한 유저 리뷰 작성자 여부 @Builder - public GetReviewDetailResponseDto(Long id, String productName, List reviewSpecData, double starPoint, + public GetReviewDetailResponseDto(Long reviewId, String productName, List reviewSpecData, double starPoint, String goodPoint, String badPoint, String shortReview, String manufacturer, int storeName, LocalDate boughtAt, LocalDate createdAt, List reviewImages, - long scrapedCount, boolean isScrap, boolean isLike + long scrapedCount, long likedCount, long commentCount, + boolean isScrap, boolean isLike, boolean isFollow, boolean isMine ) { - this.id = id; + this.reviewId = reviewId; this.productName = productName; this.reviewSpecData = reviewSpecData; this.starPoint = starPoint; @@ -48,14 +53,19 @@ public GetReviewDetailResponseDto(Long id, String productName, List revi this.boughtAt = boughtAt; this.createdAt = createdAt; this.reviewImages = reviewImages; + this.scrapedCount = scrapedCount; + this.likedCount = likedCount; + this.commentCount = commentCount; this.isScrap = isScrap; this.isLike = isLike; + this.isFollow = isFollow; + this.isMine = isMine; } - public static GetReviewDetailResponseDto from(Review review, boolean isLike, boolean isScrap) { + public static GetReviewDetailResponseDto from(Review review, boolean isLike, boolean isScrap, boolean isFollow, boolean isMine) { return GetReviewDetailResponseDto.builder() - .id(review.getId()) + .reviewId(review.getId()) .productName(review.getProductName()) .reviewSpecData(getReviewSpecDataToStr(review)) .starPoint(review.getStarPoint()) @@ -65,11 +75,15 @@ public static GetReviewDetailResponseDto from(Review review, boolean isLike, boo .manufacturer(review.getManufacturer().getCoName()) .storeName(review.getStoreName()) .boughtAt(review.getBoughtAt()) - .createdAt(review.getCreatedAt() == null ? null : review.getCreatedAt().toLocalDate()) + .createdAt(review.getCreatedAt().toLocalDate()) .reviewImages(GetReviewImageResponseDto.of(review.getReviewImages())) .scrapedCount(review.getScrapedCount()) - .isLike(isLike) + .likedCount(review.getLikedCount()) + .commentCount(review.getReviewComment().size()) .isScrap(isScrap) + .isLike(isLike) + .isFollow(isFollow) + .isMine(isMine) .build(); } diff --git a/src/main/java/com/example/betteriter/fo_domain/review/dto/ReviewCommentResponse.java b/src/main/java/com/example/betteriter/fo_domain/review/dto/ReviewCommentResponse.java new file mode 100644 index 0000000..c64aa96 --- /dev/null +++ b/src/main/java/com/example/betteriter/fo_domain/review/dto/ReviewCommentResponse.java @@ -0,0 +1,72 @@ +package com.example.betteriter.fo_domain.review.dto; + +import com.example.betteriter.fo_domain.comment.domain.Comment; +import com.example.betteriter.fo_domain.user.domain.Users; +import com.example.betteriter.global.constant.Job; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; + +/** + * - 리뷰 댓글 데이터 응답 DTO + **/ +@Getter +@NoArgsConstructor +public class ReviewCommentResponse { + private Long id; + @JsonProperty("reviewCommentUserInfo") + private ReviewCommentUserInfoResponse reviewCommentUserInfoResponse; + private String comment; + private LocalDate createdAt; + private boolean isMine; + + @Builder + public ReviewCommentResponse(Long id, ReviewCommentUserInfoResponse reviewCommentUserInfoResponse, + String comment, LocalDate createdAt, boolean isMine + ) { + this.id = id; + this.reviewCommentUserInfoResponse = reviewCommentUserInfoResponse; + this.comment = comment; + this.createdAt = createdAt; + this.isMine = isMine; + } + + public static ReviewCommentResponse from(Comment comment, boolean isMine) { + return ReviewCommentResponse.builder() + .id(comment.getId()) + .reviewCommentUserInfoResponse(ReviewCommentUserInfoResponse.from(comment.getUsers())) + .comment(comment.getComment()) + .createdAt(comment.getCreatedAt().toLocalDate()) + .isMine(isMine) + .build(); + } + + @Getter + @NoArgsConstructor + public static class ReviewCommentUserInfoResponse { + private Long userId; + private String nickname; + private Job job; + private String profileImage; + + @Builder + public ReviewCommentUserInfoResponse(Long userId, String nickname, Job job, String profileImage) { + this.userId = userId; + this.nickname = nickname; + this.job = job; + this.profileImage = profileImage; + } + + public static ReviewCommentUserInfoResponse from(Users user) { + return ReviewCommentUserInfoResponse.builder() + .userId(user.getId()) + .nickname(user.getUsersDetail().getNickName()) + .job(user.getUsersDetail().getJob()) + .profileImage(user.getUsersDetail().getProfileImage()) + .build(); + } + } +} diff --git a/src/main/java/com/example/betteriter/fo_domain/review/dto/ReviewDetailResponse.java b/src/main/java/com/example/betteriter/fo_domain/review/dto/ReviewDetailResponse.java index 39c5f0a..a1767dc 100644 --- a/src/main/java/com/example/betteriter/fo_domain/review/dto/ReviewDetailResponse.java +++ b/src/main/java/com/example/betteriter/fo_domain/review/dto/ReviewDetailResponse.java @@ -1,6 +1,5 @@ package com.example.betteriter.fo_domain.review.dto; -import com.example.betteriter.fo_domain.comment.domain.Comment; import com.example.betteriter.fo_domain.review.domain.Review; import com.example.betteriter.fo_domain.review.domain.ReviewImage; import com.example.betteriter.fo_domain.review.exception.ReviewHandler; @@ -12,13 +11,18 @@ import lombok.Getter; import lombok.NoArgsConstructor; -import java.time.LocalDate; import java.util.List; import java.util.stream.Collectors; +import static com.example.betteriter.fo_domain.review.dto.GetReviewDetailResponseDto.*; +import static com.example.betteriter.fo_domain.review.dto.ReviewDetailResponse.GetUserResponseDto.from; import static com.example.betteriter.global.common.code.status.ErrorStatus._REVIEW_IMAGE_NOT_FOUND; -@JsonPropertyOrder({"reviewDetail", "writerInfo", "reviewLikeInfo", "reviewCommentInfo", "relatedReviews"}) + +/** + * - 리뷰 상세 조회 응답 DTO +**/ +@JsonPropertyOrder({"reviewDetail", "writerInfo", "relatedReviews"}) @Getter @NoArgsConstructor public class ReviewDetailResponse { @@ -27,37 +31,31 @@ public class ReviewDetailResponse { private GetUserResponseDto writerInfo; // 리뷰 작성자 장보 @JsonProperty("relatedReviews") private List getRelatedReviewResponseDto; // 연관 리뷰 데이터 - private ReviewLikeInfo reviewLikeInfo; // 리뷰 좋아요 데이터 - private ReviewCommentInfo reviewCommentInfo; // 리뷰 댓글 데이터 @Builder public ReviewDetailResponse(GetReviewDetailResponseDto getReviewDetailResponseDto, GetUserResponseDto writerInfo, - List getRelatedReviewResponseDto, - ReviewLikeInfo reviewLikeInfo, - ReviewCommentInfo reviewCommentInfo + List getRelatedReviewResponseDto ) { this.getReviewDetailResponseDto = getReviewDetailResponseDto; this.writerInfo = writerInfo; this.getRelatedReviewResponseDto = getRelatedReviewResponseDto; - this.reviewLikeInfo = reviewLikeInfo; - this.reviewCommentInfo = reviewCommentInfo; } - public static ReviewDetailResponse of(Review review, List relatedReviews, Users currentUser) { - GetReviewDetailResponseDto reviewDetail - = GetReviewDetailResponseDto.from(review,isCurrentUserLikeReview(review,currentUser),isCurrentUserScrapReview(review,currentUser)); // 리뷰 상세 - GetUserResponseDto writerInfo = GetUserResponseDto.from(review.getWriter()); // 리뷰 작성자 데이터 + public static ReviewDetailResponse of(Review review, List relatedReviews, boolean isCurrentUserLikeReview, + boolean isCurrentUserScrapReview, boolean isCurrentUserFollow, boolean isCurrentUserIsReviewWriter + ) { + GetReviewDetailResponseDto reviewDetail // 리뷰 상세 + = GetReviewDetailResponseDto.from(review, isCurrentUserLikeReview, isCurrentUserScrapReview,isCurrentUserFollow, isCurrentUserIsReviewWriter); + + GetUserResponseDto writerInfo = from(review.getWriter()); // 리뷰 작성자 데이터 + List getRelatedReviewResponseDto = GetRelatedReviewResponseDto.from(relatedReviews); // 연관 리뷰 데이터 - ReviewLikeInfo reviewLikeInfo = ReviewLikeInfo.from(review); // 리뷰 좋아요 데이터 - ReviewCommentInfo reviewCommentInfo = ReviewCommentInfo.from(review, currentUser); // 리뷰 댓글 데이터 return ReviewDetailResponse.builder() .getReviewDetailResponseDto(reviewDetail) .writerInfo(writerInfo) .getRelatedReviewResponseDto(getRelatedReviewResponseDto) - .reviewLikeInfo(reviewLikeInfo) - .reviewCommentInfo(reviewCommentInfo) .build(); } @@ -129,128 +127,4 @@ public static ReviewDetailResponse.GetUserResponseDto from(Users writer) { .build(); } } - - /** - * - 좋아요한 유저의 닉네임,프로필,직업 - * - 리뷰의 좋아요 총 갯수 - **/ - @Getter - @NoArgsConstructor - public static class ReviewLikeInfo { - private List reviewLikeUserInfo; - private long reviewLikedCount; - - @Builder - public ReviewLikeInfo(List reviewLikeUserInfo, long reviewLikedCount) { - this.reviewLikeUserInfo = reviewLikeUserInfo; - this.reviewLikedCount = reviewLikedCount; - } - - public static ReviewLikeInfo from(Review review) { - return ReviewLikeInfo.builder() - .reviewLikeUserInfo(review.getReviewLiked() - .stream() - .map(r -> GetUserResponseForLikeAndComment.from(r.getUsers())) - .collect(Collectors.toList())) - .reviewLikedCount(review.getLikedCount()) - .build(); - } - } - - /** - * - 댓글을 단 유저의 닉네임,프로필,직업 (ReviewCommentResponse) - * - 댓글 내용, 댓글 작성일 (ReviewCommentResponse) - * - 댓글 갯수 (ReviewCommentCount) - **/ - @Getter - @NoArgsConstructor - public static class ReviewCommentInfo { - @JsonProperty("reviewComments") - private List reviewCommentResponses; - private long reviewCommentCount; - - @Builder - public ReviewCommentInfo(List reviewCommentResponses, long reviewCommentCount) { - this.reviewCommentResponses = reviewCommentResponses; - this.reviewCommentCount = reviewCommentCount; - } - - public static ReviewCommentInfo from(Review review, Users currentUser) { - return ReviewCommentInfo.builder() - .reviewCommentResponses(ReviewCommentResponse.from(review.getReviewComment(),currentUser)) - .reviewCommentCount(review.getReviewComment().size()) - .build(); - } - - @Getter - @NoArgsConstructor - public static class ReviewCommentResponse { - private Long id; - private GetUserResponseForLikeAndComment reviewCommentUserInfo; - private String comment; - private LocalDate commentCreatedAt; - private boolean isMine; // 로그인한 유저의 댓글인지 여부 - - @Builder - public ReviewCommentResponse(Long id, GetUserResponseForLikeAndComment reviewCommentUserInfo, - String comment, LocalDate commentCreatedAt, boolean isMine - ) { - this.id = id; - this.reviewCommentUserInfo = reviewCommentUserInfo; - this.comment = comment; - this.commentCreatedAt = commentCreatedAt; - this.isMine = isMine; - } - - public static List from(List comments, Users users) { - return comments.stream() - .map(c -> ReviewCommentResponse.builder() - .id(c.getId()) - .reviewCommentUserInfo(GetUserResponseForLikeAndComment.from(c.getUsers())) - .comment(c.getComment()) - .commentCreatedAt(c.getCreatedAt().toLocalDate()) - .isMine(c.getUsers().getId().equals(users.getId())) - .build()) - .collect(Collectors.toList()); - } - } - } - - /* 리뷰 좋아요, 댓글 작성자를 위한 유저 응답 dto */ - @Getter - @NoArgsConstructor - public static class GetUserResponseForLikeAndComment { - private Long id; - private String nickName; - private Job job; - private String profileImage; - - @Builder - public GetUserResponseForLikeAndComment(Long id, String nickName, Job job, String profileImage) { - this.id = id; - this.nickName = nickName; - this.job = job; - this.profileImage = profileImage; - } - - public static GetUserResponseForLikeAndComment from(Users users) { - return GetUserResponseForLikeAndComment.builder() - .id(users.getId()) - .nickName(users.getUsersDetail().getNickName()) - .job(users.getUsersDetail().getJob()) - .profileImage(users.getUsersDetail().getProfileImage()) - .build(); - } - } - - private static boolean isCurrentUserLikeReview(Review review, Users currentUser) { - return review.getReviewLiked().stream() - .anyMatch(reviewLike -> reviewLike.getUsers().getId().equals(currentUser.getId())); - } - - - private static boolean isCurrentUserScrapReview(Review review, Users currentUser) { - return review.getReviewScraped().stream() - .anyMatch(reviewScrap -> reviewScrap.getUsers().getId().equals(currentUser.getId())); - } } \ No newline at end of file diff --git a/src/main/java/com/example/betteriter/fo_domain/review/dto/ReviewLikeResponse.java b/src/main/java/com/example/betteriter/fo_domain/review/dto/ReviewLikeResponse.java new file mode 100644 index 0000000..067c997 --- /dev/null +++ b/src/main/java/com/example/betteriter/fo_domain/review/dto/ReviewLikeResponse.java @@ -0,0 +1,36 @@ +package com.example.betteriter.fo_domain.review.dto; + +import com.example.betteriter.fo_domain.user.domain.Users; +import com.example.betteriter.global.constant.Job; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * - 리뷰 좋아요 데이터 응답 DTO + **/ +@Getter +@NoArgsConstructor +public class ReviewLikeResponse { + private Long userId; + private String nickname; + private Job job; + private String profileImage; + + @Builder + public ReviewLikeResponse(Long userId, String nickname, Job job, String profileImage) { + this.userId = userId; + this.nickname = nickname; + this.job = job; + this.profileImage = profileImage; + } + + public static ReviewLikeResponse from(Users user) { + return ReviewLikeResponse.builder() + .userId(user.getId()) + .nickname(user.getUsersDetail().getNickName()) + .job(user.getUsersDetail().getJob()) + .profileImage(user.getUsersDetail().getProfileImage()) + .build(); + } +} diff --git a/src/main/java/com/example/betteriter/fo_domain/review/repository/ReviewRepository.java b/src/main/java/com/example/betteriter/fo_domain/review/repository/ReviewRepository.java index ddacff5..afc1653 100644 --- a/src/main/java/com/example/betteriter/fo_domain/review/repository/ReviewRepository.java +++ b/src/main/java/com/example/betteriter/fo_domain/review/repository/ReviewRepository.java @@ -40,32 +40,15 @@ public interface ReviewRepository extends JpaRepository { Slice findByProductNameOrderByCreatedAtDesc(String name, Pageable pageable); -// @Query("SELECT r FROM REVIEW r " + -// "LEFT JOIN r.reviewLiked rl " + -// "LEFT JOIN r.reviewScraped rs " + -// "WHERE rs.users = :user " + -// "GROUP BY r.id " + -// "ORDER BY r.createdAt DESC") -// List findAllByTargetId(Long id); -// -// @Query("SELECT r FROM REVIEW r " + -// "LEFT JOIN r.reviewLiked rl " + -// "LEFT JOIN r.reviewScraped rs " + -// "WHERE rs.users = :user " + -// "GROUP BY r.id " + -// "ORDER BY r.createdAt DESC") -// List findAllByUser(Long id); @Query("SELECT r FROM REVIEW r " + "WHERE r.writer = :user " + "ORDER BY r.id DESC") - @Where(clause = "r.status = 'ACTIVE'") List findAllByTargetUser(@Param("user") Users user); @Query("SELECT r FROM REVIEW r " + "WHERE r.writer = :user " + "ORDER BY r.id DESC") - @Where(clause = "r.status != 'DELETED'") List findAllByUser(@Param("user") Users user); @Query("SELECT r FROM REVIEW r " + @@ -73,7 +56,6 @@ public interface ReviewRepository extends JpaRepository { "LEFT JOIN r.reviewScraped rs " + "WHERE rs.users = :user " + "ORDER BY r.id DESC") - @Where(clause = "r.status = 'ACTIVE'") List findAllByReviewScrapedUser(@Param("user") Users user); @Query("SELECT r FROM REVIEW r " + @@ -81,7 +63,6 @@ public interface ReviewRepository extends JpaRepository { "LEFT JOIN r.reviewScraped rs " + "WHERE rl.users = :user " + "ORDER BY r.id DESC") - @Where(clause = "r.status = 'ACTIVE'") List findAllByReviewLikedUser(@Param("user") Users user); /* 좋아요 수 많은 리뷰 조회 */ diff --git a/src/main/java/com/example/betteriter/fo_domain/review/service/ReviewService.java b/src/main/java/com/example/betteriter/fo_domain/review/service/ReviewService.java index 9376187..af86339 100644 --- a/src/main/java/com/example/betteriter/fo_domain/review/service/ReviewService.java +++ b/src/main/java/com/example/betteriter/fo_domain/review/service/ReviewService.java @@ -2,6 +2,8 @@ import com.example.betteriter.bo_domain.menufacturer.service.ManufacturerService; import com.example.betteriter.bo_domain.spec.service.SpecService; +import com.example.betteriter.fo_domain.comment.domain.Comment; +import com.example.betteriter.fo_domain.follow.service.FollowService; import com.example.betteriter.fo_domain.review.domain.*; import com.example.betteriter.fo_domain.review.dto.*; import com.example.betteriter.fo_domain.review.exception.ReviewHandler; @@ -35,6 +37,7 @@ public class ReviewService { private final UserService userService; private final SpecService specService; private final ManufacturerService manufacturerService; + private final FollowService followService; private final ReviewLikeRepository reviewLikeRepository; private final ReviewScrapRepository reviewScrapRepository; @@ -115,8 +118,14 @@ public ReviewDetailResponse getReviewDetail(Long reviewId) { List relatedReviews = this.reviewRepository.findTop4ByProductNameOrderByScrapedCntPlusLikedCntDesc(review.getProductName()); + boolean currentUserLikeReview = this.isCurrentUserLikeReview(review, currentUser); + boolean currentUserScrapReview = this.isCurrentUserScrapReview(review, currentUser); + boolean currentUserFollowReviewWriter = this.isCurrentUserFollowReviewWriter(review, currentUser); + boolean isCurrentUserIsReviewWriter = this.currentUserIsReviewWriter(review, currentUser); + if (relatedReviews.size() == 4) { - return ReviewDetailResponse.of(review, relatedReviews, currentUser); + return ReviewDetailResponse.of(review, relatedReviews, + currentUserLikeReview, currentUserScrapReview, currentUserFollowReviewWriter, isCurrentUserIsReviewWriter); } int remain = 4 - relatedReviews.size(); // 3. 동일한 카테고리 중 좋아요 + 스크랩 순 정렬 조회 (나머지) @@ -126,7 +135,30 @@ public ReviewDetailResponse getReviewDetail(Long reviewId) { List totalRelatedReviews = Stream.concat(relatedReviews.stream(), restRelatedReviews.stream()) .collect(Collectors.toList()); - return ReviewDetailResponse.of(review, totalRelatedReviews, currentUser); + return ReviewDetailResponse.of(review, totalRelatedReviews, + currentUserLikeReview, currentUserScrapReview, + currentUserFollowReviewWriter, isCurrentUserIsReviewWriter); + } + + /* 리뷰 상세 좋아요 조회 */ + @Transactional(readOnly = true) + public List getReviewDetailLikes(Long reviewId) { + // 1. reviewId 에 해당하는 리뷰 조회 + Review review = this.findReviewById(reviewId); + + // 2. review 관련 reviewLike 리스트 가져오기 & 반환 + return review.getReviewLiked().stream() + .map(reviewLike -> ReviewLikeResponse.from(reviewLike.getUsers())) + .collect(Collectors.toList()); + } + + /* 리뷰 상세 댓글 조회 */ + @Transactional(readOnly = true) + public List getReviewDetailComments(Long reviewId) { + Users currentUser = this.getCurrentUser(); + return this.findReviewById(reviewId).getReviewComment().stream() + .map(comment -> ReviewCommentResponse.from(comment, this.isCurrentUserCommentReview(comment, currentUser))) + .collect(Collectors.toList()); } /* 리뷰 좋아요 */ @@ -263,4 +295,27 @@ public List getLikeReviewList(Users user) { public List getTargetReviewList(Users user) { return this.reviewRepository.findAllByTargetUser(user); } + + private boolean isCurrentUserLikeReview(Review review, Users currentUser) { + return review.getReviewLiked().stream() + .anyMatch(reviewLike -> reviewLike.getUsers().getId().equals(currentUser.getId())); + } + + private boolean isCurrentUserScrapReview(Review review, Users currentUser) { + return review.getReviewScraped().stream() + .anyMatch(reviewScrap -> reviewScrap.getUsers().getId().equals(currentUser.getId())); + } + + private boolean currentUserIsReviewWriter(Review review, Users currentUser) { + return review.getWriter().getId().equals(currentUser.getId()); + } + + private boolean isCurrentUserFollowReviewWriter(Review review, Users currentUser) { + return this.followService.isFollow(currentUser, review.getWriter()); + } + + /* 댓글 작성자와 로그인한 유저가 동일한지 확인 */ + private boolean isCurrentUserCommentReview(Comment comment, Users currentUser) { + return currentUser.getId().equals(comment.getUsers().getId()); + } } \ No newline at end of file diff --git a/src/test/java/com/example/betteriter/fo_domain/follow/repository/FollowReadRepositoryTest.java b/src/test/java/com/example/betteriter/fo_domain/follow/repository/FollowReadRepositoryTest.java new file mode 100644 index 0000000..27c550c --- /dev/null +++ b/src/test/java/com/example/betteriter/fo_domain/follow/repository/FollowReadRepositoryTest.java @@ -0,0 +1,91 @@ +package com.example.betteriter.fo_domain.follow.repository; + +import com.example.betteriter.fo_domain.follow.domain.Follow; +import com.example.betteriter.fo_domain.user.domain.Users; +import com.example.betteriter.fo_domain.user.repository.UsersRepository; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.test.context.ActiveProfiles; + +import java.util.List; + +import static com.example.betteriter.global.constant.RoleType.ROLE_USER; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.verify; +import static org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.Replace.NONE; + +@DataJpaTest +@AutoConfigureTestDatabase(replace = NONE) +@ActiveProfiles("test") +class FollowReadRepositoryTest { + + @Autowired + private FollowReadRepository followReadRepository; + + @Autowired + private FollowWriteRepository followWriteRepository; + + @Autowired + private UsersRepository usersRepository; + + @Test + @DisplayName("팔로워와 팔로위 정보가 주어질떄 Follow 엔티티 존재 여부를 확인한다.") + void checkFollowerAndFolloweeTest01() { + // given + + // 팔로워 + Users follower = Users.builder() + .email("danaver12@daum.net") + .roleType(ROLE_USER) + .build(); + + // 팔로위 + Users followee = Users.builder() + .email("whole34@naver.com") + .roleType(ROLE_USER) + .build(); + + this.usersRepository.saveAll(List.of(followee, follower)); + + this.followWriteRepository.save(Follow.builder(). + follower(follower) + .followee(followee).build()); + // when + boolean result = this.followReadRepository.existsByFollowerAndFollowee(follower, followee); + + // then + assertThat(result).isTrue(); + } + + @Test + @DisplayName("팔로워와 팔로위 정보가 주어질때 Follow 엔티티 존재 여부를 확인한다.") + void checkFollowerAndFolloweeTest02(){ + // given + // 팔로워 + Users follower = Users.builder() + .email("danaver12@daum.net") + .roleType(ROLE_USER) + .build(); + + // 팔로위 + Users followee = Users.builder() + .email("whole34@naver.com") + .roleType(ROLE_USER) + .build(); + + this.usersRepository.saveAll(List.of(followee, follower)); + + this.followWriteRepository.save(Follow.builder() + .follower(follower) + .followee(follower) + .build()); + // when + boolean result = this.followReadRepository.existsByFollowerAndFollowee(follower,followee); + + // then + assertThat(result).isFalse(); + } +} \ No newline at end of file diff --git a/src/test/java/com/example/betteriter/fo_domain/review/controller/ReviewControllerTest.java b/src/test/java/com/example/betteriter/fo_domain/review/controller/ReviewControllerTest.java index e4abca8..9e1b03a 100644 --- a/src/test/java/com/example/betteriter/fo_domain/review/controller/ReviewControllerTest.java +++ b/src/test/java/com/example/betteriter/fo_domain/review/controller/ReviewControllerTest.java @@ -29,6 +29,8 @@ import java.util.List; import static com.example.betteriter.global.constant.Category.PC; +import static com.example.betteriter.global.constant.Job.CEO; +import static com.example.betteriter.global.constant.Job.SW_DEVELOPER; import static com.example.betteriter.global.constant.RoleType.ROLE_USER; import static com.example.betteriter.global.constant.Status.ACTIVE; import static org.mockito.ArgumentMatchers.*; @@ -411,7 +413,7 @@ void getReviewDetailControllerTest() throws Exception { .build(); GetReviewDetailResponseDto getReviewDetailResponseDto = GetReviewDetailResponseDto.builder() - .id(1L) + .reviewId(1L) .productName("productName") .reviewSpecData(List.of("spec1", "spec2")) .starPoint(2.0) @@ -440,34 +442,11 @@ void getReviewDetailControllerTest() throws Exception { .writerName("동근") .isExpert(true).build()); - ReviewDetailResponse.ReviewLikeInfo reviewLikeInfo = ReviewDetailResponse.ReviewLikeInfo.builder() - .reviewLikeUserInfo(List.of(ReviewDetailResponse.GetUserResponseForLikeAndComment.builder() - .nickName("nickName") - .job(Job.SW_DEVELOPER) - .profileImage("profileImage") - .build())) - .reviewLikedCount(2L) - .build(); - - ReviewDetailResponse.ReviewCommentInfo reviewCommentInfo = ReviewDetailResponse.ReviewCommentInfo.builder(). - reviewCommentCount(2L) - .reviewCommentResponses(List.of(ReviewDetailResponse.ReviewCommentInfo.ReviewCommentResponse.builder() - .reviewCommentUserInfo(ReviewDetailResponse.GetUserResponseForLikeAndComment.builder() - .nickName("nickName") - .job(Job.SW_DEVELOPER) - .profileImage("profileImage") - .build()) - .comment("comment") - .commentCreatedAt(LocalDate.now()) - .build())) - .build(); ReviewDetailResponse response = ReviewDetailResponse.builder() .getReviewDetailResponseDto(getReviewDetailResponseDto) .writerInfo(writerInfo) .getRelatedReviewResponseDto(getRelatedReviewResponseDtos) - .reviewLikeInfo(reviewLikeInfo) - .reviewCommentInfo(reviewCommentInfo) .build(); given(this.reviewService.getReviewDetail(anyLong())) @@ -533,7 +512,7 @@ void getReviewDetailTest() throws Exception { .build(); GetReviewDetailResponseDto getReviewDetailResponseDto = GetReviewDetailResponseDto.builder() - .id(1L) + .reviewId(1L) .productName("productName") .reviewSpecData(List.of("spec1", "spec2")) .starPoint(2.0) @@ -562,41 +541,17 @@ void getReviewDetailTest() throws Exception { .writerName("동근") .isExpert(true).build()); - ReviewDetailResponse.ReviewLikeInfo reviewLikeInfo = ReviewDetailResponse.ReviewLikeInfo.builder() - .reviewLikeUserInfo(List.of(ReviewDetailResponse.GetUserResponseForLikeAndComment.builder() - .nickName("nickName") - .job(Job.SW_DEVELOPER) - .profileImage("profileImage") - .build())) - .reviewLikedCount(2L) - .build(); - - ReviewDetailResponse.ReviewCommentInfo reviewCommentInfo = ReviewDetailResponse.ReviewCommentInfo.builder(). - reviewCommentCount(2L) - .reviewCommentResponses(List.of(ReviewDetailResponse.ReviewCommentInfo.ReviewCommentResponse.builder() - .reviewCommentUserInfo(ReviewDetailResponse.GetUserResponseForLikeAndComment.builder() - .nickName("nickName") - .job(Job.SW_DEVELOPER) - .profileImage("profileImage") - .build()) - .comment("comment") - .commentCreatedAt(LocalDate.now()) - .isMine(true) - .build())) - .build(); ReviewDetailResponse response = ReviewDetailResponse.builder() .getReviewDetailResponseDto(getReviewDetailResponseDto) .writerInfo(writerInfo) .getRelatedReviewResponseDto(getRelatedReviewResponseDtos) - .reviewLikeInfo(reviewLikeInfo) - .reviewCommentInfo(reviewCommentInfo) .build(); given(this.reviewService.getReviewDetail(anyLong())) .willReturn(response); // when & then - mockMvc.perform(get("/review/detail/{reviewId}", 1L)) + mockMvc.perform(get("/review/{reviewId}/detail", 1L)) .andExpect(status().isOk()) .andDo(print()) .andExpect(jsonPath("$.isSuccess").value(true)) @@ -633,7 +588,7 @@ void getReviewDetailTest02() throws Exception { .build(); GetReviewDetailResponseDto getReviewDetailResponseDto = GetReviewDetailResponseDto.builder() - .id(1L) + .reviewId(1L) .productName("productName") .reviewSpecData(List.of("spec1", "spec2")) .starPoint(2.0) @@ -664,41 +619,17 @@ void getReviewDetailTest02() throws Exception { .writerName("동근") .isExpert(true).build()); - ReviewDetailResponse.ReviewLikeInfo reviewLikeInfo = ReviewDetailResponse.ReviewLikeInfo.builder() - .reviewLikeUserInfo(List.of(ReviewDetailResponse.GetUserResponseForLikeAndComment.builder() - .nickName("nickName") - .job(Job.SW_DEVELOPER) - .profileImage("profileImage") - .build())) - .reviewLikedCount(2L) - .build(); - - ReviewDetailResponse.ReviewCommentInfo reviewCommentInfo = ReviewDetailResponse.ReviewCommentInfo.builder(). - reviewCommentCount(2L) - .reviewCommentResponses(List.of(ReviewDetailResponse.ReviewCommentInfo.ReviewCommentResponse.builder() - .reviewCommentUserInfo(ReviewDetailResponse.GetUserResponseForLikeAndComment.builder() - .nickName("nickName") - .job(Job.SW_DEVELOPER) - .profileImage("profileImage") - .build()) - .comment("comment") - .commentCreatedAt(LocalDate.now()) - .isMine(true) - .build())) - .build(); ReviewDetailResponse response = ReviewDetailResponse.builder() .getReviewDetailResponseDto(getReviewDetailResponseDto) .writerInfo(writerInfo) .getRelatedReviewResponseDto(getRelatedReviewResponseDtos) - .reviewLikeInfo(reviewLikeInfo) - .reviewCommentInfo(reviewCommentInfo) .build(); given(this.reviewService.getReviewDetail(anyLong())) .willReturn(response); // when & then - mockMvc.perform(get("/review/detail/{reviewId}", 1L)) + mockMvc.perform(get("/review/{reviewId}/detail/", 1L)) .andExpect(status().isOk()) .andDo(print()) .andExpect(jsonPath("$.isSuccess").value(true)) @@ -708,4 +639,151 @@ void getReviewDetailTest02() throws Exception { .andExpect(jsonPath("$.result.reviewDetail.like").value(true)) .andExpect(jsonPath("$.result.reviewDetail.scrap").value(true)); } + + @Test + @DisplayName("리뷰 상세 조회 API 변경으로 인한 컨트롤러 테스트 재진행") + void getReviewDetailTest03() throws Exception { + // given + + Users users = Users.builder() + .id(1L) + .email("email") + .roleType(ROLE_USER) + .usersDetail(UsersDetail.builder().nickName("nickname").job(Job.SW_DEVELOPER).build()) + .build(); + + Review review = Review.builder() + .writer(users) + .category(PC) + .productName("productName") + .category(PC) + .price(10) + .storeName(1) + .status(ACTIVE) + .boughtAt(LocalDate.now()) + .starPoint(1) + .goodPoint("goodPoint") + .badPoint("badPoint") + .shortReview("short") + .build(); + + GetReviewDetailResponseDto getReviewDetailResponseDto = GetReviewDetailResponseDto.builder() + .reviewId(1L) + .productName("productName") + .reviewSpecData(List.of("spec1", "spec2")) + .starPoint(2.0) + .goodPoint("goodPoint") + .badPoint("badPoint") + .shortReview("shortReview") + .manufacturer("삼성") + .storeName(1) + .boughtAt(LocalDate.of(2023, 12, 12)) + .createdAt(LocalDate.of(2023, 12, 22)) + .reviewImages(List.of(GetReviewImageResponseDto.builder().imgUrl("imageUrl").orderNum(1).build())) + .scrapedCount(2L) + .likedCount(3L) + .commentCount(100L) + .isFollow(true) + .isMine(false) + .isLike(true) + .isScrap(true) + .build(); + + ReviewDetailResponse.GetUserResponseDto writerInfo = ReviewDetailResponse.GetUserResponseDto.builder() + .id(1L) + .nickName("nickName") + .job(Job.SW_DEVELOPER) + .profileImage("profileImage") + .isExpert(true) + .build(); + + List getRelatedReviewResponseDtos + = List.of(ReviewDetailResponse.GetRelatedReviewResponseDto.builder().productName("productName") + .reviewImage("reviewImage") + .writerName("동근") + .isExpert(true).build()); + + ReviewDetailResponse response = ReviewDetailResponse.builder() + .getReviewDetailResponseDto(getReviewDetailResponseDto) + .writerInfo(writerInfo) + .getRelatedReviewResponseDto(getRelatedReviewResponseDtos) + .build(); + + given(this.reviewService.getReviewDetail(anyLong())) + .willReturn(response); + + // when & then + mockMvc.perform(get("/review/detail/{reviewId}", 1L)) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.result.reviewDetail.manufacturer").value("삼성")) + .andExpect(jsonPath("$.result.reviewDetail.storeName").value(1)); + } + + @Test + @DisplayName("리뷰 상세 좋아요 조회를 한다.") + void getReviewDetailLikeControllerTest() throws Exception { + // given + ReviewLikeResponse response01 = ReviewLikeResponse.builder() + .userId(1L) + .nickname("nick01") + .job(CEO) + .profileImage("profileImage") + .build(); + + ReviewLikeResponse response02 = ReviewLikeResponse.builder() + .userId(2L) + .nickname("nick02") + .job(SW_DEVELOPER) + .profileImage("profileImage") + .build(); + + + List response = List.of(response01, response02); + + given(this.reviewService.getReviewDetailLikes(anyLong())) + .willReturn(response); + // when & then + mockMvc.perform(get("/review/{reviewId}/detail/likes", 1L)) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.isSuccess").value(true)) + .andExpect(jsonPath("$.code").value("SUCCESS_200")) + .andExpect(jsonPath("$.result").isNotEmpty()) + .andExpect(jsonPath("$.result[0].userId").value(1)); + } + + @Test + @DisplayName("리뷰 상세 댓글 조회를 한다.") + void getReviewDetailCommentsControllerTest() throws Exception { + // given + + + ReviewCommentResponse reviewCommentResponse01 = ReviewCommentResponse.builder() + .id(1L) + .reviewCommentUserInfoResponse(ReviewCommentResponse.ReviewCommentUserInfoResponse.builder() + .userId(1L) + .nickname("nick01") + .job(SW_DEVELOPER) + .profileImage("profileImage") + .build()) + .comment("comment01") + .createdAt(LocalDate.now()) + .isMine(true) + .build(); + + List response = List.of(reviewCommentResponse01); + + given(this.reviewService.getReviewDetailComments(1L)) + .willReturn(response); + // when & then + mockMvc.perform(get("/review/{reviewId}/detail/comments", 1L)) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.isSuccess").value(true)) + .andExpect(jsonPath("$.code").value("SUCCESS_200")) + .andExpect(jsonPath("$.result").isNotEmpty()) + .andExpect(jsonPath("$.result[0].id").value(1)) + .andExpect(jsonPath("$.result[0].reviewCommentUserInfo.userId").value(1)); + } } \ No newline at end of file diff --git a/src/test/java/com/example/betteriter/fo_domain/review/repository/ReviewRepositoryTest.java b/src/test/java/com/example/betteriter/fo_domain/review/repository/ReviewRepositoryTest.java index 2471713..edddedb 100644 --- a/src/test/java/com/example/betteriter/fo_domain/review/repository/ReviewRepositoryTest.java +++ b/src/test/java/com/example/betteriter/fo_domain/review/repository/ReviewRepositoryTest.java @@ -784,4 +784,22 @@ void findReviewByIdTest() { review.ifPresent(value -> System.out.println("hello" + value.getReviewLiked().size())); // then } + + @Test + @DisplayName("동일한 제품명을 좋아요 + 스크랩 많은 순으로 조회한다.") + void findTop4ByProductNameOrderByScrapedCntPlusLikedCntDescTest(){ + // given + Review review01 = createReview(1L); + Review review02 = createReview(2L); + Review review03 = createReview(3L); + Review review04 = createReview(4L); + + List reviews = this.reviewRepository.saveAll(List.of(review01, review02, review03, review04)); + + // when + List result = this.reviewRepository.findTop4ByProductNameOrderByScrapedCntPlusLikedCntDesc("productName"); + // then + assertThat(result).hasSize(4); + assertThat(result.get(0).getProductName()).isEqualTo("productName"); + } } \ No newline at end of file diff --git a/src/test/java/com/example/betteriter/fo_domain/review/service/ReviewServiceTest.java b/src/test/java/com/example/betteriter/fo_domain/review/service/ReviewServiceTest.java index a295a8a..e6ec3e6 100644 --- a/src/test/java/com/example/betteriter/fo_domain/review/service/ReviewServiceTest.java +++ b/src/test/java/com/example/betteriter/fo_domain/review/service/ReviewServiceTest.java @@ -5,6 +5,8 @@ import com.example.betteriter.bo_domain.spec.domain.Spec; import com.example.betteriter.bo_domain.spec.domain.SpecData; import com.example.betteriter.bo_domain.spec.service.SpecService; +import com.example.betteriter.fo_domain.comment.domain.Comment; +import com.example.betteriter.fo_domain.follow.service.FollowService; import com.example.betteriter.fo_domain.review.domain.Review; import com.example.betteriter.fo_domain.review.domain.ReviewImage; import com.example.betteriter.fo_domain.review.domain.ReviewLike; @@ -37,7 +39,6 @@ import static com.example.betteriter.global.constant.RoleType.ROLE_USER; import static com.example.betteriter.global.constant.Status.ACTIVE; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.byLessThan; import static org.mockito.ArgumentMatchers.*; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.verify; @@ -57,6 +58,9 @@ public class ReviewServiceTest { @Mock private ManufacturerService manufacturerService; + @Mock + private FollowService followService; + @Mock private ReviewRepository reviewRepository; @@ -74,16 +78,31 @@ public class ReviewServiceTest { private static Review createReview(long count) { - Users users = Users.builder() + Users writer = Users.builder() + .id(1L) .email("email") .roleType(ROLE_USER) .usersDetail(UsersDetail.builder().nickName("nickname").job(Job.SW_DEVELOPER).build()) .build(); + Users user01 = Users.builder() + .id(2L) + .email("email01") + .roleType(ROLE_USER) + .usersDetail(UsersDetail.builder().nickName("nick01").job(Job.SW_DEVELOPER).build()) + .build(); + + Users user02 = Users.builder() + .id(3L) + .email("email02") + .roleType(ROLE_USER) + .usersDetail(UsersDetail.builder().nickName("nick02").job(Job.CEO).build()) + .build(); + Review review = Review.builder() .id(count) - .writer(users) + .writer(writer) .category(PC) .productName("productName") .category(PC) @@ -101,6 +120,15 @@ private static Review createReview(long count) { .shortReview("short") .build(); + List reviewLikes = List.of(ReviewLike.builder().review(review).users(user01).build(), + ReviewLike.builder().review(review).users(user02).build()); + + List comments = List.of(Comment.builder().users(user01).comment("comment01").orderNum(1).groupId(1).status(ACTIVE).build(), + Comment.builder().users(user02).comment("comment02").orderNum(2).groupId(2).status(ACTIVE).build()); + + review.setReviewsComment(comments); + review.setReviewLikes(reviewLikes); + review.setReviewImage(createReviewImage(review)); return review; } @@ -329,16 +357,24 @@ void getReviewDetailTest01() { // given Review review = createReview(1L); + Users currentUser = Users.builder() + .email("danaver12@daum.net") + .roleType(ROLE_USER) + .build(); + given(this.reviewRepository.findById(review.getId())) .willReturn(Optional.of(review)); + given(this.userService.getCurrentUser()) + .willReturn(currentUser); + /* 동일한 제품명 리뷰 조회 */ given(this.reviewRepository.findTop4ByProductNameOrderByScrapedCntPlusLikedCntDesc(anyString())) .willReturn(List.of(createReview(2L), createReview(3L), createReview(4L), createReview(5L))); // when ReviewDetailResponse reviewDetail = this.reviewService.getReviewDetail(1L); // then - assertThat(reviewDetail.getGetReviewDetailResponseDto().getId()).isEqualTo(1L); + assertThat(reviewDetail.getGetReviewDetailResponseDto().getReviewId()).isEqualTo(1L); assertThat(reviewDetail.getGetReviewDetailResponseDto().getProductName()).isEqualTo(review.getProductName()); assertThat(reviewDetail.getGetReviewDetailResponseDto().getScrapedCount()).isEqualTo(1L); assertThat(reviewDetail.getWriterInfo().getId()).isEqualTo(review.getWriter().getId()); @@ -353,24 +389,33 @@ void getReviewDetailTest02() { // given Review review = createReview(1L); + Users currentUser = Users.builder() + .email("danaver12@daum.net") + .roleType(ROLE_USER) + .build(); + given(this.reviewRepository.findById(review.getId())) .willReturn(Optional.of(review)); + given(this.userService.getCurrentUser()) + .willReturn(currentUser); + /* 동일한 제품명 리뷰 조회 (2개) */ given(this.reviewRepository.findTop4ByProductNameOrderByScrapedCntPlusLikedCntDesc(anyString())) .willReturn(List.of(createReview(2L), createReview(3L))); /* 동일한 카테고리 리뷰 조회 (2개) */ given(this.reviewRepository.findReviewByCategoryOrderByScrapedCountAndLikedCount(any(), any())) .willReturn(new SliceImpl<>(List.of(createReview(3L), createReview(4L)))); + // when ReviewDetailResponse reviewDetail = this.reviewService.getReviewDetail(1L); // then - assertThat(reviewDetail.getGetReviewDetailResponseDto().getId()).isEqualTo(1L); + assertThat(reviewDetail.getGetReviewDetailResponseDto().getReviewId()).isEqualTo(1L); assertThat(reviewDetail.getGetReviewDetailResponseDto().getProductName()).isEqualTo(review.getProductName()); assertThat(reviewDetail.getGetReviewDetailResponseDto().getScrapedCount()).isEqualTo(1L); assertThat(reviewDetail.getWriterInfo().getId()).isEqualTo(review.getWriter().getId()); assertThat(reviewDetail.getWriterInfo().getNickName()).isEqualTo(review.getWriter().getUsersDetail().getNickName()); - assertThat(reviewDetail.getReviewLikeInfo().getReviewLikedCount()).isEqualTo(review.getLikedCount()); + verify(reviewRepository, times(1)).findById(anyLong()); verify(reviewRepository, times(1)).findReviewByCategoryOrderByScrapedCountAndLikedCount(any(Category.class), any(Pageable.class)); } @@ -410,7 +455,7 @@ void reviewLikeServiceTest() { @Test @DisplayName("리뷰 스크랩을 한다.") - void reviewScrapServiceTest(){ + void reviewScrapServiceTest() { // given // 스크랩 하는 리뷰 @@ -434,8 +479,51 @@ void reviewScrapServiceTest(){ // when // then - verify(this.reviewRepository,times(1)).findById(anyLong()); - verify(this.userService,times(1)).getCurrentUser(); - verify(this.reviewScrapRepository,times(1)).save(any(ReviewScrap.class)); + verify(this.reviewRepository, times(1)).findById(anyLong()); + verify(this.userService, times(1)).getCurrentUser(); + verify(this.reviewScrapRepository, times(1)).save(any(ReviewScrap.class)); + } + + @Test + @DisplayName("리뷰 상세 조회 좋아요 조회을 한다.") + void getReviewDetailLike() { + // given + Review review = createReview(1L); + + given(this.reviewRepository.findById(anyLong())) + .willReturn(Optional.of(review)); + + // when + List result = this.reviewService.getReviewDetailLikes(1L); + + // then + assertThat(result).hasSize(2); + + for (ReviewLikeResponse reviewLikeResponse : result) { + System.out.println(reviewLikeResponse.getUserId()); + System.out.println(reviewLikeResponse.getNickname()); + } + } + + @Test + @DisplayName("리뷰 상세 조회 댓글 조회를 한다.") + void test() { + // given + Review review = createReview(1L); + + given(this.reviewRepository.findById(anyLong())) + .willReturn(Optional.of(review)); + + given(this.userService.getCurrentUser()) + .willReturn(Users.builder().id(1L).email("email").roleType(ROLE_USER).build()); + // when + List result = this.reviewService.getReviewDetailComments(1L); + // then + assertThat(result).hasSize(2); + verify(userService, times(1)).getCurrentUser(); + for (ReviewCommentResponse reviewCommentResponse : result) { + System.out.println(reviewCommentResponse.getComment()); + System.out.println(reviewCommentResponse.isMine()); + } } } \ No newline at end of file