refactor(can): 캔 사용 내역 조회 로직을 쿼리 기반으로 개선한다

This commit is contained in:
2026-03-16 15:25:58 +09:00
parent a2f84111cc
commit 21c02deda1
4 changed files with 323 additions and 66 deletions

View File

@@ -0,0 +1,165 @@
package kr.co.vividnext.sodalive.can
import kr.co.vividnext.sodalive.can.use.CanUsage
import kr.co.vividnext.sodalive.common.CountryContext
import kr.co.vividnext.sodalive.member.Member
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
import org.mockito.Mockito.mock
import org.mockito.Mockito.`when`
import org.springframework.data.domain.PageRequest
import java.time.LocalDateTime
class CanServiceTest {
private lateinit var repository: CanRepository
private lateinit var countryContext: CountryContext
private lateinit var service: CanService
@BeforeEach
fun setUp() {
repository = mock(CanRepository::class.java)
countryContext = mock(CountryContext::class.java)
service = CanService(repository, countryContext)
}
@Test
@DisplayName("AOS 컨테이너에 대해 캔 사용 내역이 올바르게 필터링 및 맵핑되는지 확인한다")
fun `should filter can use status correctly for aos`() {
// given
val member = Member(nickname = "user1", password = "password")
member.id = 1L
val pageable = PageRequest.of(0, 10)
val useCanDto1 = createUseCanDto(CanUsage.HEART, 10, 0, "nick1", null)
val useCanDto2 = createUseCanDto(CanUsage.DONATION, 0, 5, "nick2", null)
`when`(repository.getCanUseStatus(member, pageable, "aos")).thenReturn(listOf(useCanDto1, useCanDto2))
// when
val result = service.getCanUseStatus(member, pageable, "Asia/Seoul", "aos")
// then
assertEquals(2, result.size)
assertEquals("[라이브 후원] nick1", result[0].title)
assertEquals(10, result[0].can)
assertEquals("[라이브 후원] nick2", result[1].title)
assertEquals(5, result[1].can)
}
@Test
@DisplayName("iOS 컨테이너에 대해 캔 사용 내역이 올바르게 필터링 및 맵핑되는지 확인한다")
fun `should filter can use status correctly for ios`() {
// given
val member = Member(nickname = "user1", password = "password")
member.id = 1L
val pageable = PageRequest.of(0, 10)
val useCanDto1 = createUseCanDto(CanUsage.HEART, 10, 0, "nick1", null)
val useCanDto2 = createUseCanDto(CanUsage.DONATION, 10, 0, "nick2", null)
`when`(repository.getCanUseStatus(member, pageable, "ios")).thenReturn(listOf(useCanDto1, useCanDto2))
// when
val result = service.getCanUseStatus(member, pageable, "Asia/Seoul", "ios")
// then
assertEquals(2, result.size)
}
@Test
@DisplayName("조회 결과가 없을 때 빈 리스트를 반환하는지 확인한다")
fun `should return empty list when no status exists`() {
// given
val member = Member(nickname = "user1", password = "password")
member.id = 1L
val pageable = PageRequest.of(0, 10)
`when`(repository.getCanUseStatus(member, pageable, "aos")).thenReturn(emptyList())
// when
val result = service.getCanUseStatus(member, pageable, "Asia/Seoul", "aos")
// then
assertEquals(0, result.size)
}
@Test
@DisplayName("유효하지 않은 타임존 입력 시 UTC를 기본으로 사용한다")
fun `should use UTC when timezone is invalid`() {
// given
val member = Member(nickname = "user1", password = "password")
member.id = 1L
val pageable = PageRequest.of(0, 10)
val useCanDto = createUseCanDto(CanUsage.HEART, 10, 0)
`when`(repository.getCanUseStatus(member, pageable, "aos")).thenReturn(listOf(useCanDto))
// when
val result = service.getCanUseStatus(member, pageable, "Invalid/Timezone", "aos")
// then
assertEquals(1, result.size)
}
@Test
@DisplayName("다양한 CanUsage 및 null 필드에 대해 타이틀이 올바르게 포맷팅되는지 확인한다")
fun `should handle various can usage and nullable fields correctly`() {
// given
val member = Member(nickname = "user1", password = "password")
member.id = 1L
val pageable = PageRequest.of(0, 10)
val dtos = listOf(
createUseCanDto(CanUsage.HEART, 10, 0, roomMemberNickname = null, audioContentMemberNickname = null),
createUseCanDto(CanUsage.CHANNEL_DONATION, 10, 0, recipientCreatorNickname = null),
createUseCanDto(CanUsage.LIVE, 10, 0, roomMemberNickname = "creator1"),
createUseCanDto(CanUsage.LIVE, 10, 0),
createUseCanDto(CanUsage.CHANGE_NICKNAME, 10, 0),
createUseCanDto(CanUsage.CHAT_QUOTA_PURCHASE, 10, 0)
)
`when`(repository.getCanUseStatus(member, pageable, "aos")).thenReturn(dtos)
// when
val result = service.getCanUseStatus(member, pageable, "Asia/Seoul", "aos")
// then
assertEquals("[후원]", result[0].title)
assertEquals("[채널 후원]", result[1].title)
assertEquals("[라이브] creator1", result[2].title)
assertEquals("[라이브]", result[3].title)
assertEquals("닉네임 변경", result[4].title)
assertEquals("캐릭터 톡 이용권 구매", result[5].title)
}
private fun createUseCanDto(
usage: CanUsage,
can: Int,
rewardCan: Int,
roomMemberNickname: String? = null,
recipientCreatorNickname: String? = null,
roomTitle: String? = null,
audioContentMemberNickname: String? = null,
audioContentTitle: String? = null,
communityPostMemberNickname: String? = null,
auditionTitle: String? = null,
characterName: String? = null
): UseCanQueryDto {
return UseCanQueryDto(
canUsage = usage,
can = can,
rewardCan = rewardCan,
createdAt = LocalDateTime.now(),
roomMemberNickname = roomMemberNickname,
roomTitle = roomTitle,
audioContentMemberNickname = audioContentMemberNickname,
audioContentTitle = audioContentTitle,
communityPostMemberNickname = communityPostMemberNickname,
auditionTitle = auditionTitle,
characterName = characterName,
recipientCreatorNickname = recipientCreatorNickname
)
}
}