diff --git a/src/main/java/com/example/log4u/domain/comment/dto/response/CommentResponseDto.java b/src/main/java/com/example/log4u/domain/comment/dto/response/CommentResponseDto.java index 933dddaf..ae67856e 100644 --- a/src/main/java/com/example/log4u/domain/comment/dto/response/CommentResponseDto.java +++ b/src/main/java/com/example/log4u/domain/comment/dto/response/CommentResponseDto.java @@ -1,15 +1,27 @@ package com.example.log4u.domain.comment.dto.response; +import java.time.LocalDateTime; + import com.example.log4u.domain.comment.entity.Comment; +import com.example.log4u.domain.user.entity.User; public record CommentResponseDto( Long commentId, - String content + Long userId, + String userName, + String userProfileImage, + String content, + LocalDateTime createdAt ) { - public static CommentResponseDto of(Comment comment) { + public static CommentResponseDto of(Comment comment, User user) { return new CommentResponseDto( comment.getCommentId(), - comment.getContent() + user.getUserId(), + user.getName(), + user.getProfileImage(), + comment.getContent(), + comment.getCreatedAt() ); } } + diff --git a/src/main/java/com/example/log4u/domain/comment/repository/CommentRepositoryCustom.java b/src/main/java/com/example/log4u/domain/comment/repository/CommentRepositoryCustom.java index 3ef43ad3..63d607ad 100644 --- a/src/main/java/com/example/log4u/domain/comment/repository/CommentRepositoryCustom.java +++ b/src/main/java/com/example/log4u/domain/comment/repository/CommentRepositoryCustom.java @@ -3,9 +3,10 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; +import com.example.log4u.domain.comment.dto.response.CommentResponseDto; import com.example.log4u.domain.comment.entity.Comment; public interface CommentRepositoryCustom { - Slice findByDiaryIdWithCursor(Long diaryId, Long cursorCommentId, Pageable pageable); + Slice findWithUserByDiaryId(Long diaryId, Long cursorCommentId, Pageable pageable); } diff --git a/src/main/java/com/example/log4u/domain/comment/repository/CommentRepositoryImpl.java b/src/main/java/com/example/log4u/domain/comment/repository/CommentRepositoryImpl.java index b2fa98ba..ae99f318 100644 --- a/src/main/java/com/example/log4u/domain/comment/repository/CommentRepositoryImpl.java +++ b/src/main/java/com/example/log4u/domain/comment/repository/CommentRepositoryImpl.java @@ -9,7 +9,12 @@ import org.springframework.data.domain.SliceImpl; import org.springframework.stereotype.Repository; +import com.example.log4u.domain.comment.dto.response.CommentResponseDto; import com.example.log4u.domain.comment.entity.Comment; +import com.example.log4u.domain.comment.entity.QComment; +import com.example.log4u.domain.user.entity.QUser; +import com.example.log4u.domain.user.entity.User; +import com.querydsl.core.Tuple; import com.querydsl.jpa.impl.JPAQueryFactory; import lombok.RequiredArgsConstructor; @@ -21,19 +26,31 @@ public class CommentRepositoryImpl implements CommentRepositoryCustom { private final JPAQueryFactory queryFactory; @Override - public Slice findByDiaryIdWithCursor(Long diaryId, Long cursorCommentId, Pageable pageable) { - List result = queryFactory - .selectFrom(comment) + public Slice findWithUserByDiaryId(Long diaryId, Long cursorCommentId, Pageable pageable) { + QComment comment = QComment.comment; + QUser user = QUser.user; + + List tuples = queryFactory + .select(comment, user) + .from(comment) + .join(user).on(comment.userId.eq(user.userId)) .where( comment.diaryId.eq(diaryId), cursorCommentId != null ? comment.commentId.lt(cursorCommentId) : null ) .orderBy(comment.commentId.desc()) - .limit(pageable.getPageSize() + 1) // 커서 기반 페이징 + .limit(pageable.getPageSize() + 1) .fetch(); - boolean hasNext = result.size() > pageable.getPageSize(); - List content = hasNext ? result.subList(0, pageable.getPageSize()) : result; + boolean hasNext = tuples.size() > pageable.getPageSize(); + List content = tuples.stream() + .limit(pageable.getPageSize()) + .map(tuple -> { + Comment c = tuple.get(comment); + User u = tuple.get(user); + return CommentResponseDto.of(c, u); + }) + .toList(); return new SliceImpl<>(content, pageable, hasNext); } diff --git a/src/main/java/com/example/log4u/domain/comment/service/CommentService.java b/src/main/java/com/example/log4u/domain/comment/service/CommentService.java index 53c9c392..be5d4e19 100644 --- a/src/main/java/com/example/log4u/domain/comment/service/CommentService.java +++ b/src/main/java/com/example/log4u/domain/comment/service/CommentService.java @@ -62,13 +62,10 @@ private Comment getComment(Long commentId) { public PageResponse getCommentListByDiary(Long diaryId, Long cursorCommentId, int size) { checkDiaryExists(diaryId); Pageable pageable = PageRequest.of(0, size); - Slice slice = commentRepository.findByDiaryIdWithCursor(diaryId, cursorCommentId, pageable); + Slice slice = commentRepository.findWithUserByDiaryId(diaryId, cursorCommentId, pageable); - List dtoList = slice.getContent().stream() - .map(CommentResponseDto::of) - .toList(); - - Long nextCursor = slice.hasNext() ? dtoList.getLast().commentId() : null; - return PageResponse.of(new SliceImpl<>(dtoList, pageable, slice.hasNext()), nextCursor); + Long nextCursor = slice.hasNext() ? slice.getContent().getLast().commentId() : null; + return PageResponse.of(slice, nextCursor); } + } diff --git a/src/test/java/com/example/log4u/domain/comment/service/CommonServiceTest.java b/src/test/java/com/example/log4u/domain/comment/service/CommonServiceTest.java index 457cd1d3..b7cbcbd8 100644 --- a/src/test/java/com/example/log4u/domain/comment/service/CommonServiceTest.java +++ b/src/test/java/com/example/log4u/domain/comment/service/CommonServiceTest.java @@ -6,6 +6,7 @@ import java.util.List; import java.util.Optional; +import java.util.stream.IntStream; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -149,26 +150,26 @@ void getCommentsList_In_DiaryDetail_Success() { int size = 5; Long cursorCommentId = null; - List commentList = CommentFixture.createCommentsListFixture(size + 1); // hasNext 판별 위해 +1 + List dtoList = CommentFixture.createCommentDtos(size + 1); + Pageable pageable = PageRequest.of(0, size); - boolean hasNext = commentList.size() > size; + boolean hasNext = dtoList.size() > size; + List sliced = hasNext ? dtoList.subList(0, size) : dtoList; - List sliced = hasNext ? commentList.subList(0, size) : commentList; + Slice slice = new SliceImpl<>(sliced, pageable, hasNext); - Slice slice = new SliceImpl<>(sliced, pageable, hasNext); - given(commentRepository.findByDiaryIdWithCursor(diaryId, cursorCommentId, pageable)) + given(commentRepository.findWithUserByDiaryId(diaryId, cursorCommentId, pageable)) .willReturn(slice); // when - PageResponse response = commentService.getCommentListByDiary(diaryId, cursorCommentId, - size); + PageResponse response = commentService.getCommentListByDiary(diaryId, cursorCommentId, size); // then assertThat(response.list()).hasSize(sliced.size()); assertThat(response.pageInfo().hasNext()).isEqualTo(hasNext); - assertThat(response.pageInfo().nextCursor()).isEqualTo(hasNext ? sliced.getLast().getCommentId() : null); + assertThat(response.pageInfo().nextCursor()).isEqualTo(hasNext ? sliced.getLast().commentId() : null); - verify(commentRepository).findByDiaryIdWithCursor(diaryId, cursorCommentId, pageable); + verify(commentRepository).findWithUserByDiaryId(diaryId, cursorCommentId, pageable); } } diff --git a/src/test/java/com/example/log4u/fixture/CommentFixture.java b/src/test/java/com/example/log4u/fixture/CommentFixture.java index 329ba8ce..98d6ec93 100644 --- a/src/test/java/com/example/log4u/fixture/CommentFixture.java +++ b/src/test/java/com/example/log4u/fixture/CommentFixture.java @@ -1,8 +1,11 @@ package com.example.log4u.fixture; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; +import java.util.stream.IntStream; +import com.example.log4u.domain.comment.dto.response.CommentResponseDto; import com.example.log4u.domain.comment.entity.Comment; public class CommentFixture { @@ -34,4 +37,16 @@ public static List createCommentsListFixture(int count) { } return comments; } + + public static List createCommentDtos(int size) { + return IntStream.rangeClosed(1, size) + .mapToObj(i -> new CommentResponseDto( + (long) i, + (long) i, + "사용자" + i, + "https://cdn.example.com/user" + i + ".png", + "댓글 " + i, + LocalDateTime.now().minusMinutes(i) // createdAt + )).toList(); + } }