diff --git a/src/main/java/clap/server/common/annotation/validation/password/ValidPassword.java b/src/main/java/clap/server/common/annotation/validation/password/ValidPassword.java index 8b8b436b..bd7e0b78 100644 --- a/src/main/java/clap/server/common/annotation/validation/password/ValidPassword.java +++ b/src/main/java/clap/server/common/annotation/validation/password/ValidPassword.java @@ -1,5 +1,6 @@ package clap.server.common.annotation.validation.password; +import clap.server.domain.policy.member.PasswordPolicy; import jakarta.validation.Constraint; import jakarta.validation.Payload; @@ -10,7 +11,7 @@ @Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER }) @Retention(RetentionPolicy.RUNTIME) -@Constraint(validatedBy = PasswordValidator.class) +@Constraint(validatedBy = PasswordPolicy.class) public @interface ValidPassword { String message() default "대문자, 소문자, 숫자, 특수문자를 포함하며 8자 이상이어야 합니다."; diff --git a/src/main/java/clap/server/common/annotation/validation/password/PasswordValidator.java b/src/main/java/clap/server/domain/policy/member/PasswordPolicy.java similarity index 53% rename from src/main/java/clap/server/common/annotation/validation/password/PasswordValidator.java rename to src/main/java/clap/server/domain/policy/member/PasswordPolicy.java index 03b82fd7..2237ee9e 100644 --- a/src/main/java/clap/server/common/annotation/validation/password/PasswordValidator.java +++ b/src/main/java/clap/server/domain/policy/member/PasswordPolicy.java @@ -1,13 +1,16 @@ -package clap.server.common.annotation.validation.password; +package clap.server.domain.policy.member; +import clap.server.common.annotation.architecture.Policy; +import clap.server.common.annotation.validation.password.ValidPassword; import jakarta.validation.ConstraintValidator; import jakarta.validation.ConstraintValidatorContext; import java.util.regex.Pattern; -public class PasswordValidator implements ConstraintValidator { +@Policy +public class PasswordPolicy implements ConstraintValidator { - private static final String PASSWORD_REGEX = "^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d)(?=.*[!@#$%^&*()_+={}\\[\\]:;\"'<>,.?/\\\\|]).{8,}$"; + private static final String PASSWORD_REGEX = "^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d)(?=.*[!@#$%^&*()_+{}\\[\\]:;<>,.?/~`-]).{8,20}$"; @Override public boolean isValid(String password, ConstraintValidatorContext context) { diff --git a/src/test/java/clap/server/domain/policy/member/PasswordPolicyTest.java b/src/test/java/clap/server/domain/policy/member/PasswordPolicyTest.java new file mode 100644 index 00000000..6a39df2f --- /dev/null +++ b/src/test/java/clap/server/domain/policy/member/PasswordPolicyTest.java @@ -0,0 +1,85 @@ +package clap.server.domain.policy.member; + +import jakarta.validation.ConstraintValidatorContext; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +class PasswordPolicyTest { + + private PasswordPolicy passwordPolicy; + private ConstraintValidatorContext context; + + @BeforeEach + void setUp() { + passwordPolicy = new PasswordPolicy(); + context = mock(ConstraintValidatorContext.class); // Mock ConstraintValidatorContext + } + + @Test + @DisplayName("유효한 비밀번호 - 대문자, 소문자, 숫자, 특수문자 포함") + void validPassword() { + String validPassword = "Abcdef1!"; + boolean result = passwordPolicy.isValid(validPassword, context); + assertThat(result).isTrue(); + } + + @Test + @DisplayName("유효하지 않은 비밀번호 - 대문자 없음") + void invalidPassword_noUpperCase() { + String invalidPassword = "abcdef1!"; + boolean result = passwordPolicy.isValid(invalidPassword, context); + assertThat(result).isFalse(); + } + + @Test + @DisplayName("유효하지 않은 비밀번호 - 소문자 없음") + void invalidPassword_noLowerCase() { + String invalidPassword = "ABCDEF1!"; + boolean result = passwordPolicy.isValid(invalidPassword, context); + assertThat(result).isFalse(); + } + + @Test + @DisplayName("유효하지 않은 비밀번호 - 숫자 없음") + void invalidPassword_noDigit() { + String invalidPassword = "Abcdefgh!"; + boolean result = passwordPolicy.isValid(invalidPassword, context); + assertThat(result).isFalse(); + } + + @Test + @DisplayName("유효하지 않은 비밀번호 - 특수문자 없음") + void invalidPassword_noSpecialCharacter() { + String invalidPassword = "Abcdefg1"; + boolean result = passwordPolicy.isValid(invalidPassword, context); + assertThat(result).isFalse(); + } + + @Test + @DisplayName("유효하지 않은 비밀번호 - 길이가 8자 미만") + void invalidPassword_tooShort() { + String invalidPassword = "Ab1!"; + boolean result = passwordPolicy.isValid(invalidPassword, context); + assertThat(result).isFalse(); + } + + @Test + @DisplayName("유효하지 않은 비밀번호 - 길이가 20자 초과") + void invalidPassword_tooLong() { + String invalidPassword = "Abcdefg1!Abcdefg1!Abcdefg1!"; + boolean result = passwordPolicy.isValid(invalidPassword, context); + assertThat(result).isFalse(); + } + + @Test + @DisplayName("유효하지 않은 비밀번호 - null 값") + void invalidPassword_null() { + String invalidPassword = null; + boolean result = passwordPolicy.isValid(invalidPassword, context); + assertThat(result).isFalse(); + } +}