feat(content-ranking): 랭킹 조회 언어를 전달한다

This commit is contained in:
2026-09-09 23:22:44 +09:00
parent 21f72f2827
commit e5230c0950
4 changed files with 128 additions and 11 deletions
@@ -1,5 +1,7 @@
package kr.co.vividnext.sodalive.v2.content.ranking.application
import kr.co.vividnext.sodalive.i18n.Lang
import kr.co.vividnext.sodalive.i18n.LangContext
import kr.co.vividnext.sodalive.member.Member
import kr.co.vividnext.sodalive.member.contentpreference.MemberContentPreferenceService
import kr.co.vividnext.sodalive.v2.content.ranking.domain.AudioRankingType
@@ -9,6 +11,7 @@ import kr.co.vividnext.sodalive.v2.content.ranking.port.out.AudioRankingSnapshot
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertFalse
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.mockito.Mockito
@@ -21,6 +24,41 @@ import java.time.ZonedDateTime
@ExtendWith(OutputCaptureExtension::class)
class AudioRankingQueryServiceTest {
@Test
@DisplayName("랭킹은 요청 locale의 제목만 바꾸고 순위 응답은 유지한다")
fun shouldUseRequestedLocaleTitlesWithoutChangingRankingValues() {
val snapshotPort = FakeAudioRankingQuerySnapshotPort()
val originalLatestSnapshots = listOf(snapshot(contentId = 2L, rank = 1), snapshot(contentId = 1L, rank = 2))
snapshotPort.latestSnapshots = originalLatestSnapshots
snapshotPort.previousSnapshots = listOf(snapshot(contentId = 1L, rank = 1), snapshot(contentId = 2L, rank = 2))
snapshotPort.latestSnapshotsByLocale = mapOf(
"en" to originalLatestSnapshots.map { it.copy(title = "en-title-${it.contentId}") },
"ja" to originalLatestSnapshots.map { it.copy(title = "ja-title-${it.contentId}") }
)
val langContext = LangContext().apply { setLang(Lang.EN) }
val service = service(snapshotPort, langContext = langContext)
val english = service.getRankings(AudioRankingType.REVENUE, member = null)
langContext.setLang(Lang.JA)
val japanese = service.getRankings(AudioRankingType.REVENUE, member = null)
langContext.setLang(Lang.EN)
val englishAgain = service.getRankings(AudioRankingType.REVENUE, member = null)
assertEquals(listOf("en-title-2", "en-title-1"), english.items.map { it.title })
assertEquals(listOf("ja-title-2", "ja-title-1"), japanese.items.map { it.title })
assertEquals(listOf("en-title-2", "en-title-1"), englishAgain.items.map { it.title })
assertEquals(
english.copy(items = english.items.map { it.copy(title = "") }),
japanese.copy(items = japanese.items.map { it.copy(title = "") })
)
assertEquals(
english.copy(items = english.items.map { it.copy(title = "") }),
englishAgain.copy(items = englishAgain.items.map { it.copy(title = "") })
)
assertEquals(listOf("en", "ja", "en"), snapshotPort.latestLocales)
assertEquals(listOf("en", "ja", "en"), snapshotPort.previousLocales)
}
@Test
fun shouldNotWrapGetRankingsInTransactionSoFallbackRequeryUsesFreshSnapshot() {
val method = AudioRankingQueryService::class.java.getDeclaredMethod(
@@ -223,7 +261,8 @@ class AudioRankingQueryServiceTest {
snapshotPort: FakeAudioRankingQuerySnapshotPort,
adultMember: Member? = null,
blockPort: AudioRankingBlockPort = FakeAudioRankingBlockPort(),
jobService: AudioRankingSnapshotJobService = Mockito.mock(AudioRankingSnapshotJobService::class.java)
jobService: AudioRankingSnapshotJobService = Mockito.mock(AudioRankingSnapshotJobService::class.java),
langContext: LangContext = LangContext()
): AudioRankingQueryService {
val memberContentPreferenceService = Mockito.mock(MemberContentPreferenceService::class.java)
if (adultMember != null) {
@@ -231,6 +270,7 @@ class AudioRankingQueryServiceTest {
}
return AudioRankingQueryService(
snapshotPort = snapshotPort,
langContext = langContext,
memberContentPreferenceService = memberContentPreferenceService,
blockPort = blockPort,
jobService = jobService,
@@ -275,25 +315,32 @@ private class FakeAudioRankingQuerySnapshotPort : AudioRankingSnapshotPort {
var nowUtc: LocalDateTime? = null
var currentAggregationStartAtUtc: LocalDateTime? = null
var latestCallCount: Int = 0
var latestLocales: MutableList<String> = mutableListOf()
var previousLocales: MutableList<String> = mutableListOf()
var latestSnapshotsByLocale: Map<String, List<AudioRankingSnapshotRecord>> = emptyMap()
override fun findLatestVisibleSnapshots(
rankingType: AudioRankingType,
nowUtc: LocalDateTime
nowUtc: LocalDateTime,
locale: String
): List<AudioRankingSnapshotRecord> {
this.nowUtc = nowUtc
latestLocales.add(locale)
latestCallCount += 1
if (latestSnapshotsByCall.isNotEmpty()) {
return latestSnapshotsByCall.getOrElse(latestCallCount - 1) { latestSnapshotsByCall.last() }
}
return latestSnapshots
return latestSnapshotsByLocale[locale] ?: latestSnapshots
}
override fun findPreviousVisibleSnapshots(
rankingType: AudioRankingType,
currentAggregationStartAtUtc: LocalDateTime,
nowUtc: LocalDateTime
nowUtc: LocalDateTime,
locale: String
): List<AudioRankingSnapshotRecord> {
this.currentAggregationStartAtUtc = currentAggregationStartAtUtc
previousLocales.add(locale)
return previousSnapshots
}