Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature/#98 User 단위 및 통합 테스트코드 구현 #101

Merged
merged 12 commits into from
Nov 16, 2024

Conversation

LeeHanEum
Copy link
Member

Summary

close #98

User, Auth 도메인에 대하여 단위 및 통합 테스트 코드를 작성하였습니다.

Tasks

  • UserDomainTest 단위 테스트 코드 작성
  • FakeUserRepository 객체 구현
  • 통합 및 중형 테스트를 위한 TestContainer 구현
  • UserServiceTest / AuthServiceTest 통합 테스트 코드 작성

To Reviewer

이 PR에서는 Mockito 라이브러리를 사용하지 않고, Fake 구현체와 TestContainer를 활용한 테스트 방식을 도입했습니다.
이를 통해 다음과 같은 이점을 얻을 수 있습니다:

현실성 높은 테스트 환경 제공
Fake와 TestContainer를 활용하면 실제 환경에 더 가까운 테스트가 가능해져, 과도하게 Mock된 동작으로 인한 오탐(false positive)이나 누락(false negative)을 줄일 수 있습니다.

테스트 시간 단축
Fake 구현체는 외부 리소스 의존성을 최소화하여 테스트 실행 속도를 크게 개선합니다. 이를 통해 빠른 피드백 루프가 가능해지고, 개발 생산성이 향상됩니다.

테스트 유지보수성 향상
Mockito와 같은 서드파티 라이브러리 의존도를 낮춤으로써 테스트 코드가 단순화되고, 특히 장기 프로젝트에서 발생할 수 있는 의존성 관련 문제를 최소화할 수 있습니다.

Screenshot

스크린샷 2024-11-16 오후 2 11 05 스크린샷 2024-11-16 오후 2 11 25

@LeeHanEum LeeHanEum added ✨feature create new feature dependencies Pull requests that update a dependency file labels Nov 16, 2024
@LeeHanEum LeeHanEum requested a review from a team November 16, 2024 05:12
@LeeHanEum LeeHanEum self-assigned this Nov 16, 2024
@LeeHanEum LeeHanEum linked an issue Nov 16, 2024 that may be closed by this pull request
1 task
Copy link
Contributor

coderabbitai bot commented Nov 16, 2024

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

이번 변경 사항은 여러 파일에서의 수정 및 추가 작업을 포함합니다. .coderabbit.yaml 파일이 삭제되어 시스템의 설정이 제거되었으며, build.gradle 파일에서는 JAR 생성 가능성을 활성화하고 여러 의존성을 추가했습니다. 또한, 여러 클래스에 Lombok의 @Builder 주석이 추가되어 인스턴스 생성 방식이 개선되었습니다. 테스트 파일들이 새로 추가되어 사용자 및 인증 서비스의 기능을 검증하는 유닛 테스트가 포함되었습니다.

Changes

파일 경로 변경 요약
.coderabbit.yaml 삭제: 설정 파일 제거
aics-api/build.gradle JAR 생성 활성화, 여러 testFixturesImplementation 의존성 추가
aics-api/src/main/java/kgu/developers/api/auth/application/AuthService.java @Builder 주석 추가
aics-api/src/main/java/kgu/developers/api/auth/presentation/AuthController.java @Builder 주석 추가
aics-api/src/main/java/kgu/developers/api/auth/presentation/request/LoginRequest.java @Builder 주석 추가
aics-api/src/main/java/kgu/developers/api/user/application/UserService.java @Builder 주석 추가
aics-api/src/main/java/kgu/developers/api/user/presentation/request/UserCreateRequest.java @Builder 주석 추가
aics-api/src/main/java/kgu/developers/api/user/presentation/request/UserUpdateRequest.java @Builder 주석 추가
aics-api/src/testFixtures/java/auth/application/AuthServiceTest.java 새 유닛 테스트 클래스 추가
aics-api/src/testFixtures/java/auth/presentation/AuthControllerTest.java 새 유닛 테스트 클래스 추가
aics-api/src/testFixtures/java/mock/TestContainer.java 새 테스트 컨테이너 클래스 추가
aics-api/src/testFixtures/java/user/application/UserServiceTest.java 새 유닛 테스트 클래스 추가
aics-api/src/testFixtures/java/user/presentation/UserControllerTest.java 새 클래스 추가 (비어 있음)
aics-common/src/main/java/kgu/developers/common/auth/jwt/JwtProperties.java 생성자 추가
aics-common/src/main/java/kgu/developers/common/auth/jwt/TokenProvider.java @Builder 주석 추가
aics-domain/build.gradle testFixturesImplementation 의존성 추가
aics-domain/src/main/java/kgu/developers/domain/user/domain/DeptCode.java 열거형 이름 변경 및 메서드 이름 수정
aics-domain/src/main/java/kgu/developers/domain/user/domain/User.java 메서드 및 예외 클래스 이름 변경
aics-domain/src/main/java/kgu/developers/domain/user/exception/DepartmentCodeNotValidException.java 삭제: 예외 클래스 제거
aics-domain/src/main/java/kgu/developers/domain/user/exception/DeptCodeNotValidException.java 새 예외 클래스 추가
aics-domain/src/main/java/kgu/developers/domain/user/exception/UserDomainExceptionCode.java 열거형 상수 이름 변경
aics-domain/src/testFixtures/java/mock/FakeUserRepository.java 새 모의 사용자 저장소 클래스 추가
aics-domain/src/testFixtures/java/user/application/UserServiceTest.java 새 클래스 추가 (비어 있음)
aics-domain/src/testFixtures/java/user/domain/UserDomainTest.java 새 유닛 테스트 클래스 추가
build.gradle java-test-fixtures 플러그인 추가 및 의존성 재구성

Assessment against linked issues

