test #436

Merged
klaus merged 6 commits from test into main 2026-07-12 04:18:00 +00:00
4 changed files with 21 additions and 23 deletions
Showing only changes of commit 6da2378b29 - Show all commits

View File

@@ -601,7 +601,7 @@ class DefaultHomeRecommendationQueryRepository(
join use_can uc on uc.id = ucc.use_can_id join use_can uc on uc.id = ucc.use_can_id
where ucc.status = 'RECEIVED' where ucc.status = 'RECEIVED'
and uc.is_refund = false and uc.is_refund = false
and uc.can_usage = 'CHANNEL_DONATION' and uc.can_usage in ('CHANNEL_DONATION', 'DONATION')
and ucc.created_at >= :windowStart and ucc.created_at >= :windowStart
and ucc.created_at < :windowEndExclusive and ucc.created_at < :windowEndExclusive
group by ucc.recipient_creator_id group by ucc.recipient_creator_id

View File

@@ -91,7 +91,7 @@ open class RecommendationSnapshotRefreshService(
@Transactional @Transactional
open fun refreshCheerCreatorSnapshots(nowUtc: LocalDateTime = LocalDateTime.now(ZoneOffset.UTC)): Int { open fun refreshCheerCreatorSnapshots(nowUtc: LocalDateTime = LocalDateTime.now(ZoneOffset.UTC)): Int {
val startedAt = System.currentTimeMillis() val startedAt = System.currentTimeMillis()
val window = windowPolicy.previousKstDayUtcWindow(nowUtc) val window = windowPolicy.previousKstSevenDayUtcWindow(nowUtc)
val snapshots = queryPort.findCheerCreatorSnapshots( val snapshots = queryPort.findCheerCreatorSnapshots(
window.startUtc, window.startUtc,
window.endExclusiveUtc, window.endExclusiveUtc,

View File

@@ -773,8 +773,8 @@ class DefaultHomeRecommendationQueryRepositoryTest @Autowired constructor(
} }
@Test @Test
@DisplayName("최근 응원 스냅샷은 전날 half-open 범위의 CHANNEL_DONATION 금액 distinct 후원 수만 집계한다") @DisplayName("최근 응원 스냅샷은 half-open 범위의 CHANNEL_DONATION과 DONATION 금액 distinct 후원 수만 집계한다")
fun shouldFindCheerCreatorSnapshotsWithChannelDonationOnly() { fun shouldFindCheerCreatorSnapshotsWithChannelAndGeneralDonation() {
val windowStart = LocalDateTime.of(2026, 5, 28, 15, 0) val windowStart = LocalDateTime.of(2026, 5, 28, 15, 0)
val windowEndExclusive = LocalDateTime.of(2026, 5, 29, 15, 0) val windowEndExclusive = LocalDateTime.of(2026, 5, 29, 15, 0)
val snapshotAt = windowEndExclusive.minusSeconds(1) val snapshotAt = windowEndExclusive.minusSeconds(1)
@@ -877,9 +877,9 @@ class DefaultHomeRecommendationQueryRepositoryTest @Autowired constructor(
val snapshots = repository.findCheerCreatorSnapshots(windowStart, windowEndExclusive, limit = 10) val snapshots = repository.findCheerCreatorSnapshots(windowStart, windowEndExclusive, limit = 10)
val expectedScore = scorePolicy.calculateCheerScore( val expectedScore = scorePolicy.calculateCheerScore(
donationAmount = 150, donationAmount = 1_150,
fanTalkCount = 1, fanTalkCount = 1,
donationCount = 1, donationCount = 2,
newBoost = scorePolicy.calculateCheerCreatorNewBoost(LocalDateTime.of(2026, 5, 10, 12, 0), snapshotAt) newBoost = scorePolicy.calculateCheerCreatorNewBoost(LocalDateTime.of(2026, 5, 10, 12, 0), snapshotAt)
) )
assertEquals(1, snapshots.size) assertEquals(1, snapshots.size)

View File

@@ -47,7 +47,7 @@ class RecommendationSnapshotRefreshServiceTest {
} }
@Test @Test
@DisplayName("일 스냅샷 갱신은 전날 23시 59분 59초 기준으로 DB 점수 계산 스냅샷을 저장한다") @DisplayName("일 스냅샷 갱신은 응원 크리에이터를 인기 커뮤니티와 같은 7일 window로 저장한다")
fun shouldRefreshDailySnapshotsWithPreviousDayEndSnapshotAt(output: CapturedOutput) { fun shouldRefreshDailySnapshotsWithPreviousDayEndSnapshotAt(output: CapturedOutput) {
val snapshotPort = FakeRecommendationSnapshotPort() val snapshotPort = FakeRecommendationSnapshotPort()
val queryPort = Mockito.mock(HomeRecommendationQueryPort::class.java) val queryPort = Mockito.mock(HomeRecommendationQueryPort::class.java)
@@ -71,7 +71,7 @@ class RecommendationSnapshotRefreshServiceTest {
) )
) )
) )
Mockito.`when`(queryPort.findCheerCreatorSnapshots(aiWindowStart, aiWindowEndExclusive, 16)).thenReturn( Mockito.`when`(queryPort.findCheerCreatorSnapshots(windowStart, windowEndExclusive, 16)).thenReturn(
listOf( listOf(
RecommendationSnapshotRecord( RecommendationSnapshotRecord(
sectionType = RecommendedSectionType.CHEER_CREATOR, sectionType = RecommendedSectionType.CHEER_CREATOR,
@@ -112,7 +112,7 @@ class RecommendationSnapshotRefreshServiceTest {
assertEquals(40.0, communitySnapshots.single().score, 0.0001) assertEquals(40.0, communitySnapshots.single().score, 0.0001)
Mockito.verify(queryPort).findAiCharacterSnapshots(aiWindowStart, aiWindowEndExclusive, 20) Mockito.verify(queryPort).findAiCharacterSnapshots(aiWindowStart, aiWindowEndExclusive, 20)
Mockito.verify(queryPort).findCheerCreatorSnapshots(aiWindowStart, aiWindowEndExclusive, 16) Mockito.verify(queryPort).findCheerCreatorSnapshots(windowStart, windowEndExclusive, 16)
Mockito.verify(queryPort).findPopularCommunitySnapshots(windowStart, windowEndExclusive, 20) Mockito.verify(queryPort).findPopularCommunitySnapshots(windowStart, windowEndExclusive, 20)
assertEquals(true, output.out.contains("event=recommendation_snapshot_refresh_success")) assertEquals(true, output.out.contains("event=recommendation_snapshot_refresh_success"))
assertEquals(true, output.out.contains("aiCharacterCount=1")) assertEquals(true, output.out.contains("aiCharacterCount=1"))
@@ -135,8 +135,8 @@ class RecommendationSnapshotRefreshServiceTest {
).thenReturn(emptyList()) ).thenReturn(emptyList())
Mockito.`when`( Mockito.`when`(
queryPort.findCheerCreatorSnapshots( queryPort.findCheerCreatorSnapshots(
LocalDateTime.of(2026, 5, 28, 15, 0, 0), windowStart,
LocalDateTime.of(2026, 5, 29, 15, 0, 0), windowEndExclusive,
16 16
) )
).thenReturn(emptyList()) ).thenReturn(emptyList())
@@ -179,8 +179,8 @@ class RecommendationSnapshotRefreshServiceTest {
) )
Mockito.`when`( Mockito.`when`(
queryPort.findCheerCreatorSnapshots( queryPort.findCheerCreatorSnapshots(
LocalDateTime.of(2026, 5, 28, 15, 0, 0), windowStart,
aiWindowEndExclusive, windowEndExclusive,
16 16
) )
).thenReturn( ).thenReturn(
@@ -229,8 +229,8 @@ class RecommendationSnapshotRefreshServiceTest {
).thenReturn(emptyList()) ).thenReturn(emptyList())
Mockito.`when`( Mockito.`when`(
queryPort.findCheerCreatorSnapshots( queryPort.findCheerCreatorSnapshots(
LocalDateTime.of(2026, 5, 28, 15, 0, 0), windowStart,
LocalDateTime.of(2026, 5, 29, 15, 0, 0), windowEndExclusive,
16 16
) )
).thenReturn(emptyList()) ).thenReturn(emptyList())
@@ -264,8 +264,6 @@ class RecommendationSnapshotRefreshServiceTest {
val windowStart = LocalDateTime.of(2026, 5, 22, 15, 0, 0) val windowStart = LocalDateTime.of(2026, 5, 22, 15, 0, 0)
val windowEndExclusive = LocalDateTime.of(2026, 5, 29, 15, 0, 0) val windowEndExclusive = LocalDateTime.of(2026, 5, 29, 15, 0, 0)
val snapshotAt = LocalDateTime.of(2026, 5, 29, 14, 59, 59) val snapshotAt = LocalDateTime.of(2026, 5, 29, 14, 59, 59)
val cheerWindowStart = LocalDateTime.of(2026, 5, 28, 15, 0, 0)
val cheerWindowEndExclusive = LocalDateTime.of(2026, 5, 29, 15, 0, 0)
Mockito.`when`(redissonClient.getLock(RecommendationSnapshotFallbackService.AI_CHARACTER_LOCK_KEY)).thenReturn(aiLock) Mockito.`when`(redissonClient.getLock(RecommendationSnapshotFallbackService.AI_CHARACTER_LOCK_KEY)).thenReturn(aiLock)
Mockito.`when`(redissonClient.getLock(RecommendationSnapshotFallbackService.CHEER_CREATOR_LOCK_KEY)).thenReturn(cheerLock) Mockito.`when`(redissonClient.getLock(RecommendationSnapshotFallbackService.CHEER_CREATOR_LOCK_KEY)).thenReturn(cheerLock)
Mockito.`when`(redissonClient.getLock(RecommendationSnapshotFallbackService.POPULAR_COMMUNITY_LOCK_KEY)) Mockito.`when`(redissonClient.getLock(RecommendationSnapshotFallbackService.POPULAR_COMMUNITY_LOCK_KEY))
@@ -276,7 +274,7 @@ class RecommendationSnapshotRefreshServiceTest {
Mockito.`when`(cheerLock.isHeldByCurrentThread).thenReturn(true) Mockito.`when`(cheerLock.isHeldByCurrentThread).thenReturn(true)
Mockito.`when`(popularLock.tryLock(0, -1, TimeUnit.MILLISECONDS)).thenReturn(true) Mockito.`when`(popularLock.tryLock(0, -1, TimeUnit.MILLISECONDS)).thenReturn(true)
Mockito.`when`(popularLock.isHeldByCurrentThread).thenReturn(true) Mockito.`when`(popularLock.isHeldByCurrentThread).thenReturn(true)
Mockito.`when`(queryPort.findCheerCreatorSnapshots(cheerWindowStart, cheerWindowEndExclusive, 16)).thenReturn( Mockito.`when`(queryPort.findCheerCreatorSnapshots(windowStart, windowEndExclusive, 16)).thenReturn(
listOf(snapshot(RecommendedSectionType.CHEER_CREATOR, targetId = 10L, score = 10.0, snapshotAt = snapshotAt)) listOf(snapshot(RecommendedSectionType.CHEER_CREATOR, targetId = 10L, score = 10.0, snapshotAt = snapshotAt))
) )
Mockito.`when`(queryPort.findPopularCommunitySnapshots(windowStart, windowEndExclusive, 20)).thenReturn(emptyList()) Mockito.`when`(queryPort.findPopularCommunitySnapshots(windowStart, windowEndExclusive, 20)).thenReturn(emptyList())
@@ -285,7 +283,7 @@ class RecommendationSnapshotRefreshServiceTest {
Mockito.verify(redissonClient).getLock(RecommendationSnapshotFallbackService.CHEER_CREATOR_LOCK_KEY) Mockito.verify(redissonClient).getLock(RecommendationSnapshotFallbackService.CHEER_CREATOR_LOCK_KEY)
Mockito.verify(cheerLock).tryLock(0, -1, TimeUnit.MILLISECONDS) Mockito.verify(cheerLock).tryLock(0, -1, TimeUnit.MILLISECONDS)
Mockito.verify(queryPort).findCheerCreatorSnapshots(cheerWindowStart, cheerWindowEndExclusive, 16) Mockito.verify(queryPort).findCheerCreatorSnapshots(windowStart, windowEndExclusive, 16)
assertEquals(listOf(10L), snapshotPort.findLatestSnapshots(RecommendedSectionType.CHEER_CREATOR).map { it.targetId }) assertEquals(listOf(10L), snapshotPort.findLatestSnapshots(RecommendedSectionType.CHEER_CREATOR).map { it.targetId })
Mockito.verify(cheerLock).unlock() Mockito.verify(cheerLock).unlock()
Mockito.verify(popularLock).unlock() Mockito.verify(popularLock).unlock()
@@ -322,8 +320,8 @@ class RecommendationSnapshotRefreshServiceTest {
service.refreshDailySnapshots(now) service.refreshDailySnapshots(now)
Mockito.verify(queryPort, Mockito.never()).findCheerCreatorSnapshots( Mockito.verify(queryPort, Mockito.never()).findCheerCreatorSnapshots(
LocalDateTime.of(2026, 5, 28, 15, 0, 0), windowStart,
LocalDateTime.of(2026, 5, 29, 15, 0, 0), windowEndExclusive,
16 16
) )
assertEquals( assertEquals(
@@ -361,8 +359,8 @@ class RecommendationSnapshotRefreshServiceTest {
Mockito.`when`(popularLock.isHeldByCurrentThread).thenReturn(true) Mockito.`when`(popularLock.isHeldByCurrentThread).thenReturn(true)
Mockito.`when`( Mockito.`when`(
queryPort.findCheerCreatorSnapshots( queryPort.findCheerCreatorSnapshots(
LocalDateTime.of(2026, 5, 28, 15, 0, 0), windowStart,
LocalDateTime.of(2026, 5, 29, 15, 0, 0), windowEndExclusive,
16 16
) )
).thenReturn( ).thenReturn(