feat(content-all): 전체 탭 요청 보정 정책을 추가한다

This commit is contained in:
2026-06-25 11:24:49 +09:00
parent 1f84f8eaf2
commit 2aeb9418a9
2 changed files with 95 additions and 0 deletions

View File

@@ -0,0 +1,47 @@
package kr.co.vividnext.sodalive.v2.content.all.domain
import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesPublishedDaysOfWeek
import kr.co.vividnext.sodalive.v2.common.domain.ContentSort
class MainContentAllQueryPolicy {
fun resolveType(type: String?): MainContentAllType {
return type.toEnumOrNull<MainContentAllType>() ?: MainContentAllType.AUDIO
}
fun resolveSort(sort: String?): ContentSort {
val resolved = sort.toEnumOrNull<ContentSort>() ?: ContentSort.LATEST
return if (resolved == ContentSort.OWNED) ContentSort.LATEST else resolved
}
fun resolveDayOfWeek(type: MainContentAllType, dayOfWeek: String?): SeriesPublishedDaysOfWeek? {
if (type != MainContentAllType.SERIES) return null
return dayOfWeek.toEnumOrNull<SeriesPublishedDaysOfWeek>()
}
fun createPage(page: Int?, size: Int?): MainContentPage {
return MainContentPage(
page = page?.coerceAtLeast(0) ?: DEFAULT_PAGE,
size = size?.coerceIn(MIN_SIZE, MAX_SIZE) ?: DEFAULT_SIZE
)
}
fun <T> limitItems(items: List<T>, page: MainContentPage): List<T> {
return items.take(page.size)
}
fun hasNext(items: List<*>, page: MainContentPage): Boolean {
return items.size > page.size
}
private inline fun <reified T : Enum<T>> String?.toEnumOrNull(): T? {
if (this == null) return null
return enumValues<T>().firstOrNull { it.name == this }
}
companion object {
private const val DEFAULT_PAGE = 0
private const val DEFAULT_SIZE = 20
private const val MIN_SIZE = 20
private const val MAX_SIZE = 50
}
}

View File

@@ -0,0 +1,48 @@
package kr.co.vividnext.sodalive.v2.content.all.domain
import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesPublishedDaysOfWeek
import kr.co.vividnext.sodalive.v2.common.domain.ContentSort
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertFalse
import org.junit.jupiter.api.Assertions.assertNull
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
class MainContentAllQueryPolicyTest {
private val policy = MainContentAllQueryPolicy()
@Test
@DisplayName("전체 탭 요청 기본값과 fallback을 보정한다")
fun shouldResolveDefaultsAndFallbacks() {
assertEquals(MainContentAllType.AUDIO, policy.resolveType(null))
assertEquals(MainContentAllType.AUDIO, policy.resolveType("UNKNOWN"))
assertEquals(ContentSort.LATEST, policy.resolveSort(null))
assertEquals(ContentSort.LATEST, policy.resolveSort("UNKNOWN"))
assertEquals(ContentSort.LATEST, policy.resolveSort("OWNED"))
assertEquals(ContentSort.POPULAR, policy.resolveSort("POPULAR"))
assertEquals(MainContentPage(page = 0, size = 20), policy.createPage(page = null, size = null))
assertEquals(MainContentPage(page = 0, size = 20), policy.createPage(page = -1, size = 1))
assertEquals(MainContentPage(page = 2, size = 50), policy.createPage(page = 2, size = 100))
}
@Test
@DisplayName("요일 조건은 SERIES 타입에만 적용한다")
fun shouldResolveDayOfWeekOnlyForSeriesType() {
assertEquals(SeriesPublishedDaysOfWeek.MON, policy.resolveDayOfWeek(MainContentAllType.SERIES, "MON"))
assertEquals(SeriesPublishedDaysOfWeek.RANDOM, policy.resolveDayOfWeek(MainContentAllType.SERIES, "RANDOM"))
assertNull(policy.resolveDayOfWeek(MainContentAllType.SERIES, "INVALID"))
assertNull(policy.resolveDayOfWeek(MainContentAllType.ORIGINAL, "MON"))
assertNull(policy.resolveDayOfWeek(MainContentAllType.AUDIO, "MON"))
}
@Test
@DisplayName("limit + 1 조회 결과에서 응답 목록과 hasNext를 계산한다")
fun shouldLimitItemsAndResolveHasNext() {
val items = listOf(1, 2, 3)
assertEquals(listOf(1, 2), policy.limitItems(items, MainContentPage(page = 0, size = 2)))
assertTrue(policy.hasNext(items, MainContentPage(page = 0, size = 2)))
assertFalse(policy.hasNext(listOf(1, 2), MainContentPage(page = 0, size = 2)))
}
}