Skip to content

Commit b6a514b

Browse files
authored
Merge pull request #49 from prgrms-web-devcourse-final-project/feat/38
Feat/38
2 parents 3164bcb + 063dd08 commit b6a514b

File tree

3 files changed

+85
-3
lines changed

3 files changed

+85
-3
lines changed

back/src/main/java/com/back/domain/member/member/controller/MemberController.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
@RequestMapping("/auth")
2020
@RequiredArgsConstructor
2121
@Tag(name = "MemberController", description = "회원 컨트롤러")
22-
public class MemberController {
22+
public class MemberController {
2323
private final MemberService memberService;
2424
private final Rq rq;
2525
private final EmailVerificationService emailVerificationService;
@@ -80,7 +80,7 @@ public RsData<Void> login(@RequestBody LoginRequest request) {
8080
public RsData<Void> logout() {
8181
rq.deleteCookie("accessToken");
8282
rq.deleteCookie("refreshToken");
83-
return new RsData<>("200-1", "로그아웃 성공");
83+
return new RsData<>("200-8", "로그아웃 성공");
8484
}
8585

8686
@GetMapping("/me")
@@ -100,4 +100,17 @@ public RsData<Void> refresh() {
100100

101101
return new RsData<>("200-6", "토큰 갱신 성공");
102102
}
103+
104+
@DeleteMapping("/me")
105+
@Operation(summary = "회원 탈퇴")
106+
public RsData<Void> deleteMember() {
107+
Member currentUser = rq.getActor();
108+
memberService.deleteMember(currentUser);
109+
110+
// 탈퇴 후 쿠키 삭제
111+
rq.deleteCookie("accessToken");
112+
rq.deleteCookie("refreshToken");
113+
114+
return new RsData<>("200-7", "회원 탈퇴가 완료되었습니다.");
115+
}
103116
}

back/src/main/java/com/back/domain/member/member/service/MemberService.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,22 @@ public boolean isValidToken(String token) {
9292
return authTokenService.isValidToken(token);
9393
}
9494

95+
@Transactional
96+
public void deleteMember(Member currentUser) {
97+
if (currentUser == null) {
98+
throw new ServiceException("401-1", "로그인이 필요합니다.");
99+
}
100+
101+
Member member = memberRepository.findById(currentUser.getId())
102+
.orElseThrow(() -> new ServiceException("404-1", "존재하지 않는 회원입니다."));
103+
104+
// 관련 엔티티들 먼저 삭제
105+
menteeRepository.findByMemberId(member.getId()).ifPresent(menteeRepository::delete);
106+
mentorRepository.findByMemberId(member.getId()).ifPresent(mentorRepository::delete);
107+
108+
memberRepository.delete(member);
109+
}
110+
95111
public boolean isRefreshToken(String token) {
96112
return authTokenService.isRefreshToken(token);
97113
}

back/src/test/java/com/back/domain/member/member/controller/MemberControllerTest.java

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import org.springframework.test.web.servlet.ResultActions;
1717
import org.springframework.transaction.annotation.Transactional;
1818

19+
import static org.assertj.core.api.Assertions.assertThat;
1920
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
2021
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
2122
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@@ -368,7 +369,7 @@ void t9() throws Exception {
368369

369370
result
370371
.andExpect(status().is2xxSuccessful())
371-
.andExpect(jsonPath("$.resultCode").value("200-1"))
372+
.andExpect(jsonPath("$.resultCode").value("200-8"))
372373
.andExpect(jsonPath("$.msg").value("로그아웃 성공"))
373374
.andExpect(cookie().maxAge("accessToken", 0))
374375
.andExpect(cookie().maxAge("refreshToken", 0));
@@ -443,4 +444,56 @@ void t11() throws Exception {
443444
.andExpect(jsonPath("$.msg").value("이미 존재하는 닉네임입니다."));
444445
}
445446

447+
@Test
448+
@DisplayName("회원 탈퇴 성공")
449+
void t12() throws Exception {
450+
// 멘티 회원가입
451+
String email = "[email protected]";
452+
memberService.joinMentee(email, "탈퇴사용자", "탈퇴닉네임", "password123", "Backend");
453+
454+
// 로그인하여 쿠키 받기
455+
ResultActions loginResult = mvc.perform(
456+
post("/auth/login")
457+
.contentType(MediaType.APPLICATION_JSON)
458+
.content(String.format("""
459+
{
460+
"email": "%s",
461+
"password": "password123"
462+
}
463+
""", email))
464+
);
465+
466+
Cookie accessToken = loginResult.andReturn().getResponse().getCookie("accessToken");
467+
468+
// 회원 탈퇴 요청
469+
ResultActions result = mvc
470+
.perform(
471+
delete("/auth/me")
472+
.cookie(accessToken)
473+
)
474+
.andDo(print());
475+
476+
result
477+
.andExpect(status().is2xxSuccessful())
478+
.andExpect(jsonPath("$.resultCode").value("200-7"))
479+
.andExpect(jsonPath("$.msg").value("회원 탈퇴가 완료되었습니다."))
480+
.andExpect(cookie().maxAge("accessToken", 0))
481+
.andExpect(cookie().maxAge("refreshToken", 0));
482+
483+
// 탈퇴 후 해당 이메일로 조회했을 때 없어야 함
484+
assertThat(memberService.findByEmail(email)).isEmpty();
485+
}
486+
487+
@Test
488+
@DisplayName("로그인하지 않은 상태에서 회원 탈퇴 시도 - 실패")
489+
void t13() throws Exception {
490+
// 로그인 없이 회원 탈퇴 시도
491+
ResultActions result = mvc
492+
.perform(delete("/auth/me"))
493+
.andDo(print());
494+
495+
result
496+
.andExpect(status().isUnauthorized());
497+
}
498+
446499
}

0 commit comments

Comments
 (0)