diff --git a/src/passwordler/generate_password.py b/src/passwordler/generate_password.py index f46e65d..f0206cb 100644 --- a/src/passwordler/generate_password.py +++ b/src/passwordler/generate_password.py @@ -1,3 +1,6 @@ +import random +import string + def generate_password(length=12, include_symbols=True, include_numbers=True): """ Generate a password. @@ -12,4 +15,39 @@ def generate_password(length=12, include_symbols=True, include_numbers=True): Returns: str: A randomly generated password. - """ \ No newline at end of file + """ + + if not isinstance(length, int): + raise TypeError("Length must be an integer.") + + if length < 12 or length > 100: + raise ValueError("Password length must be between 12 and 100 characters.") + + if not isinstance(include_symbols, bool): + raise TypeError("include_symbols must be a boolean value.") + + if not isinstance(include_numbers, bool): + raise TypeError("include_numbers must be a boolean value.") + + # Ensure that the password contains at least one of each type of character specified + password_characters = [random.choice(string.ascii_uppercase), random.choice(string.ascii_lowercase)] + if include_numbers: + password_characters.append(random.choice(string.digits)) + if include_symbols: + password_characters.append(random.choice(string.punctuation)) + + # Generate master list of characters to choose from + possible_chars = string.ascii_letters + if include_numbers: + possible_chars += string.digits + if include_symbols: + possible_chars += string.punctuation + + # Fill the rest of the password length with random characters from the possible set + password_characters.extend(random.choice(possible_chars) for _ in range(length - len(password_characters))) + + random.shuffle(password_characters) + + final_password = ''.join(password_characters) + print(f'Your password is: {final_password}') + return final_password \ No newline at end of file diff --git a/tests/test_generate_password.py b/tests/test_generate_password.py new file mode 100644 index 0000000..0fcea28 --- /dev/null +++ b/tests/test_generate_password.py @@ -0,0 +1,56 @@ +from passwordler.generate_password import generate_password +from passwordler.password_strength import password_strength +import pytest + +def test_generate_password_type_error(): + """ + Test if the function returns a TypeError if the type of the input is not correct. + """ + with pytest.raises(TypeError, match="Length must be an integer."): + generate_password("abc") + +def test_generate_password_value_error(): + """ + Test if the function returns a ValueError if the value of the input is not correct. + """ + with pytest.raises(ValueError, match="Password length must be between 12 and 100 characters."): + generate_password(1) + +def test_generate_password_include_symbols_type_error(): + """ + Test if the function returns a TypeError if the type of the input is not correct. + """ + with pytest.raises(TypeError, match="include_symbols must be a boolean value."): + generate_password(12, include_symbols="abc") + +def test_generate_password_include_numbers_type_error(): + """ + Test if the function returns a TypeError if the type of the input is not correct. + """ + with pytest.raises(TypeError, match="include_numbers must be a boolean value."): + generate_password(12, include_numbers="abc") + +def test_generate_password_length(): + """ + Test if the length of the generated password is correct. + """ + assert len(generate_password(12)) == 12 + assert len(generate_password(100)) == 100 + +def test_generate_password_include_symbols(): + """ + Test if the generated password includes symbols. + """ + assert any(char in generate_password(12, include_symbols=True) for char in "!@#$%^&*()") + +def test_generate_password_include_numbers(): + """ + Test if the generated password includes numbers. + """ + assert any(char in generate_password(12, include_numbers=True) for char in "0123456789") + +def test_generate_password_strength(): + """ + Test if the generated password has the correct strength. + """ + assert password_strength(generate_password(12)) == "Your password is: Strong" \ No newline at end of file