Skip to content

Commit

Permalink
Merge pull request #13 from f-lab-edu/feature/9-check-email-code
Browse files Browse the repository at this point in the history
[#9] 인증번호 확인 API 구현
  • Loading branch information
princenim authored Apr 1, 2024
2 parents c128094 + 875e425 commit 9a2458b
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.kboticketing.kboticketing.dto.EmailRequestDto;
import com.kboticketing.kboticketing.dto.UserDto;
import com.kboticketing.kboticketing.dto.VerificationCodeDto;
import com.kboticketing.kboticketing.service.UserService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
Expand All @@ -27,5 +28,10 @@ public void signUp(@RequestBody @Valid UserDto userDto) {
public void sendVerificationCode(@RequestBody @Valid EmailRequestDto emailRequestDto) {
userService.sendVerificationCode(emailRequestDto);
}

@PostMapping("verification-code-validation")
public void checkVerificationCode(@RequestBody @Valid VerificationCodeDto verificationCodeDto) {
userService.checkVerificationCode(verificationCodeDto);
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.kboticketing.kboticketing.dto;

import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

/**
* @author hazel
*/
@Getter
@RequiredArgsConstructor
public class VerificationCodeDto {

@NotBlank(message = "이메일을 입력해주세요.")
@Email(message = "이메일 형식이 아닙니다.")
private final String email;

@NotBlank(message = "인증번호를 입력해주세요.")
private final String verificationCode;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
import com.kboticketing.kboticketing.domain.User;
import com.kboticketing.kboticketing.dto.EmailRequestDto;
import com.kboticketing.kboticketing.dto.UserDto;
import com.kboticketing.kboticketing.dto.VerificationCodeDto;
import com.kboticketing.kboticketing.utils.EmailUtils;
import com.kboticketing.kboticketing.utils.exception.CustomException;
import com.kboticketing.kboticketing.utils.exception.ErrorCode;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -31,7 +33,10 @@ public class UserService {
private final RedisTemplate<String, String> redisTemplate;

public void signUp(UserDto userDto) {
//todo 인증번호 확인 로직 -> 인증번호 API 작업 후 작업 예정
Boolean hasKey = redisTemplate.hasKey(userDto.getEmail());
if (Boolean.FALSE.equals(hasKey)) {
throw new CustomException(ErrorCode.REQUEST_VERIFICATION_FIRST);
}

if (!userDto.getPassword()
.equals(userDto.getConfirmedPassword())) {
Expand Down Expand Up @@ -62,6 +67,19 @@ public void sendVerificationCode(EmailRequestDto emailRequestDto) {

emailUtil.sendEmail(verificationCode, emailRequestDto.getEmail());
}

public void checkVerificationCode(VerificationCodeDto verificationCodeDto) {
Boolean hasKey = redisTemplate.hasKey(verificationCodeDto.getEmail());
if (Boolean.FALSE.equals(hasKey)) {
throw new CustomException(ErrorCode.REQUEST_VERIFICATION_FIRST);
}

String storedVerificationCode = redisTemplate.opsForValue()
.get(verificationCodeDto.getEmail());
if (!Objects.equals(verificationCodeDto.getVerificationCode(), storedVerificationCode)) {
throw new CustomException(ErrorCode.WRONG_VERIFICATION_CODE);
}
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ public enum ErrorCode {
PASSWORD_MISMATCH(HttpStatus.BAD_REQUEST, "두 비밀번호가 일치하지 않습니다."),
EMAIL_ALREADY_EXISTS(HttpStatus.BAD_REQUEST, "이미 존재하는 이메일입니다."),
FREQUENT_VERIFICATION_REQUEST(HttpStatus.BAD_REQUEST, "잦은 인증번호 요청은 불가능합니다."),
REQUEST_VERIFICATION_FIRST(HttpStatus.BAD_REQUEST, "인증을 먼저 진행해주세요."),
WRONG_VERIFICATION_CODE(HttpStatus.BAD_REQUEST, "인증번호가 다릅니다."),

/* 500 INTERNAL_SERVER_ERROR : 서버 오류 */
FAIL_SEND_EMAIL(HttpStatus.INTERNAL_SERVER_ERROR, "이메일 전송에 실패하였습니다.");

private final HttpStatus httpStatus;
private final String message;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kboticketing.kboticketing.dto.EmailRequestDto;
import com.kboticketing.kboticketing.dto.UserDto;
import com.kboticketing.kboticketing.dto.VerificationCodeDto;
import com.kboticketing.kboticketing.service.UserService;
import com.kboticketing.kboticketing.utils.exception.CustomException;
import com.kboticketing.kboticketing.utils.exception.ErrorCode;
Expand Down Expand Up @@ -112,7 +113,7 @@ void sendVerificationEmailInputTest() throws Exception {
}

@Test
@DisplayName("[FAIL] 이메일 유효성 검증 태스트")
@DisplayName("[FAIL] 이메일 유효성 검증 테스트")
void sendVerificationEmailValidTest() throws Exception {

//given
Expand All @@ -125,4 +126,37 @@ void sendVerificationEmailValidTest() throws Exception {
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isBadRequest());
}

@Test
@DisplayName("[SUCCESS] 인증번호 확인 테스트")
void checkVerificationCodeTest() throws Exception {

//given
VerificationCodeDto verificationCodeDto = new VerificationCodeDto("[email protected]",
"123123");
String json = new ObjectMapper().writeValueAsString(verificationCodeDto);

//when, then
mockMvc.perform(post("/verification-code-validation")
.content(json)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk());
}


@Test
@DisplayName("[FAIL] 인증번호 미입력 테스트")
public void checkVerificationCodeValidationTest() throws Exception {

//given
VerificationCodeDto verificationCodeDto = new VerificationCodeDto("[email protected]",
"");
String json = new ObjectMapper().writeValueAsString(verificationCodeDto);

//when, then
mockMvc.perform(post("/verification-code-validation")
.content(json)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isBadRequest());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.kboticketing.kboticketing.domain.User;
import com.kboticketing.kboticketing.dto.EmailRequestDto;
import com.kboticketing.kboticketing.dto.UserDto;
import com.kboticketing.kboticketing.dto.VerificationCodeDto;
import com.kboticketing.kboticketing.utils.EmailUtils;
import com.kboticketing.kboticketing.utils.enums.Role;
import com.kboticketing.kboticketing.utils.exception.CustomException;
Expand All @@ -18,7 +19,6 @@
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.BDDMockito;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
Expand Down Expand Up @@ -49,6 +49,7 @@ public void signUpSuccessTest() {
// given
UserDto userDto = new UserDto("홍길동", "[email protected]", "123123", "123123", "123123");
given(userMapper.selectByEmail(any())).willReturn(null);
given(redisTemplate.hasKey(anyString())).willReturn(true);

//when, then : 아무런 예외를 던지지 않음.
assertDoesNotThrow(() -> userService.signUp(userDto));
Expand All @@ -60,6 +61,7 @@ public void signUpPasswordMismatchTest() {

//given
UserDto userDto = new UserDto("홍길동", "[email protected]", "123123", "123123", "000000");
given(redisTemplate.hasKey(anyString())).willReturn(true);

// when
CustomException customException = assertThrows(CustomException.class, () -> {
Expand All @@ -77,8 +79,8 @@ public void signUpEmailCheckTest() {
//given
UserDto userDto = new UserDto("홍길동", "[email protected]", "123123", "123123", "123123");
User user = new User("홍길동", "[email protected]", "123123", Role.USER, LocalDateTime.now());
BDDMockito.given(userMapper.selectByEmail(userDto.getEmail()))
.willReturn(user);
given(userMapper.selectByEmail(userDto.getEmail())).willReturn(user);
given(redisTemplate.hasKey(anyString())).willReturn(true);

//when
CustomException customException = assertThrows(CustomException.class, () -> {
Expand Down Expand Up @@ -123,6 +125,43 @@ public void sendVerificationAgainFailTest() {
assertThat(customException.getErrorCode()).isEqualTo(
ErrorCode.FREQUENT_VERIFICATION_REQUEST);
}

@Test
@DisplayName("[SUCCESS] 인증번호 확인 테스트")
public void checkVerificationCodeTest() {

//given
VerificationCodeDto verificationCodeDto = new VerificationCodeDto("[email protected]",
"123456");
given(redisTemplate.hasKey(anyString())).willReturn(true);
given(redisTemplate.opsForValue()).willReturn(valueOperations);
given(redisTemplate.opsForValue()
.get(verificationCodeDto.getEmail())).willReturn("123456");

//when,then
assertDoesNotThrow(() -> userService.checkVerificationCode(verificationCodeDto));
}

@Test
@DisplayName("[FAIL] 인증번호 불일치 테스트")
public void checkVerificationCodeWrongTest() {

//given
VerificationCodeDto verificationCodeDto = new VerificationCodeDto("[email protected]",
"123456");
given(redisTemplate.hasKey(anyString())).willReturn(true);
given(redisTemplate.opsForValue()).willReturn(valueOperations);
given(redisTemplate.opsForValue()
.get(verificationCodeDto.getEmail())).willReturn("999999");

//when
CustomException customException = assertThrows(CustomException.class, () -> {
userService.checkVerificationCode(verificationCodeDto);
});

//then
assertThat(customException.getErrorCode()).isEqualTo(ErrorCode.WRONG_VERIFICATION_CODE);
}
}


Expand Down

0 comments on commit 9a2458b

Please sign in to comment.