Skip to content

Commit 91644b8

Browse files
test: Add comprehensive tests for password validators
This commit introduces a new test suite for the password validation logic in `user/validators.py`. The tests cover all existing validator classes: - `UppercaseValidator` - `LowercaseValidator` - `NumericValidator` - `SpecialCharacterValidator` - `AsciiValidator` Each validator is tested for successful validation, failure cases with appropriate error messages, and correct help text generation. This ensures the reliability and correctness of the password validation system.
1 parent 033a2cc commit 91644b8

File tree

1 file changed

+241
-0
lines changed

1 file changed

+241
-0
lines changed
Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
import django.core.exceptions
2+
import django.test
3+
4+
import user.validators
5+
6+
7+
class PasswordValidatorTests(django.test.TestCase):
8+
def test_uppercase_validator_init(self):
9+
validator = user.validators.UppercaseValidator()
10+
self.assertEqual(validator.min_count, 1)
11+
self.assertEqual(validator.code, 'password_no_uppercase')
12+
13+
validator = user.validators.UppercaseValidator(min_count=3)
14+
self.assertEqual(validator.min_count, 3)
15+
16+
def test_uppercase_validator_validate_success(self):
17+
validator = user.validators.UppercaseValidator(min_count=2)
18+
validator.validate('PaSsword123')
19+
validator.validate(
20+
'TESTINGpassword',
21+
)
22+
23+
def test_uppercase_validator_validate_failure(self):
24+
validator = user.validators.UppercaseValidator(min_count=2)
25+
with self.assertRaisesMessage(
26+
django.core.exceptions.ValidationError,
27+
'Password must contain at least 2 uppercase letters.',
28+
):
29+
validator.validate('password123')
30+
31+
with self.assertRaisesMessage(
32+
django.core.exceptions.ValidationError,
33+
'Password must contain at least 2 uppercase letters.',
34+
):
35+
validator.validate('Password123!')
36+
37+
def test_uppercase_validator_validate_non_ascii(self):
38+
validator = user.validators.UppercaseValidator(min_count=1)
39+
validator.validate('PÄssword123')
40+
with self.assertRaisesMessage(
41+
django.core.exceptions.ValidationError,
42+
'Password must contain at least 1 uppercase letter.',
43+
):
44+
validator.validate('ässword123')
45+
46+
def test_uppercase_validator_get_help_text(self):
47+
validator = user.validators.UppercaseValidator(min_count=1)
48+
self.assertEqual(
49+
validator.get_help_text(),
50+
'Your password must contain at least 1 uppercase letter.',
51+
)
52+
53+
validator = user.validators.UppercaseValidator(min_count=2)
54+
self.assertEqual(
55+
validator.get_help_text(),
56+
'Your password must contain at least 2 uppercase letters.',
57+
)
58+
59+
def test_lowercase_validator_init(self):
60+
validator = user.validators.LowercaseValidator()
61+
self.assertEqual(validator.min_count, 1)
62+
self.assertEqual(validator.code, 'password_no_lowercase')
63+
64+
validator = user.validators.LowercaseValidator(min_count=3)
65+
self.assertEqual(validator.min_count, 3)
66+
67+
def test_lowercase_validator_validate_success(self):
68+
validator = user.validators.LowercaseValidator(min_count=2)
69+
validator.validate('password123')
70+
validator.validate('PASSWORDtest')
71+
72+
def test_lowercase_validator_validate_failure(self):
73+
validator = user.validators.LowercaseValidator(min_count=2)
74+
with self.assertRaisesMessage(
75+
django.core.exceptions.ValidationError,
76+
'Password must contain at least 2 lowercase letters.',
77+
):
78+
validator.validate('PASSWORD123')
79+
80+
with self.assertRaisesMessage(
81+
django.core.exceptions.ValidationError,
82+
'Password must contain at least 2 lowercase letters.',
83+
):
84+
validator.validate('PAsSWORD123!')
85+
86+
def test_lowercase_validator_validate_non_ascii(self):
87+
validator = user.validators.LowercaseValidator(min_count=1)
88+
validator.validate('pAssword123')
89+
with self.assertRaisesMessage(
90+
django.core.exceptions.ValidationError,
91+
'Password must contain at least 1 lowercase letter.',
92+
):
93+
validator.validate(
94+
'PASSWORd123',
95+
)
96+
validator.validate('PASSWORD')
97+
98+
def test_lowercase_validator_get_help_text(self):
99+
validator = user.validators.LowercaseValidator(min_count=1)
100+
self.assertEqual(
101+
validator.get_help_text(),
102+
'Your password must contain at least 1 lowercase letter.',
103+
)
104+
105+
validator = user.validators.LowercaseValidator(min_count=2)
106+
self.assertEqual(
107+
validator.get_help_text(),
108+
'Your password must contain at least 2 lowercase letters.',
109+
)
110+
111+
def test_numeric_validator_init(self):
112+
validator = user.validators.NumericValidator()
113+
self.assertEqual(validator.min_count, 1)
114+
self.assertEqual(validator.code, 'password_no_number')
115+
116+
validator = user.validators.NumericValidator(min_count=3)
117+
self.assertEqual(validator.min_count, 3)
118+
119+
def test_numeric_validator_validate_success(self):
120+
validator = user.validators.NumericValidator(min_count=2)
121+
validator.validate('password123')
122+
validator.validate('123abc456')
123+
124+
def test_numeric_validator_validate_failure(self):
125+
validator = user.validators.NumericValidator(min_count=2)
126+
with self.assertRaisesMessage(
127+
django.core.exceptions.ValidationError,
128+
'Password must contain at least 2 digits.',
129+
):
130+
validator.validate('password')
131+
132+
with self.assertRaisesMessage(
133+
django.core.exceptions.ValidationError,
134+
'Password must contain at least 2 digits.',
135+
):
136+
validator.validate('password1')
137+
138+
def test_numeric_validator_get_help_text(self):
139+
validator = user.validators.NumericValidator(min_count=1)
140+
self.assertEqual(
141+
validator.get_help_text(),
142+
'Your password must contain at least 1 digit.',
143+
)
144+
145+
validator = user.validators.NumericValidator(min_count=2)
146+
self.assertEqual(
147+
validator.get_help_text(),
148+
'Your password must contain at least 2 digits.',
149+
)
150+
151+
def test_special_character_validator_init(self):
152+
validator = user.validators.SpecialCharacterValidator()
153+
self.assertEqual(validator.min_count, 1)
154+
self.assertEqual(validator.code, 'password_no_special_char')
155+
self.assertEqual(
156+
validator.pattern.pattern,
157+
user.validators.SpecialCharacterValidator.DEFAULT_SPECIAL_CHARS,
158+
)
159+
160+
validator = user.validators.SpecialCharacterValidator(
161+
min_count=3,
162+
special_chars=r'[@#$]',
163+
)
164+
self.assertEqual(validator.min_count, 3)
165+
self.assertEqual(validator.pattern.pattern, r'[@#$]')
166+
167+
def test_special_character_validator_validate_success(self):
168+
validator = user.validators.SpecialCharacterValidator(min_count=2)
169+
validator.validate('password!@')
170+
validator.validate('test$%^&')
171+
172+
custom_validator = user.validators.SpecialCharacterValidator(
173+
min_count=1,
174+
special_chars=r'[!@#]',
175+
)
176+
custom_validator.validate('password!')
177+
custom_validator.validate('password@')
178+
custom_validator.validate('password#')
179+
180+
def test_special_character_validator_validate_failure(self):
181+
validator = user.validators.SpecialCharacterValidator(min_count=2)
182+
with self.assertRaisesMessage(
183+
django.core.exceptions.ValidationError,
184+
'Password must contain at least 2 special characters.',
185+
):
186+
validator.validate('password')
187+
188+
with self.assertRaisesMessage(
189+
django.core.exceptions.ValidationError,
190+
'Password must contain at least 2 special characters.',
191+
):
192+
validator.validate('password!')
193+
194+
custom_validator = user.validators.SpecialCharacterValidator(
195+
min_count=1,
196+
special_chars=r'[!@#]',
197+
)
198+
with self.assertRaisesMessage(
199+
django.core.exceptions.ValidationError,
200+
'Password must contain at least 1 special character.',
201+
):
202+
custom_validator.validate('password$')
203+
204+
def test_special_character_validator_get_help_text(self):
205+
validator = user.validators.SpecialCharacterValidator(min_count=1)
206+
self.assertEqual(
207+
validator.get_help_text(),
208+
'Your password must contain at least 1 special character.',
209+
)
210+
211+
validator = user.validators.SpecialCharacterValidator(min_count=2)
212+
self.assertEqual(
213+
validator.get_help_text(),
214+
'Your password must contain at least 2 special characters.',
215+
)
216+
217+
def test_ascii_validator_init(self):
218+
validator = user.validators.AsciiValidator()
219+
self.assertEqual(validator.code, 'password_not_ascii')
220+
221+
def test_ascii_validator_validate_success(self):
222+
validator = user.validators.AsciiValidator()
223+
validator.validate('password123!@#')
224+
225+
def test_ascii_validator_validate_failure(self):
226+
validator = user.validators.AsciiValidator()
227+
with self.assertRaisesMessage(
228+
django.core.exceptions.ValidationError,
229+
'Password contains non-ASCII characters.',
230+
):
231+
validator.validate('passwordñ')
232+
233+
def test_ascii_validator_get_help_text(self):
234+
validator = user.validators.AsciiValidator()
235+
self.assertEqual(
236+
validator.get_help_text(),
237+
(
238+
'Your password must only contain standard English letters,'
239+
' digits, and symbols.'
240+
),
241+
)

0 commit comments

Comments
 (0)