From 69f1a801dec2baa9359c6be7b38e44b76b7a2375 Mon Sep 17 00:00:00 2001 From: Ruidy Date: Mon, 5 Jul 2021 20:07:40 +0200 Subject: [PATCH] feat: control numbers --- README.md | 2 +- app/main.py | 9 ++++++--- app/main_test.py | 9 ++++++++- app/pass_gen.py | 16 +++++++++------- app/pass_gen_test.py | 15 +++++++++++++-- 5 files changed, 37 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index aa22c69..f2ea8ba 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ - [x] As a user I want to generate a random secure password to protect my personal accounts - [x] Minimal length - [x] Include symbols - - [ ] Include numbers + - [x] Include numbers - [ ] Include lowercase characters - [ ] Include uppercase characters - [ ] As a user I want the generated password to be copied to the clipboard diff --git a/app/main.py b/app/main.py index 593277e..042b22d 100644 --- a/app/main.py +++ b/app/main.py @@ -11,13 +11,16 @@ app = typer.Typer() def main( random: bool = True, length: int = typer.Option(8, help="Length of the generated password."), + numbers: bool = typer.Option( + True, help="If the generated password should include numeric characters." + ), symbols: bool = typer.Option( - False, help="If the generated password should includes special characters." + False, help="If the generated password should include special characters." ), ) -> None: seed = r.randint(0, 100) if random else 0 - typer.echo(generate_password(seed, length, symbols)) + typer.echo(generate_password(seed, length, symbols, numbers)) if __name__ == "__main__": - app() + app() # pragma nocover diff --git a/app/main_test.py b/app/main_test.py index 8b904fa..391eb34 100644 --- a/app/main_test.py +++ b/app/main_test.py @@ -20,7 +20,14 @@ def test_cli_can_set_symbols() -> None: args = ["--symbols"] result = _run_cli(*args) print(result.stdout) - assert "X1fH$!ZM" in result.stdout + assert """X"fH.+ZM""" in result.stdout + + +def test_cli_can_set_numbers() -> None: + args = ["--no-numbers"] + result = _run_cli(*args) + print(result.stdout) + assert "yWAcqGFz" in result.stdout def _run_cli(*args) -> Result: diff --git a/app/pass_gen.py b/app/pass_gen.py index 23783f8..49f4f09 100644 --- a/app/pass_gen.py +++ b/app/pass_gen.py @@ -3,8 +3,10 @@ import string from typing import Protocol -def generate_password(seed: int, length: int = 8, symbols: bool = False) -> str: - characters = _build_characters(symbols) +def generate_password( + seed: int, length: int = 8, symbols: bool = False, numbers: bool = True +) -> str: + characters = _build_characters(symbols=symbols, numbers=numbers) random_generator = _new_random_generator(seed) @@ -20,15 +22,15 @@ def _new_random_generator(seed: int) -> RandomSampler: return random.Random(seed) -def _build_characters(symbols: bool) -> str: +def _build_characters(symbols: bool, numbers: bool) -> str: lowercase = string.ascii_lowercase uppercase = string.ascii_uppercase - digits = string.digits - punctuation = string.punctuation - characters = lowercase + uppercase + digits + characters = lowercase + uppercase if symbols: - characters += punctuation + characters += string.punctuation + if numbers: + characters += string.digits return characters diff --git a/app/pass_gen_test.py b/app/pass_gen_test.py index b6bdd8a..c845ec1 100644 --- a/app/pass_gen_test.py +++ b/app/pass_gen_test.py @@ -27,9 +27,20 @@ def test_control_password_length(seed: int, length: int, expected: str) -> None: @pytest.mark.parametrize( ("seed", "symbols", "expected"), [ - (0, True, "X1fH$!ZM"), - (1, True, """r+iGp"58"""), + (0, True, """X"fH.+ZM"""), + (1, True, """r?iGp,&)"""), ], ) def test_password_can_contain_symbols(seed: int, symbols: bool, expected: str) -> None: assert generate_password(seed, symbols=symbols) == expected + + +@pytest.mark.parametrize( + ("seed", "numbers", "expected"), + [ + (0, False, "yWAcqGFz"), + (1, False, "iKWeqhFC"), + ], +) +def test_password_can_contain_numbers(seed: int, numbers: bool, expected: str) -> None: + assert generate_password(seed, numbers=numbers) == expected