[Spring] 회원가입 기능 리팩토링, SJ Coding Helper 프로젝트 리팩토링 (5)

TaesunPark·2023년 1월 28일
0

회원가입 리팩토링

회원가입 플로우

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";
    }

기존 회원가입 컨트롤러 문제점

  1. 테스트 코드가 없어서 리펙토링을 해도 비효율적으로 검증을 해야 한다.
  2. 요청 바디 값이 DTO가 아닌 map으로 정의되어 있어서 어떤 값을 줘야할 지 직관적으로 알 수 없다.
  3. return 값으로 String만 넘겨주기 때문에 클라이언트가 불친절하다고 느낄 수 있다.
  4. 컨트롤러 하나 메소드에서 여러 개 작업을 한다. 컨트롤러의 한 메소드에 대한 책임이 많다.
  5. URI가 restful하지 않다.

문제점 해결 방안

  1. 테스트 코드를 만들어준다.
  2. 요청 DTO를 만들어준다.
  3. 응답 DTO를 만들어준다.
  4. 하나의 서비스만 호출함으로써 컨트롤러에 대한 책임을 명확하게 해준다.
  5. restful하지 않은 URI는 추후에 리펙토링 할 예정이다.

문제점 실행하기.

1.1 이메일 보내기 및 검증하기에 대한 회원가입 컨트롤러 테스트 코드 만들기

@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() {

    }

}

1.2 회원가입 컨트롤러에 대한 테스트 코드 만들기 [리펙토링 전]


@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를 만들어주겠다.

1.3 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;
    }

}

1.4 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;
    }
}

1.5 이메일 중복 확인 컨트롤러 수정

		@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));
    }

1.6 이메일 중복 확인 서비스 수정

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;
    }
}

1.7 이메일 중복 확인 서비스 테스트 추가

@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);
    }
}

1.8 이메일 중복 확인 컨트롤러 코드 수정

		@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));
    }

1.9 회원가입 컨트롤러 코드 수정

		@PostMapping("/completeUserSignup")
    public ResponseEntity<SuccessResponse<UserInfoResponse>> completeUserSignup(@RequestBody UserInfoRequest userInfoRequest) {
        return SuccessResponse.success(SuccessCode.SIGNUP_SUCCESS, userService.signUp(userInfoRequest));
    }

1.10 회원가입 서비스 코드 수정

		@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, "회원가입 성공하였습니다.");
    }

1.11 회원카입 컨트롤러 전체 코드

@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));
    }

}

1. 12 회원가입 컨트롤러 테스트 전체 코드 및 결과

@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));
    }

}

고민한 점

  1. UserService에 너무 많은 책임을 담당해서 User에 대한 정보가 있는 기능들은 UserCheckService를 만들어줌으로써 책임을 분리해줬다.

  2. 이메일 중복 확인 하는 컨트롤러에서 클라이언트에게 전달해 줄 응답 값을 전해주는 기능을 만들어줌으로써 컨트롤러와 서비스의 책임을 확실히 해줬다.

    		@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));
        }
  1. 회원 가입을 완료할 때 중복 이메일, 중복 학번을 고려함으로써 중복 회원이 나타나지 않게끔 설계를 했다. 뿐만 아니라 중복 이메일 확인 메소드에 대한 재사용을 고려해줬다.
  2. 예외 처리에 맞는 HTTP 상태 코드를 고려해주었다.
  3. 회원 가입에 대한 플로우를 다시 생각해줬다.

다음할 일

회원가입 리펙토링을 완료했으니 이제 로그인에 대한 리펙토링을 진행하겠다.

0개의 댓글