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, id: Long = 1L ): UseCanQueryDto { return UseCanQueryDto( id = id, 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 ) } }