FIX: Error when length less than 4 in Provider().password() #2176
What does this change
Adds a warning message and adjusts the password length when the requested length is less than the number of required character categories (special characters, digits, uppercase, and lowercase).
What was wrong
When the password length was less than 4 (for example, 2), the password() function did not ensure that all required character types would be included, leading to unexpected behavior. This caused an error when the length was smaller than the minimum required for character categories.
How this fixes it
The modification checks if the requested password length is smaller than the number of required character categories. In that case, the function automatically adjusts the password length to the minimum value needed to fulfill the requirements for each character category. Additionally, a warning message is printed to inform the user of this adjustment.
Fixes #2176
Checklist
- [x] I have read the documentation about CONTRIBUTING
- [x] I have read the documentation about Coding style
- [x] I have run
make lint
Hi @fcurella, I tested everything locally with this code:
import unittest
import string
# Correct import of the password function
from faker.password_generator import password # Adjust the import to your project structure
class TestPasswordGenerator(unittest.TestCase):
def test_length(self):
# Test if the length of the password is correct
pw = password(length=12)
self.assertEqual(len(pw), 12, "Password length should be 12")
def test_special_chars(self):
# Test if the password contains at least one special character
pw = password(special_chars=True, length=10)
self.assertTrue(any(c in "!@#$%^&*()_+" for c in pw), "Password should contain at least one special character")
def test_digits(self):
# Test if the password contains at least one digit
pw = password(digits=True, length=10)
self.assertTrue(any(c in string.digits for c in pw), "Password should contain at least one digit")
def test_upper_case(self):
# Test if the password contains at least one uppercase letter
pw = password(upper_case=True, length=10)
self.assertTrue(any(c in string.ascii_uppercase for c in pw), "Password should contain at least one uppercase letter")
def test_lower_case(self):
# Test if the password contains at least one lowercase letter
pw = password(lower_case=True, length=10)
self.assertTrue(any(c in string.ascii_lowercase for c in pw), "Password should contain at least one lowercase letter")
def test_no_special_chars(self):
# Test if the password does not contain special characters when special_chars is False
pw = password(special_chars=False, length=10)
self.assertTrue(all(c not in "!@#$%^&*()_+" for c in pw), "Password should not contain special characters")
def test_all_requirements(self):
# Test if the password contains all the required character types
pw = password(special_chars=True, digits=True, upper_case=True, lower_case=True, length=12)
self.assertTrue(any(c in "!@#$%^&*()_+" for c in pw), "Password should contain at least one special character")
self.assertTrue(any(c in string.digits for c in pw), "Password should contain at least one digit")
self.assertTrue(any(c in string.ascii_uppercase for c in pw), "Password should contain at least one uppercase letter")
self.assertTrue(any(c in string.ascii_lowercase for c in pw), "Password should contain at least one lowercase letter")
def test_length_adjustment_for_required_characters(self):
# Test if the length is increased when the required character types exceed the requested length
pw = password(special_chars=True, digits=True, length=4)
self.assertGreaterEqual(len(pw), 6, "Password length should be at least 6 if multiple character types are required")
if __name__ == "__main__":
unittest.main()
Where and how should I add the tests you ask me?
@DevFoxxx you can add it to this testcase
As per the comment of @fcurella, please add the test case to the test suite in this PR.
Also, I would prefer to keep the error in case the password length is smaller than the number of required character categories. As end user, if I override the default length (10) to something lower then the categories... is because I want that length. but if it is not compatible with the categories, I would expect an error from the package.