feat(home-recommendation): 첫 오디오 조회 언어를 전달한다

This commit is contained in:
2026-09-09 23:21:15 +09:00
parent dba70483ad
commit 14394b8263
3 changed files with 34 additions and 19 deletions
@@ -1,6 +1,7 @@
package kr.co.vividnext.sodalive.v2.recommendation.application
import kr.co.vividnext.sodalive.i18n.Lang
import kr.co.vividnext.sodalive.i18n.LangContext
import kr.co.vividnext.sodalive.v2.common.domain.CreatorActivityType
import kr.co.vividnext.sodalive.v2.recommendation.domain.RecommendedSectionType
import kr.co.vividnext.sodalive.v2.recommendation.port.out.HomeAiCharacterRecommendationRecord
@@ -27,7 +28,8 @@ import java.time.ZoneOffset
class HomeRecommendationQueryServiceTest {
private val port = FakeHomeRecommendationQueryPort()
private val snapshotPort = FakeHomeRecommendationSnapshotPort()
private val service = HomeRecommendationQueryService(port, snapshotPort)
private val langContext = LangContext()
private val service = HomeRecommendationQueryService(port, snapshotPort, langContext = langContext)
@Test
@DisplayName("다시듣기 테마 콘텐츠는 AUDIO가 아니라 LIVE_REPLAY 활동으로 분류한다")
@@ -152,6 +154,7 @@ class HomeRecommendationQueryServiceTest {
assertEquals(now, port.firstAudioNow)
assertEquals(103L, port.firstAudioMemberId)
assertEquals(10, port.firstAudioLimit)
assertEquals(Lang.KO.code, port.firstAudioLocale)
assertEquals(port.firstAudioContents, contents)
}
@@ -159,7 +162,7 @@ class HomeRecommendationQueryServiceTest {
@DisplayName("AI 캐릭터 추천은 최신 스냅샷 20개를 기준으로 순서를 유지해 상세를 조립한다")
fun shouldFindAiCharactersFromLatestSnapshotsWithLimitAndDetails() {
val fallback = FakeAiCharacterSnapshotFallbackPort(emptyList())
val service = HomeRecommendationQueryService(port, snapshotPort, fallback)
val service = HomeRecommendationQueryService(port, snapshotPort, fallback, langContext = langContext)
val oldSnapshotAt = LocalDateTime.of(2026, 5, 28, 23, 59, 59)
val latestSnapshotAt = LocalDateTime.of(2026, 5, 29, 23, 59, 59)
snapshotPort.replaceSnapshots(
@@ -261,7 +264,7 @@ class HomeRecommendationQueryServiceTest {
val fallback = FakeAiCharacterSnapshotFallbackPort(
listOf(snapshot(RecommendedSectionType.AI_CHARACTER, 10L, 10.0, LocalDateTime.of(2026, 7, 9, 14, 59, 59)))
)
val service = HomeRecommendationQueryService(port, snapshotPort, fallback)
val service = HomeRecommendationQueryService(port, snapshotPort, fallback, langContext = langContext)
port.aiCharacterDetails = listOf(
HomeAiCharacterRecommendationRecord(
characterId = 10L,
@@ -286,7 +289,7 @@ class HomeRecommendationQueryServiceTest {
@DisplayName("AI 캐릭터 추천은 fallback 후에도 스냅샷이 없으면 빈 배열을 반환한다")
fun shouldReturnEmptyAiCharactersWhenFallbackDoesNotCreateSnapshots() {
val fallback = FakeAiCharacterSnapshotFallbackPort(emptyList())
val service = HomeRecommendationQueryService(port, snapshotPort, fallback)
val service = HomeRecommendationQueryService(port, snapshotPort, fallback, langContext = langContext)
val characters = service.findAiCharacterRecommendations()
@@ -302,7 +305,7 @@ class HomeRecommendationQueryServiceTest {
val fallback = FakeAiCharacterSnapshotFallbackPort(
listOf(snapshot(RecommendedSectionType.AI_CHARACTER, 99L, 99.0, LocalDateTime.of(2026, 7, 9, 14, 59, 59)))
)
val service = HomeRecommendationQueryService(port, snapshotPort, fallback)
val service = HomeRecommendationQueryService(port, snapshotPort, fallback, langContext = langContext)
snapshotPort.replaceSnapshots(
RecommendedSectionType.AI_CHARACTER,
LocalDateTime.of(2026, 7, 9, 14, 59, 59),
@@ -325,7 +328,7 @@ class HomeRecommendationQueryServiceTest {
val fallback = FakeAiCharacterSnapshotFallbackPort(
listOf(snapshot(RecommendedSectionType.AI_CHARACTER, 99L, 99.0, LocalDateTime.of(2026, 7, 9, 14, 59, 59)))
)
val service = HomeRecommendationQueryService(port, snapshotPort, fallback)
val service = HomeRecommendationQueryService(port, snapshotPort, fallback, langContext = langContext)
val snapshotAt = LocalDateTime.of(2026, 7, 9, 14, 59, 59)
snapshotPort.replaceSnapshots(
RecommendedSectionType.AI_CHARACTER,
@@ -352,7 +355,7 @@ class HomeRecommendationQueryServiceTest {
val fallback = FakeAiCharacterSnapshotFallbackPort(
listOf(snapshot(RecommendedSectionType.AI_CHARACTER, 99L, 99.0, LocalDateTime.of(2026, 7, 9, 14, 59, 59)))
)
val service = HomeRecommendationQueryService(port, snapshotPort, fallback)
val service = HomeRecommendationQueryService(port, snapshotPort, fallback, langContext = langContext)
val snapshotAt = LocalDateTime.of(2026, 7, 9, 14, 59, 59)
snapshotPort.replaceSnapshots(
RecommendedSectionType.AI_CHARACTER,
@@ -376,7 +379,8 @@ class HomeRecommendationQueryServiceTest {
port,
snapshotPort,
cheerCreatorSnapshotFallbackService = fallback,
clock = fixedClock()
clock = fixedClock(),
langContext = langContext
)
val snapshotAt = LocalDateTime.of(2026, 7, 9, 14, 59, 59)
snapshotPort.replaceSnapshots(
@@ -419,7 +423,8 @@ class HomeRecommendationQueryServiceTest {
port,
snapshotPort,
cheerCreatorSnapshotFallbackService = fallback,
clock = fixedClock()
clock = fixedClock(),
langContext = langContext
)
port.cheerCreatorDetails = listOf(
HomeCheerCreatorRecommendationRecord(
@@ -448,7 +453,8 @@ class HomeRecommendationQueryServiceTest {
port,
snapshotPort,
cheerCreatorSnapshotFallbackService = fallback,
clock = fixedClock()
clock = fixedClock(),
langContext = langContext
)
val staleSnapshotAt = LocalDateTime.of(2026, 7, 8, 14, 59, 59)
snapshotPort.replaceSnapshots(
@@ -483,7 +489,8 @@ class HomeRecommendationQueryServiceTest {
port,
snapshotPort,
cheerCreatorSnapshotFallbackService = fallback,
clock = fixedClock()
clock = fixedClock(),
langContext = langContext
)
snapshotPort.replaceSnapshots(
RecommendedSectionType.CHEER_CREATOR,
@@ -502,7 +509,7 @@ class HomeRecommendationQueryServiceTest {
@Test
@DisplayName("인기 커뮤니티 추천은 대상일 스냅샷 10개를 기준으로 크리에이터 중복을 제거하고 상세를 조립한다")
fun shouldFindPopularCommunitiesFromTargetDaySnapshotsWithLimitDetailsAndCreatorUniqueness() {
val service = HomeRecommendationQueryService(port, snapshotPort, clock = fixedClock())
val service = HomeRecommendationQueryService(port, snapshotPort, clock = fixedClock(), langContext = langContext)
val snapshotAt = LocalDateTime.of(2026, 7, 9, 14, 59, 59)
snapshotPort.replaceSnapshots(
RecommendedSectionType.POPULAR_COMMUNITY,
@@ -576,7 +583,7 @@ class HomeRecommendationQueryServiceTest {
@Test
@DisplayName("인기 커뮤니티 추천은 상위 스냅샷 중복 제거 후 뒤 후보로 기본 10개를 채운다")
fun shouldBackfillPopularCommunitiesAfterRemovingDuplicateCreators() {
val service = HomeRecommendationQueryService(port, snapshotPort, clock = fixedClock())
val service = HomeRecommendationQueryService(port, snapshotPort, clock = fixedClock(), langContext = langContext)
val snapshotAt = LocalDateTime.of(2026, 7, 9, 14, 59, 59)
snapshotPort.replaceSnapshots(
RecommendedSectionType.POPULAR_COMMUNITY,
@@ -621,7 +628,8 @@ class HomeRecommendationQueryServiceTest {
port,
snapshotPort,
popularCommunitySnapshotFallbackService = fallback,
clock = fixedClock()
clock = fixedClock(),
langContext = langContext
)
val staleSnapshotAt = LocalDateTime.of(2026, 7, 8, 14, 59, 59)
snapshotPort.replaceSnapshots(
@@ -666,7 +674,8 @@ class HomeRecommendationQueryServiceTest {
port,
snapshotPort,
popularCommunitySnapshotFallbackService = fallback,
clock = fixedClock()
clock = fixedClock(),
langContext = langContext
)
snapshotPort.replaceSnapshots(
RecommendedSectionType.POPULAR_COMMUNITY,
@@ -991,6 +1000,7 @@ class HomeRecommendationQueryServiceTest {
var firstAudioOffset: Long? = null
var firstAudioMemberId: Long? = null
var firstAudioIncludeAdultContents: Boolean? = null
var firstAudioLocale: String? = null
var aiCharacterDetailIds: List<Long> = emptyList()
val aiCharacterDetailIdRequests = mutableListOf<List<Long>>()
var randomAiCharacterExcludeIds: List<Long>? = null
@@ -1121,13 +1131,15 @@ class HomeRecommendationQueryServiceTest {
offset: Long,
limit: Int,
memberId: Long?,
includeAdultContents: Boolean
includeAdultContents: Boolean,
locale: String
): List<HomeFirstAudioContentRecord> {
firstAudioNow = now
firstAudioOffset = offset
firstAudioLimit = limit
firstAudioMemberId = memberId
firstAudioIncludeAdultContents = includeAdultContents
firstAudioLocale = locale
return firstAudioContents
}