From 94eb11ad5a66f9c55782fc33d733ea012f9b1bee Mon Sep 17 00:00:00 2001 From: Klaus Date: Thu, 5 Mar 2026 15:38:34 +0900 Subject: [PATCH] =?UTF-8?q?test(admin-member):=20=EA=B4=80=EB=A6=AC?= =?UTF-8?q?=EC=9E=90=20=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=B0=A8=EB=8B=A8=20?= =?UTF-8?q?=EC=84=9C=EB=B9=84=EC=8A=A4=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EB=A5=BC=20=EC=B6=94=EA=B0=80=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../member/AdminMemberBlockServiceTest.kt | 159 ++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 src/test/kotlin/kr/co/vividnext/sodalive/admin/member/AdminMemberBlockServiceTest.kt diff --git a/src/test/kotlin/kr/co/vividnext/sodalive/admin/member/AdminMemberBlockServiceTest.kt b/src/test/kotlin/kr/co/vividnext/sodalive/admin/member/AdminMemberBlockServiceTest.kt new file mode 100644 index 00000000..0b09bb48 --- /dev/null +++ b/src/test/kotlin/kr/co/vividnext/sodalive/admin/member/AdminMemberBlockServiceTest.kt @@ -0,0 +1,159 @@ +package kr.co.vividnext.sodalive.admin.member + +import kr.co.vividnext.sodalive.common.SodaException +import kr.co.vividnext.sodalive.member.Member +import kr.co.vividnext.sodalive.member.MemberService +import kr.co.vividnext.sodalive.member.SignOut +import kr.co.vividnext.sodalive.member.SignOutRepository +import kr.co.vividnext.sodalive.member.auth.Auth +import kr.co.vividnext.sodalive.member.auth.AuthRepository +import kr.co.vividnext.sodalive.member.auth.BlockAuth +import kr.co.vividnext.sodalive.member.auth.BlockAuthRepository +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertThrows +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.mockito.ArgumentCaptor +import org.mockito.Mockito + +class AdminMemberBlockServiceTest { + private lateinit var adminMemberRepository: AdminMemberRepository + private lateinit var signOutRepository: SignOutRepository + private lateinit var memberService: MemberService + private lateinit var authRepository: AuthRepository + private lateinit var blockAuthRepository: BlockAuthRepository + private lateinit var service: AdminMemberBlockService + + @BeforeEach + fun setup() { + adminMemberRepository = Mockito.mock(AdminMemberRepository::class.java) + signOutRepository = Mockito.mock(SignOutRepository::class.java) + memberService = Mockito.mock(MemberService::class.java) + authRepository = Mockito.mock(AuthRepository::class.java) + blockAuthRepository = Mockito.mock(BlockAuthRepository::class.java) + + service = AdminMemberBlockService( + adminMemberRepository = adminMemberRepository, + signOutRepository = signOutRepository, + memberService = memberService, + authRepository = authRepository, + blockAuthRepository = blockAuthRepository + ) + } + + @Test + fun shouldBlockAllMembersWithSameAuthAndStoreBlockAuth() { + val member = Member(password = "password", nickname = "tester") + member.id = 101L + val linkedMember = Member(password = "password", nickname = "linked") + linkedMember.id = 202L + + val auth = Auth( + name = "홍길동", + birth = "19900101", + uniqueCi = "unique-ci", + di = "di-value", + gender = 1 + ) + auth.member = member + + val request = AdminMemberBlockRequest(memberId = 101L, reason = "운영정책 위반") + + Mockito.`when`(adminMemberRepository.findByIdAndActive(memberId = request.memberId)).thenReturn(member) + Mockito.`when`( + authRepository.getActiveMemberIdsByNameAndBirthAndDiAndUniqueCi( + name = auth.name, + birth = auth.birth, + di = auth.di, + uniqueCi = auth.uniqueCi + ) + ).thenReturn(listOf(101L, 202L)) + Mockito.`when`(adminMemberRepository.findByIdAndActive(memberId = 202L)).thenReturn(linkedMember) + Mockito.`when`(blockAuthRepository.findByUniqueCiAndDi(auth.uniqueCi, auth.di)).thenReturn(null) + + service.blockMember(request) + + assertFalse(member.isActive) + assertEquals("deleted_tester", member.nickname) + assertFalse(linkedMember.isActive) + assertEquals("deleted_linked", linkedMember.nickname) + + val signOutCaptor = ArgumentCaptor.forClass(SignOut::class.java) + Mockito.verify(signOutRepository, Mockito.times(2)).save(signOutCaptor.capture()) + assertEquals(2, signOutCaptor.allValues.size) + assertTrue(signOutCaptor.allValues.all { it.reason == "운영정책 위반" }) + assertEquals(setOf(101L, 202L), signOutCaptor.allValues.mapNotNull { it.member?.id }.toSet()) + + Mockito.verify(memberService).logoutAll(memberId = 101L) + Mockito.verify(memberService).logoutAll(memberId = 202L) + Mockito.verify(authRepository).getActiveMemberIdsByNameAndBirthAndDiAndUniqueCi( + name = auth.name, + birth = auth.birth, + di = auth.di, + uniqueCi = auth.uniqueCi + ) + Mockito.verify(blockAuthRepository).findByUniqueCiAndDi(auth.uniqueCi, auth.di) + + val blockAuthCaptor = ArgumentCaptor.forClass(BlockAuth::class.java) + Mockito.verify(blockAuthRepository).save(blockAuthCaptor.capture()) + assertEquals(auth.name, blockAuthCaptor.value.name) + assertEquals(auth.birth, blockAuthCaptor.value.birth) + assertEquals(auth.uniqueCi, blockAuthCaptor.value.uniqueCi) + assertEquals(auth.di, blockAuthCaptor.value.di) + assertEquals(auth.gender, blockAuthCaptor.value.gender) + } + + @Test + fun shouldBlockMemberWithoutBlockAuthWhenMemberHasNoVerification() { + val member = Member(password = "password", nickname = "tester") + member.id = 202L + + val request = AdminMemberBlockRequest(memberId = 202L, reason = "반복 신고") + + Mockito.`when`(adminMemberRepository.findByIdAndActive(memberId = request.memberId)).thenReturn(member) + + service.blockMember(request) + + assertFalse(member.isActive) + assertEquals("deleted_tester", member.nickname) + Mockito.verify(signOutRepository).save(Mockito.any(SignOut::class.java)) + Mockito.verify(memberService).logoutAll(memberId = 202L) + Mockito.verifyNoInteractions(authRepository) + Mockito.verifyNoInteractions(blockAuthRepository) + } + + @Test + fun shouldThrowWhenReasonIsBlank() { + val request = AdminMemberBlockRequest(memberId = 1L, reason = " ") + + val exception = assertThrows(SodaException::class.java) { + service.blockMember(request) + } + + assertEquals("member.validation.signout_reason_required", exception.messageKey) + Mockito.verifyNoInteractions(adminMemberRepository) + Mockito.verifyNoInteractions(signOutRepository) + Mockito.verifyNoInteractions(memberService) + Mockito.verifyNoInteractions(authRepository) + Mockito.verifyNoInteractions(blockAuthRepository) + } + + @Test + fun shouldThrowWhenMemberNotFound() { + val request = AdminMemberBlockRequest(memberId = 303L, reason = "운영자 차단") + Mockito.`when`(adminMemberRepository.findByIdAndActive(memberId = request.memberId)).thenReturn(null) + + val exception = assertThrows(SodaException::class.java) { + service.blockMember(request) + } + + assertEquals("admin.member.not_found", exception.messageKey) + Mockito.verify(adminMemberRepository).findByIdAndActive(memberId = 303L) + Mockito.verifyNoInteractions(signOutRepository) + Mockito.verifyNoInteractions(memberService) + Mockito.verifyNoInteractions(authRepository) + Mockito.verifyNoInteractions(blockAuthRepository) + } +}