From 6e35123d7b2977ebd80208d1411b4a07534f5974 Mon Sep 17 00:00:00 2001 From: 2iedo <162278702+2iedo@users.noreply.github.com> Date: Wed, 6 Nov 2024 02:07:59 +0900 Subject: [PATCH] =?UTF-8?q?feat,=20hotfix=20:=20=ED=9A=8C=EC=9B=90?= =?UTF-8?q?=ED=83=88=ED=87=B4=20api=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20red?= =?UTF-8?q?isTemplate=20=EC=88=98=EC=A0=95=20(#170)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat, hotfix : 회원탈퇴 api 추가 및 redisTemplate 수정 * feat : 경로 추가 --- .../member/controller/MemberController.java | 7 ++++ .../sinitto/member/service/MemberService.java | 19 +++++++++-- .../auth/service/TokenServiceTest.java | 13 +++---- .../member/service/MemberServiceTest.java | 34 +++++++++++++++---- 4 files changed, 55 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/example/sinitto/member/controller/MemberController.java b/src/main/java/com/example/sinitto/member/controller/MemberController.java index 21108fc6..e063f39c 100644 --- a/src/main/java/com/example/sinitto/member/controller/MemberController.java +++ b/src/main/java/com/example/sinitto/member/controller/MemberController.java @@ -44,4 +44,11 @@ public ResponseEntity memberLogout(@MemberId Long memberId) { memberService.memberLogout(memberId); return ResponseEntity.ok().build(); } + + @Operation(summary = "멤버 회원탈퇴", description = "회원 정보를 삭제합니다.") + @DeleteMapping("/withdrawal") + public ResponseEntity deleteMember(@MemberId Long memberId) { + memberService.deleteMember(memberId); + return ResponseEntity.ok().build(); + } } diff --git a/src/main/java/com/example/sinitto/member/service/MemberService.java b/src/main/java/com/example/sinitto/member/service/MemberService.java index 8945e1ba..a9987be3 100644 --- a/src/main/java/com/example/sinitto/member/service/MemberService.java +++ b/src/main/java/com/example/sinitto/member/service/MemberService.java @@ -28,9 +28,9 @@ public class MemberService implements MemberIdProvider { private final KakaoApiService kakaoApiService; private final KakaoTokenService kakaoTokenService; private final PointRepository pointRepository; - private final RedisTemplate redisTemplate; + private final RedisTemplate redisTemplate; - public MemberService(MemberRepository memberRepository, TokenService tokenService, KakaoApiService kakaoApiService, KakaoTokenService kakaoTokenService, PointRepository pointRepository, RedisTemplate redisTemplate) { + public MemberService(MemberRepository memberRepository, TokenService tokenService, KakaoApiService kakaoApiService, KakaoTokenService kakaoTokenService, PointRepository pointRepository, RedisTemplate redisTemplate) { this.memberRepository = memberRepository; this.tokenService = tokenService; this.kakaoApiService = kakaoApiService; @@ -90,10 +90,23 @@ public void memberLogout(Long memberId) { Member member = memberRepository.findById(memberId) .orElseThrow(() -> new NotFoundException("id에 해당하는 멤버가 없습니다.")); - String storedRefreshToken = redisTemplate.opsForValue().get(member.getEmail()); + String storedRefreshToken = (String) redisTemplate.opsForHash().get(member.getEmail(), "refreshToken"); if (storedRefreshToken != null) { redisTemplate.delete(member.getEmail()); } } + + public void deleteMember(Long memberId){ + Member member = memberRepository.findById(memberId) + .orElseThrow(() -> new NotFoundException("id에 해당하는 멤버가 없습니다.")); + + String storedRefreshToken = (String) redisTemplate.opsForHash().get(member.getEmail(), "refreshToken"); + + if (storedRefreshToken != null) { + redisTemplate.delete(member.getEmail()); + } + + memberRepository.deleteById(memberId); + } } diff --git a/src/test/java/com/example/sinitto/auth/service/TokenServiceTest.java b/src/test/java/com/example/sinitto/auth/service/TokenServiceTest.java index ff7a8dcd..92b88723 100644 --- a/src/test/java/com/example/sinitto/auth/service/TokenServiceTest.java +++ b/src/test/java/com/example/sinitto/auth/service/TokenServiceTest.java @@ -1,19 +1,14 @@ package com.example.sinitto.auth.service; -import com.example.sinitto.common.exception.InvalidJwtException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.junit.jupiter.MockitoSettings; -import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.redis.core.HashOperations; import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.data.redis.core.ValueOperations; -import javax.crypto.spec.SecretKeySpec; -import java.security.Key; import java.util.Base64; import static org.junit.jupiter.api.Assertions.*; @@ -22,10 +17,10 @@ @MockitoSettings public class TokenServiceTest { @Mock - private RedisTemplate redisTemplate; + private RedisTemplate redisTemplate; @Mock - private ValueOperations valueOperations; + private HashOperations hashOperations; private TokenService tokenService; @@ -60,7 +55,7 @@ void generateRefreshTokenTest() { //given String email = "test@email.com"; - when(redisTemplate.opsForValue()).thenReturn(valueOperations); + when(redisTemplate.opsForHash()).thenReturn(hashOperations); //when String token = tokenService.generateRefreshToken(email); diff --git a/src/test/java/com/example/sinitto/member/service/MemberServiceTest.java b/src/test/java/com/example/sinitto/member/service/MemberServiceTest.java index e61fcd26..718971d4 100644 --- a/src/test/java/com/example/sinitto/member/service/MemberServiceTest.java +++ b/src/test/java/com/example/sinitto/member/service/MemberServiceTest.java @@ -13,8 +13,8 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoSettings; +import org.springframework.data.redis.core.HashOperations; import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.data.redis.core.ValueOperations; import java.util.Optional; @@ -31,9 +31,9 @@ public class MemberServiceTest { @Mock TokenService tokenService; @Mock - RedisTemplate redisTemplate; + RedisTemplate redisTemplate; @Mock - private ValueOperations valueOperations; + private HashOperations hashOperations; @InjectMocks MemberService memberService; @@ -61,7 +61,6 @@ void getMemberIdByTokenTestWhenNotInMemberRepository() { //given String token = "testtoken"; String email = "test@email.com"; - Member member = mock(Member.class); when(tokenService.extractEmailFromAccessToken(token)).thenReturn(email); when(memberRepository.findByEmail(email)).thenReturn(Optional.empty()); @@ -110,12 +109,14 @@ void registerNewMemberTestWhenExists() { void memberLogoutTest() { //given Long memberId = 1L; + String email = "test@email.com"; Member member = mock(Member.class); String storedRefreshToken = "testRefreshToken"; when(memberRepository.findById(memberId)).thenReturn(Optional.of(member)); - when(redisTemplate.opsForValue()).thenReturn(valueOperations); - when(redisTemplate.opsForValue().get(member.getEmail())).thenReturn(storedRefreshToken); + when(member.getEmail()).thenReturn(email); + when(redisTemplate.opsForHash()).thenReturn(hashOperations); + when(redisTemplate.opsForHash().get(member.getEmail(), "refreshToken")).thenReturn(storedRefreshToken); //when memberService.memberLogout(memberId); @@ -136,4 +137,25 @@ void memberLogoutTestWhenMemberIsNull() { //when, then assertThrows(NotFoundException.class, () -> memberService.memberLogout(memberId)); } + + @Test + @DisplayName("deleteMember 메소드 테스트") + void deleteMemberTest(){ + //given + Long memberId = 1L; + String email = "test@email.com"; + Member member = mock(Member.class); + String storedRefreshToken = "testRefreshToken"; + + when(memberRepository.findById(memberId)).thenReturn(Optional.of(member)); + when(member.getEmail()).thenReturn(email); + when(redisTemplate.opsForHash()).thenReturn(hashOperations); + when(redisTemplate.opsForHash().get(member.getEmail(), "refreshToken")).thenReturn(storedRefreshToken); + + //when + memberService.deleteMember(memberId); + + //when + verify(memberRepository, times(1)).deleteById(memberId); + } }