- Input
<hide/>
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class WithdrawMemberInput {
private String password;
}
- Service
- memberId, email, status, deleteDt를 제외하고 나머지는 모두 null 로 변경한다.
- 같은 이메일로는 재가입 불가능하다.
<hide/>
@Override
public void withdraw(String email, String password) {
Optional<Member> optionalMember = memberRepository.findByEmail(email);
if (!optionalMember.isPresent()) {
throw new MemberException(EMAIL_NOT_EXIST);
}
Member member = optionalMember.get();
if (!bCryptPasswordEncoder.matches(password, member.getPassword())) {
throw new MemberException(PASSWORD_NOT_MATCH);
}
member.setStatus(MemberStatus.WITHDRAW);
member.setDeleteDt(LocalDateTime.now());
member.setPassword(null);
member.setNickName(null);
member.setPhone(null);
member.setBirth(null);
member.setAddress(null);
member.setGender(null);
member.setMemberPhotoUrl(null);
member.setResetPasswordKey(null);
member.setResetPasswordLimitDt(null);
member.setEmailAuthKey(null);
memberRepository.save(member);
}
- Ctrl
<hide/>
@DeleteMapping("/member/info")
@ApiOperation(value = "회원 탈퇴 API", notes = "비밀번호를 입력하여 회원 탈퇴할 수 있다.")
public ResponseEntity<?> delete(
@ApiParam(value = "비밀번호 입력") @RequestBody WithdrawMemberInput input, Principal principal) {
String email = principal.getName();
memberService.withdraw(email, input.getPassword());
String message = "회원 탈퇴 완료";
return new ResponseEntity(message, HttpStatus.OK);
}
- test
- captor를 적용하는 비밀번호 부분 옆에 이메일을 넣는 부분은 anyString()을 넣어줘야 테스트를 통과한다.
<hide/>
@Test
@DisplayName("회원 탈퇴 - 성공")
void delete() throws Exception {
// given
Member member = Member.builder().email("egg@naver.com").password("abc123~!")
.status(MemberStatus.ING).build();
WithdrawMemberInput input = WithdrawMemberInput.builder()
.password("abc123~!")
.build();
String withdrawInputToJson = mapper.writeValueAsString(input);
User user = new User(member.getEmail(), member.getPassword(),
AuthorityUtils.NO_AUTHORITIES);
TestingAuthenticationToken testingAuthenticationToken = new TestingAuthenticationToken(user,
null);
// when
mockMvc.perform(MockMvcRequestBuilders
.delete("/api/member/info").contentType(MediaType.APPLICATION_JSON)
.content(withdrawInputToJson)
.principal(testingAuthenticationToken)).andExpect(status().isOk()).andDo(print());
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
// then
Mockito.verify(memberServiceImpl, times(1)).withdraw(anyString(), captor.capture());
assertEquals(input.getPassword(), captor.getValue());
}
<hide/>
@Test
@DisplayName("회원 탈퇴 - 성공")
void withdraw() {
// given
Member member = Member.builder()
.email("egg@naver.com")
.status(MemberStatus.ING)
.build();
String rawPassword = "abc123!@";
member.setPassword(bCryptPasswordEncoder.encode(rawPassword));
// when
given(memberRepository.findByEmail(anyString())).willReturn(Optional.of(member));
memberService.withdraw(member.getEmail(), rawPassword);
// then
assertEquals(MemberStatus.WITHDRAW,
memberRepository.findByEmail(member.getEmail()).get().getStatus());
}
@Test
@DisplayName("회원 탈퇴 (이메일 오류) - 실패")
void withdraw_fail_email() {
// given
Member member = Member.builder()
.email("egg@naver.com")
.status(MemberStatus.ING)
.build();
String rawPassword = "abc123!@";
member.setPassword(bCryptPasswordEncoder.encode(rawPassword));
// when
given(memberRepository.findByEmail(anyString())).willReturn(Optional.empty());
// then
MemberException exception = assertThrows(MemberException.class,
() -> memberService.withdraw(member.getEmail(), rawPassword));
assertEquals(MemberErrorCode.EMAIL_NOT_EXIST, exception.getErrorCode());
}
@Test
@DisplayName("회원 탈퇴 (비밀번호 오류) - 실패")
void withdraw_fail_pwd() {
// given
Member member = Member.builder()
.email("egg@naver.com")
.status(MemberStatus.ING)
.build();
String rawPassword = "abc123!@";
String wrongPassword = "xyz123!@";
member.setPassword(bCryptPasswordEncoder.encode(rawPassword));
// when
given(memberRepository.findByEmail(anyString())).willReturn(Optional.of(member));
// then
MemberException exception = assertThrows(MemberException.class,
() -> memberService.withdraw(member.getEmail(), wrongPassword));
assertEquals(MemberErrorCode.PASSWORD_NOT_MATCH, exception.getErrorCode());
}
'Spring Projcect > [팀플] In & Out 가계부' 카테고리의 다른 글
회원 수정 - 이미지 업로드 API (0) | 2022.11.01 |
---|---|
회원 비밀번호 초기화 API (0) | 2022.10.31 |
회원 이메일 인증 API (0) | 2022.10.28 |
회원 가입 API (0) | 2022.10.27 |
회원 로그아웃 API (0) | 2022.10.26 |