1. 학교 이메일 검증
2. 중복 이메일 있는지 확인
3. 중복 학번 있는지 확인
4. 비밀번호, 비밀번호 확인 값 같은지 확인
5. 회원가입 완료
@Slf4j
@RestController
@RequiredArgsConstructor
//@CrossOrigin(origins = "http://localhost:3000", allowCredentials = "true")
@CrossOrigin(origins = Constants.URL , allowCredentials = "true")
public class SignupController {
private final JavaMailSender javaMailSender;
private final UserService userService;
private final ChatbotRoomService chatbotRoomService;
private final EmailService emailService;
@Value("${spring.mail.username}")
private String from;
// 이 메소드는 리펙토링 과정을 거쳤습니다.
@PostMapping("/email")
public ResponseEntity<SuccessResponse<SendEmailResponse>> sendSejongEmail(@RequestBody SendEmailRequest sendEmailRequest, HttpServletRequest request) throws MessagingException {
return SuccessResponse.success(SuccessCode.EMAIL_SUCCESS, emailService.sendSejongEmail(sendEmailRequest, request));
}
// 이 메소드는 리펙토링 과정을 거쳤습니다.
@PostMapping("/checkEmailAuthCode")
public ResponseEntity<SuccessResponse<EmailCodeResponse>> checkEmailAuthCode(@RequestBody EmailCodeRequest emailCodeRequest, HttpServletRequest request) {
return SuccessResponse.success(SuccessCode.EMAIL_CODE_SUCCESS, emailService.checkEmailAuthCode(emailCodeRequest, request));
}
// 여기까지 리펙토링 과정을 거쳤습니다. 아래 코드부터 리펙토링 필요.
@PostMapping("/checkEmailOverlap")
public String checkEmailOverlap(@RequestBody Map<String, String> map) {
if (userService.isOverlapEmail(map.get("email") + "@sju.ac.kr"))
return "denied";
return "accepted";
}
@PostMapping("/completeUserSignup")
public String completeUserSignup(@RequestBody Map<String, String> map) {
//학번 중복 확인
if (userService.isOverlapStudentNumber(map.get("studentNumber"))) {
return "denied";
}
// db에 저장하는 구문
long id = userService.signUp(new UserDTO2(map.get("studentNumber"), map.get("pwd"), map.get("name"), map.get("email")));
System.out.println(id);
chatbotRoomService.create(new ChatbotRoomDTO(id,4L,"C", "0"));
chatbotRoomService.create(new ChatbotRoomDTO(id,4L,"P", "0"));
return "accepted";
}
@WebAppConfiguration
@SpringBootTest
class SignupControllerTest {
@Autowired
private SignupController signupController;
@Autowired
private EmailCertificationDao emailCertificationDao;
@DisplayName("이메일 보내기 컨트롤러 테스트")
@Test
void sendSejongEmail() throws MessagingException {
SendEmailRequest sendEmailRequest = new SendEmailRequest();
sendEmailRequest.setEmail("tovbskvb");
ResponseEntity<SuccessResponse<SendEmailResponse>> result = signupController.sendSejongEmail(sendEmailRequest, null);
assertThat(HttpStatus.OK).isEqualTo(result.getStatusCode());
assertThat(result.getBody().getMessage()).isEqualTo(SuccessCode.EMAIL_SUCCESS.getMessage());
}
@DisplayName("이메일 코드 검증 컨트롤러 테스트")
@Test
void checkEmailAuthCode() {
emailCertificationDao.createCodeCertification("tovbskvb@sju.ac.kr", "123456");
EmailCodeRequest emailCodeRequest = new EmailCodeRequest();
emailCodeRequest.setEmail("tovbskvb@sju.ac.kr");
emailCodeRequest.setAuthCode("123456");
ResponseEntity<SuccessResponse<EmailCodeResponse>> result = signupController.checkEmailAuthCode(emailCodeRequest, null);
assertThat(HttpStatus.OK).isEqualTo(result.getStatusCode());
assertThat(result.getBody().getMessage()).isEqualTo(SuccessCode.EMAIL_CODE_SUCCESS.getMessage());
}
@DisplayName("이메일 코드 검증 실패 컨트롤러 테스트")
@Test
void checkEmailAuthCode_FAIL() {
emailCertificationDao.createCodeCertification("tovbskvb@sju.ac.kr", "123456");
EmailCodeRequest emailCodeRequest = new EmailCodeRequest();
emailCodeRequest.setEmail("tovbskvb@sju.ac.kr");
emailCodeRequest.setAuthCode("123457");
assertThrows(NotFoundException.class,()
-> signupController.checkEmailAuthCode(emailCodeRequest, null)
);
}
@Test
void checkEmailOverlap() {
}
@Test
void completeUserSignup() {
}
}
@WebAppConfiguration
@SpringBootTest
class SignupControllerTest {
@Autowired
private SignupController signupController;
@Autowired
private EmailCertificationDao emailCertificationDao;
@Autowired
private UserService userService;
@Autowired
private UserRepository2 userRepository;
@BeforeEach
void set(){
userRepository.deleteAll();
}
@DisplayName("이메일 보내기 컨트롤러 테스트")
@Test
void sendSejongEmail() throws MessagingException {
SendEmailRequest sendEmailRequest = new SendEmailRequest();
sendEmailRequest.setEmail("tovbskvb");
ResponseEntity<SuccessResponse<SendEmailResponse>> result = signupController.sendSejongEmail(sendEmailRequest, null);
assertThat(HttpStatus.OK).isEqualTo(result.getStatusCode());
assertThat(result.getBody().getMessage()).isEqualTo(SuccessCode.EMAIL_SUCCESS.getMessage());
}
@DisplayName("이메일 코드 검증 컨트롤러 테스트")
@Test
void checkEmailAuthCode() {
emailCertificationDao.createCodeCertification("tovbskvb@sju.ac.kr", "123456");
EmailCodeRequest emailCodeRequest = new EmailCodeRequest();
emailCodeRequest.setEmail("tovbskvb@sju.ac.kr");
emailCodeRequest.setAuthCode("123456");
ResponseEntity<SuccessResponse<EmailCodeResponse>> result = signupController.checkEmailAuthCode(emailCodeRequest, null);
assertThat(HttpStatus.OK).isEqualTo(result.getStatusCode());
assertThat(result.getBody().getMessage()).isEqualTo(SuccessCode.EMAIL_CODE_SUCCESS.getMessage());
}
@DisplayName("이메일 중복 확인 성공 컨트롤러 테스트")
@Test
void checkEmailOverlap() {
HashMap map = new HashMap();
map.put("email", "tovbskvb");
String value = signupController.checkEmailOverlap(map);
assertThat(value).isEqualTo("accepted");
}
@DisplayName("이메일 중복 컨트롤러 테스트, 중복 감지")
@Test
void checkDuplicatedEmailOverlap() {
UserDTO2 userDTO2 = new UserDTO2("17011526", "1234", "박태순", "tovbskvb@sju.ac.kr");
userRepository.save(userDTO2.toEntity());
HashMap map = new HashMap();
map.put("email", "tovbskvb");
String value = signupController.checkEmailOverlap(map);
assertThat(value).isEqualTo("denied");
}
@DisplayName("회원가입 완료 컨트롤러 테스트, 성공")
@Test
void completeUserSignup() {
HashMap map = new HashMap();
map.put("studentNumber", "17011526");
map.put("pwd", "1234");
map.put("name","박태순");
map.put("email","tovbskvb@sju.ac.kr");
String value = signupController.completeUserSignup(map);
assertThat(value).isEqualTo("accepted");
}
@DisplayName("회원가입 완료 컨트롤러 테스트, 실패")
@Test
void completeSignup_FAIL() {
UserDTO2 userDTO2 = new UserDTO2("17011527", "1234", "박태순", "tovbskvb@sju.ac.kr");
User user = new User(userDTO2);
userRepository.save(user);
HashMap map = new HashMap();
map.put("studentNumber", "17011527");
map.put("pwd", "1234");
map.put("name","박태순");
map.put("email","tovbskvb@sju.ac.kr");
String value = signupController.completeUserSignup(map);
assertThat(value).isEqualTo("denied");
}
}
기존 회원가입 컨트롤러에 대한 테스트 코드 작성은 완료했다.
다행히 정상적으로 작동이 되고, sendSejongEmail 메소드와 마찬가지로 요청, 응답 DTO를 만들어주겠다.
EmailCheckRequest
DTO 추가package com.example.testlocal.module.user.application.dto.request;
public class EmailCheckRequest {
private String email;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
EmailCheckResponse
DTO 추가package com.example.testlocal.module.user.application.dto.response;
import lombok.*;
@ToString
@Getter
public class EmailCheckResponse {
private String email;
public EmailCheckResponse(String email){
this.email = email;
}
}
@PostMapping("/checkEmailOverlap")
public ResponseEntity<SuccessResponse<EmailCheckResponse>> checkEmailOverlap(@RequestBody EmailCheckRequest checkEmailRequest) {
String email = checkEmailRequest.getEmail() + "@sju.ac.kr";
Boolean isPresented = userCheckServiceImpl.isOverlapEmail(email);
if (!isPresented){
throw new ConflictException(String.format("이미 존재하는 이메일 (%s) 입니다", checkEmailRequest.getEmail()),
ErrorCode.CONFLICT_EMAIL_EXCEPTION);
}
return SuccessResponse.success(SuccessCode.EMAIL_DUPLICATED_CODE_SUCCESS, new EmailCheckResponse(email));
}
public EmailCheckResponse isOverlapEmail(String email) {
Optional<User> member = userRepository2.findByEmail(email);
if (member.isPresent()) {
return EmailCheckResponse.of(email, true);
}
return EmailCheckResponse.of(email, false);
}
→ 이렇게 코드를 작성해도 되지만 문제점은 너무 느리다. 그래서 있는 지 체크만 해줌으로써 성능 개선을 해줬다.
→ 뿐만 아니라 UserService에서 하는 책임이 너무 많아서 UserCheckService로 UserCheck라는 책임을 따로 분리해서 관리해주었다.
@RequiredArgsConstructor
@Service
public class UserCheckServiceImpl implements UserCheckService {
private final UserRepository2 userRepository;
@Override
public Boolean isOverlapEmail(String email) {
Boolean isPresented = userRepository.existsUserByEmail(email);
if (isPresented){
return false;
}
return true;
}
@Override
public Boolean isOverlapStudentNumber(String studentNumber) {
Boolean isPresented = userRepository.existsUserByStudentNumber(studentNumber);
if (isPresented){
return false;
}
return true;
}
}
@WebAppConfiguration
@SpringBootTest
class UserCheckServiceTest {
@Autowired
private UserCheckServiceImpl userCheckService;
@Autowired
private UserRepository2 userRepository;
@BeforeEach
public void init(){
userRepository.deleteAll();
}
@DisplayName("중복 이메일 테스트 성공")
@Test
public void isOverlapEmail(){
Boolean isOverlap = userCheckService.isOverlapEmail("tovbskvb@daum.net");
assertThat(isOverlap).isEqualTo(true);
}
@DisplayName("중복 이메일 테스트 실패")
@Test
public void isOverlapEmail_FAIL(){
UserDto userDTO = new UserDto("17011526", "1234", "박태순", "tovbskvb@sju.ac.kr");
User user = User.builder().email(userDTO.getEmail()).roleType(RoleType.USER).name(userDTO.getName()).studentNumber(userDTO.getStudentNumber()).password(userDTO.getPassword()).build();
userRepository.save(user);
Boolean isOverlap = userCheckService.isOverlapEmail("tovbskvb@sju.ac.kr");
assertThat(isOverlap).isEqualTo(false);
}
}
@DisplayName("이메일 중복 확인 성공 컨트롤러 테스트")
@Test
void checkEmailOverlap() {
EmailCheckRequest checkEmailRequest = new EmailCheckRequest();
checkEmailRequest.setEmail("tovbskvb");
ResponseEntity<SuccessResponse<EmailCheckResponse>> result = signupController.checkEmailOverlap(checkEmailRequest);
assertThat(HttpStatus.OK).isEqualTo(result.getStatusCode());
assertThat(result.getBody().getMessage()).isEqualTo(SuccessCode.EMAIL_DUPLICATED_CODE_SUCCESS.getMessage());
}
@DisplayName("이메일 중복 컨트롤러 테스트, 중복 감지")
@Test
void checkDuplicatedEmailOverlap() {
UserDto userDTO = new UserDto("17011526", "1234", "박태순", "tovbskvb@sju.ac.kr");
User user = User.builder().email(userDTO.getEmail()).roleType(RoleType.USER).name(userDTO.getName()).studentNumber(userDTO.getStudentNumber()).password(userDTO.getPassword()).build();
userRepository.save(user);
EmailCheckRequest checkEmailRequest = new EmailCheckRequest();
checkEmailRequest.setEmail("tovbskvb");
assertThrows(ConflictException.class, () -> signupController.checkEmailOverlap(checkEmailRequest));
}
@PostMapping("/completeUserSignup")
public ResponseEntity<SuccessResponse<UserInfoResponse>> completeUserSignup(@RequestBody UserInfoRequest userInfoRequest) {
return SuccessResponse.success(SuccessCode.SIGNUP_SUCCESS, userService.signUp(userInfoRequest));
}
@Transactional
public UserInfoResponse signUp(UserInfoRequest userInfoRequest) {
// 비밀번호 일치 확인
if (!userInfoRequest.getVerifedPwd().equals(userInfoRequest.getPwd())){
throw new UnauthorizedException(String.format("비밀번호와 비밀번호 확인 값이 다릅니다."), ErrorCode.UNAUTHORIZED_EXCEPTION);
}
// pw를 암호화하는 과정
userInfoRequest.setPwd(passwordEncoder.encode(userInfoRequest.getPwd()));
// 이메일 중복 확인
Boolean isOverlapEmail = userCheckServiceImpl.isOverlapEmail(userInfoRequest.getEmail());
if (!isOverlapEmail){
throw new ConflictException(String.format("이미 존재하는 이메일 (%s) 입니다", userInfoRequest.getEmail()),
ErrorCode.CONFLICT_EMAIL_EXCEPTION);
}
// 학번 중복 확인
Boolean isOverlapStudentNumber = userCheckServiceImpl.isOverlapStudentNumber(userInfoRequest.getStudentNumber());
if (!isOverlapStudentNumber){
throw new ConflictException(String.format("이미 존재하는 학번 (%s) 입니다", userInfoRequest.getStudentNumber()),
ErrorCode.CONFLICT_STUDENT_NUMBER_EXCEPTION);
}
return UserInfoResponse.of(userInfoRequest.getStudentNumber(), true, "회원가입 성공하였습니다.");
}
@Slf4j
@RestController
@RequiredArgsConstructor
//@CrossOrigin(origins = "http://localhost:3000", allowCredentials = "true")
@CrossOrigin(origins = Constants.URL , allowCredentials = "true")
public class SignupController {
private final JavaMailSender javaMailSender;
private final UserService userService;
private final ChatbotRoomService chatbotRoomService;
private final EmailService emailService;
private final UserCheckService userCheckServiceImpl;
@Value("${spring.mail.username}")
private String from;
@PostMapping("/email")
public ResponseEntity<SuccessResponse<SendEmailResponse>> sendSejongEmail(@RequestBody SendEmailRequest sendEmailRequest, HttpServletRequest request) throws MessagingException {
return SuccessResponse.success(SuccessCode.EMAIL_SUCCESS, emailService.sendSejongEmail(sendEmailRequest, request));
}
@PostMapping("/emailAuthCode")
public ResponseEntity<SuccessResponse<EmailCodeResponse>> checkEmailAuthCode(@RequestBody EmailCodeRequest emailCodeRequest, HttpServletRequest request) {
return SuccessResponse.success(SuccessCode.EMAIL_CODE_SUCCESS, emailService.checkEmailAuthCode(emailCodeRequest, request));
}
@PostMapping("/checkEmailOverlap")
public ResponseEntity<SuccessResponse<EmailCheckResponse>> checkEmailOverlap(@RequestBody EmailCheckRequest checkEmailRequest) {
String email = checkEmailRequest.getEmail() + "@sju.ac.kr";
Boolean isPresented = userCheckServiceImpl.isOverlapEmail(email);
if (!isPresented){
throw new ConflictException(String.format("이미 존재하는 이메일 (%s) 입니다", checkEmailRequest.getEmail()),
ErrorCode.CONFLICT_EMAIL_EXCEPTION);
}
return SuccessResponse.success(SuccessCode.EMAIL_DUPLICATED_CODE_SUCCESS, new EmailCheckResponse(email));
}
@PostMapping("/completeUserSignup")
public ResponseEntity<SuccessResponse<UserInfoResponse>> completeUserSignup(@RequestBody UserInfoRequest userInfoRequest) {
return SuccessResponse.success(SuccessCode.SIGNUP_SUCCESS, userService.signUp(userInfoRequest));
}
}
@WebAppConfiguration
@SpringBootTest
class SignupControllerTest {
@Autowired
private SignupController signupController;
@Autowired
private EmailCertificationDao emailCertificationDao;
@Autowired
private UserRepository2 userRepository;
@BeforeEach
void set(){
userRepository.deleteAll();
}
@DisplayName("이메일 보내기 컨트롤러 테스트")
@Test
void sendSejongEmail() throws MessagingException {
SendEmailRequest sendEmailRequest = new SendEmailRequest();
sendEmailRequest.setEmail("tovbskvb");
ResponseEntity<SuccessResponse<SendEmailResponse>> result = signupController.sendSejongEmail(sendEmailRequest, null);
assertThat(HttpStatus.OK).isEqualTo(result.getStatusCode());
assertThat(result.getBody().getMessage()).isEqualTo(SuccessCode.EMAIL_SUCCESS.getMessage());
}
@DisplayName("이메일 코드 검증 컨트롤러 테스트")
@Test
void checkEmailAuthCode() {
emailCertificationDao.createCodeCertification("tovbskvb@sju.ac.kr", "123456");
EmailCodeRequest emailCodeRequest = new EmailCodeRequest();
emailCodeRequest.setEmail("tovbskvb@sju.ac.kr");
emailCodeRequest.setAuthCode("123456");
ResponseEntity<SuccessResponse<EmailCodeResponse>> result = signupController.checkEmailAuthCode(emailCodeRequest, null);
assertThat(HttpStatus.OK).isEqualTo(result.getStatusCode());
assertThat(result.getBody().getMessage()).isEqualTo(SuccessCode.EMAIL_CODE_SUCCESS.getMessage());
}
@DisplayName("이메일 코드 검증 실패 컨트롤러 테스트")
@Test
void checkEmailAuthCode_FAIL() {
emailCertificationDao.createCodeCertification("tovbskvb@sju.ac.kr", "123456");
EmailCodeRequest emailCodeRequest = new EmailCodeRequest();
emailCodeRequest.setEmail("tovbskvb@sju.ac.kr");
emailCodeRequest.setAuthCode("123457");
assertThrows(NotFoundException.class,()
-> signupController.checkEmailAuthCode(emailCodeRequest, null)
);
}
@DisplayName("이메일 중복 확인 성공 컨트롤러 테스트")
@Test
void checkEmailOverlap() {
EmailCheckRequest checkEmailRequest = new EmailCheckRequest();
checkEmailRequest.setEmail("tovbskvb");
ResponseEntity<SuccessResponse<EmailCheckResponse>> result = signupController.checkEmailOverlap(checkEmailRequest);
assertThat(HttpStatus.OK).isEqualTo(result.getStatusCode());
assertThat(result.getBody().getMessage()).isEqualTo(SuccessCode.EMAIL_DUPLICATED_CODE_SUCCESS.getMessage());
}
@DisplayName("이메일 중복 컨트롤러 테스트, 중복 감지")
@Test
void checkDuplicatedEmailOverlap() {
UserDto userDTO = new UserDto("17011526", "1234", "박태순", "tovbskvb@sju.ac.kr");
User user = User.builder().email(userDTO.getEmail()).roleType(RoleType.USER).name(userDTO.getName()).studentNumber(userDTO.getStudentNumber()).password(userDTO.getPassword()).build();
userRepository.save(user);
EmailCheckRequest checkEmailRequest = new EmailCheckRequest();
checkEmailRequest.setEmail("tovbskvb");
assertThrows(ConflictException.class, () -> signupController.checkEmailOverlap(checkEmailRequest));
}
@DisplayName("회원가입 완료 컨트롤러 테스트, 성공")
@Test
void completeUserSignup() {
UserInfoRequest userInfoRequest = new UserInfoRequest();
userInfoRequest.setStudentNumber("17011526");
userInfoRequest.setEmail("tovbskvb@sju.ac.kr");
userInfoRequest.setName("박태순");
userInfoRequest.setPwd("1234");
userInfoRequest.setVerifedPwd("1234");
ResponseEntity<SuccessResponse<UserInfoResponse>> result = signupController.completeUserSignup(userInfoRequest);
assertThat(HttpStatus.OK).isEqualTo(result.getStatusCode());
assertThat(result.getBody().getMessage()).isEqualTo(SuccessCode.SIGNUP_SUCCESS.getMessage());
}
@DisplayName("회원가입 완료 컨트롤러 테스트, 실패, 이메일 중복")
@Test
void 회원가입_실패_이메일_중복() {
UserDto userDTO = new UserDto("17011526", "1234", "박태순", "tovbskvb@sju.ac.kr");
User user = User.builder().email(userDTO.getEmail()).roleType(RoleType.USER).name(userDTO.getName()).studentNumber(userDTO.getStudentNumber()).password(userDTO.getPassword()).build();
userRepository.save(user);
UserInfoRequest userInfoRequest = new UserInfoRequest();
userInfoRequest.setStudentNumber("17011527");
userInfoRequest.setEmail("tovbskvb@sju.ac.kr");
userInfoRequest.setName("박태순");
userInfoRequest.setPwd("1234");
userInfoRequest.setVerifedPwd("1234");
assertThrows(ConflictException.class, () -> signupController.completeUserSignup(userInfoRequest));
}
@DisplayName("회원가입 완료 컨트롤러 테스트, 실패, 비밀번호확인 잘 못 입력")
@Test
void 회원가입_실패_비밀번호확인_잘_못_입력() {
UserDto userDTO = new UserDto("17011526", "1234", "박태순", "tovbskvb@sju.ac.kr");
User user = User.builder().email(userDTO.getEmail()).roleType(RoleType.USER).name(userDTO.getName()).studentNumber(userDTO.getStudentNumber()).password(userDTO.getPassword()).build();
userRepository.save(user);
UserInfoRequest userInfoRequest = new UserInfoRequest();
userInfoRequest.setStudentNumber("17011527");
userInfoRequest.setEmail("tovbskvb1@sju.ac.kr");
userInfoRequest.setName("박태순");
userInfoRequest.setPwd("1234");
userInfoRequest.setVerifedPwd("1235");
assertThrows(UnauthorizedException.class, () -> signupController.completeUserSignup(userInfoRequest));
}
@DisplayName("회원가입 완료 컨트롤러 테스트, 실패, 학번 중복")
@Test
void 회원가입_실패_학번_중복() {
UserDto userDTO = new UserDto("17011526", "1234", "박태순", "tovbskvb@sju.ac.kr");
User user = User.builder().email(userDTO.getEmail()).roleType(RoleType.USER).name(userDTO.getName()).studentNumber(userDTO.getStudentNumber()).password(userDTO.getPassword()).build();
userRepository.save(user);
UserInfoRequest userInfoRequest = new UserInfoRequest();
userInfoRequest.setStudentNumber("17011526");
userInfoRequest.setEmail("tovbskvb1@sju.ac.kr");
userInfoRequest.setName("박태순");
userInfoRequest.setPwd("1234");
userInfoRequest.setVerifedPwd("1234");
assertThrows(ConflictException.class, () -> signupController.completeUserSignup(userInfoRequest));
}
}
UserService에 너무 많은 책임을 담당해서 User에 대한 정보가 있는 기능들은 UserCheckService를 만들어줌으로써 책임을 분리해줬다.
이메일 중복 확인 하는 컨트롤러에서 클라이언트에게 전달해 줄 응답 값을 전해주는 기능을 만들어줌으로써 컨트롤러와 서비스의 책임을 확실히 해줬다.
@PostMapping("/checkEmailOverlap")
public ResponseEntity<SuccessResponse<EmailCheckResponse>> checkEmailOverlap(@RequestBody EmailCheckRequest checkEmailRequest) {
String email = checkEmailRequest.getEmail() + "@sju.ac.kr";
Boolean isPresented = userCheckServiceImpl.isOverlapEmail(email);
return SuccessResponse.success(SuccessCode.EMAIL_DUPLICATED_CODE_SUCCESS, EmailCheckResponse.of(email, isPresented));
}
회원가입 리펙토링을 완료했으니 이제 로그인에 대한 리펙토링을 진행하겠다.