From d4485c3270d733f69a8dc82c01b6e057dc88c80c Mon Sep 17 00:00:00 2001 From: leedy5521 <80202719+dev2yup@users.noreply.github.com> Date: Fri, 30 Jan 2026 19:36:56 +0900 Subject: [PATCH] =?UTF-8?q?[refactor/#301]=20=EB=8C=93=EA=B8=80=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20API=20=EB=8C=80=EB=8C=93=EA=B8=80=20?= =?UTF-8?q?=EA=B0=9C=EC=88=98=20=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?(#305)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: 댓글 조회 API 대댓글 개수 필드 추가 * test/refactor: 댓글 조회 API 컨트롤러 테스트 수정 * fix: 레포지토리 수정 * test/refactor: 댓글 조회 API 서비스 테스트 수정 --- .../dto/response/CommentListResponse.java | 1 + .../repository/CommentRepositoryImpl.java | 21 +++++++++++++------ .../controller/CommentControllerTest.java | 8 ++++++- .../comment/service/CommentServiceTest.java | 4 ++++ 4 files changed, 27 insertions(+), 7 deletions(-) diff --git a/clokey-api/src/main/java/org/clokey/domain/comment/dto/response/CommentListResponse.java b/clokey-api/src/main/java/org/clokey/domain/comment/dto/response/CommentListResponse.java index ecf8dd88..2b2ccb44 100644 --- a/clokey-api/src/main/java/org/clokey/domain/comment/dto/response/CommentListResponse.java +++ b/clokey-api/src/main/java/org/clokey/domain/comment/dto/response/CommentListResponse.java @@ -10,4 +10,5 @@ public record CommentListResponse( String profileImageUrl, @Schema(description = "댓글 내용", example = "이 옷 정보 알려주세요!") String content, @Schema(description = "대댓글 존재 여부", example = "false") boolean replied, + @Schema(description = "총 대댓글 개수", example = "0") long replyCount, @Schema(description = "내가 작성한 댓글인가?", example = "false") boolean isMine) {} diff --git a/clokey-api/src/main/java/org/clokey/domain/comment/repository/CommentRepositoryImpl.java b/clokey-api/src/main/java/org/clokey/domain/comment/repository/CommentRepositoryImpl.java index 32faca15..f18cc699 100644 --- a/clokey-api/src/main/java/org/clokey/domain/comment/repository/CommentRepositoryImpl.java +++ b/clokey-api/src/main/java/org/clokey/domain/comment/repository/CommentRepositoryImpl.java @@ -5,9 +5,11 @@ import static org.clokey.history.entity.QHistoryImage.historyImage; import static org.clokey.member.entity.QMember.member; +import com.querydsl.core.Tuple; import com.querydsl.core.types.Projections; import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; import com.querydsl.jpa.impl.JPAQueryFactory; import java.util.ArrayList; import java.util.List; @@ -52,6 +54,7 @@ public Slice findAllParentCommentByHistoryId( member.profileImageUrl, comment.content, Expressions.constant(false), + Expressions.constant(0L), member.id.eq(currentMemberId))) .from(comment) .join(comment.member, member) @@ -71,9 +74,10 @@ public Slice findAllParentCommentByHistoryId( results = results.subList(0, size); } - List parentIdsWithReplies = + NumberExpression replyCountExpression = comment.id.count(); + List replyCounts = queryFactory - .select(comment.comment.id) + .select(comment.comment.id, replyCountExpression) .from(comment) .where( comment.comment.id.in( @@ -83,9 +87,13 @@ public Slice findAllParentCommentByHistoryId( .groupBy(comment.comment.id) .fetch(); - // 각 부모 댓글이 대댓글을 가지고 있는지 여부 조회 - Map repliedMap = - parentIdsWithReplies.stream().collect(Collectors.toMap(id -> id, id -> true)); + // 각 부모 댓글별 대댓글 개수 조회 + Map replyCountMap = + replyCounts.stream() + .collect( + Collectors.toMap( + tuple -> tuple.get(comment.comment.id), + tuple -> tuple.get(replyCountExpression))); List finalResults = results.stream() @@ -97,7 +105,8 @@ public Slice findAllParentCommentByHistoryId( c.nickname(), c.profileImageUrl(), c.content(), - repliedMap.getOrDefault(c.commentId(), false), + replyCountMap.getOrDefault(c.commentId(), 0L) > 0, + replyCountMap.getOrDefault(c.commentId(), 0L), c.isMine())) .toList(); diff --git a/clokey-api/src/test/java/org/clokey/domain/comment/controller/CommentControllerTest.java b/clokey-api/src/test/java/org/clokey/domain/comment/controller/CommentControllerTest.java index 7ce08240..1f95e3ec 100644 --- a/clokey-api/src/test/java/org/clokey/domain/comment/controller/CommentControllerTest.java +++ b/clokey-api/src/test/java/org/clokey/domain/comment/controller/CommentControllerTest.java @@ -1,6 +1,5 @@ package org.clokey.domain.comment.controller; -import static org.junit.jupiter.api.Assertions.*; import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.willDoNothing; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; @@ -292,6 +291,7 @@ class 기록의_댓글_목록_조회_요청_시 { "testProfile", "testContent1", false, + 0L, true), new CommentListResponse( 2L, @@ -300,6 +300,7 @@ class 기록의_댓글_목록_조회_요청_시 { "testProfile", "testContent2", false, + 0L, true)); given(commentService.getHistoryComments(1L, null, 2, SortDirection.ASC)) @@ -333,6 +334,7 @@ class 기록의_댓글_목록_조회_요청_시 { "testProfile", "testContent2", false, + 0L, true), new CommentListResponse( 1L, @@ -341,6 +343,7 @@ class 기록의_댓글_목록_조회_요청_시 { "testProfile", "testContent1", false, + 0L, true)); given(commentService.getHistoryComments(1L, null, 2, SortDirection.DESC)) @@ -374,6 +377,7 @@ class 기록의_댓글_목록_조회_요청_시 { "testProfile", "testContent2", false, + 0L, true)); given(commentService.getHistoryComments(1L, null, 1, SortDirection.ASC)) @@ -406,6 +410,7 @@ class 기록의_댓글_목록_조회_요청_시 { "testProfile", "testContent1", false, + 0L, true), new CommentListResponse( 2L, @@ -414,6 +419,7 @@ class 기록의_댓글_목록_조회_요청_시 { "testProfile", "testContent2", false, + 0L, true)); given(commentService.getHistoryComments(1L, null, 1, SortDirection.ASC)) diff --git a/clokey-api/src/test/java/org/clokey/domain/comment/service/CommentServiceTest.java b/clokey-api/src/test/java/org/clokey/domain/comment/service/CommentServiceTest.java index a9190d0d..11eab2dd 100644 --- a/clokey-api/src/test/java/org/clokey/domain/comment/service/CommentServiceTest.java +++ b/clokey-api/src/test/java/org/clokey/domain/comment/service/CommentServiceTest.java @@ -363,6 +363,10 @@ void setUp() { // then assertThat(response.content()).extracting("commentId").containsExactly(1L, 2L, 3L); + assertThat(response.content()) + .extracting("commentId", "replied", "replyCount") + .containsExactly( + tuple(1L, true, 1L), tuple(2L, false, 0L), tuple(3L, false, 0L)); } @Test