feat(content-ranking): 스냅샷 공개 조회 저장소를 추가한다
This commit is contained in:
+113
-3
@@ -1,6 +1,7 @@
|
||||
package kr.co.vividnext.sodalive.v2.ranking.adapter.out.persistence
|
||||
|
||||
import kr.co.vividnext.sodalive.configs.QueryDslConfig
|
||||
import kr.co.vividnext.sodalive.v2.ranking.domain.CreatorRankingType
|
||||
import kr.co.vividnext.sodalive.v2.ranking.port.out.CreatorRankingSnapshotRecord
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
@@ -37,8 +38,10 @@ class DefaultCreatorRankingSnapshotRepositoryTest @Autowired constructor(
|
||||
)
|
||||
|
||||
adapter.replaceSnapshots(
|
||||
rankingType = CreatorRankingType.WEEKLY,
|
||||
aggregationStartAtUtc = startAt,
|
||||
aggregationEndAtUtc = endAt,
|
||||
visibleFromAtUtc = endAt.plusHours(9),
|
||||
newSnapshots = listOf(snapshotRecord(creatorId = 3L, aggregationStartAtUtc = startAt, aggregationEndAtUtc = endAt))
|
||||
)
|
||||
|
||||
@@ -47,6 +50,28 @@ class DefaultCreatorRankingSnapshotRepositoryTest @Autowired constructor(
|
||||
assertEquals(listOf(3L), adapter.findLatestSnapshots().map { it.creatorId })
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("스냅샷은 랭킹 타입과 공개 노출 시각을 저장하고 같은 타입/기간만 교체한다")
|
||||
fun shouldPersistRankingTypeAndVisibleFromAtAndReplaceByTypeAndPeriod() {
|
||||
val startAt = LocalDateTime.of(2026, 5, 31, 15, 0)
|
||||
val endAt = LocalDateTime.of(2026, 6, 7, 15, 0)
|
||||
val visibleFromAt = LocalDateTime.of(2026, 6, 8, 0, 0)
|
||||
repository.save(snapshot(creatorId = 1L, aggregationStartAtUtc = startAt, aggregationEndAtUtc = endAt))
|
||||
|
||||
adapter.replaceSnapshots(
|
||||
rankingType = CreatorRankingType.WEEKLY,
|
||||
aggregationStartAtUtc = startAt,
|
||||
aggregationEndAtUtc = endAt,
|
||||
visibleFromAtUtc = visibleFromAt,
|
||||
newSnapshots = listOf(snapshotRecord(creatorId = 2L, aggregationStartAtUtc = startAt, aggregationEndAtUtc = endAt))
|
||||
)
|
||||
|
||||
val saved = repository.findAll().single()
|
||||
assertEquals(CreatorRankingType.WEEKLY, saved.rankingType)
|
||||
assertEquals(visibleFromAt, saved.visibleFromAtUtc)
|
||||
assertEquals(2L, saved.creatorId)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("최신 완료 주차 스냅샷은 최신 종료 시각 기준으로 최종 점수 내림차순 조회한다")
|
||||
fun shouldFindLatestSnapshotsByLatestAggregationEndAndFinalScoreDescending() {
|
||||
@@ -90,6 +115,79 @@ class DefaultCreatorRankingSnapshotRepositoryTest @Autowired constructor(
|
||||
assertEquals(listOf(latestEndAt, latestEndAt, latestEndAt), latestSnapshots.map { it.aggregationEndAtUtc })
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("최신 공개 스냅샷은 visibleFromAt이 현재 시각 이하인 최신 노출 시각 기준으로 조회한다")
|
||||
fun shouldFindLatestVisibleSnapshotsByVisibleFromAt() {
|
||||
val previousStartAt = LocalDateTime.of(2026, 5, 24, 15, 0)
|
||||
val previousEndAt = LocalDateTime.of(2026, 5, 31, 15, 0)
|
||||
val latestStartAt = LocalDateTime.of(2026, 5, 31, 15, 0)
|
||||
val latestEndAt = LocalDateTime.of(2026, 6, 7, 15, 0)
|
||||
repository.saveAll(
|
||||
listOf(
|
||||
snapshot(
|
||||
creatorId = 1L,
|
||||
aggregationStartAtUtc = previousStartAt,
|
||||
aggregationEndAtUtc = previousEndAt,
|
||||
visibleFromAtUtc = LocalDateTime.of(2026, 6, 1, 0, 0),
|
||||
finalScore = 100.0
|
||||
),
|
||||
snapshot(
|
||||
creatorId = 2L,
|
||||
aggregationStartAtUtc = latestStartAt,
|
||||
aggregationEndAtUtc = latestEndAt,
|
||||
visibleFromAtUtc = LocalDateTime.of(2026, 6, 8, 0, 0),
|
||||
finalScore = 200.0
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
val beforeVisible = adapter.findLatestVisibleSnapshots(
|
||||
rankingType = CreatorRankingType.WEEKLY,
|
||||
nowUtc = LocalDateTime.of(2026, 6, 7, 23, 59, 59)
|
||||
)
|
||||
val afterVisible = adapter.findLatestVisibleSnapshots(
|
||||
rankingType = CreatorRankingType.WEEKLY,
|
||||
nowUtc = LocalDateTime.of(2026, 6, 8, 0, 0)
|
||||
)
|
||||
|
||||
assertEquals(listOf(1L), beforeVisible.map { it.creatorId })
|
||||
assertEquals(listOf(2L), afterVisible.map { it.creatorId })
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("직전 공개 스냅샷은 현재 공개 스냅샷보다 이전 집계 시작 시각 중 최신 공개 기준으로 조회한다")
|
||||
fun shouldFindPreviousVisibleSnapshotsBeforeCurrentVisibleSnapshot() {
|
||||
val oldestStartAt = LocalDateTime.of(2026, 5, 17, 15, 0)
|
||||
val previousStartAt = LocalDateTime.of(2026, 5, 24, 15, 0)
|
||||
val latestStartAt = LocalDateTime.of(2026, 5, 31, 15, 0)
|
||||
repository.saveAll(
|
||||
listOf(
|
||||
snapshot(creatorId = 1L, aggregationStartAtUtc = oldestStartAt, aggregationEndAtUtc = oldestStartAt.plusWeeks(1)),
|
||||
snapshot(
|
||||
creatorId = 2L,
|
||||
aggregationStartAtUtc = previousStartAt,
|
||||
aggregationEndAtUtc = previousStartAt.plusWeeks(1),
|
||||
finalScore = 300.0
|
||||
),
|
||||
snapshot(
|
||||
creatorId = 3L,
|
||||
aggregationStartAtUtc = previousStartAt,
|
||||
aggregationEndAtUtc = previousStartAt.plusWeeks(1),
|
||||
finalScore = 200.0
|
||||
),
|
||||
snapshot(creatorId = 4L, aggregationStartAtUtc = latestStartAt, aggregationEndAtUtc = latestStartAt.plusWeeks(1))
|
||||
)
|
||||
)
|
||||
|
||||
val previous = adapter.findPreviousVisibleSnapshots(
|
||||
rankingType = CreatorRankingType.WEEKLY,
|
||||
currentAggregationStartAtUtc = latestStartAt,
|
||||
nowUtc = LocalDateTime.of(2026, 6, 8, 0, 0)
|
||||
)
|
||||
|
||||
assertEquals(listOf(2L, 3L), previous.map { it.creatorId })
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("직전 완료 주차 스냅샷은 최신 종료 시각보다 이전인 가장 큰 종료 시각 기준으로 조회한다")
|
||||
fun shouldFindPreviousCompletedSnapshotsBeforeLatestPeriod() {
|
||||
@@ -181,7 +279,13 @@ class DefaultCreatorRankingSnapshotRepositoryTest @Autowired constructor(
|
||||
snapshotRecord(creatorId = 22L, finalScore = 500.0, aggregationStartAtUtc = startAt, aggregationEndAtUtc = endAt)
|
||||
)
|
||||
|
||||
adapter.replaceSnapshots(startAt, endAt, candidates)
|
||||
adapter.replaceSnapshots(
|
||||
rankingType = CreatorRankingType.WEEKLY,
|
||||
aggregationStartAtUtc = startAt,
|
||||
aggregationEndAtUtc = endAt,
|
||||
visibleFromAtUtc = endAt.plusHours(9),
|
||||
newSnapshots = candidates
|
||||
)
|
||||
|
||||
val latestSnapshots = adapter.findLatestSnapshots()
|
||||
assertEquals(22, latestSnapshots.size)
|
||||
@@ -192,11 +296,14 @@ class DefaultCreatorRankingSnapshotRepositoryTest @Autowired constructor(
|
||||
creatorId: Long,
|
||||
finalScore: Double = 100.0,
|
||||
aggregationStartAtUtc: LocalDateTime,
|
||||
aggregationEndAtUtc: LocalDateTime
|
||||
aggregationEndAtUtc: LocalDateTime,
|
||||
visibleFromAtUtc: LocalDateTime = aggregationEndAtUtc.plusHours(9)
|
||||
): CreatorRankingSnapshot {
|
||||
return CreatorRankingSnapshot(
|
||||
rankingType = CreatorRankingType.WEEKLY,
|
||||
aggregationStartAtUtc = aggregationStartAtUtc,
|
||||
aggregationEndAtUtc = aggregationEndAtUtc,
|
||||
visibleFromAtUtc = visibleFromAtUtc,
|
||||
creatorId = creatorId,
|
||||
nickname = "creator-$creatorId",
|
||||
profileImageUrl = "profile-$creatorId.png",
|
||||
@@ -221,11 +328,14 @@ class DefaultCreatorRankingSnapshotRepositoryTest @Autowired constructor(
|
||||
creatorId: Long,
|
||||
finalScore: Double = 100.0,
|
||||
aggregationStartAtUtc: LocalDateTime,
|
||||
aggregationEndAtUtc: LocalDateTime
|
||||
aggregationEndAtUtc: LocalDateTime,
|
||||
visibleFromAtUtc: LocalDateTime = aggregationEndAtUtc.plusHours(9)
|
||||
): CreatorRankingSnapshotRecord {
|
||||
return CreatorRankingSnapshotRecord(
|
||||
rankingType = CreatorRankingType.WEEKLY,
|
||||
aggregationStartAtUtc = aggregationStartAtUtc,
|
||||
aggregationEndAtUtc = aggregationEndAtUtc,
|
||||
visibleFromAtUtc = visibleFromAtUtc,
|
||||
creatorId = creatorId,
|
||||
nickname = "creator-$creatorId",
|
||||
profileImageUrl = "profile-$creatorId.png",
|
||||
|
||||
Reference in New Issue
Block a user