feat(community): 게시물 댓글 조회 포트를 구현한다

This commit is contained in:
2026-07-07 11:55:46 +09:00
parent fe9adf35e7
commit cf8acacedf
3 changed files with 370 additions and 0 deletions
@@ -353,6 +353,111 @@ class DefaultCreatorChannelCommunityQueryRepositoryTest @Autowired constructor(
assertFalse(adultInactivePurchasedPost.id in adultBlockedPosts.map { it.postId })
}
@Test
@DisplayName("게시물 ID 상세 조회는 좋아요와 구매와 성인 정책 필드를 채운다")
fun shouldFindCommunityPostByIdWithLikePurchaseAndAdultPolicy() {
val viewer = saveMember("detail-viewer", MemberRole.USER)
val creator = saveMember("detail-creator", MemberRole.CREATOR)
val liker = saveMember("detail-liker", MemberRole.USER)
val paidPost = saveCommunity(creator, isFixed = true, price = 100, isAdult = false)
val adultPost = saveCommunity(creator, isFixed = false, price = 0, isAdult = true)
val inactivePost = saveCommunity(creator, isFixed = false, price = 0, isActive = false)
saveCommunityOrder(viewer, paidPost, CanUsage.PAID_COMMUNITY_POST, isRefund = false)
saveCommunityLike(viewer, paidPost, isActive = true)
saveCommunityLike(liker, paidPost, isActive = true)
saveCommunityComment(viewer, paidPost, isActive = true)
flushAndClear()
val record = repository.findCommunityPost(paidPost.id!!, viewer.id!!, canViewAdultContent = true)
val blockedAdultRecord = repository.findCommunityPost(adultPost.id!!, viewer.id!!, canViewAdultContent = false)
val inactiveRecord = repository.findCommunityPost(inactivePost.id!!, viewer.id!!, canViewAdultContent = true)
assertNotNull(record)
assertEquals(paidPost.id, record!!.postId)
assertTrue(record.existOrdered)
assertTrue(record.isLiked)
assertEquals(2, record.likeCount)
assertEquals(1, record.commentCount)
assertTrue(record.isPinned)
assertNull(blockedAdultRecord)
assertNull(inactiveRecord)
}
@Test
@DisplayName("최상위 댓글 목록은 비밀 댓글과 차단 작성자를 필터링하고 최신 답글을 반환한다")
fun shouldFindVisibleRootCommentsWithLatestReply() {
val creator = saveMember("visible-comment-creator", MemberRole.CREATOR)
val viewer = saveMember("visible-comment-viewer", MemberRole.USER)
val writer = saveMember("visible-comment-writer", MemberRole.USER)
val secretWriter = saveMember("visible-secret-writer", MemberRole.USER)
val blockedWriter = saveMember("visible-blocked-writer", MemberRole.USER)
val replyWriter = saveMember("visible-reply-writer", MemberRole.USER)
val post = saveCommunity(creator, isFixed = false, price = 0, isCommentAvailable = true)
val oldComment = saveCommunityComment(writer, post, isActive = true)
val newComment = saveCommunityComment(viewer, post, isActive = true)
saveCommunityComment(secretWriter, post, isActive = true, isSecret = true)
saveCommunityComment(blockedWriter, post, isActive = true)
saveCommunityComment(writer, post, isActive = false)
val oldReply = saveCommunityComment(replyWriter, post, isActive = true, parent = newComment)
val latestReply = saveCommunityComment(replyWriter, post, isActive = true, parent = newComment)
val hiddenSecretReply = saveCommunityComment(secretWriter, post, isActive = true, isSecret = true, parent = newComment)
saveBlock(viewer, blockedWriter, isActive = true)
flushAndClear()
updateCreatedAt("CreatorCommunityComment", oldComment.id!!, LocalDateTime.of(2026, 7, 6, 10, 0))
updateCreatedAt("CreatorCommunityComment", newComment.id!!, LocalDateTime.of(2026, 7, 6, 11, 0))
updateCreatedAt("CreatorCommunityComment", oldReply.id!!, LocalDateTime.of(2026, 7, 6, 11, 1))
updateCreatedAt("CreatorCommunityComment", latestReply.id!!, LocalDateTime.of(2026, 7, 6, 11, 2))
updateCreatedAt("CreatorCommunityComment", hiddenSecretReply.id!!, LocalDateTime.of(2026, 7, 6, 11, 3))
flushAndClear()
val viewerCount = repository.countCommunityComments(post.id!!, viewer.id!!, creator.id!!)
val creatorCount = repository.countCommunityComments(post.id!!, creator.id!!, creator.id!!)
val comments = repository.findCommunityComments(post.id!!, viewer.id!!, creator.id!!, offset = 0, limit = 10)
val latestReplies = repository.findLatestRepliesByCommentIds(comments.map { it.commentId }, viewer.id!!)
assertEquals(2, viewerCount)
assertEquals(4, creatorCount)
assertEquals(listOf(newComment.id, oldComment.id), comments.map { it.commentId })
assertEquals(listOf(latestReply.id), latestReplies.map { it.commentId })
assertEquals(newComment.id, latestReplies.single().parentCommentId)
}
@Test
@DisplayName("답글 조회는 보이는 최상위 댓글 context와 활성 답글만 반환한다")
fun shouldFindVisibleRepliesForRootCommentOnly() {
val creator = saveMember("reply-context-creator", MemberRole.CREATOR)
val viewer = saveMember("reply-context-viewer", MemberRole.USER)
val writer = saveMember("reply-context-writer", MemberRole.USER)
val blockedWriter = saveMember("reply-context-blocked", MemberRole.USER)
val secretWriter = saveMember("reply-context-secret", MemberRole.USER)
val post = saveCommunity(creator, isFixed = false, price = 0, isCommentAvailable = true)
val root = saveCommunityComment(writer, post, isActive = true)
val secretRoot = saveCommunityComment(secretWriter, post, isActive = true, isSecret = true)
val oldReply = saveCommunityComment(writer, post, isActive = true, parent = root)
val newReply = saveCommunityComment(writer, post, isActive = true, parent = root)
saveCommunityComment(secretWriter, post, isActive = true, isSecret = true, parent = root)
saveCommunityComment(writer, post, isActive = false, parent = root)
saveCommunityComment(blockedWriter, post, isActive = true, parent = root)
saveBlock(viewer, blockedWriter, isActive = true)
flushAndClear()
updateCreatedAt("CreatorCommunityComment", oldReply.id!!, LocalDateTime.of(2026, 7, 6, 10, 0))
updateCreatedAt("CreatorCommunityComment", newReply.id!!, LocalDateTime.of(2026, 7, 6, 11, 0))
flushAndClear()
val context = repository.findRootCommentContext(root.id!!, viewer.id!!, canViewAdultContent = true)
val invisibleSecretContext = repository.findRootCommentContext(secretRoot.id!!, viewer.id!!, canViewAdultContent = true)
val replyContext = repository.findRootCommentContext(newReply.id!!, viewer.id!!, canViewAdultContent = true)
val count = repository.countCommunityReplies(root.id!!, viewer.id!!)
val replies = repository.findCommunityReplies(root.id!!, viewer.id!!, offset = 0, limit = 10)
assertNotNull(context)
assertEquals(post.id, context!!.postId)
assertNull(invisibleSecretContext)
assertNull(replyContext)
assertEquals(2, count)
assertEquals(listOf(newReply.id, oldReply.id), replies.map { it.commentId })
}
private fun saveMember(
nickname: String,
role: MemberRole,