From a1d4ef498ba8addb66a006c2dc51e8d6604efe17 Mon Sep 17 00:00:00 2001 From: Ruidy Date: Tue, 3 Aug 2021 14:28:58 +0200 Subject: [PATCH] feat: can read stored passwords --- app/data/sqlite.py | 4 ++-- app/data/type.py | 3 ++- app/main.py | 9 ++++++++- app/repositories/fake.py | 3 +++ app/repositories/sqlite.py | 3 +++ app/repositories/type.py | 3 +++ app/usecases/pass_gen.py | 4 ++++ tests/main_test.py | 14 +++++++++++++- tests/pass_gen_test.py | 10 +++++++++- 9 files changed, 47 insertions(+), 6 deletions(-) diff --git a/app/data/sqlite.py b/app/data/sqlite.py index d44b986..1d23722 100644 --- a/app/data/sqlite.py +++ b/app/data/sqlite.py @@ -11,5 +11,5 @@ class DB: def commit(self) -> None: self.connection.commit() - def execute(self, query: str, *args: Any) -> None: - self.cursor.execute(query, *args) + def execute(self, query: str, *args: Any) -> sqlite3.Cursor: + return self.cursor.execute(query, *args) diff --git a/app/data/type.py b/app/data/type.py index 9648bd8..f9f2570 100644 --- a/app/data/type.py +++ b/app/data/type.py @@ -1,3 +1,4 @@ +from sqlite3 import Cursor from typing import Any, Protocol @@ -5,5 +6,5 @@ class DBConnector(Protocol): def commit(self) -> None: ... - def execute(self, query: str, *args: Any) -> None: + def execute(self, query: str, *args: Any) -> Cursor: ... diff --git a/app/main.py b/app/main.py index db08e7d..b3cceba 100644 --- a/app/main.py +++ b/app/main.py @@ -11,7 +11,7 @@ app = typer.Typer() @app.command() -def main( +def save( length: int = typer.Option( 8, "--length", @@ -57,3 +57,10 @@ def main( utils.copy_to_clipboard(password) return typer.echo("The password has been copied to your clipboard 😉\nPaste it using cmd + v") + + +@app.command() +def read() -> None: + sqlite_repo = sqlite.get_instance() + stored_passwords = sqlite_repo.list_all() + typer.echo(stored_passwords) diff --git a/app/repositories/fake.py b/app/repositories/fake.py index d486049..e5a4822 100644 --- a/app/repositories/fake.py +++ b/app/repositories/fake.py @@ -5,6 +5,9 @@ class FakeRepository: def save(self, password: str) -> None: ... + def list_all(self) -> list[str]: + return ["2yW4AcqG", "iK2ZWeqh"] + @classmethod def get_instance(cls) -> FakeRepository: return FakeRepository() diff --git a/app/repositories/sqlite.py b/app/repositories/sqlite.py index edd8077..13e9eba 100644 --- a/app/repositories/sqlite.py +++ b/app/repositories/sqlite.py @@ -13,6 +13,9 @@ class PasswordRepository: except Exception as e: print(e) + def list_all(self) -> list[str]: + return [row[0] for row in self.db.execute("SELECT * FROM passwords").fetchall()] + def get_instance() -> PasswordRepository: db = sqlite.DB() diff --git a/app/repositories/type.py b/app/repositories/type.py index e0d74b6..dd56122 100644 --- a/app/repositories/type.py +++ b/app/repositories/type.py @@ -4,3 +4,6 @@ from typing import Protocol class Repository(Protocol): def save(self, password: str) -> None: ... + + def list_all(self) -> list[str]: + ... diff --git a/app/usecases/pass_gen.py b/app/usecases/pass_gen.py index 8b5b02d..15b3d68 100644 --- a/app/usecases/pass_gen.py +++ b/app/usecases/pass_gen.py @@ -39,3 +39,7 @@ def _build_characters(symbols: bool, numbers: bool) -> str: string.digits if numbers else "", ] ) + + +def list_all_saved_passwords(repo: Repository) -> list[str]: + return repo.list_all() diff --git a/tests/main_test.py b/tests/main_test.py index 3de76b8..8a87b08 100644 --- a/tests/main_test.py +++ b/tests/main_test.py @@ -40,7 +40,19 @@ def test_cli_can_save_to_file() -> None: assert "2yW4AcqG" in content +def test_cli_can_save_to_db() -> None: + _run_cli() + result = _run_cli_read() + assert "2yW4AcqG" in result.stdout + + def _run_cli(*args: Any) -> Result: - result = runner.invoke(app, ["--no-random", *args]) + result = runner.invoke(app, ["save", "--no-random", *args]) + assert result.exit_code == 0 + return result + + +def _run_cli_read(*args: Any) -> Result: + result = runner.invoke(app, ["read", *args]) assert result.exit_code == 0 return result diff --git a/tests/pass_gen_test.py b/tests/pass_gen_test.py index 140d29e..fa43351 100644 --- a/tests/pass_gen_test.py +++ b/tests/pass_gen_test.py @@ -1,7 +1,7 @@ import pytest from app.repositories.fake import FakeRepository -from app.usecases.pass_gen import PassGenOptions, generate_password +from app.usecases.pass_gen import PassGenOptions, generate_password, list_all_saved_passwords fake_repo = FakeRepository.get_instance() @@ -52,3 +52,11 @@ def test_password_can_contain_symbols(seed: int, symbols: bool, expected: str) - def test_password_can_contain_numbers(seed: int, numbers: bool, expected: str) -> None: options = PassGenOptions(seed=seed, numbers=numbers) assert generate_password(fake_repo, options) == expected + + +@pytest.mark.parametrize( + "expected", + [["2yW4AcqG", "iK2ZWeqh"]], +) +def test_can_read_all_saved_passwords(expected: list[str]) -> None: + assert list_all_saved_passwords(fake_repo) == expected