Spring Projcect/[팀플] In & Out 가계부

회원 비밀번호 초기화 API

계란💕 2022. 10. 31. 15:26
  • service
    • uuid 오류, 비밀번호와 비밀번호 확인이 다른 경우, 유효기간이 지난 경우는 초기화할 수 없도록 예외처리한다.
    • 새로운 비밀번호는 인코딩해서 데이터베이스에 저장한다.
<hide/>
@Override
public void resetPassword(String uuid, ResetPasswordInput input) {

    Optional<Member> optionalMember = memberRepository.findByResetPasswordKey(uuid);
    if (!optionalMember.isPresent()) {
        throw new MemberException(RESET_PASSWORD_KEY_NOT_EXIST);
    }

    if (!input.getNewPassword().equals(input.getConfirmNewPassword())) {
        throw new MemberException(MemberErrorCode.CONFIRM_PASSWORD);
    }

    Member member = optionalMember.get();
    if (member.getResetPasswordLimitDt().isBefore(LocalDateTime.now())) {
        throw new MemberException(RESET_PASSWORD_KEY_EXPIRED);
    }

    validatePassword(input.getNewPassword());
    String encPassword = bCryptPasswordEncoder.encode(input.getNewPassword());
    member.setPassword(encPassword);
    memberRepository.save(member);

}

 

 

  • ctrl
<hide/>
@PostMapping("/password/email/phone/sending")
@ApiOperation(value = "비밀번호 초기화 API", notes = "이메일 인증을 완료하면 새롭게 비밀번호를 설정 가능하다.")
public ResponseEntity<?> resetPassword(HttpServletRequest request, @ApiParam(value = "새로운 비밀번호를 입력") @RequestBody ResetPasswordInput input){
    String uuid = request.getParameter("id");
    memberService.resetPassword(uuid, input);
    String message = "비밀번호 초기화가 완료됐습니다.";
    return new ResponseEntity(message, HttpStatus.OK);
}

 

 

  • test
<hide/>

@Test
@DisplayName("회원 비밀번호 초기화")
void resetPassword() throws Exception {

    // given
    ResetPasswordInput input = ResetPasswordInput.builder().newPassword("abc123!@")
        .confirmNewPassword("abc123!@").build();
    String inputToJson = mapper.writeValueAsString(input);

    // when
    String uuid = UUID.randomUUID().toString();
    mockMvc.perform(MockMvcRequestBuilders.post("/api/password/email/phone/sending?id=" + uuid)
            .contentType(MediaType.APPLICATION_JSON).content(inputToJson))
        .andExpect(status().isOk()).andDo(print());
    ArgumentCaptor<ResetPasswordInput> captor = ArgumentCaptor.forClass(
        ResetPasswordInput.class);

    // then
    Mockito.verify(memberServiceImpl, times(1)).resetPassword(anyString(), captor.capture());
    assertEquals(input.getNewPassword(), captor.getValue().getNewPassword());

}

 

 

<hide/>

@Test
@DisplayName("비밀번호 초기화 - 성공")
void resetPassword() {

    // given
    ResetPasswordInput input = ResetPasswordInput.builder().newPassword("abc123!@")
        .confirmNewPassword("abc123!@").build();

    // when
    String uuid = UUID.randomUUID().toString();
    Member member = Member.builder().email("egg@naver.com").resetPasswordKey(uuid)
        .resetPasswordLimitDt(LocalDateTime.now().plusDays(1)).status(MemberStatus.ING).build();
    given(memberRepository.findByResetPasswordKey(anyString())).willReturn(Optional.of(member));

    // then
    memberService.resetPassword(uuid, input);
}


@Test
@DisplayName("비밀번호 초기화 실패 - (1) uuid 오류")
void resetPassword_fail_uuid() {

    // given
    ResetPasswordInput input = ResetPasswordInput.builder().newPassword("abc123!@")
        .confirmNewPassword("abc123!@").build();

    // when
    String uuid = UUID.randomUUID().toString();
    given(memberRepository.findByResetPasswordKey(anyString())).willReturn(Optional.empty());

    // then
    MemberException exception = assertThrows(MemberException.class,
        () -> memberService.resetPassword(uuid, input));
    assertEquals(exception.getErrorCode(), RESET_PASSWORD_KEY_NOT_EXIST);
}


@Test
@DisplayName("비밀번호 초기화 실패 - (2) 비밀번호 확인 불일치")
void resetPassword_fail_password_not_match() {

    // given
    ResetPasswordInput input = ResetPasswordInput.builder().newPassword("abc123!@")
        .confirmNewPassword("abc123!@#$%").build();

    // when
    String uuid = UUID.randomUUID().toString();
    Member member = Member.builder().email("egg@naver.com").resetPasswordKey(uuid)
        .resetPasswordLimitDt(LocalDateTime.now().plusDays(1)).status(MemberStatus.ING).build();
    given(memberRepository.findByResetPasswordKey(anyString())).willReturn(Optional.of(member));

    // then
    MemberException exception = assertThrows(MemberException.class,
        () -> memberService.resetPassword(uuid, input));
    assertEquals(exception.getErrorCode(), CONFIRM_PASSWORD);
}


@Test
@DisplayName("비밀번호 초기화 실패 - (3) 초기화 기간 만료")
void resetPassword_fail_resetDt_expired() {

    // given
    ResetPasswordInput input = ResetPasswordInput.builder().newPassword("abc123!@")
        .confirmNewPassword("abc123!@").build();

    // when
    String uuid = UUID.randomUUID().toString();
    Member member = Member.builder().email("egg@naver.com").resetPasswordKey(uuid)
        .resetPasswordLimitDt(LocalDateTime.now()).status(MemberStatus.ING).build();
    given(memberRepository.findByResetPasswordKey(anyString())).willReturn(Optional.of(member));

    // then
    MemberException exception = assertThrows(MemberException.class,
        () -> memberService.resetPassword(uuid, input));
    assertEquals(exception.getErrorCode(), RESET_PASSWORD_KEY_EXPIRED);
}

 

 

 

'Spring Projcect > [팀플] In & Out 가계부' 카테고리의 다른 글

회원 유효성 검증  (0) 2022.11.10
회원 수정 - 이미지 업로드 API  (0) 2022.11.01
회원 탈퇴 API  (0) 2022.10.30
회원 이메일 인증 API  (0) 2022.10.28
회원 가입 API  (0) 2022.10.27