Skip to content

Commit 8d413d3

Browse files
authored
Merge pull request DDD-Community#129 from Minsu-Lee/feature/fix-password-letter-validation
한글 포함 비밀번호가 영문자 조건을 통과하던 문제 수정
2 parents 17309ac + ddd03ba commit 8d413d3

3 files changed

Lines changed: 118 additions & 1 deletion

File tree

domain/src/main/kotlin/com/anddd/nevera/domain/model/validation/PasswordValidationError.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.anddd.nevera.domain.model.validation
33
sealed interface PasswordValidationError {
44
data class TooShort(val minLength: Int) : PasswordValidationError
55
data class TooLong(val maxLength: Int) : PasswordValidationError
6+
data object ContainsInvalidCharacter : PasswordValidationError
67
data object MissingLetter : PasswordValidationError
78
data object MissingDigit : PasswordValidationError
89
data object MissingSpecialChar : PasswordValidationError

domain/src/main/kotlin/com/anddd/nevera/domain/usecase/validation/ValidatePasswordUseCase.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,20 @@ class ValidatePasswordUseCase @Inject constructor() {
1414
val errors = buildList {
1515
if (password.length < MIN_LENGTH) add(PasswordValidationError.TooShort(MIN_LENGTH))
1616
if (password.length > MAX_LENGTH) add(PasswordValidationError.TooLong(MAX_LENGTH))
17-
if (password.none { it.isLetter() }) add(PasswordValidationError.MissingLetter)
1817
if (password.none { it.isDigit() }) add(PasswordValidationError.MissingDigit)
1918
if (password.none { it in SPECIAL_CHARS }) add(PasswordValidationError.MissingSpecialChar)
19+
if (password.none { it in 'a'..'z' || it in 'A'..'Z' }) add(PasswordValidationError.MissingLetter)
20+
if (password.any { !isAllowedPasswordChar(it) }) add(PasswordValidationError.ContainsInvalidCharacter)
2021
}
2122

2223
return if (errors.isEmpty()) PasswordValidationResult.Valid
2324
else PasswordValidationResult.Invalid(errors)
2425
}
2526

27+
private fun isAllowedPasswordChar(c: Char): Boolean {
28+
return c in 'a'..'z' || c in 'A'..'Z' || c.isDigit() || c in SPECIAL_CHARS
29+
}
30+
2631
companion object {
2732
private const val MIN_LENGTH = 8
2833
private const val MAX_LENGTH = 20
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package com.anddd.nevera.domain.usecase.validation
2+
3+
import com.anddd.nevera.domain.model.validation.PasswordValidationError
4+
import com.anddd.nevera.domain.model.validation.PasswordValidationResult
5+
import org.junit.jupiter.api.Assertions.assertEquals
6+
import org.junit.jupiter.api.Assertions.assertFalse
7+
import org.junit.jupiter.api.Assertions.assertTrue
8+
import org.junit.jupiter.api.Test
9+
10+
class ValidatePasswordUseCaseTest {
11+
12+
private val useCase = ValidatePasswordUseCase()
13+
14+
@Test
15+
fun `빈 문자열은 Empty를 반환한다`() {
16+
val result = useCase("")
17+
18+
assertEquals(PasswordValidationResult.Empty, result)
19+
}
20+
21+
@Test
22+
fun `공백 문자열은 Empty를 반환한다`() {
23+
val result = useCase(" ")
24+
25+
assertEquals(PasswordValidationResult.Empty, result)
26+
}
27+
28+
@Test
29+
fun `8자 미만이면 TooShort 에러를 반환한다`() {
30+
val result = useCase("Ab1!")
31+
32+
assertTrue(result is PasswordValidationResult.Invalid)
33+
assertTrue((result as PasswordValidationResult.Invalid).errors.contains(PasswordValidationError.TooShort(8)))
34+
}
35+
36+
@Test
37+
fun `20자 초과이면 TooLong 에러를 반환한다`() {
38+
val result = useCase("Password1!Password1!a")
39+
40+
assertTrue(result is PasswordValidationResult.Invalid)
41+
assertTrue((result as PasswordValidationResult.Invalid).errors.contains(PasswordValidationError.TooLong(20)))
42+
}
43+
44+
@Test
45+
fun `한글이 포함되면 ContainsInvalidCharacter 에러를 반환한다`() {
46+
val result = useCase("Password1!가")
47+
48+
assertTrue(result is PasswordValidationResult.Invalid)
49+
val errors = (result as PasswordValidationResult.Invalid).errors
50+
assertTrue(errors.contains(PasswordValidationError.ContainsInvalidCharacter))
51+
assertFalse(errors.contains(PasswordValidationError.MissingLetter))
52+
}
53+
54+
@Test
55+
fun `한글만 입력된 비밀번호는 ContainsInvalidCharacter와 MissingLetter 에러를 반환한다`() {
56+
val result = useCase("가나다라마바1!")
57+
58+
assertTrue(result is PasswordValidationResult.Invalid)
59+
val errors = (result as PasswordValidationResult.Invalid).errors
60+
assertTrue(errors.contains(PasswordValidationError.ContainsInvalidCharacter))
61+
assertTrue(errors.contains(PasswordValidationError.MissingLetter))
62+
}
63+
64+
@Test
65+
fun `영문자가 없으면 MissingLetter 에러를 반환한다`() {
66+
val result = useCase("12345678!")
67+
68+
assertTrue(result is PasswordValidationResult.Invalid)
69+
assertTrue((result as PasswordValidationResult.Invalid).errors.contains(PasswordValidationError.MissingLetter))
70+
}
71+
72+
@Test
73+
fun `숫자가 없으면 MissingDigit 에러를 반환한다`() {
74+
val result = useCase("Password!!")
75+
76+
assertTrue(result is PasswordValidationResult.Invalid)
77+
assertTrue((result as PasswordValidationResult.Invalid).errors.contains(PasswordValidationError.MissingDigit))
78+
}
79+
80+
@Test
81+
fun `특수문자가 없으면 MissingSpecialChar 에러를 반환한다`() {
82+
val result = useCase("Password11")
83+
84+
assertTrue(result is PasswordValidationResult.Invalid)
85+
assertTrue((result as PasswordValidationResult.Invalid).errors.contains(PasswordValidationError.MissingSpecialChar))
86+
}
87+
88+
@Test
89+
fun `특수문자만 있으면 MissingLetter와 MissingDigit 에러를 반환한다`() {
90+
val result = useCase("!!!!!!!!!")
91+
92+
assertTrue(result is PasswordValidationResult.Invalid)
93+
val errors = (result as PasswordValidationResult.Invalid).errors
94+
assertTrue(errors.contains(PasswordValidationError.MissingLetter))
95+
assertTrue(errors.contains(PasswordValidationError.MissingDigit))
96+
}
97+
98+
@Test
99+
fun `영문 소문자, 숫자, 특수문자를 포함한 비밀번호는 Valid를 반환한다`() {
100+
val result = useCase("password1!")
101+
102+
assertEquals(PasswordValidationResult.Valid, result)
103+
}
104+
105+
@Test
106+
fun `영문 대문자, 숫자, 특수문자를 포함한 비밀번호는 Valid를 반환한다`() {
107+
val result = useCase("Password1!")
108+
109+
assertEquals(PasswordValidationResult.Valid, result)
110+
}
111+
}

0 commit comments

Comments
 (0)