feat(creator-channel): 커뮤니티 조회에 본문 번역을 적용한다
This commit is contained in:
+23
-4
@@ -21,6 +21,7 @@ import kr.co.vividnext.sodalive.v2.creator.channel.community.port.out.CreatorCha
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.community.port.out.CreatorChannelCommunityCreatorRecord
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.community.port.out.CreatorChannelCommunityPostRecord
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.community.port.out.CreatorChannelCommunityQueryPort
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.community.translation.application.CreatorCommunityTranslationService
|
||||
import org.springframework.beans.factory.ObjectProvider
|
||||
import org.springframework.beans.factory.annotation.Value
|
||||
import org.springframework.stereotype.Service
|
||||
@@ -36,6 +37,7 @@ class CreatorChannelCommunityQueryService(
|
||||
private val audioContentCloudFront: AudioContentCloudFront,
|
||||
private val messageSource: SodaMessageSource,
|
||||
private val langContext: LangContext,
|
||||
private val creatorCommunityTranslationService: CreatorCommunityTranslationService,
|
||||
@Value("\${cloud.aws.cloud-front.host}")
|
||||
private val cloudFrontHost: String
|
||||
) {
|
||||
@@ -69,6 +71,9 @@ class CreatorChannelCommunityQueryService(
|
||||
offset = communityPage.offset,
|
||||
limit = communityPage.fetchLimit
|
||||
)
|
||||
val communityPosts = queryPolicy.limitItems(fetchedPosts, communityPage)
|
||||
val displayContents = creatorCommunityTranslationService
|
||||
.findDisplayContents(communityPosts.map { it.postId }, langContext.lang.code)
|
||||
|
||||
return CreatorChannelCommunityTab(
|
||||
communityPostCount = queryPort.countCommunityPosts(
|
||||
@@ -76,7 +81,9 @@ class CreatorChannelCommunityQueryService(
|
||||
viewerId = viewerId,
|
||||
canViewAdultContent = canViewAdultContent
|
||||
),
|
||||
communityPosts = queryPolicy.limitItems(fetchedPosts, communityPage).map { it.toDomain(viewerId) },
|
||||
communityPosts = communityPosts.map {
|
||||
it.copy(content = displayContents[it.postId]?.content ?: it.content).toDomain(viewerId)
|
||||
},
|
||||
page = communityPage,
|
||||
hasNext = queryPolicy.hasNext(fetchedPosts, communityPage)
|
||||
)
|
||||
@@ -89,7 +96,7 @@ class CreatorChannelCommunityQueryService(
|
||||
canViewAdultContent: Boolean,
|
||||
limit: Int
|
||||
): List<CreatorChannelCommunityPost> {
|
||||
return queryPortProvider.getObject()
|
||||
val posts = queryPortProvider.getObject()
|
||||
.findHomeCommunityPosts(
|
||||
creatorId = creatorId,
|
||||
viewerId = viewerId,
|
||||
@@ -97,7 +104,12 @@ class CreatorChannelCommunityQueryService(
|
||||
canViewAdultContent = canViewAdultContent,
|
||||
limit = limit
|
||||
)
|
||||
.map { it.toDomain(viewerId) }
|
||||
val displayContents = creatorCommunityTranslationService
|
||||
.findDisplayContents(posts.map { it.postId }, langContext.lang.code)
|
||||
|
||||
return posts.map {
|
||||
it.copy(content = displayContents[it.postId]?.content ?: it.content).toDomain(viewerId)
|
||||
}
|
||||
}
|
||||
|
||||
fun getCommunityPostDetail(
|
||||
@@ -113,8 +125,15 @@ class CreatorChannelCommunityQueryService(
|
||||
|
||||
validateNotBlocked(queryPort, viewerId, postRecord.creatorId)
|
||||
|
||||
val locale = langContext.lang.code
|
||||
val displayContent = creatorCommunityTranslationService
|
||||
.findDisplayContents(listOf(postRecord.postId), locale)[postRecord.postId]
|
||||
if (displayContent?.hasValidTranslation != true) {
|
||||
creatorCommunityTranslationService.requestTranslations(postRecord.postId, locale)
|
||||
}
|
||||
|
||||
return CreatorChannelCommunityPostDetail(
|
||||
post = postRecord.toDomain(viewerId),
|
||||
post = postRecord.copy(content = displayContent?.content ?: postRecord.content).toDomain(viewerId),
|
||||
comments = getCommunityComments(postId, viewer, page = 0, size = 20, now = now)
|
||||
)
|
||||
}
|
||||
|
||||
+152
@@ -13,6 +13,8 @@ import kr.co.vividnext.sodalive.member.MemberRole
|
||||
import kr.co.vividnext.sodalive.member.block.BlockMember
|
||||
import kr.co.vividnext.sodalive.member.contentpreference.MemberContentPreference
|
||||
import kr.co.vividnext.sodalive.support.EmbeddedRedisInitializer
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.community.translation.application.CreatorCommunityDisplayContent
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.community.translation.application.CreatorCommunityTranslationService
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.mockito.Mockito
|
||||
@@ -47,6 +49,9 @@ class CreatorChannelCommunityEndToEndTest @Autowired constructor(
|
||||
@MockBean
|
||||
private lateinit var audioContentCloudFront: AudioContentCloudFront
|
||||
|
||||
@MockBean
|
||||
private lateinit var creatorCommunityTranslationService: CreatorCommunityTranslationService
|
||||
|
||||
@Test
|
||||
@DisplayName("커뮤니티 탭 API는 E2E로 정렬, fallback, 성인 필터, 유료 미디어 접근 정책을 반환한다")
|
||||
fun shouldReturnCommunityTabThroughControllerServiceAndRepository() {
|
||||
@@ -97,6 +102,41 @@ class CreatorChannelCommunityEndToEndTest @Autowired constructor(
|
||||
Mockito.verifyNoMoreInteractions(audioContentCloudFront)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("커뮤니티 탭 API는 저장 번역을 페이지 단위로 선택하고 유료 미리보기를 유지한다")
|
||||
fun shouldUseStoredTranslationsForCommunityTabWithoutScheduling() {
|
||||
val fixture = createFixture()
|
||||
val postIds = listOf(
|
||||
fixture.pinnedPostId,
|
||||
fixture.purchasedPaidPostId,
|
||||
fixture.unpurchasedPaidPostId,
|
||||
fixture.noImagePostId
|
||||
)
|
||||
Mockito.`when`(creatorCommunityTranslationService.findDisplayContents(postIds, "ja"))
|
||||
.thenReturn(
|
||||
mapOf(
|
||||
fixture.pinnedPostId to CreatorCommunityDisplayContent("translated pinned", true),
|
||||
fixture.purchasedPaidPostId to CreatorCommunityDisplayContent("translated purchased", true),
|
||||
fixture.unpurchasedPaidPostId to CreatorCommunityDisplayContent("가나다라마바사아자차카타파하🙂끝", true),
|
||||
fixture.noImagePostId to CreatorCommunityDisplayContent("no image community", false)
|
||||
)
|
||||
)
|
||||
|
||||
mockMvc.perform(
|
||||
get("/api/v2/creator-channels/${fixture.creatorId}/community")
|
||||
.header("Accept-Language", "ja")
|
||||
.with(user(MemberAdapter(fixture.viewer)))
|
||||
)
|
||||
.andExpect(status().isOk)
|
||||
.andExpect(jsonPath("$.data.communityPosts[0].content").value("translated pinned"))
|
||||
.andExpect(jsonPath("$.data.communityPosts[1].content").value("translated purchased"))
|
||||
.andExpect(jsonPath("$.data.communityPosts[2].content").value("가나다라마바사아자차카타파하🙂..."))
|
||||
.andExpect(jsonPath("$.data.communityPosts[3].content").value("no image community"))
|
||||
|
||||
Mockito.verify(creatorCommunityTranslationService).findDisplayContents(postIds, "ja")
|
||||
Mockito.verifyNoMoreInteractions(creatorCommunityTranslationService)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("커뮤니티 상세 API는 초기 댓글 20개와 최신 답글을 반환한다")
|
||||
fun shouldReturnCommunityPostDetailWithInitialComments() {
|
||||
@@ -115,6 +155,74 @@ class CreatorChannelCommunityEndToEndTest @Autowired constructor(
|
||||
.andExpect(jsonPath("$.data.comments.comments[0].createdAtUtc").value(org.hamcrest.Matchers.endsWith("Z")))
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("커뮤니티 상세 API는 저장 번역문에 유료 미리보기를 적용하고 요청 언어만 예약한다")
|
||||
fun shouldSelectTranslatedContentBeforePaidMaskingAndRequestCurrentLanguage() {
|
||||
val fixture = createTranslatedPaidDetailFixture(purchased = false)
|
||||
Mockito.`when`(creatorCommunityTranslationService.findDisplayContents(listOf(fixture.postId), "ja"))
|
||||
.thenReturn(mapOf(fixture.postId to CreatorCommunityDisplayContent("translated paid content", true)))
|
||||
|
||||
mockMvc.perform(
|
||||
get("/api/v2/creator-channels/community-posts/${fixture.postId}")
|
||||
.header("Accept-Language", "ja")
|
||||
.with(user(MemberAdapter(fixture.viewer)))
|
||||
)
|
||||
.andExpect(status().isOk)
|
||||
.andExpect(jsonPath("$.data.content").value("translated paid..."))
|
||||
|
||||
Mockito.verify(creatorCommunityTranslationService, Mockito.never()).requestTranslations(fixture.postId, "ja")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("커뮤니티 상세 API는 구매자에게 선택한 유료 번역문 전체를 반환한다")
|
||||
fun shouldReturnFullTranslatedContentToBuyer() {
|
||||
val fixture = createTranslatedPaidDetailFixture(purchased = true)
|
||||
Mockito.`when`(creatorCommunityTranslationService.findDisplayContents(listOf(fixture.postId), "ja"))
|
||||
.thenReturn(mapOf(fixture.postId to CreatorCommunityDisplayContent("translated paid content", true)))
|
||||
|
||||
mockMvc.perform(
|
||||
get("/api/v2/creator-channels/community-posts/${fixture.postId}")
|
||||
.header("Accept-Language", "ja")
|
||||
.with(user(MemberAdapter(fixture.viewer)))
|
||||
)
|
||||
.andExpect(status().isOk)
|
||||
.andExpect(jsonPath("$.data.content").value("translated paid content"))
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("커뮤니티 상세 API는 소유자에게 선택한 유료 번역문 전체를 반환한다")
|
||||
fun shouldReturnFullTranslatedContentToOwner() {
|
||||
val fixture = createTranslatedPaidOwnerDetailFixture()
|
||||
Mockito.`when`(creatorCommunityTranslationService.findDisplayContents(listOf(fixture.postId), "ja"))
|
||||
.thenReturn(mapOf(fixture.postId to CreatorCommunityDisplayContent("translated paid content", true)))
|
||||
|
||||
mockMvc.perform(
|
||||
get("/api/v2/creator-channels/community-posts/${fixture.postId}")
|
||||
.header("Accept-Language", "ja")
|
||||
.with(user(MemberAdapter(fixture.viewer)))
|
||||
)
|
||||
.andExpect(status().isOk)
|
||||
.andExpect(jsonPath("$.data.content").value("translated paid content"))
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("커뮤니티 상세 API는 반복 요청을 모두 성공시키고 같은 요청 언어만 전달한다")
|
||||
fun shouldKeepRepeatedCommunityDetailRequestsSuccessful() {
|
||||
val fixture = createTranslatedPaidDetailFixture(purchased = false)
|
||||
Mockito.`when`(creatorCommunityTranslationService.findDisplayContents(listOf(fixture.postId), "ja"))
|
||||
.thenReturn(emptyMap())
|
||||
|
||||
repeat(2) {
|
||||
mockMvc.perform(
|
||||
get("/api/v2/creator-channels/community-posts/${fixture.postId}")
|
||||
.header("Accept-Language", "ja")
|
||||
.with(user(MemberAdapter(fixture.viewer)))
|
||||
).andExpect(status().isOk)
|
||||
}
|
||||
|
||||
Mockito.verify(creatorCommunityTranslationService, Mockito.times(2)).requestTranslations(fixture.postId, "ja")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("커뮤니티 댓글 API는 댓글 페이지와 최신 답글을 반환한다")
|
||||
fun shouldReturnPagedCommunityCommentsWithLatestReply() {
|
||||
@@ -131,6 +239,8 @@ class CreatorChannelCommunityEndToEndTest @Autowired constructor(
|
||||
.andExpect(jsonPath("$.data.comments.length()").value(20))
|
||||
.andExpect(jsonPath("$.data.hasNext").value(true))
|
||||
.andExpect(jsonPath("$.data.comments[0].latestReply.commentId").value(fixture.latestReplyId))
|
||||
|
||||
Mockito.verifyNoInteractions(creatorCommunityTranslationService)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -148,6 +258,8 @@ class CreatorChannelCommunityEndToEndTest @Autowired constructor(
|
||||
.andExpect(jsonPath("$.data.replyCount").value(1))
|
||||
.andExpect(jsonPath("$.data.replies[0].commentId").value(fixture.latestReplyId))
|
||||
.andExpect(jsonPath("$.data.replies[0].latestReply").doesNotExist())
|
||||
|
||||
Mockito.verifyNoInteractions(creatorCommunityTranslationService)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -176,6 +288,8 @@ class CreatorChannelCommunityEndToEndTest @Autowired constructor(
|
||||
)
|
||||
.andExpect(status().isOk)
|
||||
.andExpect(jsonPath("$.success").value(false))
|
||||
|
||||
Mockito.verifyNoInteractions(creatorCommunityTranslationService)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -189,6 +303,8 @@ class CreatorChannelCommunityEndToEndTest @Autowired constructor(
|
||||
)
|
||||
.andExpect(status().isOk)
|
||||
.andExpect(jsonPath("$.success").value(false))
|
||||
|
||||
Mockito.verifyNoInteractions(creatorCommunityTranslationService)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -435,6 +551,42 @@ class CreatorChannelCommunityEndToEndTest @Autowired constructor(
|
||||
}!!
|
||||
}
|
||||
|
||||
private fun createTranslatedPaidDetailFixture(purchased: Boolean): PostFixture {
|
||||
return transactionTemplate.execute {
|
||||
val viewer = saveMember("community-translated-viewer-$purchased", MemberRole.USER)
|
||||
val creator = saveMember("community-translated-creator-$purchased", MemberRole.CREATOR)
|
||||
savePreference(viewer, isAdultContentVisible = true)
|
||||
val post = saveCommunity(
|
||||
creator = creator,
|
||||
isFixed = false,
|
||||
price = 100,
|
||||
content = "source paid content"
|
||||
)
|
||||
if (purchased) {
|
||||
saveCommunityOrder(viewer, post)
|
||||
}
|
||||
entityManager.flush()
|
||||
entityManager.clear()
|
||||
PostFixture(viewer = viewer, postId = post.id!!)
|
||||
}!!
|
||||
}
|
||||
|
||||
private fun createTranslatedPaidOwnerDetailFixture(): PostFixture {
|
||||
return transactionTemplate.execute {
|
||||
val creator = saveMember("community-translated-owner", MemberRole.CREATOR)
|
||||
savePreference(creator, isAdultContentVisible = true)
|
||||
val post = saveCommunity(
|
||||
creator = creator,
|
||||
isFixed = false,
|
||||
price = 100,
|
||||
content = "source paid content"
|
||||
)
|
||||
entityManager.flush()
|
||||
entityManager.clear()
|
||||
PostFixture(viewer = creator, postId = post.id!!)
|
||||
}!!
|
||||
}
|
||||
|
||||
private fun createCommentUnavailableFixture(): PostFixture {
|
||||
return transactionTemplate.execute {
|
||||
val viewer = saveMember("community-unavailable-viewer", MemberRole.USER)
|
||||
|
||||
+108
-1
@@ -15,6 +15,8 @@ import kr.co.vividnext.sodalive.v2.creator.channel.community.port.out.CreatorCha
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.community.port.out.CreatorChannelCommunityCreatorRecord
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.community.port.out.CreatorChannelCommunityPostRecord
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.community.port.out.CreatorChannelCommunityQueryPort
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.community.translation.application.CreatorCommunityDisplayContent
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.community.translation.application.CreatorCommunityTranslationService
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertNull
|
||||
import org.junit.jupiter.api.Assertions.assertThrows
|
||||
@@ -175,6 +177,92 @@ class CreatorChannelCommunityQueryServiceTest {
|
||||
assertEquals(true, posts.single().isLiked)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("커뮤니티 탭은 페이지 본문을 한 번에 번역 선택한 뒤 유료 미리보기를 적용한다")
|
||||
fun shouldUseStoredTranslationsOnceForCommunityTabBeforePaidMasking() {
|
||||
val port = FakeCreatorChannelCommunityQueryPort().apply {
|
||||
communityPosts = listOf(
|
||||
communityPostRecord(11L, price = 0).copy(content = "source free"),
|
||||
communityPostRecord(12L, price = 100).copy(content = "source paid"),
|
||||
communityPostRecord(13L, price = 100, existOrdered = true).copy(content = "source buyer"),
|
||||
communityPostRecord(14L, creatorId = 10L, price = 100).copy(content = "source owner"),
|
||||
communityPostRecord(15L, price = 0).copy(content = "source stale")
|
||||
)
|
||||
}
|
||||
val translationService = Mockito.mock(CreatorCommunityTranslationService::class.java)
|
||||
val service = createService(port, creatorCommunityTranslationService = translationService)
|
||||
val postIds = port.communityPosts.map { it.postId }
|
||||
Mockito.`when`(translationService.findDisplayContents(postIds, "en"))
|
||||
.thenReturn(
|
||||
mapOf(
|
||||
11L to CreatorCommunityDisplayContent("translated free", true),
|
||||
12L to CreatorCommunityDisplayContent("가나다라마바사아자차카타파하🙂끝", true),
|
||||
13L to CreatorCommunityDisplayContent("translated buyer", true),
|
||||
14L to CreatorCommunityDisplayContent("translated owner", true),
|
||||
15L to CreatorCommunityDisplayContent("source stale", false)
|
||||
)
|
||||
)
|
||||
|
||||
val posts = service.getCommunityTab(1L, createMember(id = 10L), 0, 20).communityPosts
|
||||
|
||||
assertEquals(
|
||||
listOf(
|
||||
"translated free",
|
||||
"가나다라마바사아자차카타파하🙂...",
|
||||
"translated buyer",
|
||||
"translated owner",
|
||||
"source stale"
|
||||
),
|
||||
posts.map { it.content }
|
||||
)
|
||||
Mockito.verify(translationService).findDisplayContents(postIds, "en")
|
||||
Mockito.verifyNoMoreInteractions(translationService)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("커뮤니티 탭 번역 조회는 fetchLimit 다음 게시글을 제외한 반환 페이지 ID만 사용한다")
|
||||
fun shouldExcludeFetchLimitPlusOnePostFromCommunityTabTranslationLookup() {
|
||||
val port = FakeCreatorChannelCommunityQueryPort().apply {
|
||||
communityPosts = (1L..51L).map { communityPostRecord(it, price = 0) }
|
||||
}
|
||||
val translationService = Mockito.mock(CreatorCommunityTranslationService::class.java)
|
||||
val service = createService(port, creatorCommunityTranslationService = translationService)
|
||||
val returnedPostIds = (1L..50L).toList()
|
||||
Mockito.`when`(translationService.findDisplayContents(returnedPostIds, "en")).thenReturn(emptyMap())
|
||||
|
||||
val tab = service.getCommunityTab(1L, createMember(id = 10L), page = 0, size = 50)
|
||||
|
||||
assertEquals(50, tab.communityPosts.size)
|
||||
assertTrue(tab.hasNext)
|
||||
Mockito.verify(translationService).findDisplayContents(returnedPostIds, "en")
|
||||
Mockito.verifyNoMoreInteractions(translationService)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("채널 홈의 고정과 일반 본문은 각 그룹에서 번역 선택만 하고 작업을 만들지 않는다")
|
||||
fun shouldUseStoredTranslationsForPinnedAndNormalHomeCommunityPostsWithoutScheduling() {
|
||||
val port = FakeCreatorChannelCommunityQueryPort()
|
||||
val translationService = Mockito.mock(CreatorCommunityTranslationService::class.java)
|
||||
val service = createService(port, creatorCommunityTranslationService = translationService)
|
||||
port.homeCommunityPosts = listOf(communityPostRecord(21L, price = 0).copy(content = "source pinned"))
|
||||
Mockito.`when`(translationService.findDisplayContents(listOf(21L), "en"))
|
||||
.thenReturn(mapOf(21L to CreatorCommunityDisplayContent("translated pinned", true)))
|
||||
|
||||
val pinnedPosts = service.findHomeCommunityPosts(1L, 10L, true, false, 3)
|
||||
|
||||
port.homeCommunityPosts = listOf(communityPostRecord(22L, price = 0).copy(content = "source normal"))
|
||||
Mockito.`when`(translationService.findDisplayContents(listOf(22L), "en"))
|
||||
.thenReturn(mapOf(22L to CreatorCommunityDisplayContent("translated normal", true)))
|
||||
|
||||
val normalPosts = service.findHomeCommunityPosts(1L, 10L, false, false, 3)
|
||||
|
||||
assertEquals("translated pinned", pinnedPosts.single().content)
|
||||
assertEquals("translated normal", normalPosts.single().content)
|
||||
Mockito.verify(translationService).findDisplayContents(listOf(21L), "en")
|
||||
Mockito.verify(translationService).findDisplayContents(listOf(22L), "en")
|
||||
Mockito.verifyNoMoreInteractions(translationService)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("커뮤니티 상세는 게시글과 초기 댓글 및 최신 답글을 조립한다")
|
||||
fun shouldAssembleCommunityPostDetailWithInitialComments() {
|
||||
@@ -201,6 +289,20 @@ class CreatorChannelCommunityQueryServiceTest {
|
||||
assertEquals("https://cdn.test/profile/default-profile.png", detail.comments.comments.first().writerProfileImageUrl)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("v2 상세는 원문과 같은 유효 번역문에도 누락 예약을 요청하지 않는다")
|
||||
fun shouldNotRequestTranslationsWhenV2DetailHasValidTranslationMatchingSourceText() {
|
||||
val port = FakeCreatorChannelCommunityQueryPort()
|
||||
val translationService = Mockito.mock(CreatorCommunityTranslationService::class.java)
|
||||
val service = createService(port, creatorCommunityTranslationService = translationService)
|
||||
Mockito.`when`(translationService.findDisplayContents(listOf(1L), "en"))
|
||||
.thenReturn(mapOf(1L to CreatorCommunityDisplayContent("content-1", true)))
|
||||
|
||||
service.getCommunityPostDetail(1L, createMember(id = 10L), LocalDateTime.of(2026, 7, 6, 10, 0))
|
||||
|
||||
Mockito.verify(translationService, Mockito.never()).requestTranslations(1L, "en")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("댓글 불가 게시글은 댓글 port를 호출하지 않고 빈 댓글 응답을 반환한다")
|
||||
fun shouldReturnEmptyCommentsWhenCommentUnavailable() {
|
||||
@@ -298,7 +400,9 @@ class CreatorChannelCommunityQueryServiceTest {
|
||||
private fun createService(
|
||||
port: FakeCreatorChannelCommunityQueryPort,
|
||||
audioContentCloudFront: AudioContentCloudFront = Mockito.mock(AudioContentCloudFront::class.java),
|
||||
canViewAdultContent: Boolean = true
|
||||
canViewAdultContent: Boolean = true,
|
||||
creatorCommunityTranslationService: CreatorCommunityTranslationService =
|
||||
Mockito.mock(CreatorCommunityTranslationService::class.java)
|
||||
): CreatorChannelCommunityQueryService {
|
||||
val preferenceService = Mockito.mock(MemberContentPreferenceService::class.java)
|
||||
Mockito.`when`(
|
||||
@@ -306,6 +410,8 @@ class CreatorChannelCommunityQueryServiceTest {
|
||||
).thenReturn(canViewAdultContent)
|
||||
val langContext = LangContext()
|
||||
langContext.setLang(Lang.EN)
|
||||
Mockito.`when`(creatorCommunityTranslationService.findDisplayContents(Mockito.anyList(), Mockito.anyString()))
|
||||
.thenReturn(emptyMap())
|
||||
return CreatorChannelCommunityQueryService(
|
||||
queryPortProvider = FixedCreatorChannelCommunityQueryPortProvider(port),
|
||||
queryPolicy = CreatorChannelCommunityQueryPolicy(),
|
||||
@@ -313,6 +419,7 @@ class CreatorChannelCommunityQueryServiceTest {
|
||||
audioContentCloudFront = audioContentCloudFront,
|
||||
messageSource = SodaMessageSource(),
|
||||
langContext = langContext,
|
||||
creatorCommunityTranslationService = creatorCommunityTranslationService,
|
||||
cloudFrontHost = "https://cdn.test"
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user