Objective Addressed Explanation
FakeUserRepository를 이용한 User TestCode 작성 (#98)
FakeUserRepository를 이용한 User TestCode 작성 (#98)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

🧹 Outside diff range and nitpick comments (31)
aics-domain/src/main/java/kgu/developers/domain/user/exception/DeptCodeNotValidException.java (1)

7-11: 예외 메시지 추가를 고려해보세요.

현재 구현은 기본적인 예외 코드만 전달하고 있습니다. 문제가 발생한 학과 코드 값을 포함하는 상세 메시지를 추가하면 디버깅에 도움이 될 것 같습니다.

다음과 같이 수정하는 것을 제안드립니다:

 public class DeptCodeNotValidException extends CustomException {
+    public DeptCodeNotValidException(String deptCode) {
+        super(DEPT_CODE_NOT_VALID, String.format("유효하지 않은 학과 코드입니다: %s", deptCode));
+    }
-    public DeptCodeNotValidException() {
-        super(DEPT_CODE_NOT_VALID);
-    }
 }
aics-domain/build.gradle (1)

14-16: 테스트 픽스처 구현이 적절히 설정되었습니다.

테스트 픽스처 의존성이 메인 구현 의존성과 일치하도록 잘 구성되어 있습니다. 이는 PR의 목표인 FakeRepository를 활용한 테스트 구현을 위한 좋은 기반이 될 것입니다.

다음 사항들을 고려해보시면 좋을 것 같습니다:

  1. 테스트 픽스처의 재사용성을 높이기 위해 문서화를 추가하는 것을 고려해보세요.
  2. 테스트 픽스처가 실제 구현체와 동일한 동작을 보장하도록 계약 테스트(Contract Test)의 구현을 고려해보세요.
aics-api/src/main/java/kgu/developers/api/auth/presentation/request/LoginRequest.java (1)

Line range hint 11-18: 요청 DTO에 대한 유효성 검증 테스트 추가를 제안드립니다.

현재 @NotNull 검증이 적용되어 있는데, 이에 대한 테스트 케이스를 추가하면 좋을 것 같습니다. 특히 다음과 같은 케이스들을 고려해보시면 좋겠습니다:

  • userId가 null인 경우
  • password가 null인 경우
  • 모든 필드가 정상적으로 입력된 경우

테스트 코드 작성에 도움이 필요하시다면 제가 예시 코드를 제공해드릴 수 있습니다.

aics-common/src/main/java/kgu/developers/common/auth/jwt/JwtProperties.java (2)

6-7: Lombok 어노테이션 사용 최적화 필요

@AllArgsConstructor를 import 했지만 사용하지 않고 있습니다. 불필요한 import는 제거하는 것이 좋습니다.

-import lombok.AllArgsConstructor;

Line range hint 1-22: 보안 관련 속성 검증 로직 추가 필요

JWT 관련 중요 설정을 다루는 클래스이므로, 속성값 검증 로직을 추가하는 것이 좋습니다.

다음과 같은 검증 로직 추가를 제안드립니다:

@PostConstruct
public void validate() {
    if (issuer == null || issuer.trim().isEmpty()) {
        throw new IllegalStateException("JWT issuer must not be null or empty");
    }
    if (secretKey == null || secretKey.length() < 32) {
        throw new IllegalStateException("JWT secret key must be at least 32 characters long");
    }
}
aics-api/build.gradle (1)

15-21: 테스트 의존성 중복 검토 필요

일부 프로젝트에 대해 직접 의존성과 testFixtures 의존성이 중복 선언되어 있습니다. 특히 ':aics-domain'과 ':aics-global-utils' 프로젝트가 해당됩니다. 이는 불필요한 의존성을 야기할 수 있습니다.

각 프로젝트의 테스트 픽스처 사용 목적을 검토하시고, 실제로 필요한 의존성만 남기는 것을 권장드립니다. 예를 들어:

testFixturesImplementation project(':aics-domain')
testFixturesImplementation project(':aics-common')
testFixturesImplementation project(':aics-infra')
testFixturesImplementation project(':aics-global-utils')

-testFixturesImplementation testFixtures(project(':aics-domain'))
-testFixturesImplementation testFixtures(project(':aics-global-utils'))
aics-api/src/main/java/kgu/developers/api/user/presentation/request/UserUpdateRequest.java (1)

Line range hint 15-16: 이메일 도메인 검증 강화 검토 필요

현재 이메일 정규식은 모든 도메인을 허용하고 있습니다. 경기대학교 도메인(kyonggi.ac.kr)으로 제한하는 것이 더 안전할 수 있습니다.

다음과 같이 정규식을 수정하는 것을 고려해보세요:

-@Pattern(regexp = "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}$", message = "유효한 이메일 형식이 아닙니다.")
+@Pattern(regexp = "^[A-Za-z0-9._%+-]+@kyonggi\\.ac\\.kr$", message = "경기대학교 이메일만 사용 가능합니다.")
aics-domain/src/main/java/kgu/developers/domain/user/exception/UserDomainExceptionCode.java (1)

Line range hint 1-27: 클래스 수준의 문서화가 필요합니다.

이 enum 클래스의 목적과 각 예외 코드의 사용 사례를 설명하는 JavaDoc 문서를 추가하면 좋을 것 같습니다.

다음과 같은 문서화를 제안합니다:

+/**
+ * 사용자 도메인과 관련된 예외 상황을 정의하는 열거형 클래스입니다.
+ * 각 예외 코드는 특정 HTTP 상태 코드와 에러 메시지를 포함합니다.
+ *
+ * @see kgu.developers.common.exception.ExceptionCode
+ */
 @Getter
 @AllArgsConstructor
 public enum UserDomainExceptionCode implements ExceptionCode {
aics-domain/src/main/java/kgu/developers/domain/user/domain/DeptCode.java (1)

23-29: null 반환 대신 Optional 사용을 고려해보세요.

현재 구현은 일치하는 코드가 없을 경우 null을 반환하는데, 이는 잠재적인 NullPointerException의 위험이 있습니다.

다음과 같이 개선하는 것을 제안드립니다:

-public static DeptCode from(String code) {
+public static Optional<DeptCode> from(String code) {
   for (DeptCode condition : values()) {
     if (condition.year.equals(code)) {
-      return condition;
+      return Optional.of(condition);
     }
   }
-  return null;
+  return Optional.empty();
}
aics-api/src/testFixtures/java/mock/TestContainer.java (2)

1-11: 보안 관련 테스트 구성에 대한 제안

테스트 환경에서도 민감한 정보(예: JWT 설정)를 안전하게 관리하는 것이 좋습니다. 테스트용 프로퍼티를 외부 설정 파일로 분리하는 것을 고려해보세요.

다음과 같은 방식으로 개선할 수 있습니다:

+ // src/test/resources/application-test.yml 파일 생성
+ jwt:
+   issuer: testIssuer
+   secret-key: testSecretKey

12-17: 클래스 문서화 개선 제안

테스트 컨테이너의 목적과 사용 방법을 명확히 하기 위해 JavaDoc 문서화를 추가하면 좋을 것 같습니다.

+ /**
+  * 사용자 인증 관련 테스트를 위한 테스트 컨테이너
+  * FakeUserRepository를 사용하여 실제 데이터베이스 없이 테스트를 수행합니다.
+  * 
+  * @see FakeUserRepository
+  * @see UserService
+  * @see AuthService
+  * @see AuthController
+  */
public class TestContainer {
aics-api/src/main/java/kgu/developers/api/user/presentation/request/UserCreateRequest.java (1)

Line range hint 39-40: Major 열거형에 대한 추가 검증 고려가 필요합니다.

현재 Major 필드는 @NotNull 검증만 수행하고 있습니다. Major 열거형에 정의된 값만 허용되도록 @EnumValidator 같은 추가 검증을 고려해보시는 것이 좋을 것 같습니다.

 @Schema(description = "전공 이름", example = "CSE", requiredMode = REQUIRED)
 @NotNull
+@EnumValidator(enumClass = Major.class, message = "유효하지 않은 전공입니다.")
 Major major
aics-api/src/testFixtures/java/auth/presentation/AuthControllerTest.java (2)

3-16: 테스트 검증을 위한 추가 Assertion 라이브러리 제안

보다 다양한 테스트 케이스 검증을 위해 다음과 같은 AssertJ의 추가 기능을 활용하는 것이 좋습니다:

  • assertThatThrownBy(): 예외 처리 테스트
  • assertThatCode(): 예외가 발생하지 않는 케이스 테스트
  • assertSoftly(): 여러 검증을 한번에 수행

17-20: medium test 전환 계획에 대한 구체화 필요

현재 주석은 medium test로의 전환 계획을 언급하고 있지만, 다음 사항들을 추가로 명시하면 좋을 것 같습니다:

  • 전환 시기
  • 구체적인 전환 방법
  • TestContainer 변경 사항
build.gradle (1)

57-62: 테스트 의존성 최적화를 검토해주세요.

현재 구성된 테스트 픽스처 의존성들이 테스트 환경 구축에 필요한 기능들을 포함하고 있습니다. 하지만 몇 가지 고려사항이 있습니다:

  1. springdoc-openapi-starter-webmvc-ui는 테스트 픽스처에서 실제로 필요한지 검토가 필요합니다.
  2. 테스트 실행 속도 향상을 위해 각 모듈별로 실제 필요한 의존성만 선택적으로 포함하는 것이 좋습니다.
aics-domain/src/testFixtures/java/mock/FakeUserRepository.java (3)

23-35: save 메서드 최적화 검토 필요

현재 구현에서는 새로운 User 객체를 생성하여 모든 필드를 복사하고 있습니다. 테스트 환경에서는 입력된 User 객체를 직접 저장하는 것으로 충분할 수 있습니다.

다음과 같이 간소화하는 것을 고려해보세요:

@Override
public User save(User user) {
-    User newUser = User.builder()
-        .id(user.getId())
-        .password(user.getPassword())
-        .name(user.getName())
-        .email(user.getEmail())
-        .phone(user.getPhone())
-        .role(user.getRole())
-        .major(user.getMajor())
-        .build();
-    data.add(newUser);
-    return newUser;
+    data.add(user);
+    return user;
}

38-40: existsById 메서드 성능 최적화 제안

현재 구현은 stream().anyMatch()를 사용하고 있습니다. 간단한 존재 여부 확인의 경우 일반 for-each나 contains를 사용하는 것이 더 효율적일 수 있습니다.

@Override
public boolean existsById(String userId) {
-    return data.stream().anyMatch(item -> item.getId().equals(userId));
+    for (User user : data) {
+        if (user.getId().equals(userId)) {
+            return true;
+        }
+    }
+    return false;
}

43-45: findById 메서드 일관성 개선 제안

existsById와 유사한 로직을 수행하지만 다른 스타일로 구현되어 있습니다. 코드 일관성을 위해 유사한 구현 스타일을 사용하는 것이 좋습니다.

@Override
public Optional<User> findById(String userId) {
-    return data.stream().filter(item -> item.getId().equals(userId)).findAny();
+    for (User user : data) {
+        if (user.getId().equals(userId)) {
+            return Optional.of(user);
+        }
+    }
+    return Optional.empty();
}
aics-domain/src/testFixtures/java/user/domain/UserDomainTest.java (2)

18-41: 테스트 케이스 보완이 필요해 보입니다.

현재 구현은 기본적인 속성 검증을 잘 수행하고 있으나, 다음 사항들을 고려해보시면 좋겠습니다:

  1. 비밀번호 인코딩 검증
  2. 전화번호 형식 유효성 검증
  3. 이메일 형식 유효성 검증

다음과 같이 테스트 케이스를 보완해보세요:

 @Test
 @DisplayName("USER 객체를 생성할 수 있다")
 public void createUser_Success() {
     // given
     String id = "202411345";
     String password = "password";
     String name = "홍길동";
     String email = "valid@kyonggi.ac.kr";
     String phone = "010-1234-5678";
     Major major = Major.CSE;

     // when
     User user = User.create(id, password, name, email, phone, major);

     // then
     assertNotNull(user);
     assertEquals(id, user.getId());
-    assertEquals(password, user.getPassword());
+    assertTrue(passwordEncoder.matches(password, user.getPassword()));
     assertEquals(name, user.getName());
     assertEquals(email, user.getEmail());
     assertEquals(phone, user.getPhone());
     assertEquals(Role.USER, user.getRole());
     assertEquals(major, user.getMajor());
+    assertTrue(user.getPhone().matches("\\d{3}-\\d{4}-\\d{4}"));
+    assertTrue(user.getEmail().matches("^[A-Za-z0-9+_.-]+@kyonggi\\.ac\\.kr$"));
 }

61-77: 학과 코드 유효성 검증에 대한 문서화가 필요합니다.

테스트 코드에서 사용된 학과 코드의 유효성 규칙이 명확하지 않습니다. 다음 사항들을 보완해주세요:

  1. 유효한 학과 코드의 규칙 문서화
  2. 테스트 케이스에 사용된 "202410345"가 왜 잘못된 코드인지 설명
  3. 다양한 경계값 테스트 추가

코드에 다음과 같이 주석을 추가하여 문서화해보세요:

 @Test
 @DisplayName("잘못된 학과 코드로 USER 생성 시 DeptCodeNotValidException이 발생 한다")
 public void createUser_InvalidDeptCode_ThrowsException() {
     // given
-    String id = "202410345"; // 잘못된 학과 코드
+    // 학번 구조: YYYY(입학년도) + DD(학과코드) + XXX(순번)
+    // 컴퓨터공학부 학과코드: 11
+    // 잘못된 학과 코드 10을 사용하여 테스트
+    String id = "202410345";
     String password = "password";
     String name = "홍길동";
     String email = "valid@kyonggi.ac.kr";
     String phone = "010-1234-5678";
     Major major = Major.CSE;

     // when & then
     assertThatThrownBy(() -> {
         User.create(id, password, name, email, phone, major);
     }).isInstanceOf(DeptCodeNotValidException.class);
 }
aics-common/src/main/java/kgu/developers/common/auth/jwt/TokenProvider.java (2)

Line range hint 44-52: 토큰 검증 로직 개선 필요

validateToken 메소드의 예외 처리가 너무 광범위합니다. 다음과 같은 개선이 필요합니다:

  1. 구체적인 예외 처리 (ExpiredJwtException, MalformedJwtException 등)
  2. 명시적인 만료 시간 검증
  3. 로깅 추가

다음과 같이 수정하는 것을 권장드립니다:

public boolean validateToken(String token) {
    try {
-       Jwts.parser()
-               .setSigningKey(jwtProperties.getSecretKey())
-               .parseClaimsJws(token);
-       return true;
-   } catch (Exception e) {
-       return false;
+       Claims claims = Jwts.parser()
+               .setSigningKey(jwtProperties.getSecretKey())
+               .parseClaimsJws(token)
+               .getBody();
+       return !claims.getExpiration().before(new Date());
+   } catch (ExpiredJwtException e) {
+       log.warn("만료된 JWT 토큰입니다: {}", e.getMessage());
+       return false;
+   } catch (MalformedJwtException e) {
+       log.warn("유효하지 않은 JWT 토큰입니다: {}", e.getMessage());
+       return false;
+   } catch (Exception e) {
+       log.error("JWT 토큰 검증 중 예외 발생: {}", e.getMessage());
+       return false;
    }
}

Line range hint 54-67: 인증 구현 개선 필요

getAuthentication 메소드에서 다음과 같은 개선이 필요합니다:

  1. 하드코딩된 "ROLE_USER" 역할
  2. 빈 문자열 비밀번호 사용
  3. 사용자 역할 정보가 토큰에 포함되어 있지 않음

다음과 같은 개선사항을 제안드립니다:

  1. 사용자 역할을 토큰 클레임에 포함
  2. 역할 정보를 상수로 분리
  3. UserDetails 구현체를 별도 클래스로 분리

토큰 생성 시 다음과 같이 역할 정보를 포함하는 것을 고려해보세요:

private String makeToken(Date expiry, String userId, Set<String> roles) {
    return Jwts.builder()
            // ... existing code ...
            .claim("roles", roles)
            .signWith(HS256, jwtProperties.getSecretKey())
            .compact();
}
aics-api/src/testFixtures/java/auth/application/AuthServiceTest.java (2)

24-52: 테스트 설정이 FakeUserRepository를 효과적으로 활용하고 있습니다.

Mockito 대신 FakeUserRepository를 사용한 접근 방식이 PR의 목표와 잘 부합합니다. 다만, 몇 가지 개선 사항을 제안드립니다:

  1. 테스트용 상수값들을 클래스 상단에 정의하면 재사용성과 가독성이 향상될 것 같습니다.
  2. 테스트 데이터 생성 로직을 별도의 팩토리 메서드로 분리하면 좋을 것 같습니다.

다음과 같은 리팩토링을 제안드립니다:

 public class AuthServiceTest {
+    private static final String TEST_USER_ID = "202411345";
+    private static final String TEST_PASSWORD = "password1234";
+    private static final String TEST_NAME = "홍길동";
+    private static final String TEST_EMAIL = "test@kyonggi.ac.kr";
+    private static final String TEST_PHONE = "010-1234-5678";
     private AuthService authService;
+    private FakeUserRepository fakeUserRepository;
+    private BCryptPasswordEncoder bCryptPasswordEncoder;

     @BeforeEach
     public void init() {
-        FakeUserRepository fakeUserRepository = new FakeUserRepository();
-        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
+        fakeUserRepository = new FakeUserRepository();
+        bCryptPasswordEncoder = new BCryptPasswordEncoder();
         // ... (authService 설정 코드는 동일)
+        saveTestUser();
+    }
 
-        fakeUserRepository.save(User.builder()
+    private void saveTestUser() {
+        User testUser = User.builder()
-            .id("202411345")
-            .password(bCryptPasswordEncoder.encode("password1234"))
-            .name("홍길동")
-            .email("test@kyonggi.ac.kr")
-            .phone("010-1234-5678")
+            .id(TEST_USER_ID)
+            .password(bCryptPasswordEncoder.encode(TEST_PASSWORD))
+            .name(TEST_NAME)
+            .email(TEST_EMAIL)
+            .phone(TEST_PHONE)
             .major(Major.CSE)
-            .build());
+            .build();
+        fakeUserRepository.save(testUser);
     }

72-88: 실패 케이스에 대한 테스트가 적절히 구현되어 있습니다.

예외 검증이 잘 되어있습니다. 다만, 다음과 같은 추가 테스트 케이스들도 고려해보시면 좋을 것 같습니다:

  1. 존재하지 않는 사용자 ID로 로그인 시도
  2. 빈 문자열이나 null 값으로 로그인 시도
  3. 특수문자나 SQL 인젝션 문자열로 로그인 시도

테스트 케이스 추가를 원하시면 구현을 도와드리겠습니다.

aics-api/src/main/java/kgu/developers/api/user/application/UserService.java (1)

Line range hint 77-86: 보안 컨텍스트 처리 개선이 필요합니다

현재 me() 메소드의 예외 처리가 모든 예외를 UserNotAuthenticatedException으로 변환하고 있습니다. 이는 다른 종류의 보안 관련 문제를 식별하기 어렵게 만듭니다.

다음과 같이 구체적인 예외 처리를 추가하는 것을 제안드립니다:

 public User me() {
     try {
         Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
         String userId = ((UserDetails)principal).getUsername();
         return getUserById(userId);
-    } catch (Exception e) {
+    } catch (NullPointerException e) {
         throw new UserNotAuthenticatedException();
+    } catch (ClassCastException e) {
+        throw new InvalidAuthenticationTypeException();
     }
 }
aics-domain/src/main/java/kgu/developers/domain/user/domain/User.java (2)

70-72: 사용자 생성 메서드의 가독성이 개선되었습니다.

매개변수 배치와 validateDept 호출이 명확해졌습니다. 다만, 생성 메서드에 대한 문서화가 필요해 보입니다.

다음과 같이 메서드 문서화를 추가하는 것을 제안드립니다:

+/**
+ * 새로운 사용자 엔티티를 생성합니다.
+ * @param id 학번
+ * @param password 비밀번호
+ * @param name 이름
+ * @param email 경기대학교 이메일
+ * @param phone 전화번호
+ * @param major 전공
+ * @return 생성된 사용자 엔티티
+ * @throws DeptCodeNotValidException 유효하지 않은 학과 코드인 경우
+ * @throws EmailDomainNotValidException 유효하지 않은 이메일 도메인인 경우
+ */
 public static User create(String id, String password,
     String name, String email,
     String phone, Major major) {

116-119: 이메일 도메인 검증이 상수화되어 개선되었습니다.

도메인 문자열을 상수로 분리하고 null 체크를 추가한 것이 좋은 변경입니다. 다만, 이메일 형식 자체에 대한 추가적인 검증도 고려해볼 만합니다.

정규식을 사용한 이메일 형식 검증을 추가하는 것을 제안드립니다:

 private static boolean isValidEmailDomain(String email) {
-    return email != null && email.endsWith(ACCESSIBLE_EMAIL_DOMAIN);
+    return email != null && 
+           email.matches("^[A-Za-z0-9+_.-]+@kyonggi\\.ac\\.kr$");
 }
aics-api/src/testFixtures/java/user/application/UserServiceTest.java (4)

23-50: 테스트 데이터 설정 개선이 필요합니다

다음과 같은 개선사항을 제안드립니다:

  1. 테스트 데이터를 별도의 테스트 픽스처 클래스로 분리하여 재사용성을 높이는 것이 좋습니다.
  2. 비밀번호와 같은 민감한 정보는 상수로 분리하는 것이 좋습니다.
  3. 각 테스트 케이스에 필요한 데이터만 설정하는 것이 테스트의 의도를 더 명확하게 할 수 있습니다.

예시 리팩토링:

private static final String TEST_PASSWORD = "password1234";
private static final String TEST_EMAIL_DOMAIN = "kyonggi.ac.kr";

private TestUserFixture testUser;

@BeforeEach
public void init() {
    BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
    FakeUserRepository fakeUserRepository = new FakeUserRepository();

    this.userService = UserService.builder()
        .userRepository(fakeUserRepository)
        .bCryptPasswordEncoder(bCryptPasswordEncoder)
        .build();

    testUser = TestUserFixture.createDefaultUser(bCryptPasswordEncoder);
    fakeUserRepository.save(testUser.toEntity());
}

72-90: 예외 메시지 검증을 추가해주세요

예외가 발생하는 것은 확인하고 있지만, 예외 메시지가 적절한지는 확인하고 있지 않습니다. 사용자에게 더 명확한 피드백을 제공하기 위해 예외 메시지도 검증하면 좋을 것 같습니다.

 assertThatThrownBy(() -> {
     userService.createUser(request);
-}).isInstanceOf(UserIdDuplicateException.class);
+}).isInstanceOf(UserIdDuplicateException.class)
+  .hasMessageContaining("이미 존재하는 사용자 ID입니다");

92-103: getUserById 성공 케이스의 검증을 보완해주세요

현재는 이름만 검증하고 있는데, 사용자의 다른 중요한 정보들도 함께 검증하면 좋을 것 같습니다.

 // then
-assertEquals("홍길동", result.getName());
+assertEquals("홍길동", result.getName());
+assertEquals("test@kyonggi.ac.kr", result.getEmail());
+assertEquals("010-1234-5678", result.getPhone());
+assertEquals(Major.CSE, result.getMajor());

1-117: 테스트 아키텍처에 대한 제안

FakeRepository를 사용한 접근 방식이 좋습니다. 다음과 같은 개선사항을 고려해보시면 좋을 것 같습니다:

  1. 테스트 격리를 위해 @Nested 클래스를 사용하여 관련 테스트들을 그룹화
  2. 테스트 데이터 생성을 위한 빌더나 팩토리 메서드 도입
  3. 반복되는 검증 로직을 커스텀 Assertion으로 추출

예시 구조:

@DisplayName("UserService 테스트")
class UserServiceTest {
    @Nested
    @DisplayName("사용자 생성 시")
    class CreateUser {
        @Test
        @DisplayName("유효한 요청이면 성공한다")
        void success() { ... }
        
        @Test
        @DisplayName("중복된 ID면 실패한다")
        void duplicateId() { ... }
    }

    @Nested
    @DisplayName("사용자 조회 시")
    class GetUser { ... }
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 5634485 and d9b11b8.

📒 Files selected for processing (25)
  • .coderabbit.yaml (0 hunks)
  • aics-api/build.gradle (1 hunks)
  • aics-api/src/main/java/kgu/developers/api/auth/application/AuthService.java (1 hunks)
  • aics-api/src/main/java/kgu/developers/api/auth/presentation/AuthController.java (1 hunks)
  • aics-api/src/main/java/kgu/developers/api/auth/presentation/request/LoginRequest.java (1 hunks)
  • aics-api/src/main/java/kgu/developers/api/user/application/UserService.java (1 hunks)
  • aics-api/src/main/java/kgu/developers/api/user/presentation/request/UserCreateRequest.java (1 hunks)
  • aics-api/src/main/java/kgu/developers/api/user/presentation/request/UserUpdateRequest.java (1 hunks)
  • aics-api/src/testFixtures/java/auth/application/AuthServiceTest.java (1 hunks)
  • aics-api/src/testFixtures/java/auth/presentation/AuthControllerTest.java (1 hunks)
  • aics-api/src/testFixtures/java/mock/TestContainer.java (1 hunks)
  • aics-api/src/testFixtures/java/user/application/UserServiceTest.java (1 hunks)
  • aics-api/src/testFixtures/java/user/presentation/UserControllerTest.java (1 hunks)
  • aics-common/src/main/java/kgu/developers/common/auth/jwt/JwtProperties.java (2 hunks)
  • aics-common/src/main/java/kgu/developers/common/auth/jwt/TokenProvider.java (1 hunks)
  • aics-domain/build.gradle (1 hunks)
  • aics-domain/src/main/java/kgu/developers/domain/user/domain/DeptCode.java (2 hunks)
  • aics-domain/src/main/java/kgu/developers/domain/user/domain/User.java (7 hunks)
  • aics-domain/src/main/java/kgu/developers/domain/user/exception/DepartmentCodeNotValidException.java (0 hunks)
  • aics-domain/src/main/java/kgu/developers/domain/user/exception/DeptCodeNotValidException.java (1 hunks)
  • aics-domain/src/main/java/kgu/developers/domain/user/exception/UserDomainExceptionCode.java (1 hunks)
  • aics-domain/src/testFixtures/java/mock/FakeUserRepository.java (1 hunks)
  • aics-domain/src/testFixtures/java/user/application/UserServiceTest.java (1 hunks)
  • aics-domain/src/testFixtures/java/user/domain/UserDomainTest.java (1 hunks)
  • build.gradle (3 hunks)
💤 Files with no reviewable changes (2)
  • .coderabbit.yaml
  • aics-domain/src/main/java/kgu/developers/domain/user/exception/DepartmentCodeNotValidException.java
✅ Files skipped from review due to trivial changes (3)
  • aics-api/src/main/java/kgu/developers/api/auth/application/AuthService.java
  • aics-api/src/testFixtures/java/user/presentation/UserControllerTest.java
  • aics-domain/src/testFixtures/java/user/application/UserServiceTest.java
🔇 Additional comments (21)
aics-domain/src/main/java/kgu/developers/domain/user/exception/DeptCodeNotValidException.java (2)

1-1: 클래스 설계가 깔끔하고 명확합니다!

예외 클래스의 구현이 간단명료하며, CustomException을 상속받아 도메인 특화 예외를 잘 표현하고 있습니다. 상수를 static import하여 코드의 가독성도 향상되었습니다.

Also applies to: 3-3, 5-5, 7-11


1-11: 기존 코드와의 호환성을 확인해주세요.

DepartmentCodeNotValidException에서 DeptCodeNotValidException으로의 변경이 이루어졌습니다. 이 예외를 사용하는 모든 코드가 업데이트되었는지 확인이 필요합니다.

다음 스크립트로 기존 예외 클래스의 사용처를 확인할 수 있습니다:

✅ Verification successful

Based on the search results, I can generate the final response since we have clear evidence that:

  1. There are no occurrences of the old DepartmentCodeNotValidException in the codebase
  2. The new DeptCodeNotValidException is properly used in all relevant places (User domain class and its tests)

예외 클래스 이름 변경이 올바르게 적용되었습니다.

기존 DepartmentCodeNotValidException의 사용처가 발견되지 않았으며, 새로운 DeptCodeNotValidException이 도메인 클래스와 테스트 코드에서 정상적으로 사용되고 있습니다.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: 기존 DepartmentCodeNotValidException 사용 여부 확인

# 기존 예외 클래스 사용 검색
echo "Checking for old exception class usage..."
rg "DepartmentCodeNotValidException"

# 새로운 예외 클래스 사용 검색
echo "Checking for new exception class usage..."
rg "DeptCodeNotValidException"

Length of output: 1189

aics-api/src/main/java/kgu/developers/api/auth/presentation/request/LoginRequest.java (1)

7-7: @builder 어노테이션 추가가 적절합니다.

Record 클래스에 Builder 패턴을 적용함으로써 테스트 코드 작성 시 객체 생성이 더욱 유연해질 것으로 보입니다. 특히 테스트 데이터 설정이 더욱 명확하고 가독성이 좋아질 것으로 예상됩니다.

Also applies to: 9-9

aics-api/build.gradle (1)

Line range hint 1-6: JAR 구성 설정 검토 필요

bootJarjar 태스크가 모두 활성화되어 있습니다. 이는 빌드 시 두 개의 다른 JAR 파일이 생성될 수 있으며, 배포 시 혼란을 야기할 수 있습니다. Spring Boot 애플리케이션의 경우 일반적으로 bootJar만 활성화하고 jar는 비활성화하는 것이 권장됩니다.

다음 설정을 권장드립니다:

bootJar {
    enabled = true
}

jar {
-    enabled = true
+    enabled = false
}
aics-api/src/main/java/kgu/developers/api/user/presentation/request/UserUpdateRequest.java (1)

9-9: Builder 패턴 적용이 잘 되었습니다!

테스트 코드 작성 시 객체 생성이 더욱 용이해질 것으로 보입니다.

aics-domain/src/main/java/kgu/developers/domain/user/exception/UserDomainExceptionCode.java (1)

16-16: DEPARTMENT_CODE_NOT_VALID에서 DEPT_CODE_NOT_VALID로의 변경이 확인되었습니다.

이름 변경이 적절하게 이루어졌습니다. 다만, 관련된 다른 코드들에서도 일관성 있게 변경되었는지 확인이 필요합니다.

다음 스크립트를 실행하여 코드베이스 전체에서 일관성을 확인하겠습니다:

✅ Verification successful

코드베이스 전체에서 'department'에서 'dept'로의 일관된 변경이 확인되었습니다.

검증 결과:

  • 'department' 키워드가 포함된 파일이 전혀 발견되지 않았습니다.
  • 모든 관련 코드가 'dept' 키워드를 일관되게 사용하고 있습니다:
    • DeptCode 열거형
    • DeptCodeNotValidException 예외 클래스
    • DEPT_CODE_NOT_VALID 예외 코드
    • 기타 도메인의 카테고리 상수들 (DEPT_INTRO, DEPT_INFO, DEPT_NEWS)
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: 'department' 관련 네이밍이 모두 'dept'로 변경되었는지 확인

# department 키워드 검색
echo "Checking for remaining 'department' occurrences:"
rg -i "department" --type java

# dept 키워드 검색으로 변경된 부분 확인
echo -e "\nChecking for new 'dept' occurrences:"
rg -i "dept" --type java

Length of output: 3563

aics-domain/src/main/java/kgu/developers/domain/user/domain/DeptCode.java (2)

Line range hint 10-17: 코드 구조가 깔끔하고 명확합니다!

열거형의 이름을 DepartmentCodeCondition에서 DeptCode로 변경한 것이 더 간결하고 가독성이 좋습니다.


32-41: from() 메소드의 null 반환값 처리를 확인해주세요.

40번 라인에서 from() 메소드의 반환값이 null일 경우에 대한 처리가 안전하게 되어있는지 확인이 필요합니다.

다음 스크립트로 이 메소드의 사용처들을 확인해보세요:

✅ Verification successful

Let me check the from() method implementation to verify the null safety.


Let me try to find the from method using ripgrep instead.


from() 메소드의 null 처리가 안전하게 구현되어 있습니다.

isValidDeptCode() 메소드에서 from() 메소드의 null 반환값은 condition != null 체크를 통해 안전하게 처리되고 있습니다. 또한 User 클래스에서도 isValidDeptCode()의 결과를 적절히 예외 처리하고 있어 전반적인 null 안전성이 확보되어 있습니다.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find all usages of isValidDeptCode to verify null handling
rg -l "isValidDeptCode" | xargs rg -A 5 "isValidDeptCode"

Length of output: 1876


Script:

#!/bin/bash
# Find the implementation of from() method in DeptCode.java
ast-grep --pattern 'from($_) {
  $$$
}'

Length of output: 41


Script:

#!/bin/bash
# Find the implementation of from method in DeptCode.java
rg -A 10 "from\(" aics-domain/src/main/java/kgu/developers/domain/user/domain/DeptCode.java

Length of output: 557

aics-api/src/testFixtures/java/mock/TestContainer.java (1)

12-37: 테스트 정리(cleanup) 메커니즘 추가 제안

테스트 실행 후 리소스를 정리하기 위한 메커니즘이 필요해 보입니다.

다음과 같은 cleanup 메서드 추가를 제안드립니다:

public class TestContainer {
+    public void cleanup() {
+        // FakeUserRepository 데이터 초기화
+        if (userRepository instanceof FakeUserRepository) {
+            ((FakeUserRepository) userRepository).clear();
+        }
+    }
}

아래 스크립트로 테스트 클래스에서 cleanup 메서드 호출 여부를 확인할 수 있습니다:

aics-api/src/main/java/kgu/developers/api/user/presentation/request/UserCreateRequest.java (1)

9-9: @builder 어노테이션 추가 적절합니다.

Builder 패턴의 도입으로 테스트 코드 작성이 용이해지고, 객체 생성의 유연성이 향상되었습니다. PR의 목표인 테스트 코드 구현에 잘 부합하는 변경사항입니다.

Also applies to: 11-11

aics-api/src/main/java/kgu/developers/api/auth/presentation/AuthController.java (1)

Line range hint 28-38: 로그인 API 구현이 적절해 보입니다.

컨트롤러의 기본 구현은 잘 되어있습니다. API 문서화를 위한 Swagger 어노테이션과 validation 처리가 잘 구현되어 있습니다.

aics-api/src/testFixtures/java/auth/presentation/AuthControllerTest.java (1)

27-28: TestContainer 구현 검증 필요

TestContainer의 구현이 적절한지 확인이 필요합니다.

✅ Verification successful

Let me gather more information about the test container implementation and its dependencies.


Let me check the AuthController implementation and its tests to complete the verification.


TestContainer 구현이 적절함을 확인했습니다

TestContainer의 구현이 다음과 같은 이유로 적절합니다:

  • 필요한 모든 의존성(UserRepository, UserService, AuthService, AuthController)이 올바르게 초기화되어 있습니다
  • FakeUserRepository를 통해 테스트용 저장소가 적절히 구현되어 있습니다
  • BCryptPasswordEncoder, TokenProvider 등 인증에 필요한 컴포넌트들이 테스트 환경에 맞게 구성되어 있습니다
  • AuthControllerTest에서 실제 로그인 시나리오를 성공적으로 테스트하고 있습니다
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# TestContainer 구현 확인
rg -t java "class TestContainer" -A 10

Length of output: 1079


Script:

#!/bin/bash
# Check FakeUserRepository implementation
rg -t java "class FakeUserRepository" -A 10

# Check full TestContainer implementation
rg -t java "class TestContainer" -A 30

# Check AuthController test usage
rg -t java "TestContainer.*authController" 

Length of output: 3476


Script:

#!/bin/bash
# Check AuthController implementation
rg -t java "class AuthController" -A 10

# Check AuthController tests
rg -t java "class.*AuthControllerTest" -A 20

# Check AuthService implementation
rg -t java "class AuthService" -A 10

Length of output: 6989

build.gradle (1)

3-3: 테스트 픽스처 플러그인 설정이 적절합니다.

java-test-fixtures 플러그인의 추가는 테스트 코드의 재사용성과 모듈 간 공유를 가능하게 하여, FakeRepository 구현과 테스트 코드 관리에 적합한 환경을 제공합니다.

Also applies to: 23-23

aics-domain/src/testFixtures/java/user/domain/UserDomainTest.java (1)

1-15: 패키지 구조와 임포트 선언이 잘 구성되어 있습니다!

테스트에 필요한 라이브러리와 도메인 클래스들이 적절하게 임포트되어 있습니다.

aics-api/src/testFixtures/java/auth/application/AuthServiceTest.java (2)

1-21: 클래스 구조가 잘 구성되어 있습니다!

필요한 의존성들이 잘 임포트되어 있으며, 테스트 클래스의 기본 구조가 깔끔합니다.


54-70: 로그인 성공 테스트가 잘 구현되어 있습니다.

테스트 구조와 검증 로직이 명확합니다. 하지만 토큰 발급에 대한 실제 검증이 누락되어 있습니다.

토큰 발급 검증을 위해 다음과 같은 개선을 제안드립니다:

     @Test
     @DisplayName("login은 토큰을 발급할 수 있다")
     public void login_Success() {
         // given
         String userId = "202411345";
         String password = "password1234";
 
         // when
+        String token = authService.login(LoginRequest.builder()
+            .userId(userId)
+            .password(password)
+            .build());
 
         // then
-        assertThatCode(() -> {
-            authService.login(LoginRequest.builder()
-                .userId(userId)
-                .password(password)
-                .build()
-            );
-        }).doesNotThrowAnyException();
+        assertThat(token).isNotNull().isNotEmpty();
aics-api/src/main/java/kgu/developers/api/user/application/UserService.java (1)

Line range hint 32-45: 보안 관련 검증이 필요합니다

사용자 생성 로직에서 다음 사항들을 검증해주시기 바랍니다:

  1. 비밀번호 복잡도 요구사항
  2. 이메일 형식 검증
  3. 전화번호 형식 검증
✅ Verification successful

입력값 검증이 이미 적절히 구현되어 있습니다

UserCreateRequest 클래스에 다음과 같은 검증이 이미 구현되어 있습니다:

  • 비밀번호: @Pattern 정규식으로 복잡도 요구사항이 검증됨
  • 이메일: @Pattern(regexp = "^[A-Za-z0-9._%+-]+@(kyonggi|kgu)\\.ac\\.kr$") 로 학교 이메일 형식 검증
  • 전화번호: @Pattern(regexp = "^\\d{2,4}-\\d{3,4}-\\d{4}$") 로 형식 검증

추가로 도메인 계층에서도 User 클래스의 validateDept(), isValidEmailDomain() 등을 통해 이중으로 검증하고 있습니다.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: 비밀번호 정책 및 입력값 검증 로직 확인

# 비밀번호 정책 관련 코드 검색
rg -l "password.*validation|password.*policy" 

# 입력값 검증 관련 코드 검색
ast-grep --pattern 'class $_ implements Validator { $$$ }'

Length of output: 108


Script:

#!/bin/bash
# 사용자 입력 검증 관련 코드 검색을 위한 다양한 패턴 시도

# 1. UserCreateRequest 클래스 검색
rg -A 10 "class UserCreateRequest"

# 2. @Valid, @Validated 어노테이션 사용 검색
rg -l "@Valid|@Validated"

# 3. Bean Validation 제약조건 검색
rg "@Pattern|@Email|@Size|@NotBlank|@NotNull" 

# 4. 정규식 패턴이나 유효성 검증 메서드 검색
rg "Pattern\.compile|\.matches\(|validate[A-Z]|isValid"

Length of output: 6812

aics-domain/src/main/java/kgu/developers/domain/user/domain/User.java (4)

6-6: 임포트 구문과 어노테이션 변경이 적절합니다.

DeptCode 관련 임포트와 보호 수준이 지정된 @AllArgsConstructor 어노테이션의 사용이 적절합니다.

Also applies to: 17-17, 23-23, 38-38


85-87: 이메일 업데이트 로직이 간결해졌습니다.

유효성 검사와 예외 처리가 명확하게 구현되었습니다.


96-96: 권한 부여 로직이 개선되었습니다.

Role.USER.name()을 사용하여 하드코딩된 문자열을 제거한 것이 좋은 변경입니다.


109-113: 학과 코드 검증 로직의 책임이 명확해졌습니다.

검증 로직이 단순화되었고 예외 처리가 명확해졌습니다. 다만, 메서드 이름이 변경된 만큼 다른 부분에서의 호출도 모두 업데이트되었는지 확인이 필요합니다.

다음 스크립트로 변경된 메서드 이름의 일관성을 확인하겠습니다:

✅ Verification successful

메서드 이름 변경이 일관되게 적용되었습니다.

코드베이스 검사 결과, validateDept, isValidDeptCode, DeptCodeNotValidException 등의 새로운 명명이 일관되게 사용되고 있으며, 이전 메서드명(validateDepartment, isValidDepartmentCode)은 더 이상 사용되지 않음을 확인했습니다.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: 이전 메서드명이 아직 사용되고 있는지 확인

# 이전 메서드명 검색
echo "Checking for old method names..."
rg "validateDepartment|isValidDepartmentCode|DepartmentCodeNotValidException" 

Length of output: 154


Script:

#!/bin/bash
# 메서드 호출과 관련된 모든 파일 검색
echo "Searching for method calls and related files..."

# 현재 메서드명 검색
echo "Current method names:"
rg "validateDept|isValidDeptCode|DeptCodeNotValidException" -A 2

# User 클래스의 전체 내용 확인
echo -e "\nChecking User class implementation:"
fd "User.java" --exec cat {}

Length of output: 7045

Comment on lines +18 to +36
public TestContainer() {
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
this.userRepository = new FakeUserRepository();
this.userService = UserService.builder()
.userRepository(this.userRepository)
.bCryptPasswordEncoder(bCryptPasswordEncoder)
.build();
this.authService = AuthService.builder()
.userService(this.userService)
.passwordEncoder(bCryptPasswordEncoder)
.tokenProvider(TokenProvider.builder()
.jwtProperties(new JwtProperties("testIssuer", "testSecretKey"))
.build()
)
.build();
this.authController = AuthController.builder()
.authService(this.authService)
.build();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

테스트 성능 및 유지보수성 개선 제안

몇 가지 개선 사항을 제안드립니다:

  1. 테스트 성능 향상을 위한 BCryptPasswordEncoder 설정:
- BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
+ // 테스트 환경에서는 낮은 강도를 사용하여 성능 향상
+ BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder(4);
  1. 컴포넌트 초기화 모듈화:
+ private TokenProvider createTokenProvider() {
+     return TokenProvider.builder()
+         .jwtProperties(new JwtProperties("testIssuer", "testSecretKey"))
+         .build();
+ }
+
+ private UserService createUserService(BCryptPasswordEncoder encoder) {
+     return UserService.builder()
+         .userRepository(this.userRepository)
+         .bCryptPasswordEncoder(encoder)
+         .build();
+ }
  1. 테스트 설정값 상수화:
+ private static final String TEST_ISSUER = "testIssuer";
+ private static final String TEST_SECRET_KEY = "testSecretKey";

Committable suggestion skipped: line range outside the PR's diff.

import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Builder
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

@builder 어노테이션 제거 시 테스트 코드 수정 필요

TestContainer.java 파일에서 AuthController.builder()를 사용하고 있어 수정이 필요합니다:

  • aics-api/src/testFixtures/java/mock/TestContainer.java에서 AuthController 빌더 패턴 사용 중
🔗 Analysis chain

테스트 코드에 미치는 영향 확인 필요

@builder 어노테이션 제거가 테스트 코드에 영향을 미칠 수 있습니다.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if any test files are using AuthController's builder pattern

# Search for AuthController.builder() usage in test files
rg -t java "AuthController\.builder\(\)" src/test/

Length of output: 102


Script:

#!/bin/bash
# First, let's find all test files in the repository
fd -t f "Test.*\.java$"

# Then, let's search for any builder pattern usage related to AuthController
rg -t java "AuthController.*builder" 

# Also check for any test files that might be importing or using AuthController
rg -t java "AuthController" 

Length of output: 1209

Copy link
Contributor

@LeeShinHaeng LeeShinHaeng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!
참고해서 추후에 올라올 테스트 이슈에 적용하도록 할게요!! 👍

@kgu-developers kgu-developers deleted a comment from coderabbitai bot Nov 16, 2024
LeeHanEum and others added 2 commits November 16, 2024 22:50
…operties.java

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@LeeHanEum LeeHanEum merged commit 7bea2da into develop Nov 16, 2024
2 checks passed
@LeeHanEum LeeHanEum deleted the feature/#98-user-test-code branch November 16, 2024 13:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dependencies Pull requests that update a dependency file ✨feature create new feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

FakeUserRepository를 이용한 User TestCode 작성
2 participants