Files
sodalive-backend-spring-boot/src/test/kotlin/kr/co/vividnext/sodalive/member/MemberServiceCacheEvictionTest.kt

196 lines
7.6 KiB
Kotlin

package kr.co.vividnext.sodalive.member
import com.fasterxml.jackson.databind.ObjectMapper
import kr.co.vividnext.sodalive.common.CountryContext
import kr.co.vividnext.sodalive.i18n.LangContext
import kr.co.vividnext.sodalive.i18n.SodaMessageSource
import kr.co.vividnext.sodalive.member.auth.Auth
import kr.co.vividnext.sodalive.member.auth.AuthRepository
import kr.co.vividnext.sodalive.member.block.BlockMember
import kr.co.vividnext.sodalive.member.block.BlockMemberRepository
import kr.co.vividnext.sodalive.member.block.MemberBlockRequest
import kr.co.vividnext.sodalive.member.contentpreference.MemberContentPreferenceService
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.mockito.Mockito
import org.springframework.cache.Cache
import org.springframework.cache.CacheManager
import java.util.Optional
class MemberServiceCacheEvictionTest {
private lateinit var memberRepository: MemberRepository
private lateinit var blockMemberRepository: BlockMemberRepository
private lateinit var authRepository: AuthRepository
private lateinit var cacheManager: CacheManager
private lateinit var cache: Cache
private lateinit var service: MemberService
@BeforeEach
fun setup() {
memberRepository = mock()
blockMemberRepository = mock()
authRepository = mock()
cacheManager = mock()
cache = mock()
Mockito.`when`(cacheManager.getCache("cache_ttl_3_hours")).thenReturn(cache)
service = MemberService(
repository = memberRepository,
tokenRepository = mock(),
stipulationRepository = mock(),
stipulationAgreeRepository = mock(),
creatorFollowingRepository = mock(),
blockMemberRepository = blockMemberRepository,
signOutRepository = mock(),
nicknameChangeLogRepository = mock(),
memberTagRepository = mock(),
liveReservationRepository = mock(),
chargeRepository = mock(),
memberPointRepository = mock(),
orderService = mock(),
emailService = mock(),
pushTokenService = mock(),
canPaymentService = mock(),
nicknameGenerateService = mock(),
memberNotificationService = mock(),
s3Uploader = mock(),
validator = mock(),
tokenProvider = mock(),
passwordEncoder = mock(),
authenticationManagerBuilder = mock(),
messageSource = SodaMessageSource(),
langContext = LangContext(),
countryContext = CountryContext(),
memberContentPreferenceService = mock<MemberContentPreferenceService>(),
objectMapper = ObjectMapper(),
cacheManager = cacheManager,
s3Bucket = "test-bucket",
cloudFrontHost = "https://cdn.test"
)
}
@Test
fun shouldEvictRecommendLiveCacheForRequesterAndTargetOnBlock() {
val memberId = 100L
val blockedMemberId = 200L
val member = createMember(id = memberId, nickname = "requester")
val blockedMember = createMember(id = blockedMemberId, nickname = "target")
Mockito.`when`(memberRepository.findById(memberId)).thenReturn(Optional.of(member))
Mockito.`when`(memberRepository.findById(blockedMemberId)).thenReturn(Optional.of(blockedMember))
Mockito.`when`(
blockMemberRepository.getBlockAccount(
blockedMemberId = blockedMemberId,
memberId = memberId
)
).thenReturn(null)
service.memberBlock(MemberBlockRequest(blockMemberId = blockedMemberId), memberId)
verifyRecommendLiveCacheEvicted(memberId)
verifyRecommendLiveCacheEvicted(blockedMemberId)
Mockito.verifyNoInteractions(authRepository)
}
@Test
fun shouldBlockOnlyRequestedMemberEvenWhenTargetHasAuth() {
// 차단 대상에게 본인인증 정보가 연결된 상황을 준비한다.
val memberId = 500L
val blockedMemberId = 600L
val linkedMemberId = 601L
val member = createMember(id = memberId, nickname = "requester2")
val blockedMember = createMember(id = blockedMemberId, nickname = "target2")
val auth = Auth(
name = "홍길동",
birth = "19900101",
uniqueCi = "unique-ci",
di = "di-value",
gender = 1
)
auth.member = blockedMember
// 요청자와 요청 대상만 조회 가능하도록 목 동작을 설정한다.
Mockito.`when`(memberRepository.findById(memberId)).thenReturn(Optional.of(member))
Mockito.`when`(memberRepository.findById(blockedMemberId)).thenReturn(Optional.of(blockedMember))
Mockito.`when`(
blockMemberRepository.getBlockAccount(
blockedMemberId = blockedMemberId,
memberId = memberId
)
).thenReturn(null)
Mockito.`when`(
authRepository.getMemberIdsByNameAndBirthAndDiAndGender(
name = auth.name,
birth = auth.birth,
di = auth.di,
gender = auth.gender
)
).thenReturn(listOf(blockedMemberId, linkedMemberId))
// 차단 API를 실행한다.
service.memberBlock(MemberBlockRequest(blockMemberId = blockedMemberId), memberId)
// 요청한 blockMemberId 한 건만 차단 처리 및 캐시 무효화되는지 검증한다.
Mockito.verify(blockMemberRepository).getBlockAccount(
blockedMemberId = blockedMemberId,
memberId = memberId
)
Mockito.verify(blockMemberRepository, Mockito.never()).getBlockAccount(
blockedMemberId = linkedMemberId,
memberId = memberId
)
verifyRecommendLiveCacheEvicted(memberId)
verifyRecommendLiveCacheEvicted(blockedMemberId)
verifyRecommendLiveCacheNotEvicted(linkedMemberId)
Mockito.verifyNoInteractions(authRepository)
}
@Test
fun shouldEvictRecommendLiveCacheForRequesterAndTargetOnUnblock() {
val memberId = 300L
val blockedMemberId = 400L
val blockMember = BlockMember(isActive = true)
Mockito.`when`(
blockMemberRepository.getBlockAccount(
blockedMemberId = blockedMemberId,
memberId = memberId
)
).thenReturn(blockMember)
service.memberUnBlock(MemberBlockRequest(blockMemberId = blockedMemberId), memberId)
assertEquals(false, blockMember.isActive)
verifyRecommendLiveCacheEvicted(memberId)
verifyRecommendLiveCacheEvicted(blockedMemberId)
}
private fun verifyRecommendLiveCacheEvicted(memberId: Long) {
Mockito.verify(cache).evict("getRecommendLive:$memberId:false")
Mockito.verify(cache).evict("getRecommendLive:$memberId:true")
Mockito.verify(cache).evict("getRecommendLive:$memberId")
}
private fun verifyRecommendLiveCacheNotEvicted(memberId: Long) {
Mockito.verify(cache, Mockito.never()).evict("getRecommendLive:$memberId:false")
Mockito.verify(cache, Mockito.never()).evict("getRecommendLive:$memberId:true")
Mockito.verify(cache, Mockito.never()).evict("getRecommendLive:$memberId")
}
private fun createMember(id: Long, nickname: String): Member {
val member = Member(
email = "$nickname@test.com",
password = "password",
nickname = nickname
)
member.id = id
return member
}
private inline fun <reified T> mock(): T {
return Mockito.mock(T::class.java)
}
}