diff --git a/src/main/java/cotato/bookitlist/member/dto/MemberDto.java b/src/main/java/cotato/bookitlist/member/dto/MemberDto.java index 8918d8f..efd61b5 100644 --- a/src/main/java/cotato/bookitlist/member/dto/MemberDto.java +++ b/src/main/java/cotato/bookitlist/member/dto/MemberDto.java @@ -8,7 +8,7 @@ public record MemberDto( String email, String name, String profileLink, - ProfileStatus profileStatus, + ProfileStatus status, boolean isMe ) { diff --git a/src/main/java/cotato/bookitlist/member/dto/response/MemberResponse.java b/src/main/java/cotato/bookitlist/member/dto/response/MemberResponse.java index 119ed33..7fa6dca 100644 --- a/src/main/java/cotato/bookitlist/member/dto/response/MemberResponse.java +++ b/src/main/java/cotato/bookitlist/member/dto/response/MemberResponse.java @@ -10,7 +10,7 @@ public record MemberResponse( String email, String name, String profileLink, - ProfileStatus profileStatus, + ProfileStatus status, boolean isMe ) { @@ -21,7 +21,7 @@ public static MemberResponse from(MemberDto dto) { dto.email(), dto.name(), dto.profileLink(), - dto.profileStatus(), + dto.status(), true ); } @@ -31,7 +31,7 @@ public static MemberResponse from(MemberDto dto) { null, dto.name(), dto.profileLink(), - dto.profileStatus(), + dto.status(), false ); } diff --git a/src/main/java/cotato/bookitlist/post/service/PostService.java b/src/main/java/cotato/bookitlist/post/service/PostService.java index a54b253..d64b3d6 100644 --- a/src/main/java/cotato/bookitlist/post/service/PostService.java +++ b/src/main/java/cotato/bookitlist/post/service/PostService.java @@ -71,7 +71,10 @@ public PostListResponse getAllPost(Pageable pageable, Long memberId) { @Transactional(readOnly = true) public PostListResponse searchPost(String isbn13, Long memberId, Long loginMemberId, Pageable pageable) { - return PostListResponse.fromDto(postRepository.findPublicPostWithLikedByIsbn13(isbn13, memberId, loginMemberId, pageable), loginMemberId); + return PostListResponse.fromDto( + postRepository.findPublicPostWithLikedByIsbn13(isbn13, memberId, loginMemberId, pageable), + loginMemberId + ); } @Transactional(readOnly = true) diff --git a/src/main/java/cotato/bookitlist/review/controller/ReviewController.java b/src/main/java/cotato/bookitlist/review/controller/ReviewController.java index 75ea4d2..5dac62f 100644 --- a/src/main/java/cotato/bookitlist/review/controller/ReviewController.java +++ b/src/main/java/cotato/bookitlist/review/controller/ReviewController.java @@ -94,14 +94,15 @@ public ResponseEntity getAllReview( @GetMapping public ResponseEntity searchReview( - @IsValidIsbn @RequestParam String isbn13, + @IsValidIsbn @RequestParam(required = false) String isbn13, + @RequestParam(name = "member-id", required = false) Long memberId, @PageableDefault(sort = "createdAt", direction = Sort.Direction.DESC) Pageable pageable, @AuthenticationPrincipal AuthDetails details ) { if (details == null) { - return ResponseEntity.ok(reviewService.searchReview(isbn13, DEFAULT_USER_ID, pageable)); + return ResponseEntity.ok(reviewService.searchReview(isbn13, memberId, DEFAULT_USER_ID, pageable)); } - return ResponseEntity.ok(reviewService.searchReview(isbn13, details.getId(), pageable)); + return ResponseEntity.ok(reviewService.searchReview(isbn13, memberId, details.getId(), pageable)); } @GetMapping("/count") diff --git a/src/main/java/cotato/bookitlist/review/repository/querydsl/ReviewRepositoryCustom.java b/src/main/java/cotato/bookitlist/review/repository/querydsl/ReviewRepositoryCustom.java index 39dbc95..57abb93 100644 --- a/src/main/java/cotato/bookitlist/review/repository/querydsl/ReviewRepositoryCustom.java +++ b/src/main/java/cotato/bookitlist/review/repository/querydsl/ReviewRepositoryCustom.java @@ -8,6 +8,6 @@ import java.util.Optional; public interface ReviewRepositoryCustom { - Page findPublicReviewWithLikedByIsbn13(String isbn13, Long memberId, Pageable pageable); + Page findPublicReviewWithLikedByIsbn13(String isbn13, Long memberId, Long loginMemberId, Pageable pageable); Optional findPublicReviewDetailByReviewId(Long reviewId, Long memberId); } diff --git a/src/main/java/cotato/bookitlist/review/repository/querydsl/ReviewRepositoryCustomImpl.java b/src/main/java/cotato/bookitlist/review/repository/querydsl/ReviewRepositoryCustomImpl.java index 5b5adf5..937458e 100644 --- a/src/main/java/cotato/bookitlist/review/repository/querydsl/ReviewRepositoryCustomImpl.java +++ b/src/main/java/cotato/bookitlist/review/repository/querydsl/ReviewRepositoryCustomImpl.java @@ -29,7 +29,7 @@ public class ReviewRepositoryCustomImpl implements ReviewRepositoryCustom { private final JPAQueryFactory queryFactory; @Override - public Page findPublicReviewWithLikedByIsbn13(String isbn13, Long memberId, Pageable pageable) { + public Page findPublicReviewWithLikedByIsbn13(String isbn13, Long memberId, Long loginMemberId, Pageable pageable) { List result = queryFactory .select( Projections.constructor( @@ -41,7 +41,7 @@ public Page findPublicReviewWithLikedByIsbn13(String isbn13, Long mem review.likeCount, review.viewCount, Expressions.cases() - .when(isLikedByMember(memberId, review.id)) + .when(isLikedByMember(loginMemberId, review.id)) .then(true) .otherwise(false) .as("liked"), @@ -50,7 +50,7 @@ public Page findPublicReviewWithLikedByIsbn13(String isbn13, Long mem ) .from(review) .join(review.member, member) - .where(review.book.isbn13.eq(isbn13), review.status.eq(ReviewStatus.PUBLIC), review.member.status.eq(ProfileStatus.PUBLIC)) + .where(isbnEq(isbn13), memberIdEq(memberId), review.status.eq(ReviewStatus.PUBLIC), review.member.status.eq(ProfileStatus.PUBLIC)) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) .orderBy(review.createdAt.desc()) @@ -59,7 +59,7 @@ public Page findPublicReviewWithLikedByIsbn13(String isbn13, Long mem JPAQuery countQuery = queryFactory .select(review.count()) .from(review) - .where(review.book.isbn13.eq(isbn13)) + .where(isbnEq(isbn13), memberIdEq(memberId)) .from(review); return PageableExecutionUtils.getPage(result, pageable, countQuery::fetchOne); @@ -89,7 +89,7 @@ public Optional findPublicReviewDetailByReviewId(Long reviewId, ) .from(review) .join(review.member, member) - .where(review.id.eq(reviewId), review.status.eq(ReviewStatus.PUBLIC), review.member.status.eq(ProfileStatus.PUBLIC)) + .where(review.id.eq(reviewId), buildReviewAccessCondition(review.member.id, memberId)) .fetchOne()); } @@ -100,4 +100,26 @@ private BooleanExpression isLikedByMember(Long memberId, NumberPath review .and(reviewLike.review.id.eq(reviewId))) .exists(); } + + private BooleanExpression isbnEq(String isbn13) { + if (isbn13 == null) { + return null; + } + return review.book.isbn13.eq(isbn13); + } + + private BooleanExpression memberIdEq(Long memberId) { + if (memberId == null) { + return null; + } + return review.member.id.eq(memberId); + } + + private BooleanExpression buildReviewAccessCondition(NumberPath reviewMemberId, Long memberId) { + return Expressions.cases() + .when(reviewMemberId.eq(memberId)) + .then(true) + .otherwise(review.status.eq(ReviewStatus.PUBLIC) + .and(review.member.status.eq(ProfileStatus.PUBLIC))); + } } diff --git a/src/main/java/cotato/bookitlist/review/service/ReviewService.java b/src/main/java/cotato/bookitlist/review/service/ReviewService.java index 5ac6238..7b8ec9f 100644 --- a/src/main/java/cotato/bookitlist/review/service/ReviewService.java +++ b/src/main/java/cotato/bookitlist/review/service/ReviewService.java @@ -70,8 +70,11 @@ public ReviewListResponse getAllReview(Pageable pageable, Long memberId) { } @Transactional(readOnly = true) - public ReviewListResponse searchReview(String isbn13, Long memberId, Pageable pageable) { - return ReviewListResponse.fromDto(reviewRepository.findPublicReviewWithLikedByIsbn13(isbn13, memberId, pageable), memberId); + public ReviewListResponse searchReview(String isbn13, Long memberId, Long loginMemberId, Pageable pageable) { + return ReviewListResponse.fromDto( + reviewRepository.findPublicReviewWithLikedByIsbn13(isbn13, memberId, loginMemberId, pageable), + loginMemberId + ); } @Transactional(readOnly = true) diff --git a/src/test/java/cotato/bookitlist/post/controller/PostControllerTest.java b/src/test/java/cotato/bookitlist/post/controller/PostControllerTest.java index 079f1a5..6469703 100644 --- a/src/test/java/cotato/bookitlist/post/controller/PostControllerTest.java +++ b/src/test/java/cotato/bookitlist/post/controller/PostControllerTest.java @@ -438,10 +438,11 @@ void givenPostIdNonPrivate_whenDeletingPost_thenDeletePost() throws Exception { @DisplayName("로그인한 유저가 memberId를 이용해 게시글을 조회한다.") void givenMemberIdWithLogin_whenSearchingPost_thenReturnPostListResponse() throws Exception { //given + Long memberId = 2L; //when & then mockMvc.perform(get("/posts") - .param("member-id", "2") + .param("member-id", String.valueOf(memberId)) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(jsonPath("$.totalResults").value(6)) @@ -451,13 +452,14 @@ void givenMemberIdWithLogin_whenSearchingPost_thenReturnPostListResponse() throw @Test - @DisplayName("유저가 memberId를 이용해 게시글을 조회한다.") + @DisplayName("로그인 하지 않은 유저가 memberId를 이용해 게시글을 조회한다.") void givenMemberId_whenSearchingPost_thenReturnPostListResponse() throws Exception { //given + Long memberId = 2L; //when & then mockMvc.perform(get("/posts") - .param("member-id", "2") + .param("member-id", String.valueOf(memberId)) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(jsonPath("$.totalResults").value(6)) diff --git a/src/test/java/cotato/bookitlist/review/controller/ReviewControllerTest.java b/src/test/java/cotato/bookitlist/review/controller/ReviewControllerTest.java index 17bb957..e23401d 100644 --- a/src/test/java/cotato/bookitlist/review/controller/ReviewControllerTest.java +++ b/src/test/java/cotato/bookitlist/review/controller/ReviewControllerTest.java @@ -344,6 +344,38 @@ void givenPrivateReviewId_whenDeletingReview_thenDeleteReview() throws Exception ; } + @Test + @WithCustomMockUser + @DisplayName("로그인한 유저가 memberId를 이용해 한줄요약을 조회한다.") + void givenMemberIdWithLogin_whenSearchingReview_thenReturnReviewListResponse() throws Exception { + //given + Long memberId = 2L; + + //when & then + mockMvc.perform(get("/reviews") + .param("member-id", String.valueOf(memberId)) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.totalResults").value(5)) + .andExpect(jsonPath("$.reviewList[0].liked").value(true)) + ; + } + + @Test + @DisplayName("로그인하지 않은 유저가 memberId를 이용해 한줄요약을 조회한다.") + void givenMemberId_whenSearchingReview_thenReturnReviewListResponse() throws Exception { + //given + Long memberId = 2L; + + //when & then + mockMvc.perform(get("/reviews") + .param("member-id", String.valueOf(memberId)) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(jsonPath("$.totalResults").value(5)) + .andExpect(jsonPath("$.reviewList[0].liked").value(false)) + ; + } + @Test @DisplayName("좋아요가 많은 순으로 한줄요약을 4개 반환한다.") void givenPageStartAndRecommendType_whenGettingMostLikeReviews_thenReturnMostLikeReviews() throws Exception {