From dfc3dcb9628c391888ee2094a4ec19d55ac72857 Mon Sep 17 00:00:00 2001 From: ahnyunki Date: Wed, 27 Mar 2024 16:39:38 +0900 Subject: [PATCH 1/6] =?UTF-8?q?feat:=20TalkRoom=20=EC=A2=8B=EC=95=84?= =?UTF-8?q?=EC=9A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84=20(#40)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/talkroom/TalkRoomController.java | 1 - .../talkroomlike/TalkRoomLikeController.java | 44 ++++ .../response/TalkRoomFindAllResponse.java | 14 +- .../response/TalkRoomFindOneResponse.java | 23 ++- .../response/TalkRoomLikeQueryResponse.java | 22 ++ .../response/TalkRoomLikeUserIdResponse.java | 22 ++ ...ava => TalkRoomQueryCommentsResponse.java} | 4 +- ...> TalkRoomQueryReadingStatusResponse.java} | 4 +- .../talkroomlike/TalkRoomLikeService.java | 55 +++++ .../repository/TalkRoomRepositoryImpl.java | 191 +++++++++++++----- .../domain/talkroomlike/TalkRoomLike.java | 16 +- .../repository/TalkRoomLikeRepository.java | 12 ++ .../com/jisungin/exception/ErrorCode.java | 3 +- 13 files changed, 350 insertions(+), 61 deletions(-) create mode 100644 src/main/java/com/jisungin/api/talkroomlike/TalkRoomLikeController.java create mode 100644 src/main/java/com/jisungin/application/talkroom/response/TalkRoomLikeQueryResponse.java create mode 100644 src/main/java/com/jisungin/application/talkroom/response/TalkRoomLikeUserIdResponse.java rename src/main/java/com/jisungin/application/talkroom/response/{TalkRoomQueryComments.java => TalkRoomQueryCommentsResponse.java} (76%) rename src/main/java/com/jisungin/application/talkroom/response/{TalkRoomQueryReadingStatus.java => TalkRoomQueryReadingStatusResponse.java} (75%) create mode 100644 src/main/java/com/jisungin/application/talkroomlike/TalkRoomLikeService.java create mode 100644 src/main/java/com/jisungin/domain/talkroomlike/repository/TalkRoomLikeRepository.java diff --git a/src/main/java/com/jisungin/api/talkroom/TalkRoomController.java b/src/main/java/com/jisungin/api/talkroom/TalkRoomController.java index 02a3aea..0523ad5 100644 --- a/src/main/java/com/jisungin/api/talkroom/TalkRoomController.java +++ b/src/main/java/com/jisungin/api/talkroom/TalkRoomController.java @@ -31,7 +31,6 @@ public class TalkRoomController { private final TalkRoomService talkRoomService; - // TODO. 회원 도메인이 개발되면 변경 예정 @PostMapping("/talk-rooms") public ApiResponse createTalkRoom(@Valid @RequestBody TalkRoomCreateRequest request, @Auth AuthContext authContext) { diff --git a/src/main/java/com/jisungin/api/talkroomlike/TalkRoomLikeController.java b/src/main/java/com/jisungin/api/talkroomlike/TalkRoomLikeController.java new file mode 100644 index 0000000..ad81678 --- /dev/null +++ b/src/main/java/com/jisungin/api/talkroomlike/TalkRoomLikeController.java @@ -0,0 +1,44 @@ +package com.jisungin.api.talkroomlike; + +import com.jisungin.api.ApiResponse; +import com.jisungin.api.oauth.Auth; +import com.jisungin.api.oauth.AuthContext; +import com.jisungin.application.talkroomlike.TalkRoomLikeService; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RequiredArgsConstructor +@RequestMapping("/v1") +@RestController +public class TalkRoomLikeController { + + private final TalkRoomLikeService talkRoomLikeService; + + @PostMapping("/talk-rooms/{talkRoomId}/likes") + public ApiResponse likeTalkRoom(@PathVariable Long talkRoomId, + @Auth AuthContext authContext) { + talkRoomLikeService.likeTalkRoom(talkRoomId, authContext.getUserId()); + + return ApiResponse.builder() + .message("좋아요 성공") + .status(HttpStatus.OK) + .build(); + } + + @DeleteMapping("/talk-rooms/{talkRoomId}/likes") + public ApiResponse nuLikeTalkRoom(@PathVariable Long talkRoomId, + @Auth AuthContext authContext) { + talkRoomLikeService.unLikeTalkRoom(talkRoomId, authContext.getUserId()); + + return ApiResponse.builder() + .message("좋아요 취소") + .status(HttpStatus.OK) + .build(); + } + +} diff --git a/src/main/java/com/jisungin/application/talkroom/response/TalkRoomFindAllResponse.java b/src/main/java/com/jisungin/application/talkroom/response/TalkRoomFindAllResponse.java index 3601052..0953fa6 100644 --- a/src/main/java/com/jisungin/application/talkroom/response/TalkRoomFindAllResponse.java +++ b/src/main/java/com/jisungin/application/talkroom/response/TalkRoomFindAllResponse.java @@ -17,7 +17,9 @@ public class TalkRoomFindAllResponse { private String content; private String bookName; private String bookImage; - private List readingStatuses = new ArrayList<>(); + private List readingStatuses = new ArrayList<>(); + private List likeCounts = new ArrayList<>(); + private List userIds = new ArrayList<>(); @Builder @QueryProjection @@ -31,8 +33,16 @@ public TalkRoomFindAllResponse(Long talkRoomId, String userName, String title, S this.bookImage = bookImage; } - public void addTalkRoomStatus(List readingStatuses) { + public void addTalkRoomStatus(List readingStatuses) { this.readingStatuses = readingStatuses; } + public void addTalkRoomLikeUserIds(List userIds) { + this.userIds = userIds; + } + + public void addLikeCounts(List likeCounts) { + this.likeCounts = likeCounts; + } + } diff --git a/src/main/java/com/jisungin/application/talkroom/response/TalkRoomFindOneResponse.java b/src/main/java/com/jisungin/application/talkroom/response/TalkRoomFindOneResponse.java index a9c3a55..b4f7f39 100644 --- a/src/main/java/com/jisungin/application/talkroom/response/TalkRoomFindOneResponse.java +++ b/src/main/java/com/jisungin/application/talkroom/response/TalkRoomFindOneResponse.java @@ -17,8 +17,11 @@ public class TalkRoomFindOneResponse { private String content; private String bookName; private String bookImage; - private List readingStatuses = new ArrayList<>(); - private List comments = new ArrayList<>(); + private List readingStatuses = new ArrayList<>(); + private List comments = new ArrayList<>(); + private Long likeCount; + private Long commentCount; + private List userIds = new ArrayList<>(); @Builder @QueryProjection @@ -32,12 +35,24 @@ public TalkRoomFindOneResponse(Long talkRoomId, String userName, String title, S this.bookImage = bookImage; } - public void addTalkRoomStatus(List readingStatuses) { + public void addTalkRoomStatus(List readingStatuses) { this.readingStatuses = readingStatuses; } - public void addTalkRoomComments(List comments) { + public void addTalkRoomComments(List comments) { this.comments = comments; } + public void addLikeCount(Long likeCount) { + this.likeCount = likeCount; + } + + public void addCommentCount(Long commentCount) { + this.commentCount = commentCount; + } + + public void addUserIds(List userIds) { + this.userIds = userIds; + } + } diff --git a/src/main/java/com/jisungin/application/talkroom/response/TalkRoomLikeQueryResponse.java b/src/main/java/com/jisungin/application/talkroom/response/TalkRoomLikeQueryResponse.java new file mode 100644 index 0000000..118c8f3 --- /dev/null +++ b/src/main/java/com/jisungin/application/talkroom/response/TalkRoomLikeQueryResponse.java @@ -0,0 +1,22 @@ +package com.jisungin.application.talkroom.response; + +import com.querydsl.core.annotations.QueryProjection; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class TalkRoomLikeQueryResponse { + + private Long talkRoomId; + private Long likeCount; + + @Builder + @QueryProjection + public TalkRoomLikeQueryResponse(Long talkRoomId, Long likeCount) { + this.talkRoomId = talkRoomId; + this.likeCount = likeCount; + } + +} diff --git a/src/main/java/com/jisungin/application/talkroom/response/TalkRoomLikeUserIdResponse.java b/src/main/java/com/jisungin/application/talkroom/response/TalkRoomLikeUserIdResponse.java new file mode 100644 index 0000000..8748b91 --- /dev/null +++ b/src/main/java/com/jisungin/application/talkroom/response/TalkRoomLikeUserIdResponse.java @@ -0,0 +1,22 @@ +package com.jisungin.application.talkroom.response; + +import com.querydsl.core.annotations.QueryProjection; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class TalkRoomLikeUserIdResponse { + + private Long talkRoomId; + private Long userId; + + @Builder + @QueryProjection + public TalkRoomLikeUserIdResponse(Long talkRoomId, Long userId) { + this.talkRoomId = talkRoomId; + this.userId = userId; + } + +} diff --git a/src/main/java/com/jisungin/application/talkroom/response/TalkRoomQueryComments.java b/src/main/java/com/jisungin/application/talkroom/response/TalkRoomQueryCommentsResponse.java similarity index 76% rename from src/main/java/com/jisungin/application/talkroom/response/TalkRoomQueryComments.java rename to src/main/java/com/jisungin/application/talkroom/response/TalkRoomQueryCommentsResponse.java index d9d5489..34e549e 100644 --- a/src/main/java/com/jisungin/application/talkroom/response/TalkRoomQueryComments.java +++ b/src/main/java/com/jisungin/application/talkroom/response/TalkRoomQueryCommentsResponse.java @@ -7,7 +7,7 @@ @Getter @NoArgsConstructor -public class TalkRoomQueryComments { +public class TalkRoomQueryCommentsResponse { private Long commentId; private String userName; @@ -15,7 +15,7 @@ public class TalkRoomQueryComments { @Builder @QueryProjection - public TalkRoomQueryComments(Long commentId, String userName, String content) { + public TalkRoomQueryCommentsResponse(Long commentId, String userName, String content) { this.commentId = commentId; this.userName = userName; this.content = content; diff --git a/src/main/java/com/jisungin/application/talkroom/response/TalkRoomQueryReadingStatus.java b/src/main/java/com/jisungin/application/talkroom/response/TalkRoomQueryReadingStatusResponse.java similarity index 75% rename from src/main/java/com/jisungin/application/talkroom/response/TalkRoomQueryReadingStatus.java rename to src/main/java/com/jisungin/application/talkroom/response/TalkRoomQueryReadingStatusResponse.java index 8399f40..7a4a393 100644 --- a/src/main/java/com/jisungin/application/talkroom/response/TalkRoomQueryReadingStatus.java +++ b/src/main/java/com/jisungin/application/talkroom/response/TalkRoomQueryReadingStatusResponse.java @@ -8,7 +8,7 @@ @Getter @NoArgsConstructor -public class TalkRoomQueryReadingStatus { +public class TalkRoomQueryReadingStatusResponse { private Long talkRoomId; @@ -16,7 +16,7 @@ public class TalkRoomQueryReadingStatus { @Builder @QueryProjection - public TalkRoomQueryReadingStatus(Long talkRoomId, ReadingStatus readingStatus) { + public TalkRoomQueryReadingStatusResponse(Long talkRoomId, ReadingStatus readingStatus) { this.talkRoomId = talkRoomId; this.readingStatus = readingStatus; } diff --git a/src/main/java/com/jisungin/application/talkroomlike/TalkRoomLikeService.java b/src/main/java/com/jisungin/application/talkroomlike/TalkRoomLikeService.java new file mode 100644 index 0000000..2a9bc29 --- /dev/null +++ b/src/main/java/com/jisungin/application/talkroomlike/TalkRoomLikeService.java @@ -0,0 +1,55 @@ +package com.jisungin.application.talkroomlike; + +import com.jisungin.domain.talkroom.TalkRoom; +import com.jisungin.domain.talkroom.repository.TalkRoomRepository; +import com.jisungin.domain.talkroomlike.TalkRoomLike; +import com.jisungin.domain.talkroomlike.repository.TalkRoomLikeRepository; +import com.jisungin.domain.user.User; +import com.jisungin.domain.user.repository.UserRepository; +import com.jisungin.exception.BusinessException; +import com.jisungin.exception.ErrorCode; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Transactional(readOnly = true) +@RequiredArgsConstructor +@Service +public class TalkRoomLikeService { + + private final TalkRoomLikeRepository talkRoomLikeRepository; + private final TalkRoomRepository talkRoomRepository; + private final UserRepository userRepository; + + @Transactional + public void likeTalkRoom(Long talkRoomId, Long userId) { + TalkRoom talkRoom = talkRoomRepository.findById(talkRoomId) + .orElseThrow(() -> new BusinessException(ErrorCode.TALK_ROOM_NOT_FOUND)); + + User user = userRepository.findById(userId).orElseThrow(() -> new BusinessException(ErrorCode.USER_NOT_FOUND)); + + if (talkRoomLikeRepository.findByTalkRoomIdAndUserId(talkRoomId, userId).isPresent()) { + throw new BusinessException(ErrorCode.LIKE_EXIST); + } + + TalkRoomLike talkRoomLike = TalkRoomLike.likeTalkRoom(user, talkRoom); + + talkRoomLikeRepository.save(talkRoomLike); + } + + + @Transactional + public void unLikeTalkRoom(Long talkRoomId, Long userId) { + TalkRoom talkRoom = talkRoomRepository.findById(talkRoomId) + .orElseThrow(() -> new BusinessException(ErrorCode.TALK_ROOM_NOT_FOUND)); + + User user = userRepository.findById(userId) + .orElseThrow(() -> new BusinessException(ErrorCode.TALK_ROOM_NOT_FOUND)); + + TalkRoomLike talkRoomLike = talkRoomLikeRepository.findByTalkRoomIdAndUserId(talkRoom.getId(), user.getId()) + .orElseThrow(() -> new BusinessException(ErrorCode.TALK_ROOM_LIKE_NOT_FOUND)); + + talkRoomLikeRepository.delete(talkRoomLike); + } + +} diff --git a/src/main/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryImpl.java b/src/main/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryImpl.java index 0175155..0945dd7 100644 --- a/src/main/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryImpl.java +++ b/src/main/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryImpl.java @@ -4,18 +4,23 @@ import static com.jisungin.domain.comment.QComment.comment; import static com.jisungin.domain.talkroom.QTalkRoom.talkRoom; import static com.jisungin.domain.talkroom.QTalkRoomRole.talkRoomRole; +import static com.jisungin.domain.talkroomlike.QTalkRoomLike.talkRoomLike; import static com.jisungin.domain.user.QUser.user; import com.jisungin.application.response.PageResponse; import com.jisungin.application.talkroom.request.TalkRoomSearchServiceRequest; import com.jisungin.application.talkroom.response.QTalkRoomFindAllResponse; import com.jisungin.application.talkroom.response.QTalkRoomFindOneResponse; -import com.jisungin.application.talkroom.response.QTalkRoomQueryComments; -import com.jisungin.application.talkroom.response.QTalkRoomQueryReadingStatus; +import com.jisungin.application.talkroom.response.QTalkRoomLikeQueryResponse; +import com.jisungin.application.talkroom.response.QTalkRoomLikeUserIdResponse; +import com.jisungin.application.talkroom.response.QTalkRoomQueryCommentsResponse; +import com.jisungin.application.talkroom.response.QTalkRoomQueryReadingStatusResponse; import com.jisungin.application.talkroom.response.TalkRoomFindAllResponse; import com.jisungin.application.talkroom.response.TalkRoomFindOneResponse; -import com.jisungin.application.talkroom.response.TalkRoomQueryComments; -import com.jisungin.application.talkroom.response.TalkRoomQueryReadingStatus; +import com.jisungin.application.talkroom.response.TalkRoomLikeQueryResponse; +import com.jisungin.application.talkroom.response.TalkRoomLikeUserIdResponse; +import com.jisungin.application.talkroom.response.TalkRoomQueryCommentsResponse; +import com.jisungin.application.talkroom.response.TalkRoomQueryReadingStatusResponse; import com.querydsl.core.types.OrderSpecifier; import com.querydsl.jpa.impl.JPAQueryFactory; import java.util.List; @@ -28,6 +33,7 @@ public class TalkRoomRepositoryImpl implements TalkRoomRepositoryCustom { private final JPAQueryFactory queryFactory; + // 토크룸 페이징 조회 @Override public PageResponse findAllTalkRoom(TalkRoomSearchServiceRequest search) { @@ -35,11 +41,21 @@ public PageResponse findAllTalkRoom(TalkRoomSearchServi List findTalkRoom = findTalkRoomBySearch(search); //TalkRoomRole 컬렉션을 MAP 한방에 조회 - Map> talkRoomRoleMap = findTalkRoomRoleMap(toTalkRoomIds(findTalkRoom)); + Map> talkRoomRoleMap = findTalkRoomRoleMap( + toTalkRoomIds(findTalkRoom)); //루프를 돌면서 컬렉션 추가(추가 쿼리 실행X) findTalkRoom.forEach(t -> t.addTalkRoomStatus(talkRoomRoleMap.get(t.getTalkRoomId()))); + // 좋아요 추가 + Map> likeCountMap = talkRoomLikeCount(toTalkRoomIds(findTalkRoom)); + findTalkRoom.forEach(t -> t.addLikeCounts(likeCountMap.get(t.getTalkRoomId()))); + + // 좋아요한 유저 ID 정보들 + Map> talkRoomLikeUserMap = findTalkRoomLikeUserId( + toTalkRoomIds(findTalkRoom)); + findTalkRoom.forEach(t -> t.addTalkRoomLikeUserIds(talkRoomLikeUserMap.get(t.getTalkRoomId()))); + long totalCount = getTotalTalkRoomCount(); return PageResponse.builder() @@ -49,63 +65,141 @@ public PageResponse findAllTalkRoom(TalkRoomSearchServi .build(); } + // 토크룸 단건 조회 @Override public TalkRoomFindOneResponse findOneTalkRoom(Long talkRoomId) { TalkRoomFindOneResponse findOneTalkRoom = findTalkRoomByTalkRoomId(talkRoomId); - List talkRoomRoles = findTalkRoomRoleByTalkRoomId(talkRoomId); + List talkRoomRoles = findTalkRoomRoleByTalkRoomId(talkRoomId); findOneTalkRoom.addTalkRoomStatus(talkRoomRoles); - List talkRoomComments = findCommentsByTalkRoomId(talkRoomId); + List talkRoomComments = findCommentsByTalkRoomId(talkRoomId); findOneTalkRoom.addTalkRoomComments(talkRoomComments); + findOneTalkRoom.addLikeCount(findOneTalkRoomLikeCount(talkRoomId)); + + findOneTalkRoom.addCommentCount(findOneTalkRoomCommentCount(talkRoomId)); + + List userIds = findOneTalkRoomLikeUserId(talkRoomId); + findOneTalkRoom.addUserIds(userIds); + return findOneTalkRoom; } - private List findCommentsByTalkRoomId(Long talkRoomId) { - return queryFactory.select(new QTalkRoomQueryComments( - comment.id.as("commentId"), + // 토크룸 페이징 조회 쿼리 + private List findTalkRoomBySearch(TalkRoomSearchServiceRequest search) { + return queryFactory.select(new QTalkRoomFindAllResponse( + talkRoom.id.as("talkRoomId"), user.name.as("userName"), - comment.content + talkRoom.title, + talkRoom.content, + book.title, + book.imageUrl.as("bookImage") )) - .from(comment) - .join(comment.talkRoom, talkRoom) - .join(comment.user, user) - .where(comment.talkRoom.id.eq(talkRoomId)) + .from(talkRoom) + .join(talkRoom.user, user) + .join(talkRoom.book, book) + .offset(search.getOffset()) + .limit(search.getSize()) + .orderBy(condition(search.getOrder())) .fetch(); } - private List findTalkRoomRoleByTalkRoomId(Long talkRoomId) { - return queryFactory.select(new QTalkRoomQueryReadingStatus( - talkRoom.id, - talkRoomRole.readingStatus - )) + // 쿼리에서 가져온 토크룸 ID를 List 객체에 넣어주는 로직 + private List toTalkRoomIds(List findTalkRoom) { + return findTalkRoom.stream() + .map(t -> t.getTalkRoomId()) + .collect(Collectors.toList()); + } + + // 토크룸 상태 가져온 후 Map<>에 넣어주는 로직 + private Map> findTalkRoomRoleMap(List talkRoomIds) { + List talkRoomRoles = queryFactory.select( + new QTalkRoomQueryReadingStatusResponse( + talkRoom.id, + talkRoomRole.readingStatus + )) .from(talkRoomRole) .join(talkRoomRole.talkRoom, talkRoom) - .where(talkRoomRole.talkRoom.id.eq(talkRoomId)) + .where(talkRoomRole.talkRoom.id.in(talkRoomIds)) + .fetch(); + + return talkRoomRoles.stream() + .collect(Collectors.groupingBy(TalkRoomQueryReadingStatusResponse::getTalkRoomId)); + } + + // 좋아요 총 개수 가져온 후 Map<>에 넣어주는 로직 + public Map> talkRoomLikeCount(List talkRoomId) { + List likeCount = queryFactory.select(new QTalkRoomLikeQueryResponse( + talkRoom.id.as("talkRoomId"), + talkRoomLike.count().as("likeCount") + )) + .from(talkRoomLike) + .join(talkRoomLike.talkRoom, talkRoom) + .where(talkRoomLike.talkRoom.id.in(talkRoomId)) + .groupBy(talkRoom.id) .fetch(); + + return likeCount.stream() + .collect(Collectors.groupingBy(TalkRoomLikeQueryResponse::getTalkRoomId)); } - private List toTalkRoomIds(List findTalkRoom) { - return findTalkRoom.stream() - .map(t -> t.getTalkRoomId()) - .collect(Collectors.toList()); + // 토크룸 좋아요 누른 사용자 ID 가져온 후 Map<>에 넣어주는 로직 + private Map> findTalkRoomLikeUserId(List talkRoomIds) { + List talkRoomLikeUserIds = queryFactory.select(new QTalkRoomLikeUserIdResponse( + talkRoom.id.as("talkRoomId"), + user.id.as("userId") + )) + .from(talkRoomLike) + .join(talkRoomLike.talkRoom, talkRoom) + .join(talkRoomLike.user, user) + .where(talkRoomLike.talkRoom.id.in(talkRoomIds)) + .fetch(); + + return talkRoomLikeUserIds.stream() + .collect(Collectors.groupingBy(TalkRoomLikeUserIdResponse::getTalkRoomId)); + } + + // 토크룸 좋아요 누른 사용자 ID 가져온 후 Map<>에 넣어주는 로직 + private List findOneTalkRoomLikeUserId(Long talkRoomId) { + return queryFactory.select(new QTalkRoomLikeUserIdResponse( + talkRoom.id.as("talkRoomId"), + user.id.as("userId") + )) + .from(talkRoomLike) + .join(talkRoomLike.talkRoom, talkRoom) + .join(talkRoomLike.user, user) + .where(talkRoomLike.talkRoom.id.eq(talkRoomId)) + .fetch(); } - private Map> findTalkRoomRoleMap(List talkRoomIds) { - List talkRoomRoles = queryFactory.select(new QTalkRoomQueryReadingStatus( + // 토크룸 단건 조회 시 토크룸 상태 가져오는 쿼리 + private List findTalkRoomRoleByTalkRoomId(Long talkRoomId) { + return queryFactory.select(new QTalkRoomQueryReadingStatusResponse( talkRoom.id, talkRoomRole.readingStatus )) .from(talkRoomRole) .join(talkRoomRole.talkRoom, talkRoom) - .where(talkRoomRole.talkRoom.id.in(talkRoomIds)) + .where(talkRoomRole.talkRoom.id.eq(talkRoomId)) .fetch(); + } - return talkRoomRoles.stream() - .collect(Collectors.groupingBy(TalkRoomQueryReadingStatus::getTalkRoomId)); + // 토크룸에 저장된 의견들 가져오는 쿼리 + private List findCommentsByTalkRoomId(Long talkRoomId) { + return queryFactory.select(new QTalkRoomQueryCommentsResponse( + comment.id.as("commentId"), + user.name.as("userName"), + comment.content + )) + .from(comment) + .join(comment.talkRoom, talkRoom) + .join(comment.user, user) + .where(comment.talkRoom.id.eq(talkRoomId)) + .fetch(); } + // 토크룸 전체 개수 가져오는 쿼리 private long getTotalTalkRoomCount() { return queryFactory .select(talkRoom.count()) @@ -115,24 +209,7 @@ private long getTotalTalkRoomCount() { .fetchOne(); } - private List findTalkRoomBySearch(TalkRoomSearchServiceRequest search) { - return queryFactory.select(new QTalkRoomFindAllResponse( - talkRoom.id.as("talkRoomId"), - user.name.as("userName"), - talkRoom.title, - talkRoom.content, - book.title, - book.imageUrl.as("bookImage") - )) - .from(talkRoom) - .join(talkRoom.user, user) - .join(talkRoom.book, book) - .offset(search.getOffset()) - .limit(search.getSize()) - .orderBy(condition(search.getOrder())) - .fetch(); - } - + // 토크룸 단건 조회 쿼리 private TalkRoomFindOneResponse findTalkRoomByTalkRoomId(Long talkRoomId) { return queryFactory.select(new QTalkRoomFindOneResponse( talkRoom.id.as("talkRoomId"), @@ -149,6 +226,24 @@ private TalkRoomFindOneResponse findTalkRoomByTalkRoomId(Long talkRoomId) { .fetchOne(); } + // 토크룸 단건 조회 시 좋아요 총 개수 찾아오는 로직 + private Long findOneTalkRoomLikeCount(Long talkRoomId) { + return queryFactory.select(talkRoomLike.count()) + .from(talkRoomLike) + .join(talkRoomLike.talkRoom, talkRoom) + .where(talkRoomLike.talkRoom.id.eq(talkRoomId)) + .fetchOne(); + } + + // 토크룸 단건 조회 시 의견 총 개수 가져오는 로직 + private Long findOneTalkRoomCommentCount(Long talkRoomId) { + return queryFactory.select(comment.count()) + .from(comment) + .join(comment.talkRoom, talkRoom) + .where(comment.talkRoom.id.eq(talkRoomId)) + .fetchOne(); + } + /** * 아직 좋아요 기능이 구현 되지 않아 최신순으로만 정렬 */ diff --git a/src/main/java/com/jisungin/domain/talkroomlike/TalkRoomLike.java b/src/main/java/com/jisungin/domain/talkroomlike/TalkRoomLike.java index 9c55e0d..6e09bd0 100644 --- a/src/main/java/com/jisungin/domain/talkroomlike/TalkRoomLike.java +++ b/src/main/java/com/jisungin/domain/talkroomlike/TalkRoomLike.java @@ -3,7 +3,14 @@ import com.jisungin.domain.BaseEntity; import com.jisungin.domain.talkroom.TalkRoom; import com.jisungin.domain.user.User; -import jakarta.persistence.*; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; @@ -33,4 +40,11 @@ private TalkRoomLike(User user, TalkRoom talkRoom) { this.talkRoom = talkRoom; } + public static TalkRoomLike likeTalkRoom(User user, TalkRoom talkRoom) { + return TalkRoomLike.builder() + .user(user) + .talkRoom(talkRoom) + .build(); + } + } diff --git a/src/main/java/com/jisungin/domain/talkroomlike/repository/TalkRoomLikeRepository.java b/src/main/java/com/jisungin/domain/talkroomlike/repository/TalkRoomLikeRepository.java new file mode 100644 index 0000000..fb33c44 --- /dev/null +++ b/src/main/java/com/jisungin/domain/talkroomlike/repository/TalkRoomLikeRepository.java @@ -0,0 +1,12 @@ +package com.jisungin.domain.talkroomlike.repository; + +import com.jisungin.domain.talkroomlike.TalkRoomLike; +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface TalkRoomLikeRepository extends JpaRepository { + + Optional findByTalkRoomIdAndUserId(Long talkRoomId, Long userId); +} diff --git a/src/main/java/com/jisungin/exception/ErrorCode.java b/src/main/java/com/jisungin/exception/ErrorCode.java index e6a3e33..39b131b 100644 --- a/src/main/java/com/jisungin/exception/ErrorCode.java +++ b/src/main/java/com/jisungin/exception/ErrorCode.java @@ -17,7 +17,8 @@ public enum ErrorCode { UNAUTHORIZED_REQUEST(400, "권한이 없는 사용자입니다."), COMMENT_NOT_FOUND(404, "의견을 찾을 수 없습니다."), REVIEW_NOT_FOUND(404, "리뷰를 찾을 수 없습니다."), - REQUEST_TIME_OUT(408, "요청 시간이 만료 되었습니다."); + TALK_ROOM_LIKE_NOT_FOUND(404, "토크방 좋아요를 찾을 수 없습니다."), + LIKE_EXIST(400, "이미 좋아요를 눌렀습니다."); private final int code; From e3f728fc3cd90de0599f0ab9630733790357f929 Mon Sep 17 00:00:00 2001 From: ahnyunki Date: Wed, 27 Mar 2024 16:40:05 +0900 Subject: [PATCH 2/6] =?UTF-8?q?feat:=20TalkRoom=20=EC=A2=8B=EC=95=84?= =?UTF-8?q?=EC=9A=94=20=EA=B8=B0=EB=8A=A5=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1=20(#40)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/jisungin/ControllerTestSupport.java | 8 +- .../TalkRoomLikeControllerTest.java | 44 +++ .../service/talkroom/TalkRoomServiceTest.java | 294 ++++++++++++++++++ .../talkroomlike/TalkRoomLikeServiceTest.java | 232 ++++++++++++++ .../TalkRoomRepositoryImplTest.java | 242 ++++++++++++++ 5 files changed, 819 insertions(+), 1 deletion(-) create mode 100644 src/test/java/com/jisungin/api/talkroomlike/TalkRoomLikeControllerTest.java create mode 100644 src/test/java/com/jisungin/application/talkroomlike/TalkRoomLikeServiceTest.java diff --git a/src/test/java/com/jisungin/ControllerTestSupport.java b/src/test/java/com/jisungin/ControllerTestSupport.java index 5928924..9f12774 100644 --- a/src/test/java/com/jisungin/ControllerTestSupport.java +++ b/src/test/java/com/jisungin/ControllerTestSupport.java @@ -5,9 +5,11 @@ import com.jisungin.api.oauth.AuthContext; import com.jisungin.api.review.ReviewController; import com.jisungin.api.talkroom.TalkRoomController; +import com.jisungin.api.talkroomlike.TalkRoomLikeController; import com.jisungin.application.comment.CommentService; import com.jisungin.application.review.ReviewService; import com.jisungin.application.talkroom.TalkRoomService; +import com.jisungin.application.talkroomlike.TalkRoomLikeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; @@ -16,7 +18,8 @@ @WebMvcTest(controllers = { TalkRoomController.class, CommentController.class, - ReviewController.class + ReviewController.class, + TalkRoomLikeController.class }) public abstract class ControllerTestSupport { @@ -38,4 +41,7 @@ public abstract class ControllerTestSupport { @MockBean protected ReviewService reviewService; + @MockBean + protected TalkRoomLikeService talkRoomLikeService; + } diff --git a/src/test/java/com/jisungin/api/talkroomlike/TalkRoomLikeControllerTest.java b/src/test/java/com/jisungin/api/talkroomlike/TalkRoomLikeControllerTest.java new file mode 100644 index 0000000..c0c8872 --- /dev/null +++ b/src/test/java/com/jisungin/api/talkroomlike/TalkRoomLikeControllerTest.java @@ -0,0 +1,44 @@ +package com.jisungin.api.talkroomlike; + +import static org.springframework.http.MediaType.APPLICATION_JSON; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import com.jisungin.ControllerTestSupport; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class TalkRoomLikeControllerTest extends ControllerTestSupport { + + @Test + @DisplayName("유저가 토크방에 좋아요를 누를 수 있다.") + void likeTalkRoom() throws Exception { + // when // then + mockMvc.perform(post("/v1/talk-rooms/1/likes") + .contentType(APPLICATION_JSON) + ) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value("200")) + .andExpect(jsonPath("$.status").value("OK")) + .andExpect(jsonPath("$.message").value("좋아요 성공")); + } + + @Test + @DisplayName("유저가 토크방 좋아요를 취소 할 수 있다.") + void unLikeTalkRoom() throws Exception { + // when // then + mockMvc.perform(delete("/v1/talk-rooms/1/likes") + .contentType(APPLICATION_JSON) + ) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value("200")) + .andExpect(jsonPath("$.status").value("OK")) + .andExpect(jsonPath("$.message").value("좋아요 취소")); + } + +} \ No newline at end of file diff --git a/src/test/java/com/jisungin/application/service/talkroom/TalkRoomServiceTest.java b/src/test/java/com/jisungin/application/service/talkroom/TalkRoomServiceTest.java index 383e5f7..8d368aa 100644 --- a/src/test/java/com/jisungin/application/service/talkroom/TalkRoomServiceTest.java +++ b/src/test/java/com/jisungin/application/service/talkroom/TalkRoomServiceTest.java @@ -23,12 +23,15 @@ import com.jisungin.domain.talkroom.TalkRoomRole; import com.jisungin.domain.talkroom.repository.TalkRoomRepository; import com.jisungin.domain.talkroom.repository.TalkRoomRoleRepository; +import com.jisungin.domain.talkroomlike.TalkRoomLike; +import com.jisungin.domain.talkroomlike.repository.TalkRoomLikeRepository; import com.jisungin.domain.user.User; import com.jisungin.domain.user.repository.UserRepository; import com.jisungin.exception.BusinessException; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; import java.util.stream.IntStream; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.DisplayName; @@ -55,8 +58,12 @@ class TalkRoomServiceTest extends ServiceTestSupport { @Autowired CommentRepository commentRepository; + @Autowired + TalkRoomLikeRepository talkRoomLikeRepository; + @AfterEach void tearDown() { + talkRoomLikeRepository.deleteAllInBatch(); commentRepository.deleteAllInBatch(); talkRoomRoleRepository.deleteAllInBatch(); talkRoomRepository.deleteAllInBatch(); @@ -610,6 +617,293 @@ void deleteTalkRoomWithComment() { assertThat(0).isEqualTo(talkRoomRepository.findAll().size()); } + @Test + @DisplayName("토크방을 페이징 조회 시 토크방에는 좋아요 총 개수가 표시되어야 한다.") + void findAllTalkRoomWithLikeCount() { + // given + List users = IntStream.range(0, 10) + .mapToObj(i -> User.builder() + .name("user@gmail.com " + i) + .profileImage("image") + .oauthId( + OauthId.builder() + .oauthId("oauthId " + i) + .oauthType(OauthType.KAKAO) + .build() + ) + .build()).toList(); + + userRepository.saveAll(users); + + Book book = createBook(); + bookRepository.save(book); + + List talkRoom = IntStream.range(0, 20) + .mapToObj(i -> TalkRoom.builder() + .user(users.get(0)) + .book(book) + .title("토론방 " + i) + .content("내용 " + i) + .build()) + .toList(); + + talkRoomRepository.saveAll(talkRoom); + + for (TalkRoom t : talkRoom) { + createTalkRoomRole(t); + } + + List likes = IntStream.range(0, 5).mapToObj(i -> TalkRoomLike.builder() + .user(users.get(i)) + .talkRoom(talkRoom.get(0)) + .build()) + .toList(); + + talkRoomLikeRepository.saveAll(likes); + + TalkRoomSearchServiceRequest search = TalkRoomSearchServiceRequest.builder() + .page(2) + .size(10) + .order(null) + .build(); + + // when + PageResponse response = talkRoomService.findAllTalkRoom(search); + + // then + assertThat(5L).isEqualTo(response.getQueryResponse().get(9).getLikeCounts().get(0).getLikeCount()); + } + + @Test + @DisplayName("토크방 페이지 조회 시 토크방에 좋아요 누른 사용자 ID들이 프론트에 전송되어야 한다.") + void findAllTalkRoomWithLikeUserId() { + // given + List users = IntStream.range(0, 10) + .mapToObj(i -> User.builder() + .name("user@gmail.com " + i) + .profileImage("image") + .oauthId( + OauthId.builder() + .oauthId("oauthId " + i) + .oauthType(OauthType.KAKAO) + .build() + ) + .build()).toList(); + + userRepository.saveAll(users); + + Book book = createBook(); + bookRepository.save(book); + + List talkRoom = IntStream.range(0, 20) + .mapToObj(i -> TalkRoom.builder() + .user(users.get(0)) + .book(book) + .title("토론방 " + i) + .content("내용 " + i) + .build()) + .toList(); + + talkRoomRepository.saveAll(talkRoom); + + for (TalkRoom t : talkRoom) { + createTalkRoomRole(t); + } + + List likes1 = IntStream.range(0, 5).mapToObj(i -> TalkRoomLike.builder() + .user(users.get(i)) + .talkRoom(talkRoom.get(0)) + .build()) + .toList(); + + List likes2 = IntStream.range(5, 10).mapToObj(i -> TalkRoomLike.builder() + .user(users.get(i)) + .talkRoom(talkRoom.get(i)) + .build()) + .toList(); + + List likes = new ArrayList<>(); + likes.addAll(likes1); + likes.addAll(likes2); + + talkRoomLikeRepository.saveAll(likes); + + TalkRoomSearchServiceRequest search = TalkRoomSearchServiceRequest.builder() + .page(2) + .size(10) + .order(null) + .build(); + + // when + PageResponse response = talkRoomService.findAllTalkRoom(search); + + // then + assertThat(users.get(0).getId()).isEqualTo(response.getQueryResponse().get(9).getUserIds().get(0).getUserId()); + assertThat(users.get(1).getId()).isEqualTo(response.getQueryResponse().get(9).getUserIds().get(1).getUserId()); + assertThat(users.get(2).getId()).isEqualTo(response.getQueryResponse().get(9).getUserIds().get(2).getUserId()); + assertThat(users.get(3).getId()).isEqualTo(response.getQueryResponse().get(9).getUserIds().get(3).getUserId()); + assertThat(users.get(4).getId()).isEqualTo(response.getQueryResponse().get(9).getUserIds().get(4).getUserId()); + } + + @Test + @DisplayName("토크방 단건 조회 시 좋아요 개수가 표시 된다.") + void findOneTalkRoomWithLikeCount() { + // given + List users = IntStream.range(0, 10) + .mapToObj(i -> User.builder() + .name("user@gmail.com " + i) + .profileImage("image") + .oauthId( + OauthId.builder() + .oauthId("oauthId " + i) + .oauthType(OauthType.KAKAO) + .build() + ) + .build()).toList(); + + userRepository.saveAll(users); + + Book book = createBook(); + bookRepository.save(book); + + List talkRoom = IntStream.range(0, 20) + .mapToObj(i -> TalkRoom.builder() + .user(users.get(0)) + .book(book) + .title("토론방 " + i) + .content("내용 " + i) + .build()) + .toList(); + + talkRoomRepository.saveAll(talkRoom); + + for (TalkRoom t : talkRoom) { + createTalkRoomRole(t); + } + + List likes = IntStream.range(0, 5).mapToObj(i -> TalkRoomLike.builder() + .user(users.get(i)) + .talkRoom(talkRoom.get(0)) + .build()) + .toList(); + + talkRoomLikeRepository.saveAll(likes); + + // when + TalkRoomFindOneResponse response = talkRoomService.findOneTalkRoom(talkRoom.get(0).getId()); + + // then + assertThat(5L).isEqualTo(response.getLikeCount()); + } + + @Test + @DisplayName("토크방 단건 조회 시 좋아요한 유저의 ID가 보내진다.") + void findOneTalkRoomWithLikeUserId() { + // given + List users = IntStream.range(0, 10) + .mapToObj(i -> User.builder() + .name("user@gmail.com " + i) + .profileImage("image") + .oauthId( + OauthId.builder() + .oauthId("oauthId " + i) + .oauthType(OauthType.KAKAO) + .build() + ) + .build()).toList(); + + userRepository.saveAll(users); + + Book book = createBook(); + bookRepository.save(book); + + List talkRoom = IntStream.range(0, 20) + .mapToObj(i -> TalkRoom.builder() + .user(users.get(0)) + .book(book) + .title("토론방 " + i) + .content("내용 " + i) + .build()) + .toList(); + + talkRoomRepository.saveAll(talkRoom); + + for (TalkRoom t : talkRoom) { + createTalkRoomRole(t); + } + + List likes = IntStream.range(0, 5).mapToObj(i -> TalkRoomLike.builder() + .user(users.get(i)) + .talkRoom(talkRoom.get(0)) + .build()) + .toList(); + + talkRoomLikeRepository.saveAll(likes); + + // when + TalkRoomFindOneResponse response = talkRoomService.findOneTalkRoom(talkRoom.get(0).getId()); + + // then + assertThat(users.get(0).getId()).isEqualTo(response.getUserIds().get(0).getUserId()); + assertThat(users.get(1).getId()).isEqualTo(response.getUserIds().get(1).getUserId()); + assertThat(users.get(2).getId()).isEqualTo(response.getUserIds().get(2).getUserId()); + assertThat(users.get(3).getId()).isEqualTo(response.getUserIds().get(3).getUserId()); + assertThat(users.get(4).getId()).isEqualTo(response.getUserIds().get(4).getUserId()); + } + + @Test + @DisplayName("토크방 단건 조회 시 의견 개수가 표시 된다.") + void findOneTalkRoomWithCommentCount() { + // given + List users = IntStream.range(0, 10) + .mapToObj(i -> User.builder() + .name("user@gmail.com " + i) + .profileImage("image") + .oauthId( + OauthId.builder() + .oauthId("oauthId " + i) + .oauthType(OauthType.KAKAO) + .build() + ) + .build()).toList(); + + userRepository.saveAll(users); + + Book book = createBook(); + bookRepository.save(book); + + List talkRoom = IntStream.range(0, 20) + .mapToObj(i -> TalkRoom.builder() + .user(users.get(0)) + .book(book) + .title("토론방 " + i) + .content("내용 " + i) + .build()) + .toList(); + + talkRoomRepository.saveAll(talkRoom); + + for (TalkRoom t : talkRoom) { + createTalkRoomRole(t); + } + + List comments = IntStream.range(0, 5) + .mapToObj(i -> Comment.builder() + .talkRoom(talkRoom.get(0)) + .user(users.get(0)) + .content("의견 " + i) + .build()) + .collect(Collectors.toList()); + + commentRepository.saveAll(comments); + + // when + TalkRoomFindOneResponse response = talkRoomService.findOneTalkRoom(talkRoom.get(0).getId()); + + // then + assertThat(5L).isEqualTo(response.getCommentCount()); + } + private static Comment createComment(TalkRoom talkRoom, User user) { return Comment.builder() .talkRoom(talkRoom) diff --git a/src/test/java/com/jisungin/application/talkroomlike/TalkRoomLikeServiceTest.java b/src/test/java/com/jisungin/application/talkroomlike/TalkRoomLikeServiceTest.java new file mode 100644 index 0000000..6a7bd8c --- /dev/null +++ b/src/test/java/com/jisungin/application/talkroomlike/TalkRoomLikeServiceTest.java @@ -0,0 +1,232 @@ +package com.jisungin.application.talkroomlike; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import com.jisungin.ServiceTestSupport; +import com.jisungin.application.talkroom.TalkRoomService; +import com.jisungin.domain.ReadingStatus; +import com.jisungin.domain.book.Book; +import com.jisungin.domain.book.repository.BookRepository; +import com.jisungin.domain.oauth.OauthId; +import com.jisungin.domain.oauth.OauthType; +import com.jisungin.domain.talkroom.TalkRoom; +import com.jisungin.domain.talkroom.TalkRoomRole; +import com.jisungin.domain.talkroom.repository.TalkRoomRepository; +import com.jisungin.domain.talkroom.repository.TalkRoomRoleRepository; +import com.jisungin.domain.talkroomlike.TalkRoomLike; +import com.jisungin.domain.talkroomlike.repository.TalkRoomLikeRepository; +import com.jisungin.domain.user.User; +import com.jisungin.domain.user.repository.UserRepository; +import com.jisungin.exception.BusinessException; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +class TalkRoomLikeServiceTest extends ServiceTestSupport { + + @Autowired + TalkRoomRepository talkRoomRepository; + + @Autowired + TalkRoomRoleRepository talkRoomRoleRepository; + + @Autowired + TalkRoomService talkRoomService; + + @Autowired + BookRepository bookRepository; + + @Autowired + UserRepository userRepository; + + @Autowired + TalkRoomLikeService talkRoomLikeService; + + @Autowired + TalkRoomLikeRepository talkRoomLikeRepository; + + @AfterEach + void tearDown() { + talkRoomLikeRepository.deleteAllInBatch(); + talkRoomRoleRepository.deleteAllInBatch(); + talkRoomRepository.deleteAllInBatch(); + userRepository.deleteAllInBatch(); + bookRepository.deleteAllInBatch(); + } + + @Test + @DisplayName("유저가 토크방을 좋아요 한다.") + void likeTalkRoom() { + // given + User user = createUser(); + userRepository.save(user); + + Book book = createBook(); + bookRepository.save(book); + + TalkRoom talkRoom = createTalkRoom(book, user); + talkRoomRepository.save(talkRoom); + + createTalkRoomRole(talkRoom); + + // when + talkRoomLikeService.likeTalkRoom(talkRoom.getId(), user.getId()); + + // then + List talkRoomLikes = talkRoomLikeRepository.findAll(); + assertThat(1).isEqualTo(talkRoomLikes.size()); + } + + @Test + @DisplayName("토크방이 없는 상태에선 좋아요 할 수 없다.") + void likeTalkRoomWithTalkRoomEmpty() { + // given + User user = createUser(); + userRepository.save(user); + + // when // then + assertThatThrownBy(() -> talkRoomLikeService.likeTalkRoom(1L, user.getId())) + .isInstanceOf(BusinessException.class) + .hasMessage("토크방을 찾을 수 없습니다."); + } + + @Test + @DisplayName("로그인을 하지 않는 상태에선 좋아요를 누를 수 없다.") + void likeTalkRoomWithUserEmpty() { + // given + User user = createUser(); + userRepository.save(user); + + Book book = createBook(); + bookRepository.save(book); + + TalkRoom talkRoom = createTalkRoom(book, user); + talkRoomRepository.save(talkRoom); + + createTalkRoomRole(talkRoom); + // when // then + assertThatThrownBy(() -> talkRoomLikeService.likeTalkRoom(talkRoom.getId(), 100L)) + .isInstanceOf(BusinessException.class) + .hasMessage("사용자를 찾을 수 없습니다."); + } + + @Test + @DisplayName("유저가 좋아요를 취소한다.") + void unLikeTalkRoom() { + // given + User user = createUser(); + userRepository.save(user); + + Book book = createBook(); + bookRepository.save(book); + + TalkRoom talkRoom = createTalkRoom(book, user); + talkRoomRepository.save(talkRoom); + + createTalkRoomRole(talkRoom); + + TalkRoomLike talkRoomLike = createTalkRoomLike(talkRoom, user); + talkRoomLikeRepository.save(talkRoomLike); + + // when + talkRoomLikeService.unLikeTalkRoom(talkRoom.getId(), user.getId()); + + // then + List talkRoomLikes = talkRoomLikeRepository.findAll(); + assertThat(0).isEqualTo(talkRoomLikes.size()); + } + + @Test + @DisplayName("유저A의 좋아요를 유저B가 취소할 순 없다.") + void unLikeTalkRoomWithUserB() { + // given + User user = createUser(); + userRepository.save(user); + + User userB = User.builder() + .name("userB@gmail.com") + .profileImage("image") + .oauthId( + OauthId.builder() + .oauthId("oauthId2") + .oauthType(OauthType.KAKAO) + .build() + ) + .build(); + userRepository.save(userB); + + Book book = createBook(); + bookRepository.save(book); + + TalkRoom talkRoom = createTalkRoom(book, user); + talkRoomRepository.save(talkRoom); + + createTalkRoomRole(talkRoom); + + TalkRoomLike talkRoomLike = createTalkRoomLike(talkRoom, user); + talkRoomLikeRepository.save(talkRoomLike); + + // when // then + assertThatThrownBy(() -> talkRoomLikeService.unLikeTalkRoom(talkRoom.getId(), userB.getId())) + .isInstanceOf(BusinessException.class) + .hasMessage("토크방 좋아요를 찾을 수 없습니다."); + } + + private static TalkRoomLike createTalkRoomLike(TalkRoom talkRoom, User user) { + return TalkRoomLike.builder() + .talkRoom(talkRoom) + .user(user) + .build(); + } + + private void createTalkRoomRole(TalkRoom talkRoom) { + List request = new ArrayList<>(); + request.add("읽는 중"); + request.add("읽음"); + + List readingStatus = ReadingStatus.createReadingStatus(request); + + readingStatus.stream().map(status -> TalkRoomRole.roleCreate(talkRoom, status)) + .forEach(talkRoomRoleRepository::save); + } + + private static TalkRoom createTalkRoom(Book book, User user) { + return TalkRoom.builder() + .book(book) + .title("토크방") + .content("내용") + .user(user) + .build(); + } + + private static User createUser() { + return User.builder() + .name("user@gmail.com") + .profileImage("image") + .oauthId( + OauthId.builder() + .oauthId("oauthId") + .oauthType(OauthType.KAKAO) + .build() + ) + .build(); + } + + private static Book createBook() { + return Book.builder() + .title("제목") + .content("내용") + .authors("작가") + .isbn("11111") + .publisher("publisher") + .dateTime(LocalDateTime.now()) + .imageUrl("www") + .build(); + } + +} \ No newline at end of file diff --git a/src/test/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryImplTest.java b/src/test/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryImplTest.java index 050d3aa..2848746 100644 --- a/src/test/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryImplTest.java +++ b/src/test/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryImplTest.java @@ -16,11 +16,14 @@ import com.jisungin.domain.oauth.OauthType; import com.jisungin.domain.talkroom.TalkRoom; import com.jisungin.domain.talkroom.TalkRoomRole; +import com.jisungin.domain.talkroomlike.TalkRoomLike; +import com.jisungin.domain.talkroomlike.repository.TalkRoomLikeRepository; import com.jisungin.domain.user.User; import com.jisungin.domain.user.repository.UserRepository; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; import java.util.stream.IntStream; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.DisplayName; @@ -44,8 +47,12 @@ class TalkRoomRepositoryImplTest extends RepositoryTestSupport { @Autowired CommentRepository commentRepository; + @Autowired + TalkRoomLikeRepository talkRoomLikeRepository; + @AfterEach void tearDown() { + talkRoomLikeRepository.deleteAllInBatch(); commentRepository.deleteAllInBatch(); talkRoomRoleRepository.deleteAllInBatch(); talkRoomRepository.deleteAllInBatch(); @@ -123,6 +130,241 @@ void talkRoomFindOneComment() { assertThat("user@gmail.com").isEqualTo(findOneTalkRoom.getComments().get(0).getUserName()); } + @Test + @DisplayName("querydsl 좋아요 총 개수 조회") + void likeTalkRoomFindCount() { + // given + List users = IntStream.range(0, 10) + .mapToObj(i -> User.builder() + .name("user@gmail.com " + i) + .profileImage("image") + .oauthId( + OauthId.builder() + .oauthId("oauthId " + i) + .oauthType(OauthType.KAKAO) + .build() + ) + .build()).toList(); + + userRepository.saveAll(users); + + Book book = createBook(); + bookRepository.save(book); + + List talkRoom = IntStream.range(0, 20) + .mapToObj(i -> TalkRoom.builder() + .user(users.get(0)) + .book(book) + .title("토론방 " + i) + .content("내용 " + i) + .build()) + .toList(); + + talkRoomRepository.saveAll(talkRoom); + + for (TalkRoom t : talkRoom) { + createTalkRoomRole(t); + } + + List likes1 = IntStream.range(0, 5).mapToObj(i -> TalkRoomLike.builder() + .user(users.get(i)) + .talkRoom(talkRoom.get(0)) + .build()) + .toList(); + + List likes2 = IntStream.range(5, 10).mapToObj(i -> TalkRoomLike.builder() + .user(users.get(i)) + .talkRoom(talkRoom.get(i)) + .build()) + .toList(); + + List likes = new ArrayList<>(); + likes.addAll(likes1); + likes.addAll(likes2); + + talkRoomLikeRepository.saveAll(likes); + + TalkRoomSearchServiceRequest search = TalkRoomSearchServiceRequest.builder() + .page(2) + .size(10) + .order(null) + .build(); + + // when + PageResponse response = talkRoomRepository.findAllTalkRoom(search); + + // then + assertThat(users.get(0).getId()).isEqualTo(response.getQueryResponse().get(9).getUserIds().get(0).getUserId()); + assertThat(users.get(1).getId()).isEqualTo(response.getQueryResponse().get(9).getUserIds().get(1).getUserId()); + } + + @Test + @DisplayName("querydsl 토크방 단건 조회 시 좋아요 개수 표시 테스트") + void findOneTalkRoomWithLikeCount() { + List users = IntStream.range(0, 10) + .mapToObj(i -> User.builder() + .name("user@gmail.com " + i) + .profileImage("image") + .oauthId( + OauthId.builder() + .oauthId("oauthId " + i) + .oauthType(OauthType.KAKAO) + .build() + ) + .build()).toList(); + + userRepository.saveAll(users); + + Book book = createBook(); + bookRepository.save(book); + + List talkRoom = IntStream.range(0, 20) + .mapToObj(i -> TalkRoom.builder() + .user(users.get(0)) + .book(book) + .title("토론방 " + i) + .content("내용 " + i) + .build()) + .toList(); + + talkRoomRepository.saveAll(talkRoom); + + for (TalkRoom t : talkRoom) { + createTalkRoomRole(t); + } + + List likes1 = IntStream.range(0, 5).mapToObj(i -> TalkRoomLike.builder() + .user(users.get(i)) + .talkRoom(talkRoom.get(0)) + .build()) + .toList(); + + List likes2 = IntStream.range(5, 10).mapToObj(i -> TalkRoomLike.builder() + .user(users.get(i)) + .talkRoom(talkRoom.get(i)) + .build()) + .toList(); + + List likes = new ArrayList<>(); + likes.addAll(likes1); + likes.addAll(likes2); + + talkRoomLikeRepository.saveAll(likes); + + // when + TalkRoomFindOneResponse response = talkRoomRepository.findOneTalkRoom(talkRoom.get(0).getId()); + + // then + assertThat(5L).isEqualTo(response.getLikeCount()); + } + + @Test + @DisplayName("querydsl 토크방 단건 조회 시 의견 개수 표시 테스트") + void findOneTalkRoomWithCommentCount() { + List users = IntStream.range(0, 10) + .mapToObj(i -> User.builder() + .name("user@gmail.com " + i) + .profileImage("image") + .oauthId( + OauthId.builder() + .oauthId("oauthId " + i) + .oauthType(OauthType.KAKAO) + .build() + ) + .build()).toList(); + + userRepository.saveAll(users); + + Book book = createBook(); + bookRepository.save(book); + + List talkRoom = IntStream.range(0, 20) + .mapToObj(i -> TalkRoom.builder() + .user(users.get(0)) + .book(book) + .title("토론방 " + i) + .content("내용 " + i) + .build()) + .toList(); + + talkRoomRepository.saveAll(talkRoom); + + for (TalkRoom t : talkRoom) { + createTalkRoomRole(t); + } + + List comments = IntStream.range(0, 5) + .mapToObj(i -> Comment.builder() + .talkRoom(talkRoom.get(0)) + .user(users.get(0)) + .content("의견 " + i) + .build()) + .collect(Collectors.toList()); + + commentRepository.saveAll(comments); + + // when + TalkRoomFindOneResponse response = talkRoomRepository.findOneTalkRoom(talkRoom.get(0).getId()); + + // then + assertThat(5L).isEqualTo(response.getCommentCount()); + } + + @Test + @DisplayName("querydsl 토크방 단건 조회 시 좋아요 누른 userId 반환") + void findOneTalkRoomWithUserId() { + // given + List users = IntStream.range(0, 10) + .mapToObj(i -> User.builder() + .name("user@gmail.com " + i) + .profileImage("image") + .oauthId( + OauthId.builder() + .oauthId("oauthId " + i) + .oauthType(OauthType.KAKAO) + .build() + ) + .build()).toList(); + + userRepository.saveAll(users); + + Book book = createBook(); + bookRepository.save(book); + + List talkRoom = IntStream.range(0, 20) + .mapToObj(i -> TalkRoom.builder() + .user(users.get(0)) + .book(book) + .title("토론방 " + i) + .content("내용 " + i) + .build()) + .toList(); + + talkRoomRepository.saveAll(talkRoom); + + for (TalkRoom t : talkRoom) { + createTalkRoomRole(t); + } + + List likes = IntStream.range(0, 5).mapToObj(i -> TalkRoomLike.builder() + .user(users.get(i)) + .talkRoom(talkRoom.get(0)) + .build()) + .toList(); + + talkRoomLikeRepository.saveAll(likes); + + // when + TalkRoomFindOneResponse response = talkRoomRepository.findOneTalkRoom(talkRoom.get(0).getId()); + + // then + assertThat(users.get(0).getId()).isEqualTo(response.getUserIds().get(0).getUserId()); + assertThat(users.get(1).getId()).isEqualTo(response.getUserIds().get(1).getUserId()); + assertThat(users.get(2).getId()).isEqualTo(response.getUserIds().get(2).getUserId()); + assertThat(users.get(3).getId()).isEqualTo(response.getUserIds().get(3).getUserId()); + assertThat(users.get(4).getId()).isEqualTo(response.getUserIds().get(4).getUserId()); + } + private static Comment createComment(TalkRoom talkRoom, User user) { return Comment.builder() .talkRoom(talkRoom) From fc32aedbe73d5b2adc7d4378828d17caad641e90 Mon Sep 17 00:00:00 2001 From: ahnyunki Date: Wed, 27 Mar 2024 20:32:32 +0900 Subject: [PATCH 3/6] =?UTF-8?q?feat:=20TalkRoom=20=EC=A2=8B=EC=95=84?= =?UTF-8?q?=EC=9A=94=20=EC=A0=95=EB=A0=AC=20=EB=B0=8F=20=EC=A0=9C=EB=AA=A9?= =?UTF-8?q?=20=EA=B2=80=EC=83=89=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= =?UTF-8?q?=20(#40)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/talkroom/TalkRoomController.java | 2 +- .../request/TalkRoomSearchRequest.java | 8 +- .../com/jisungin/application/OrderType.java | 21 + .../{response => }/PageResponse.java | 2 +- .../application/talkroom/TalkRoomService.java | 2 +- .../request/TalkRoomSearchServiceRequest.java | 10 +- .../response/TalkRoomFindAllResponse.java | 9 +- .../response/TalkRoomFindOneResponse.java | 8 +- .../response/TalkRoomLikeQueryResponse.java | 22 - .../talkroom/repository/OrderByNull.java | 14 + .../repository/TalkRoomRepositoryCustom.java | 2 +- .../repository/TalkRoomRepositoryImpl.java | 93 ++-- .../com/jisungin/exception/ErrorCode.java | 3 +- .../TalkRoomRepositoryImplTest.java | 421 ------------------ 14 files changed, 94 insertions(+), 523 deletions(-) create mode 100644 src/main/java/com/jisungin/application/OrderType.java rename src/main/java/com/jisungin/application/{response => }/PageResponse.java (92%) delete mode 100644 src/main/java/com/jisungin/application/talkroom/response/TalkRoomLikeQueryResponse.java create mode 100644 src/main/java/com/jisungin/domain/talkroom/repository/OrderByNull.java delete mode 100644 src/test/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryImplTest.java diff --git a/src/main/java/com/jisungin/api/talkroom/TalkRoomController.java b/src/main/java/com/jisungin/api/talkroom/TalkRoomController.java index 0523ad5..dd47ba0 100644 --- a/src/main/java/com/jisungin/api/talkroom/TalkRoomController.java +++ b/src/main/java/com/jisungin/api/talkroom/TalkRoomController.java @@ -6,7 +6,7 @@ import com.jisungin.api.talkroom.request.TalkRoomCreateRequest; import com.jisungin.api.talkroom.request.TalkRoomEditRequest; import com.jisungin.api.talkroom.request.TalkRoomSearchRequest; -import com.jisungin.application.response.PageResponse; +import com.jisungin.application.PageResponse; import com.jisungin.application.talkroom.TalkRoomService; import com.jisungin.application.talkroom.response.TalkRoomFindAllResponse; import com.jisungin.application.talkroom.response.TalkRoomFindOneResponse; diff --git a/src/main/java/com/jisungin/api/talkroom/request/TalkRoomSearchRequest.java b/src/main/java/com/jisungin/api/talkroom/request/TalkRoomSearchRequest.java index 7b2590f..e3260c3 100644 --- a/src/main/java/com/jisungin/api/talkroom/request/TalkRoomSearchRequest.java +++ b/src/main/java/com/jisungin/api/talkroom/request/TalkRoomSearchRequest.java @@ -1,5 +1,6 @@ package com.jisungin.api.talkroom.request; +import com.jisungin.application.OrderType; import com.jisungin.application.talkroom.request.TalkRoomSearchServiceRequest; import lombok.Builder; import lombok.Getter; @@ -17,18 +18,21 @@ public class TalkRoomSearchRequest { private String order; + private String search; + @Builder - private TalkRoomSearchRequest(Integer page, Integer size, String order) { + private TalkRoomSearchRequest(Integer page, Integer size, String order, String search) { this.page = page != null ? page : 1; this.size = size != null ? size : 1; this.order = order != null ? order : "recent"; + this.search = search; } public TalkRoomSearchServiceRequest toService() { return TalkRoomSearchServiceRequest.builder() .page(page) .size(size) - .order(order) + .orderType(OrderType.conversionOrderType(order)) .build(); } diff --git a/src/main/java/com/jisungin/application/OrderType.java b/src/main/java/com/jisungin/application/OrderType.java new file mode 100644 index 0000000..9978683 --- /dev/null +++ b/src/main/java/com/jisungin/application/OrderType.java @@ -0,0 +1,21 @@ +package com.jisungin.application; + +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public enum OrderType { + + RECENT("최신순"), + RECOMMEND("좋아요순"); + + private final String text; + + public static OrderType conversionOrderType(String order) { + return switch (order) { + case "recent" -> RECENT; + case "recommend" -> RECOMMEND; + default -> RECENT; + }; + } + +} diff --git a/src/main/java/com/jisungin/application/response/PageResponse.java b/src/main/java/com/jisungin/application/PageResponse.java similarity index 92% rename from src/main/java/com/jisungin/application/response/PageResponse.java rename to src/main/java/com/jisungin/application/PageResponse.java index b51b5cc..f46e52b 100644 --- a/src/main/java/com/jisungin/application/response/PageResponse.java +++ b/src/main/java/com/jisungin/application/PageResponse.java @@ -1,4 +1,4 @@ -package com.jisungin.application.response; +package com.jisungin.application; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/com/jisungin/application/talkroom/TalkRoomService.java b/src/main/java/com/jisungin/application/talkroom/TalkRoomService.java index 1d2780c..7e8a7d9 100644 --- a/src/main/java/com/jisungin/application/talkroom/TalkRoomService.java +++ b/src/main/java/com/jisungin/application/talkroom/TalkRoomService.java @@ -1,6 +1,6 @@ package com.jisungin.application.talkroom; -import com.jisungin.application.response.PageResponse; +import com.jisungin.application.PageResponse; import com.jisungin.application.talkroom.request.TalkRoomCreateServiceRequest; import com.jisungin.application.talkroom.request.TalkRoomEditServiceRequest; import com.jisungin.application.talkroom.request.TalkRoomSearchServiceRequest; diff --git a/src/main/java/com/jisungin/application/talkroom/request/TalkRoomSearchServiceRequest.java b/src/main/java/com/jisungin/application/talkroom/request/TalkRoomSearchServiceRequest.java index 821e2dd..02c9fc4 100644 --- a/src/main/java/com/jisungin/application/talkroom/request/TalkRoomSearchServiceRequest.java +++ b/src/main/java/com/jisungin/application/talkroom/request/TalkRoomSearchServiceRequest.java @@ -3,6 +3,7 @@ import static java.lang.Math.max; import static java.lang.Math.min; +import com.jisungin.application.OrderType; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -17,13 +18,16 @@ public class TalkRoomSearchServiceRequest { private Integer size; - private String order; + private OrderType orderType; + + private String search; @Builder - private TalkRoomSearchServiceRequest(Integer page, Integer size, String order) { + private TalkRoomSearchServiceRequest(Integer page, Integer size, OrderType orderType, String search) { this.page = page; this.size = size; - this.order = order; + this.orderType = orderType; + this.search = search; } public long getOffset() { diff --git a/src/main/java/com/jisungin/application/talkroom/response/TalkRoomFindAllResponse.java b/src/main/java/com/jisungin/application/talkroom/response/TalkRoomFindAllResponse.java index 0953fa6..8c928db 100644 --- a/src/main/java/com/jisungin/application/talkroom/response/TalkRoomFindAllResponse.java +++ b/src/main/java/com/jisungin/application/talkroom/response/TalkRoomFindAllResponse.java @@ -18,19 +18,20 @@ public class TalkRoomFindAllResponse { private String bookName; private String bookImage; private List readingStatuses = new ArrayList<>(); - private List likeCounts = new ArrayList<>(); private List userIds = new ArrayList<>(); + private Long likeCount; @Builder @QueryProjection public TalkRoomFindAllResponse(Long talkRoomId, String userName, String title, String content, String bookName, - String bookImage) { + String bookImage, Long likeCount) { this.talkRoomId = talkRoomId; this.userName = userName; this.title = title; this.content = content; this.bookName = bookName; this.bookImage = bookImage; + this.likeCount = likeCount; } public void addTalkRoomStatus(List readingStatuses) { @@ -41,8 +42,4 @@ public void addTalkRoomLikeUserIds(List userIds) { this.userIds = userIds; } - public void addLikeCounts(List likeCounts) { - this.likeCounts = likeCounts; - } - } diff --git a/src/main/java/com/jisungin/application/talkroom/response/TalkRoomFindOneResponse.java b/src/main/java/com/jisungin/application/talkroom/response/TalkRoomFindOneResponse.java index b4f7f39..315860c 100644 --- a/src/main/java/com/jisungin/application/talkroom/response/TalkRoomFindOneResponse.java +++ b/src/main/java/com/jisungin/application/talkroom/response/TalkRoomFindOneResponse.java @@ -26,13 +26,15 @@ public class TalkRoomFindOneResponse { @Builder @QueryProjection public TalkRoomFindOneResponse(Long talkRoomId, String userName, String title, String content, String bookName, - String bookImage) { + String bookImage, Long likeCount, Long commentCount) { this.talkRoomId = talkRoomId; this.userName = userName; this.title = title; this.content = content; this.bookName = bookName; this.bookImage = bookImage; + this.likeCount = likeCount; + this.commentCount = commentCount; } public void addTalkRoomStatus(List readingStatuses) { @@ -43,10 +45,6 @@ public void addTalkRoomComments(List comments) { this.comments = comments; } - public void addLikeCount(Long likeCount) { - this.likeCount = likeCount; - } - public void addCommentCount(Long commentCount) { this.commentCount = commentCount; } diff --git a/src/main/java/com/jisungin/application/talkroom/response/TalkRoomLikeQueryResponse.java b/src/main/java/com/jisungin/application/talkroom/response/TalkRoomLikeQueryResponse.java deleted file mode 100644 index 118c8f3..0000000 --- a/src/main/java/com/jisungin/application/talkroom/response/TalkRoomLikeQueryResponse.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.jisungin.application.talkroom.response; - -import com.querydsl.core.annotations.QueryProjection; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@NoArgsConstructor -public class TalkRoomLikeQueryResponse { - - private Long talkRoomId; - private Long likeCount; - - @Builder - @QueryProjection - public TalkRoomLikeQueryResponse(Long talkRoomId, Long likeCount) { - this.talkRoomId = talkRoomId; - this.likeCount = likeCount; - } - -} diff --git a/src/main/java/com/jisungin/domain/talkroom/repository/OrderByNull.java b/src/main/java/com/jisungin/domain/talkroom/repository/OrderByNull.java new file mode 100644 index 0000000..0b35d80 --- /dev/null +++ b/src/main/java/com/jisungin/domain/talkroom/repository/OrderByNull.java @@ -0,0 +1,14 @@ +package com.jisungin.domain.talkroom.repository; + +import com.querydsl.core.types.NullExpression; +import com.querydsl.core.types.Order; +import com.querydsl.core.types.OrderSpecifier; + +public class OrderByNull extends OrderSpecifier { + public static final OrderByNull DEFAULT = new OrderByNull(); + + private OrderByNull() { + super(Order.ASC, NullExpression.DEFAULT, NullHandling.Default); + } + +} \ No newline at end of file diff --git a/src/main/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryCustom.java b/src/main/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryCustom.java index 86dbcf9..f11163e 100644 --- a/src/main/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryCustom.java +++ b/src/main/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryCustom.java @@ -1,6 +1,6 @@ package com.jisungin.domain.talkroom.repository; -import com.jisungin.application.response.PageResponse; +import com.jisungin.application.PageResponse; import com.jisungin.application.talkroom.request.TalkRoomSearchServiceRequest; import com.jisungin.application.talkroom.response.TalkRoomFindAllResponse; import com.jisungin.application.talkroom.response.TalkRoomFindOneResponse; diff --git a/src/main/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryImpl.java b/src/main/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryImpl.java index 0945dd7..d279af2 100644 --- a/src/main/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryImpl.java +++ b/src/main/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryImpl.java @@ -1,5 +1,7 @@ package com.jisungin.domain.talkroom.repository; +import static com.jisungin.application.OrderType.RECENT; +import static com.jisungin.application.OrderType.RECOMMEND; import static com.jisungin.domain.book.QBook.book; import static com.jisungin.domain.comment.QComment.comment; import static com.jisungin.domain.talkroom.QTalkRoom.talkRoom; @@ -7,21 +9,21 @@ import static com.jisungin.domain.talkroomlike.QTalkRoomLike.talkRoomLike; import static com.jisungin.domain.user.QUser.user; -import com.jisungin.application.response.PageResponse; +import com.jisungin.application.OrderType; +import com.jisungin.application.PageResponse; import com.jisungin.application.talkroom.request.TalkRoomSearchServiceRequest; import com.jisungin.application.talkroom.response.QTalkRoomFindAllResponse; import com.jisungin.application.talkroom.response.QTalkRoomFindOneResponse; -import com.jisungin.application.talkroom.response.QTalkRoomLikeQueryResponse; import com.jisungin.application.talkroom.response.QTalkRoomLikeUserIdResponse; import com.jisungin.application.talkroom.response.QTalkRoomQueryCommentsResponse; import com.jisungin.application.talkroom.response.QTalkRoomQueryReadingStatusResponse; import com.jisungin.application.talkroom.response.TalkRoomFindAllResponse; import com.jisungin.application.talkroom.response.TalkRoomFindOneResponse; -import com.jisungin.application.talkroom.response.TalkRoomLikeQueryResponse; import com.jisungin.application.talkroom.response.TalkRoomLikeUserIdResponse; import com.jisungin.application.talkroom.response.TalkRoomQueryCommentsResponse; import com.jisungin.application.talkroom.response.TalkRoomQueryReadingStatusResponse; import com.querydsl.core.types.OrderSpecifier; +import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.jpa.impl.JPAQueryFactory; import java.util.List; import java.util.Map; @@ -37,25 +39,22 @@ public class TalkRoomRepositoryImpl implements TalkRoomRepositoryCustom { @Override public PageResponse findAllTalkRoom(TalkRoomSearchServiceRequest search) { - //루트 조회(toOne 코드를 모두 한번에 조회) + //루트 조회(toOne 코드를 모두 한번에 조회) -> Query 1번 발생 List findTalkRoom = findTalkRoomBySearch(search); - //TalkRoomRole 컬렉션을 MAP 한방에 조회 + //TalkRoomRole 컬렉션을 MAP 한방에 조회 -> Query 1번 발생 Map> talkRoomRoleMap = findTalkRoomRoleMap( toTalkRoomIds(findTalkRoom)); //루프를 돌면서 컬렉션 추가(추가 쿼리 실행X) findTalkRoom.forEach(t -> t.addTalkRoomStatus(talkRoomRoleMap.get(t.getTalkRoomId()))); - // 좋아요 추가 - Map> likeCountMap = talkRoomLikeCount(toTalkRoomIds(findTalkRoom)); - findTalkRoom.forEach(t -> t.addLikeCounts(likeCountMap.get(t.getTalkRoomId()))); - - // 좋아요한 유저 ID 정보들 + // 좋아요한 유저 ID 정보들 추가 -> Query 1번 발생 Map> talkRoomLikeUserMap = findTalkRoomLikeUserId( toTalkRoomIds(findTalkRoom)); findTalkRoom.forEach(t -> t.addTalkRoomLikeUserIds(talkRoomLikeUserMap.get(t.getTalkRoomId()))); + // query 1번 발생 long totalCount = getTotalTalkRoomCount(); return PageResponse.builder() @@ -76,10 +75,6 @@ public TalkRoomFindOneResponse findOneTalkRoom(Long talkRoomId) { List talkRoomComments = findCommentsByTalkRoomId(talkRoomId); findOneTalkRoom.addTalkRoomComments(talkRoomComments); - findOneTalkRoom.addLikeCount(findOneTalkRoomLikeCount(talkRoomId)); - - findOneTalkRoom.addCommentCount(findOneTalkRoomCommentCount(talkRoomId)); - List userIds = findOneTalkRoomLikeUserId(talkRoomId); findOneTalkRoom.addUserIds(userIds); @@ -94,17 +89,25 @@ private List findTalkRoomBySearch(TalkRoomSearchService talkRoom.title, talkRoom.content, book.title, - book.imageUrl.as("bookImage") + book.imageUrl.as("bookImage"), + talkRoomLike.count().as("likeCount") )) .from(talkRoom) .join(talkRoom.user, user) .join(talkRoom.book, book) + .leftJoin(talkRoomLike).on(talkRoom.eq(talkRoomLike.talkRoom)) + .groupBy(talkRoom.id) + .where(searchQuery(search.getSearch())) .offset(search.getOffset()) .limit(search.getSize()) - .orderBy(condition(search.getOrder())) + .orderBy(condition(search.getOrderType())) .fetch(); } + private BooleanExpression searchQuery(String search) { + return search != null ? talkRoom.title.contains(search) : null; + } + // 쿼리에서 가져온 토크룸 ID를 List 객체에 넣어주는 로직 private List toTalkRoomIds(List findTalkRoom) { return findTalkRoom.stream() @@ -128,23 +131,7 @@ private Map> findTalkRoomRoleMap( .collect(Collectors.groupingBy(TalkRoomQueryReadingStatusResponse::getTalkRoomId)); } - // 좋아요 총 개수 가져온 후 Map<>에 넣어주는 로직 - public Map> talkRoomLikeCount(List talkRoomId) { - List likeCount = queryFactory.select(new QTalkRoomLikeQueryResponse( - talkRoom.id.as("talkRoomId"), - talkRoomLike.count().as("likeCount") - )) - .from(talkRoomLike) - .join(talkRoomLike.talkRoom, talkRoom) - .where(talkRoomLike.talkRoom.id.in(talkRoomId)) - .groupBy(talkRoom.id) - .fetch(); - - return likeCount.stream() - .collect(Collectors.groupingBy(TalkRoomLikeQueryResponse::getTalkRoomId)); - } - - // 토크룸 좋아요 누른 사용자 ID 가져온 후 Map<>에 넣어주는 로직 + // 페이징 조회 -> 토크룸 좋아요 누른 사용자 ID 가져온 후 Map<>에 넣어주는 로직 private Map> findTalkRoomLikeUserId(List talkRoomIds) { List talkRoomLikeUserIds = queryFactory.select(new QTalkRoomLikeUserIdResponse( talkRoom.id.as("talkRoomId"), @@ -160,7 +147,7 @@ private Map> findTalkRoomLikeUserId(List< .collect(Collectors.groupingBy(TalkRoomLikeUserIdResponse::getTalkRoomId)); } - // 토크룸 좋아요 누른 사용자 ID 가져온 후 Map<>에 넣어주는 로직 + // 단건 조회 -> 토크룸 좋아요 누른 사용자 ID 가져온 후 Map<>에 넣어주는 로직 private List findOneTalkRoomLikeUserId(Long talkRoomId) { return queryFactory.select(new QTalkRoomLikeUserIdResponse( talkRoom.id.as("talkRoomId"), @@ -217,39 +204,27 @@ private TalkRoomFindOneResponse findTalkRoomByTalkRoomId(Long talkRoomId) { talkRoom.title, talkRoom.content, book.title, - book.imageUrl.as("bookImage") + book.imageUrl.as("bookImage"), + talkRoomLike.count().as("likeCount"), + comment.count().as("commentCount") )) .from(talkRoom) .join(talkRoom.user, user) .join(talkRoom.book, book) + .leftJoin(talkRoomLike).on(talkRoom.eq(talkRoomLike.talkRoom)) + .leftJoin(comment).on(talkRoom.eq(comment.talkRoom)) + .groupBy(talkRoom.id) .where(talkRoom.id.eq(talkRoomId)) .fetchOne(); } - // 토크룸 단건 조회 시 좋아요 총 개수 찾아오는 로직 - private Long findOneTalkRoomLikeCount(Long talkRoomId) { - return queryFactory.select(talkRoomLike.count()) - .from(talkRoomLike) - .join(talkRoomLike.talkRoom, talkRoom) - .where(talkRoomLike.talkRoom.id.eq(talkRoomId)) - .fetchOne(); - } - - // 토크룸 단건 조회 시 의견 총 개수 가져오는 로직 - private Long findOneTalkRoomCommentCount(Long talkRoomId) { - return queryFactory.select(comment.count()) - .from(comment) - .join(comment.talkRoom, talkRoom) - .where(comment.talkRoom.id.eq(talkRoomId)) - .fetchOne(); - } - - /** - * 아직 좋아요 기능이 구현 되지 않아 최신순으로만 정렬 - */ - private OrderSpecifier condition(String order) { -// if (order.equals("recent")) - return talkRoom.id.desc(); + private OrderSpecifier condition(OrderType orderType) { + if (RECENT.equals(orderType)) { + return talkRoom.id.desc(); + } else if (RECOMMEND.equals(orderType)) { + return talkRoomLike.count().desc(); + } + return OrderByNull.DEFAULT; } } diff --git a/src/main/java/com/jisungin/exception/ErrorCode.java b/src/main/java/com/jisungin/exception/ErrorCode.java index 39b131b..dc31295 100644 --- a/src/main/java/com/jisungin/exception/ErrorCode.java +++ b/src/main/java/com/jisungin/exception/ErrorCode.java @@ -18,7 +18,8 @@ public enum ErrorCode { COMMENT_NOT_FOUND(404, "의견을 찾을 수 없습니다."), REVIEW_NOT_FOUND(404, "리뷰를 찾을 수 없습니다."), TALK_ROOM_LIKE_NOT_FOUND(404, "토크방 좋아요를 찾을 수 없습니다."), - LIKE_EXIST(400, "이미 좋아요를 눌렀습니다."); + LIKE_EXIST(400, "이미 좋아요를 눌렀습니다."), + REQUEST_TIME_OUT(408, "요청 시간이 만료 되었습니다."); private final int code; diff --git a/src/test/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryImplTest.java b/src/test/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryImplTest.java deleted file mode 100644 index 2848746..0000000 --- a/src/test/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryImplTest.java +++ /dev/null @@ -1,421 +0,0 @@ -package com.jisungin.domain.talkroom.repository; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.jisungin.RepositoryTestSupport; -import com.jisungin.application.response.PageResponse; -import com.jisungin.application.talkroom.request.TalkRoomSearchServiceRequest; -import com.jisungin.application.talkroom.response.TalkRoomFindAllResponse; -import com.jisungin.application.talkroom.response.TalkRoomFindOneResponse; -import com.jisungin.domain.ReadingStatus; -import com.jisungin.domain.book.Book; -import com.jisungin.domain.book.repository.BookRepository; -import com.jisungin.domain.comment.Comment; -import com.jisungin.domain.comment.repository.CommentRepository; -import com.jisungin.domain.oauth.OauthId; -import com.jisungin.domain.oauth.OauthType; -import com.jisungin.domain.talkroom.TalkRoom; -import com.jisungin.domain.talkroom.TalkRoomRole; -import com.jisungin.domain.talkroomlike.TalkRoomLike; -import com.jisungin.domain.talkroomlike.repository.TalkRoomLikeRepository; -import com.jisungin.domain.user.User; -import com.jisungin.domain.user.repository.UserRepository; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.IntStream; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; - -class TalkRoomRepositoryImplTest extends RepositoryTestSupport { - - @Autowired - TalkRoomRepository talkRoomRepository; - - @Autowired - TalkRoomRoleRepository talkRoomRoleRepository; - - @Autowired - BookRepository bookRepository; - - @Autowired - UserRepository userRepository; - - @Autowired - CommentRepository commentRepository; - - @Autowired - TalkRoomLikeRepository talkRoomLikeRepository; - - @AfterEach - void tearDown() { - talkRoomLikeRepository.deleteAllInBatch(); - commentRepository.deleteAllInBatch(); - talkRoomRoleRepository.deleteAllInBatch(); - talkRoomRepository.deleteAllInBatch(); - userRepository.deleteAllInBatch(); - bookRepository.deleteAllInBatch(); - } - - @Test - @DisplayName("querydsl 페이징 조회 테스트") - void pageTest() { - // given - User user = createUser(); - userRepository.save(user); - - Book book = createBook(); - bookRepository.save(book); - - List talkRoom = IntStream.range(0, 20) - .mapToObj(i -> TalkRoom.builder() - .user(user) - .book(book) - .title("토론방 " + i) - .content("내용 " + i) - .build()) - .toList(); - - talkRoomRepository.saveAll(talkRoom); - - for (TalkRoom t : talkRoom) { - createTalkRoomRole(t); - } - - TalkRoomSearchServiceRequest search = TalkRoomSearchServiceRequest.builder() - .page(1) - .size(10) - .order(null) - .build(); - - // when - PageResponse talkRooms = talkRoomRepository.findAllTalkRoom(search); - - // then - assertThat(10L).isEqualTo(talkRooms.getQueryResponse().size()); - assertThat("토론방 19").isEqualTo(talkRooms.getQueryResponse().get(0).getTitle()); - assertThat("내용 19").isEqualTo(talkRooms.getQueryResponse().get(0).getContent()); - assertThat(2).isEqualTo(talkRooms.getQueryResponse().get(0).getReadingStatuses().size()); - assertThat(20).isEqualTo(talkRooms.getTotalCount()); - } - - @Test - @DisplayName("querydsl 단건 조회 토크방 의견 조회 테스트") - void talkRoomFindOneComment() { - // given - User user = createUser(); - userRepository.save(user); - - Book book = createBook(); - bookRepository.save(book); - - TalkRoom talkRoom = createTalkRoom(book, user); - talkRoomRepository.save(talkRoom); - - createTalkRoomRole(talkRoom); - - Comment comment = createComment(talkRoom, user); - - commentRepository.save(comment); - // when - TalkRoomFindOneResponse findOneTalkRoom = talkRoomRepository.findOneTalkRoom(talkRoom.getId()); - - // then - assertThat("토론방").isEqualTo(findOneTalkRoom.getTitle()); - assertThat(2).isEqualTo(findOneTalkRoom.getReadingStatuses().size()); - assertThat("의견 남기기").isEqualTo(findOneTalkRoom.getComments().get(0).getContent()); - assertThat("user@gmail.com").isEqualTo(findOneTalkRoom.getComments().get(0).getUserName()); - } - - @Test - @DisplayName("querydsl 좋아요 총 개수 조회") - void likeTalkRoomFindCount() { - // given - List users = IntStream.range(0, 10) - .mapToObj(i -> User.builder() - .name("user@gmail.com " + i) - .profileImage("image") - .oauthId( - OauthId.builder() - .oauthId("oauthId " + i) - .oauthType(OauthType.KAKAO) - .build() - ) - .build()).toList(); - - userRepository.saveAll(users); - - Book book = createBook(); - bookRepository.save(book); - - List talkRoom = IntStream.range(0, 20) - .mapToObj(i -> TalkRoom.builder() - .user(users.get(0)) - .book(book) - .title("토론방 " + i) - .content("내용 " + i) - .build()) - .toList(); - - talkRoomRepository.saveAll(talkRoom); - - for (TalkRoom t : talkRoom) { - createTalkRoomRole(t); - } - - List likes1 = IntStream.range(0, 5).mapToObj(i -> TalkRoomLike.builder() - .user(users.get(i)) - .talkRoom(talkRoom.get(0)) - .build()) - .toList(); - - List likes2 = IntStream.range(5, 10).mapToObj(i -> TalkRoomLike.builder() - .user(users.get(i)) - .talkRoom(talkRoom.get(i)) - .build()) - .toList(); - - List likes = new ArrayList<>(); - likes.addAll(likes1); - likes.addAll(likes2); - - talkRoomLikeRepository.saveAll(likes); - - TalkRoomSearchServiceRequest search = TalkRoomSearchServiceRequest.builder() - .page(2) - .size(10) - .order(null) - .build(); - - // when - PageResponse response = talkRoomRepository.findAllTalkRoom(search); - - // then - assertThat(users.get(0).getId()).isEqualTo(response.getQueryResponse().get(9).getUserIds().get(0).getUserId()); - assertThat(users.get(1).getId()).isEqualTo(response.getQueryResponse().get(9).getUserIds().get(1).getUserId()); - } - - @Test - @DisplayName("querydsl 토크방 단건 조회 시 좋아요 개수 표시 테스트") - void findOneTalkRoomWithLikeCount() { - List users = IntStream.range(0, 10) - .mapToObj(i -> User.builder() - .name("user@gmail.com " + i) - .profileImage("image") - .oauthId( - OauthId.builder() - .oauthId("oauthId " + i) - .oauthType(OauthType.KAKAO) - .build() - ) - .build()).toList(); - - userRepository.saveAll(users); - - Book book = createBook(); - bookRepository.save(book); - - List talkRoom = IntStream.range(0, 20) - .mapToObj(i -> TalkRoom.builder() - .user(users.get(0)) - .book(book) - .title("토론방 " + i) - .content("내용 " + i) - .build()) - .toList(); - - talkRoomRepository.saveAll(talkRoom); - - for (TalkRoom t : talkRoom) { - createTalkRoomRole(t); - } - - List likes1 = IntStream.range(0, 5).mapToObj(i -> TalkRoomLike.builder() - .user(users.get(i)) - .talkRoom(talkRoom.get(0)) - .build()) - .toList(); - - List likes2 = IntStream.range(5, 10).mapToObj(i -> TalkRoomLike.builder() - .user(users.get(i)) - .talkRoom(talkRoom.get(i)) - .build()) - .toList(); - - List likes = new ArrayList<>(); - likes.addAll(likes1); - likes.addAll(likes2); - - talkRoomLikeRepository.saveAll(likes); - - // when - TalkRoomFindOneResponse response = talkRoomRepository.findOneTalkRoom(talkRoom.get(0).getId()); - - // then - assertThat(5L).isEqualTo(response.getLikeCount()); - } - - @Test - @DisplayName("querydsl 토크방 단건 조회 시 의견 개수 표시 테스트") - void findOneTalkRoomWithCommentCount() { - List users = IntStream.range(0, 10) - .mapToObj(i -> User.builder() - .name("user@gmail.com " + i) - .profileImage("image") - .oauthId( - OauthId.builder() - .oauthId("oauthId " + i) - .oauthType(OauthType.KAKAO) - .build() - ) - .build()).toList(); - - userRepository.saveAll(users); - - Book book = createBook(); - bookRepository.save(book); - - List talkRoom = IntStream.range(0, 20) - .mapToObj(i -> TalkRoom.builder() - .user(users.get(0)) - .book(book) - .title("토론방 " + i) - .content("내용 " + i) - .build()) - .toList(); - - talkRoomRepository.saveAll(talkRoom); - - for (TalkRoom t : talkRoom) { - createTalkRoomRole(t); - } - - List comments = IntStream.range(0, 5) - .mapToObj(i -> Comment.builder() - .talkRoom(talkRoom.get(0)) - .user(users.get(0)) - .content("의견 " + i) - .build()) - .collect(Collectors.toList()); - - commentRepository.saveAll(comments); - - // when - TalkRoomFindOneResponse response = talkRoomRepository.findOneTalkRoom(talkRoom.get(0).getId()); - - // then - assertThat(5L).isEqualTo(response.getCommentCount()); - } - - @Test - @DisplayName("querydsl 토크방 단건 조회 시 좋아요 누른 userId 반환") - void findOneTalkRoomWithUserId() { - // given - List users = IntStream.range(0, 10) - .mapToObj(i -> User.builder() - .name("user@gmail.com " + i) - .profileImage("image") - .oauthId( - OauthId.builder() - .oauthId("oauthId " + i) - .oauthType(OauthType.KAKAO) - .build() - ) - .build()).toList(); - - userRepository.saveAll(users); - - Book book = createBook(); - bookRepository.save(book); - - List talkRoom = IntStream.range(0, 20) - .mapToObj(i -> TalkRoom.builder() - .user(users.get(0)) - .book(book) - .title("토론방 " + i) - .content("내용 " + i) - .build()) - .toList(); - - talkRoomRepository.saveAll(talkRoom); - - for (TalkRoom t : talkRoom) { - createTalkRoomRole(t); - } - - List likes = IntStream.range(0, 5).mapToObj(i -> TalkRoomLike.builder() - .user(users.get(i)) - .talkRoom(talkRoom.get(0)) - .build()) - .toList(); - - talkRoomLikeRepository.saveAll(likes); - - // when - TalkRoomFindOneResponse response = talkRoomRepository.findOneTalkRoom(talkRoom.get(0).getId()); - - // then - assertThat(users.get(0).getId()).isEqualTo(response.getUserIds().get(0).getUserId()); - assertThat(users.get(1).getId()).isEqualTo(response.getUserIds().get(1).getUserId()); - assertThat(users.get(2).getId()).isEqualTo(response.getUserIds().get(2).getUserId()); - assertThat(users.get(3).getId()).isEqualTo(response.getUserIds().get(3).getUserId()); - assertThat(users.get(4).getId()).isEqualTo(response.getUserIds().get(4).getUserId()); - } - - private static Comment createComment(TalkRoom talkRoom, User user) { - return Comment.builder() - .talkRoom(talkRoom) - .user(user) - .content("의견 남기기") - .build(); - } - - private void createTalkRoomRole(TalkRoom talkRoom) { - List request = new ArrayList<>(); - request.add("읽는 중"); - request.add("읽음"); - - List readingStatus = ReadingStatus.createReadingStatus(request); - - readingStatus.stream().map(status -> TalkRoomRole.roleCreate(talkRoom, status)) - .forEach(talkRoomRoleRepository::save); - } - - private static TalkRoom createTalkRoom(Book book, User user) { - return TalkRoom.builder() - .book(book) - .title("토론방") - .content("내용") - .user(user) - .build(); - } - - private static User createUser() { - return User.builder() - .name("user@gmail.com") - .profileImage("image") - .oauthId( - OauthId.builder() - .oauthId("oauthId") - .oauthType(OauthType.KAKAO) - .build() - ) - .build(); - } - - private static Book createBook() { - return Book.builder() - .title("제목") - .content("내용") - .authors("작가") - .isbn("11111") - .publisher("publisher") - .dateTime(LocalDateTime.now()) - .imageUrl("www") - .build(); - } - -} \ No newline at end of file From d0f7802890ccfcdd0384cc6022b0e539d4dc3005 Mon Sep 17 00:00:00 2001 From: ahnyunki Date: Wed, 27 Mar 2024 20:32:50 +0900 Subject: [PATCH 4/6] =?UTF-8?q?test:=20TalkRoom=20=EC=A2=8B=EC=95=84?= =?UTF-8?q?=EC=9A=94=20=EC=A0=95=EB=A0=AC=20=EB=B0=8F=20=EC=A0=9C=EB=AA=A9?= =?UTF-8?q?=20=EA=B2=80=EC=83=89=20=EA=B8=B0=EB=8A=A5=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1=20(#40)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/talkroom/TalkRoomServiceTest.java | 305 +++++---- .../repository/TalkRoomRepositoryTest.java | 582 ++++++++++++++++++ 2 files changed, 756 insertions(+), 131 deletions(-) create mode 100644 src/test/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryTest.java diff --git a/src/test/java/com/jisungin/application/service/talkroom/TalkRoomServiceTest.java b/src/test/java/com/jisungin/application/service/talkroom/TalkRoomServiceTest.java index 8d368aa..79513b8 100644 --- a/src/test/java/com/jisungin/application/service/talkroom/TalkRoomServiceTest.java +++ b/src/test/java/com/jisungin/application/service/talkroom/TalkRoomServiceTest.java @@ -4,7 +4,8 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import com.jisungin.ServiceTestSupport; -import com.jisungin.application.response.PageResponse; +import com.jisungin.application.OrderType; +import com.jisungin.application.PageResponse; import com.jisungin.application.talkroom.TalkRoomService; import com.jisungin.application.talkroom.request.TalkRoomCreateServiceRequest; import com.jisungin.application.talkroom.request.TalkRoomEditServiceRequest; @@ -302,14 +303,7 @@ void getTalkRooms() { Book book = createBook(); bookRepository.save(book); - List talkRoom = IntStream.range(0, 20) - .mapToObj(i -> TalkRoom.builder() - .user(user) - .book(book) - .title("토론방 " + i) - .content("내용 " + i) - .build()) - .toList(); + List talkRoom = listTalkRooms(20, user, book); talkRoomRepository.saveAll(talkRoom); @@ -320,6 +314,7 @@ void getTalkRooms() { TalkRoomSearchServiceRequest search = TalkRoomSearchServiceRequest.builder() .page(1) .size(10) + .orderType(OrderType.RECENT) .build(); // when @@ -341,14 +336,7 @@ void getTalkRoomsPageTotalCount() { Book book = createBook(); bookRepository.save(book); - List talkRoom = IntStream.range(0, 103) - .mapToObj(i -> TalkRoom.builder() - .user(user) - .book(book) - .title("토론방 " + i) - .content("내용 " + i) - .build()) - .toList(); + List talkRoom = listTalkRooms(103, user, book); talkRoomRepository.saveAll(talkRoom); @@ -378,14 +366,7 @@ void getTalkRoomsMiddle() { Book book = createBook(); bookRepository.save(book); - List talkRoom = IntStream.range(0, 103) - .mapToObj(i -> TalkRoom.builder() - .user(user) - .book(book) - .title("토론방 " + i) - .content("내용 " + i) - .build()) - .toList(); + List talkRoom = listTalkRooms(103, user, book); talkRoomRepository.saveAll(talkRoom); @@ -396,6 +377,7 @@ void getTalkRoomsMiddle() { TalkRoomSearchServiceRequest search = TalkRoomSearchServiceRequest.builder() .page(5) .size(10) + .orderType(OrderType.RECENT) .build(); // when @@ -417,14 +399,7 @@ void getTalkRoomsLast() { Book book = createBook(); bookRepository.save(book); - List talkRoom = IntStream.range(0, 103) - .mapToObj(i -> TalkRoom.builder() - .user(user) - .book(book) - .title("토론방 " + i) - .content("내용 " + i) - .build()) - .toList(); + List talkRoom = listTalkRooms(103, user, book); talkRoomRepository.saveAll(talkRoom); @@ -435,6 +410,7 @@ void getTalkRoomsLast() { TalkRoomSearchServiceRequest search = TalkRoomSearchServiceRequest.builder() .page(11) .size(10) + .orderType(OrderType.RECENT) .build(); // when @@ -621,31 +597,14 @@ void deleteTalkRoomWithComment() { @DisplayName("토크방을 페이징 조회 시 토크방에는 좋아요 총 개수가 표시되어야 한다.") void findAllTalkRoomWithLikeCount() { // given - List users = IntStream.range(0, 10) - .mapToObj(i -> User.builder() - .name("user@gmail.com " + i) - .profileImage("image") - .oauthId( - OauthId.builder() - .oauthId("oauthId " + i) - .oauthType(OauthType.KAKAO) - .build() - ) - .build()).toList(); + List users = listUsers(); userRepository.saveAll(users); Book book = createBook(); bookRepository.save(book); - List talkRoom = IntStream.range(0, 20) - .mapToObj(i -> TalkRoom.builder() - .user(users.get(0)) - .book(book) - .title("토론방 " + i) - .content("내용 " + i) - .build()) - .toList(); + List talkRoom = listTalkRooms(20, users.get(0), book); talkRoomRepository.saveAll(talkRoom); @@ -664,45 +623,28 @@ void findAllTalkRoomWithLikeCount() { TalkRoomSearchServiceRequest search = TalkRoomSearchServiceRequest.builder() .page(2) .size(10) - .order(null) + .orderType(OrderType.RECENT) .build(); // when PageResponse response = talkRoomService.findAllTalkRoom(search); // then - assertThat(5L).isEqualTo(response.getQueryResponse().get(9).getLikeCounts().get(0).getLikeCount()); + assertThat(5L).isEqualTo(response.getQueryResponse().get(9).getLikeCount()); } @Test @DisplayName("토크방 페이지 조회 시 토크방에 좋아요 누른 사용자 ID들이 프론트에 전송되어야 한다.") void findAllTalkRoomWithLikeUserId() { // given - List users = IntStream.range(0, 10) - .mapToObj(i -> User.builder() - .name("user@gmail.com " + i) - .profileImage("image") - .oauthId( - OauthId.builder() - .oauthId("oauthId " + i) - .oauthType(OauthType.KAKAO) - .build() - ) - .build()).toList(); + List users = listUsers(); userRepository.saveAll(users); Book book = createBook(); bookRepository.save(book); - List talkRoom = IntStream.range(0, 20) - .mapToObj(i -> TalkRoom.builder() - .user(users.get(0)) - .book(book) - .title("토론방 " + i) - .content("내용 " + i) - .build()) - .toList(); + List talkRoom = listTalkRooms(20, users.get(0), book); talkRoomRepository.saveAll(talkRoom); @@ -731,7 +673,7 @@ void findAllTalkRoomWithLikeUserId() { TalkRoomSearchServiceRequest search = TalkRoomSearchServiceRequest.builder() .page(2) .size(10) - .order(null) + .orderType(OrderType.RECENT) .build(); // when @@ -749,31 +691,14 @@ void findAllTalkRoomWithLikeUserId() { @DisplayName("토크방 단건 조회 시 좋아요 개수가 표시 된다.") void findOneTalkRoomWithLikeCount() { // given - List users = IntStream.range(0, 10) - .mapToObj(i -> User.builder() - .name("user@gmail.com " + i) - .profileImage("image") - .oauthId( - OauthId.builder() - .oauthId("oauthId " + i) - .oauthType(OauthType.KAKAO) - .build() - ) - .build()).toList(); + List users = listUsers(); userRepository.saveAll(users); Book book = createBook(); bookRepository.save(book); - List talkRoom = IntStream.range(0, 20) - .mapToObj(i -> TalkRoom.builder() - .user(users.get(0)) - .book(book) - .title("토론방 " + i) - .content("내용 " + i) - .build()) - .toList(); + List talkRoom = listTalkRooms(20, users.get(0), book); talkRoomRepository.saveAll(talkRoom); @@ -800,31 +725,14 @@ void findOneTalkRoomWithLikeCount() { @DisplayName("토크방 단건 조회 시 좋아요한 유저의 ID가 보내진다.") void findOneTalkRoomWithLikeUserId() { // given - List users = IntStream.range(0, 10) - .mapToObj(i -> User.builder() - .name("user@gmail.com " + i) - .profileImage("image") - .oauthId( - OauthId.builder() - .oauthId("oauthId " + i) - .oauthType(OauthType.KAKAO) - .build() - ) - .build()).toList(); + List users = listUsers(); userRepository.saveAll(users); Book book = createBook(); bookRepository.save(book); - List talkRoom = IntStream.range(0, 20) - .mapToObj(i -> TalkRoom.builder() - .user(users.get(0)) - .book(book) - .title("토론방 " + i) - .content("내용 " + i) - .build()) - .toList(); + List talkRoom = listTalkRooms(20, users.get(0), book); talkRoomRepository.saveAll(talkRoom); @@ -855,31 +763,14 @@ void findOneTalkRoomWithLikeUserId() { @DisplayName("토크방 단건 조회 시 의견 개수가 표시 된다.") void findOneTalkRoomWithCommentCount() { // given - List users = IntStream.range(0, 10) - .mapToObj(i -> User.builder() - .name("user@gmail.com " + i) - .profileImage("image") - .oauthId( - OauthId.builder() - .oauthId("oauthId " + i) - .oauthType(OauthType.KAKAO) - .build() - ) - .build()).toList(); + List users = listUsers(); userRepository.saveAll(users); Book book = createBook(); bookRepository.save(book); - List talkRoom = IntStream.range(0, 20) - .mapToObj(i -> TalkRoom.builder() - .user(users.get(0)) - .book(book) - .title("토론방 " + i) - .content("내용 " + i) - .build()) - .toList(); + List talkRoom = listTalkRooms(20, users.get(0), book); talkRoomRepository.saveAll(talkRoom); @@ -904,6 +795,158 @@ void findOneTalkRoomWithCommentCount() { assertThat(5L).isEqualTo(response.getCommentCount()); } + @Test + @DisplayName("토크방을 좋아요 순으로 정렬을 한다.") + void findAllTalkRoomWithOrderLike() { + // given + List users = listUsers(); + + userRepository.saveAll(users); + + Book book = createBook(); + bookRepository.save(book); + + List talkRoom = listTalkRooms(20, users.get(0), book); + + talkRoomRepository.saveAll(talkRoom); + + for (TalkRoom t : talkRoom) { + createTalkRoomRole(t); + } + + List likes1 = IntStream.range(0, 10).mapToObj(i -> TalkRoomLike.builder() + .user(users.get(i)) + .talkRoom(talkRoom.get(0)) + .build()) + .toList(); + + List likes2 = IntStream.range(0, 9).mapToObj(i -> TalkRoomLike.builder() + .user(users.get(i)) + .talkRoom(talkRoom.get(1)) + .build()) + .toList(); + + List likes = new ArrayList<>(); + likes.addAll(likes1); + likes.addAll(likes2); + + talkRoomLikeRepository.saveAll(likes); + + TalkRoomSearchServiceRequest search = TalkRoomSearchServiceRequest.builder() + .page(1) + .size(10) + .orderType(OrderType.RECOMMEND) + .build(); + + // when + PageResponse response = talkRoomService.findAllTalkRoom(search); + + // then + assertThat(10L).isEqualTo(response.getQueryResponse().get(0).getLikeCount()); + } + + @Test + @DisplayName("토크방 제목을 입력해서 조회한다.") + void findAllTalkRoomWithSearch() { + // given + List users = listUsers(); + + userRepository.saveAll(users); + + Book book = createBook(); + bookRepository.save(book); + + List talkRoom = listTalkRooms(20, users.get(0), book); + + TalkRoom talkRoom1 = TalkRoom.builder() + .user(users.get(0)) + .book(book) + .title("검색어") + .content("내용") + .build(); + + TalkRoom talkRoom2 = TalkRoom.builder() + .user(users.get(0)) + .book(book) + .title("아무내용 검색어 아무내용") + .content("내용") + .build(); + + TalkRoom talkRoom3 = TalkRoom.builder() + .user(users.get(0)) + .book(book) + .title("아무내용 아무내용 검색어") + .content("내용") + .build(); + + talkRoomRepository.save(talkRoom1); + talkRoomRepository.save(talkRoom2); + talkRoomRepository.save(talkRoom3); + + talkRoomRepository.saveAll(talkRoom); + + for (TalkRoom t : talkRoom) { + createTalkRoomRole(t); + } + + List likes1 = IntStream.range(0, 10).mapToObj(i -> TalkRoomLike.builder() + .user(users.get(i)) + .talkRoom(talkRoom.get(0)) + .build()) + .toList(); + + List likes2 = IntStream.range(0, 9).mapToObj(i -> TalkRoomLike.builder() + .user(users.get(i)) + .talkRoom(talkRoom.get(1)) + .build()) + .toList(); + + List likes = new ArrayList<>(); + likes.addAll(likes1); + likes.addAll(likes2); + + talkRoomLikeRepository.saveAll(likes); + + TalkRoomSearchServiceRequest search = TalkRoomSearchServiceRequest.builder() + .page(1) + .size(10) + .search("검색어") + .build(); + + // when + PageResponse response = talkRoomService.findAllTalkRoom(search); + + // then + assertThat(talkRoom1.getTitle()).isEqualTo(response.getQueryResponse().get(0).getTitle()); + assertThat(talkRoom2.getTitle()).isEqualTo(response.getQueryResponse().get(1).getTitle()); + assertThat(talkRoom3.getTitle()).isEqualTo(response.getQueryResponse().get(2).getTitle()); + } + + private static List listUsers() { + return IntStream.range(0, 10) + .mapToObj(i -> User.builder() + .name("user@gmail.com " + i) + .profileImage("image") + .oauthId( + OauthId.builder() + .oauthId("oauthId " + i) + .oauthType(OauthType.KAKAO) + .build() + ) + .build()).toList(); + } + + private static List listTalkRooms(int endExclusive, User users, Book book) { + return IntStream.range(0, endExclusive) + .mapToObj(i -> TalkRoom.builder() + .user(users) + .book(book) + .title("토론방 " + i) + .content("내용 " + i) + .build()) + .toList(); + } + private static Comment createComment(TalkRoom talkRoom, User user) { return Comment.builder() .talkRoom(talkRoom) diff --git a/src/test/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryTest.java b/src/test/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryTest.java new file mode 100644 index 0000000..a6a5163 --- /dev/null +++ b/src/test/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryTest.java @@ -0,0 +1,582 @@ +package com.jisungin.domain.talkroom.repository; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.jisungin.RepositoryTestSupport; +import com.jisungin.application.OrderType; +import com.jisungin.application.PageResponse; +import com.jisungin.application.talkroom.request.TalkRoomSearchServiceRequest; +import com.jisungin.application.talkroom.response.TalkRoomFindAllResponse; +import com.jisungin.application.talkroom.response.TalkRoomFindOneResponse; +import com.jisungin.domain.ReadingStatus; +import com.jisungin.domain.book.Book; +import com.jisungin.domain.book.repository.BookRepository; +import com.jisungin.domain.comment.Comment; +import com.jisungin.domain.comment.repository.CommentRepository; +import com.jisungin.domain.oauth.OauthId; +import com.jisungin.domain.oauth.OauthType; +import com.jisungin.domain.talkroom.TalkRoom; +import com.jisungin.domain.talkroom.TalkRoomRole; +import com.jisungin.domain.talkroomlike.TalkRoomLike; +import com.jisungin.domain.talkroomlike.repository.TalkRoomLikeRepository; +import com.jisungin.domain.user.User; +import com.jisungin.domain.user.repository.UserRepository; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +class TalkRoomRepositoryTest extends RepositoryTestSupport { + + @Autowired + TalkRoomRepository talkRoomRepository; + + @Autowired + TalkRoomRoleRepository talkRoomRoleRepository; + + @Autowired + BookRepository bookRepository; + + @Autowired + UserRepository userRepository; + + @Autowired + CommentRepository commentRepository; + + @Autowired + TalkRoomLikeRepository talkRoomLikeRepository; + + @AfterEach + void tearDown() { + talkRoomLikeRepository.deleteAllInBatch(); + commentRepository.deleteAllInBatch(); + talkRoomRoleRepository.deleteAllInBatch(); + talkRoomRepository.deleteAllInBatch(); + userRepository.deleteAllInBatch(); + bookRepository.deleteAllInBatch(); + } + + @Test + @DisplayName("querydsl 페이징 조회 테스트") + void pageTest() { + // given + User user = createUser(); + userRepository.save(user); + + Book book = createBook(); + bookRepository.save(book); + + List talkRoom = IntStream.range(0, 20) + .mapToObj(i -> TalkRoom.builder() + .user(user) + .book(book) + .title("토론방 " + i) + .content("내용 " + i) + .build()) + .toList(); + + talkRoomRepository.saveAll(talkRoom); + + for (TalkRoom t : talkRoom) { + createTalkRoomRole(t); + } + + TalkRoomSearchServiceRequest search = TalkRoomSearchServiceRequest.builder() + .page(1) + .size(10) + .orderType(OrderType.RECENT) + .build(); + + // when + PageResponse talkRooms = talkRoomRepository.findAllTalkRoom(search); + + // then + assertThat(10L).isEqualTo(talkRooms.getQueryResponse().size()); + assertThat("토론방 19").isEqualTo(talkRooms.getQueryResponse().get(0).getTitle()); + assertThat("내용 19").isEqualTo(talkRooms.getQueryResponse().get(0).getContent()); + assertThat(2).isEqualTo(talkRooms.getQueryResponse().get(0).getReadingStatuses().size()); + assertThat(20).isEqualTo(talkRooms.getTotalCount()); + } + + @Test + @DisplayName("querydsl 단건 조회 토크방 의견 조회 테스트") + void talkRoomFindOneComment() { + // given + User user = createUser(); + userRepository.save(user); + + Book book = createBook(); + bookRepository.save(book); + + TalkRoom talkRoom = createTalkRoom(book, user); + talkRoomRepository.save(talkRoom); + + createTalkRoomRole(talkRoom); + + Comment comment = createComment(talkRoom, user); + + commentRepository.save(comment); + // when + TalkRoomFindOneResponse findOneTalkRoom = talkRoomRepository.findOneTalkRoom(talkRoom.getId()); + + // then + assertThat("토론방").isEqualTo(findOneTalkRoom.getTitle()); + assertThat(2).isEqualTo(findOneTalkRoom.getReadingStatuses().size()); + assertThat("의견 남기기").isEqualTo(findOneTalkRoom.getComments().get(0).getContent()); + assertThat("user@gmail.com").isEqualTo(findOneTalkRoom.getComments().get(0).getUserName()); + } + + @Test + @DisplayName("querydsl 좋아요 총 개수 조회") + void likeTalkRoomFindCount() { + // given + List users = IntStream.range(0, 10) + .mapToObj(i -> User.builder() + .name("user@gmail.com " + i) + .profileImage("image") + .oauthId( + OauthId.builder() + .oauthId("oauthId " + i) + .oauthType(OauthType.KAKAO) + .build() + ) + .build()).toList(); + + userRepository.saveAll(users); + + Book book = createBook(); + bookRepository.save(book); + + List talkRoom = IntStream.range(0, 20) + .mapToObj(i -> TalkRoom.builder() + .user(users.get(0)) + .book(book) + .title("토론방 " + i) + .content("내용 " + i) + .build()) + .toList(); + + talkRoomRepository.saveAll(talkRoom); + + for (TalkRoom t : talkRoom) { + createTalkRoomRole(t); + } + + List likes1 = IntStream.range(0, 5).mapToObj(i -> TalkRoomLike.builder() + .user(users.get(i)) + .talkRoom(talkRoom.get(0)) + .build()) + .toList(); + + List likes2 = IntStream.range(5, 10).mapToObj(i -> TalkRoomLike.builder() + .user(users.get(i)) + .talkRoom(talkRoom.get(i)) + .build()) + .toList(); + + List likes = new ArrayList<>(); + likes.addAll(likes1); + likes.addAll(likes2); + + talkRoomLikeRepository.saveAll(likes); + + TalkRoomSearchServiceRequest search = TalkRoomSearchServiceRequest.builder() + .page(2) + .size(10) + .orderType(OrderType.RECENT) + .build(); + + // when + PageResponse response = talkRoomRepository.findAllTalkRoom(search); + + // then + assertThat(5L).isEqualTo(response.getQueryResponse().get(9).getLikeCount()); + } + + @Test + @DisplayName("querydsl 토크방 단건 조회 시 좋아요 개수 표시 테스트") + void findOneTalkRoomWithLikeCount() { + List users = IntStream.range(0, 10) + .mapToObj(i -> User.builder() + .name("user@gmail.com " + i) + .profileImage("image") + .oauthId( + OauthId.builder() + .oauthId("oauthId " + i) + .oauthType(OauthType.KAKAO) + .build() + ) + .build()).toList(); + + userRepository.saveAll(users); + + Book book = createBook(); + bookRepository.save(book); + + List talkRoom = IntStream.range(0, 20) + .mapToObj(i -> TalkRoom.builder() + .user(users.get(0)) + .book(book) + .title("토론방 " + i) + .content("내용 " + i) + .build()) + .toList(); + + talkRoomRepository.saveAll(talkRoom); + + for (TalkRoom t : talkRoom) { + createTalkRoomRole(t); + } + + List likes1 = IntStream.range(0, 5).mapToObj(i -> TalkRoomLike.builder() + .user(users.get(i)) + .talkRoom(talkRoom.get(0)) + .build()) + .toList(); + + List likes2 = IntStream.range(5, 10).mapToObj(i -> TalkRoomLike.builder() + .user(users.get(i)) + .talkRoom(talkRoom.get(i)) + .build()) + .toList(); + + List likes = new ArrayList<>(); + likes.addAll(likes1); + likes.addAll(likes2); + + talkRoomLikeRepository.saveAll(likes); + + // when + TalkRoomFindOneResponse response = talkRoomRepository.findOneTalkRoom(talkRoom.get(0).getId()); + + // then + assertThat(5L).isEqualTo(response.getLikeCount()); + } + + @Test + @DisplayName("querydsl 토크방 단건 조회 시 의견 개수 표시 테스트") + void findOneTalkRoomWithCommentCount() { + List users = IntStream.range(0, 10) + .mapToObj(i -> User.builder() + .name("user@gmail.com " + i) + .profileImage("image") + .oauthId( + OauthId.builder() + .oauthId("oauthId " + i) + .oauthType(OauthType.KAKAO) + .build() + ) + .build()).toList(); + + userRepository.saveAll(users); + + Book book = createBook(); + bookRepository.save(book); + + List talkRoom = IntStream.range(0, 20) + .mapToObj(i -> TalkRoom.builder() + .user(users.get(0)) + .book(book) + .title("토론방 " + i) + .content("내용 " + i) + .build()) + .toList(); + + talkRoomRepository.saveAll(talkRoom); + + for (TalkRoom t : talkRoom) { + createTalkRoomRole(t); + } + + List comments = IntStream.range(0, 5) + .mapToObj(i -> Comment.builder() + .talkRoom(talkRoom.get(0)) + .user(users.get(0)) + .content("의견 " + i) + .build()) + .collect(Collectors.toList()); + + commentRepository.saveAll(comments); + + // when + TalkRoomFindOneResponse response = talkRoomRepository.findOneTalkRoom(talkRoom.get(0).getId()); + + // then + assertThat(5L).isEqualTo(response.getCommentCount()); + } + + @Test + @DisplayName("querydsl 토크방 단건 조회 시 좋아요 누른 userId 반환") + void findOneTalkRoomWithUserId() { + // given + List users = IntStream.range(0, 10) + .mapToObj(i -> User.builder() + .name("user@gmail.com " + i) + .profileImage("image") + .oauthId( + OauthId.builder() + .oauthId("oauthId " + i) + .oauthType(OauthType.KAKAO) + .build() + ) + .build()).toList(); + + userRepository.saveAll(users); + + Book book = createBook(); + bookRepository.save(book); + + List talkRoom = IntStream.range(0, 20) + .mapToObj(i -> TalkRoom.builder() + .user(users.get(0)) + .book(book) + .title("토론방 " + i) + .content("내용 " + i) + .build()) + .toList(); + + talkRoomRepository.saveAll(talkRoom); + + for (TalkRoom t : talkRoom) { + createTalkRoomRole(t); + } + + List likes = IntStream.range(0, 5).mapToObj(i -> TalkRoomLike.builder() + .user(users.get(i)) + .talkRoom(talkRoom.get(0)) + .build()) + .toList(); + + talkRoomLikeRepository.saveAll(likes); + + // when + TalkRoomFindOneResponse response = talkRoomRepository.findOneTalkRoom(talkRoom.get(0).getId()); + + // then + assertThat(users.get(0).getId()).isEqualTo(response.getUserIds().get(0).getUserId()); + assertThat(users.get(1).getId()).isEqualTo(response.getUserIds().get(1).getUserId()); + assertThat(users.get(2).getId()).isEqualTo(response.getUserIds().get(2).getUserId()); + assertThat(users.get(3).getId()).isEqualTo(response.getUserIds().get(3).getUserId()); + assertThat(users.get(4).getId()).isEqualTo(response.getUserIds().get(4).getUserId()); + } + + @Test + @DisplayName("querydsl 좋아요순 정렬 조회") + void findAllTalkRoomWithOrderLike() { + // given + List users = IntStream.range(0, 10) + .mapToObj(i -> User.builder() + .name("user@gmail.com " + i) + .profileImage("image") + .oauthId( + OauthId.builder() + .oauthId("oauthId " + i) + .oauthType(OauthType.KAKAO) + .build() + ) + .build()).toList(); + + userRepository.saveAll(users); + + Book book = createBook(); + bookRepository.save(book); + + List talkRoom = IntStream.range(0, 20) + .mapToObj(i -> TalkRoom.builder() + .user(users.get(0)) + .book(book) + .title("토론방 " + i) + .content("내용 " + i) + .build()) + .toList(); + + talkRoomRepository.saveAll(talkRoom); + + for (TalkRoom t : talkRoom) { + createTalkRoomRole(t); + } + + List likes1 = IntStream.range(0, 10).mapToObj(i -> TalkRoomLike.builder() + .user(users.get(i)) + .talkRoom(talkRoom.get(0)) + .build()) + .toList(); + + List likes2 = IntStream.range(0, 9).mapToObj(i -> TalkRoomLike.builder() + .user(users.get(i)) + .talkRoom(talkRoom.get(1)) + .build()) + .toList(); + + List likes = new ArrayList<>(); + likes.addAll(likes1); + likes.addAll(likes2); + + talkRoomLikeRepository.saveAll(likes); + + TalkRoomSearchServiceRequest search = TalkRoomSearchServiceRequest.builder() + .page(1) + .size(10) + .orderType(OrderType.RECOMMEND) + .build(); + + // when + PageResponse response = talkRoomRepository.findAllTalkRoom(search); + + // then + assertThat(10L).isEqualTo(response.getQueryResponse().get(0).getLikeCount()); + } + + @Test + @DisplayName("querydsl 토크방 제목 검색") + void findAllTalkRoomWithSearch() { + // given + List users = IntStream.range(0, 10) + .mapToObj(i -> User.builder() + .name("user@gmail.com " + i) + .profileImage("image") + .oauthId( + OauthId.builder() + .oauthId("oauthId " + i) + .oauthType(OauthType.KAKAO) + .build() + ) + .build()).toList(); + + userRepository.saveAll(users); + + Book book = createBook(); + bookRepository.save(book); + + List talkRoom = IntStream.range(0, 20) + .mapToObj(i -> TalkRoom.builder() + .user(users.get(0)) + .book(book) + .title("토론방 " + i) + .content("내용 " + i) + .build()) + .toList(); + + TalkRoom talkRoom1 = TalkRoom.builder() + .user(users.get(0)) + .book(book) + .title("검색어") + .content("내용") + .build(); + + TalkRoom talkRoom2 = TalkRoom.builder() + .user(users.get(0)) + .book(book) + .title("아무내용 검색어 아무내용") + .content("내용") + .build(); + + TalkRoom talkRoom3 = TalkRoom.builder() + .user(users.get(0)) + .book(book) + .title("아무내용 아무내용 검색어") + .content("내용") + .build(); + + talkRoomRepository.save(talkRoom1); + talkRoomRepository.save(talkRoom2); + talkRoomRepository.save(talkRoom3); + + talkRoomRepository.saveAll(talkRoom); + + for (TalkRoom t : talkRoom) { + createTalkRoomRole(t); + } + + List likes1 = IntStream.range(0, 10).mapToObj(i -> TalkRoomLike.builder() + .user(users.get(i)) + .talkRoom(talkRoom.get(0)) + .build()) + .toList(); + + List likes2 = IntStream.range(0, 9).mapToObj(i -> TalkRoomLike.builder() + .user(users.get(i)) + .talkRoom(talkRoom.get(1)) + .build()) + .toList(); + + List likes = new ArrayList<>(); + likes.addAll(likes1); + likes.addAll(likes2); + + talkRoomLikeRepository.saveAll(likes); + + TalkRoomSearchServiceRequest search = TalkRoomSearchServiceRequest.builder() + .page(1) + .size(10) + .search("검색어") + .build(); + + // when + PageResponse response = talkRoomRepository.findAllTalkRoom(search); + + // then + assertThat(talkRoom1.getTitle()).isEqualTo(response.getQueryResponse().get(0).getTitle()); + assertThat(talkRoom2.getTitle()).isEqualTo(response.getQueryResponse().get(1).getTitle()); + assertThat(talkRoom3.getTitle()).isEqualTo(response.getQueryResponse().get(2).getTitle()); + } + + private static Comment createComment(TalkRoom talkRoom, User user) { + return Comment.builder() + .talkRoom(talkRoom) + .user(user) + .content("의견 남기기") + .build(); + } + + private void createTalkRoomRole(TalkRoom talkRoom) { + List request = new ArrayList<>(); + request.add("읽는 중"); + request.add("읽음"); + + List readingStatus = ReadingStatus.createReadingStatus(request); + + readingStatus.stream().map(status -> TalkRoomRole.roleCreate(talkRoom, status)) + .forEach(talkRoomRoleRepository::save); + } + + private static TalkRoom createTalkRoom(Book book, User user) { + return TalkRoom.builder() + .book(book) + .title("토론방") + .content("내용") + .user(user) + .build(); + } + + private static User createUser() { + return User.builder() + .name("user@gmail.com") + .profileImage("image") + .oauthId( + OauthId.builder() + .oauthId("oauthId") + .oauthType(OauthType.KAKAO) + .build() + ) + .build(); + } + + private static Book createBook() { + return Book.builder() + .title("제목") + .content("내용") + .authors("작가") + .isbn("11111") + .publisher("publisher") + .dateTime(LocalDateTime.now()) + .imageUrl("www") + .build(); + } + +} \ No newline at end of file From 2341b1c96b4279702f6515cd7066fe45bcd164af Mon Sep 17 00:00:00 2001 From: ahnyunki Date: Wed, 27 Mar 2024 21:23:09 +0900 Subject: [PATCH 5/6] =?UTF-8?q?refactor:=20search=20=EA=B0=9D=EC=B2=B4=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20(#40)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/jisungin/api/talkroom/request/TalkRoomSearchRequest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/jisungin/api/talkroom/request/TalkRoomSearchRequest.java b/src/main/java/com/jisungin/api/talkroom/request/TalkRoomSearchRequest.java index e3260c3..1aa6d45 100644 --- a/src/main/java/com/jisungin/api/talkroom/request/TalkRoomSearchRequest.java +++ b/src/main/java/com/jisungin/api/talkroom/request/TalkRoomSearchRequest.java @@ -32,6 +32,7 @@ public TalkRoomSearchServiceRequest toService() { return TalkRoomSearchServiceRequest.builder() .page(page) .size(size) + .search(search) .orderType(OrderType.conversionOrderType(order)) .build(); } From 658588a2e0c6372a23a367268f51ac849017d4d9 Mon Sep 17 00:00:00 2001 From: ahnyunki Date: Wed, 27 Mar 2024 22:04:22 +0900 Subject: [PATCH 6/6] =?UTF-8?q?refactor:=20convertToOrderType=20=EB=A9=94?= =?UTF-8?q?=EC=86=8C=EB=93=9C=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?(#40)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jisungin/api/talkroom/request/TalkRoomSearchRequest.java | 2 +- src/main/java/com/jisungin/application/OrderType.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/jisungin/api/talkroom/request/TalkRoomSearchRequest.java b/src/main/java/com/jisungin/api/talkroom/request/TalkRoomSearchRequest.java index 1aa6d45..52b4fc2 100644 --- a/src/main/java/com/jisungin/api/talkroom/request/TalkRoomSearchRequest.java +++ b/src/main/java/com/jisungin/api/talkroom/request/TalkRoomSearchRequest.java @@ -33,7 +33,7 @@ public TalkRoomSearchServiceRequest toService() { .page(page) .size(size) .search(search) - .orderType(OrderType.conversionOrderType(order)) + .orderType(OrderType.convertToOrderType(order)) .build(); } diff --git a/src/main/java/com/jisungin/application/OrderType.java b/src/main/java/com/jisungin/application/OrderType.java index 9978683..013dca5 100644 --- a/src/main/java/com/jisungin/application/OrderType.java +++ b/src/main/java/com/jisungin/application/OrderType.java @@ -10,7 +10,7 @@ public enum OrderType { private final String text; - public static OrderType conversionOrderType(String order) { + public static OrderType convertToOrderType(String order) { return switch (order) { case "recent" -> RECENT; case "recommend" -> RECOMMEND;