feat(recommend): 크리에이터 데뷔 판정 정책을 추가한다
This commit is contained in:
@@ -0,0 +1,19 @@
|
|||||||
|
package kr.co.vividnext.sodalive.v2.recommend.domain
|
||||||
|
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
import java.time.temporal.ChronoUnit
|
||||||
|
|
||||||
|
class CreatorDebutPolicy {
|
||||||
|
fun resolveDebutAt(firstContentPublishedAt: LocalDateTime?, firstLiveAt: LocalDateTime?): LocalDateTime? {
|
||||||
|
return listOfNotNull(firstContentPublishedAt, firstLiveAt).minOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isNewCreator(debutAt: LocalDateTime?, now: LocalDateTime): Boolean {
|
||||||
|
if (debutAt == null) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
val days = ChronoUnit.DAYS.between(debutAt.toLocalDate(), now.toLocalDate())
|
||||||
|
return days in 0..30
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package kr.co.vividnext.sodalive.v2.recommend.domain
|
||||||
|
|
||||||
|
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
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
|
class CreatorDebutPolicyTest {
|
||||||
|
private val policy = CreatorDebutPolicy()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("첫 공개 콘텐츠만 있으면 콘텐츠 공개일을 데뷔일로 선택한다")
|
||||||
|
fun shouldResolveDebutAtFromFirstContentOnly() {
|
||||||
|
val firstContentPublishedAt = LocalDateTime.of(2026, 5, 1, 10, 0)
|
||||||
|
|
||||||
|
val debutAt = policy.resolveDebutAt(firstContentPublishedAt, firstLiveAt = null)
|
||||||
|
|
||||||
|
assertEquals(firstContentPublishedAt, debutAt)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("첫 라이브만 있으면 라이브 일시를 데뷔일로 선택한다")
|
||||||
|
fun shouldResolveDebutAtFromFirstLiveOnly() {
|
||||||
|
val firstLiveAt = LocalDateTime.of(2026, 5, 2, 10, 0)
|
||||||
|
|
||||||
|
val debutAt = policy.resolveDebutAt(firstContentPublishedAt = null, firstLiveAt)
|
||||||
|
|
||||||
|
assertEquals(firstLiveAt, debutAt)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("첫 공개 콘텐츠와 첫 라이브가 모두 있으면 빠른 일시를 데뷔일로 선택한다")
|
||||||
|
fun shouldResolveEarliestDebutAtWhenBothExist() {
|
||||||
|
val firstContentPublishedAt = LocalDateTime.of(2026, 5, 3, 10, 0)
|
||||||
|
val firstLiveAt = LocalDateTime.of(2026, 5, 2, 10, 0)
|
||||||
|
|
||||||
|
val debutAt = policy.resolveDebutAt(firstContentPublishedAt, firstLiveAt)
|
||||||
|
|
||||||
|
assertEquals(firstLiveAt, debutAt)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("첫 공개 콘텐츠와 첫 라이브가 모두 없으면 데뷔일은 null이다")
|
||||||
|
fun shouldReturnNullWhenDebutSourcesDoNotExist() {
|
||||||
|
val debutAt = policy.resolveDebutAt(firstContentPublishedAt = null, firstLiveAt = null)
|
||||||
|
|
||||||
|
assertNull(debutAt)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("데뷔 후 30일 이내이면 신규 크리에이터로 판정한다")
|
||||||
|
fun shouldReturnTrueWhenCreatorIsWithinThirtyDaysFromDebut() {
|
||||||
|
val now = LocalDateTime.of(2026, 5, 30, 12, 0)
|
||||||
|
|
||||||
|
assertTrue(policy.isNewCreator(now.minusDays(0), now))
|
||||||
|
assertTrue(policy.isNewCreator(now.minusDays(30), now))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("데뷔 후 30일이 지났거나 데뷔일이 없으면 신규 크리에이터가 아니다")
|
||||||
|
fun shouldReturnFalseWhenCreatorIsNotWithinThirtyDaysFromDebut() {
|
||||||
|
val now = LocalDateTime.of(2026, 5, 30, 12, 0)
|
||||||
|
|
||||||
|
assertFalse(policy.isNewCreator(now.minusDays(31), now))
|
||||||
|
assertFalse(policy.isNewCreator(now.plusDays(1), now))
|
||||||
|
assertFalse(policy.isNewCreator(debutAt = null, now))
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user