From a6694f5273c1c5969ef21ee71cae3a5ebbeae740 Mon Sep 17 00:00:00 2001 From: Jonathan Wren Date: Sat, 27 Nov 2021 14:21:23 -0800 Subject: [PATCH] fix handling of user input (stdin, input, getpass) --- tests/bdd/features/config_file.feature | 1 + tests/lib/fixtures.py | 40 ++++++++++++++++---------- tests/lib/when_steps.py | 8 ++++-- 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/tests/bdd/features/config_file.feature b/tests/bdd/features/config_file.feature index 27acdbeb..5f93aa62 100644 --- a/tests/bdd/features/config_file.feature +++ b/tests/bdd/features/config_file.feature @@ -88,6 +88,7 @@ Feature: Multiple journals Scenario: Don't overwrite main config when decrypting a journal in an alternate config Given the config "editor_encrypted.yaml" exists + And we use the password "bad doggie no biscuit" if prompted And we use the config "basic_encrypted.yaml" When we run "jrnl --cf editor_encrypted.yaml --decrypt" Then the config should contain "encrypt: true" diff --git a/tests/lib/fixtures.py b/tests/lib/fixtures.py index d34dbc90..51e6106b 100644 --- a/tests/lib/fixtures.py +++ b/tests/lib/fixtures.py @@ -182,19 +182,22 @@ def toml_version(working_dir): @fixture def mock_password(request): - password = get_fixture(request, "password") - user_input = get_fixture(request, "user_input") + def _mock_password(): + password = get_fixture(request, "password") + user_input = get_fixture(request, "user_input") - if password: - password = password.splitlines() + if password: + password = password.splitlines() - elif user_input: - password = user_input.splitlines() + elif user_input: + password = user_input.splitlines() - if not password: - return {} + if not password: + password = Exception("Unexpected call for password") - return {"getpass": lambda: patch("getpass.getpass", side_effect=password)} + return patch("getpass.getpass", side_effect=password) + + return {"getpass": _mock_password} @fixture @@ -219,14 +222,21 @@ def should_not(): @fixture def mock_user_input(request, is_tty): - user_input = get_fixture(request, "user_input", "") - user_input = user_input.splitlines() if is_tty else [user_input] - if not user_input: - return {} + def _generator(target): + def _mock_user_input(): + user_input = get_fixture(request, "user_input", "") + user_input = user_input.splitlines() if is_tty else [user_input] + + if not user_input: + user_input = Exception("Unexpected call for user input") + + return patch(target, side_effect=user_input) + + return _mock_user_input return { - "stdin": lambda: patch("sys.stdin.read", side_effect=user_input), - "input": lambda: patch("builtins.input", side_effect=user_input), + "stdin": _generator("sys.stdin.read"), + "input": _generator("builtins.input"), } diff --git a/tests/lib/when_steps.py b/tests/lib/when_steps.py index 35251a8c..a715d947 100644 --- a/tests/lib/when_steps.py +++ b/tests/lib/when_steps.py @@ -20,10 +20,11 @@ def when_we_change_directory(directory_name): command = '(?P[^"]+)' -input_method = '(?Penter|pipe)' +input_method = "(?Penter|pipe)" user_input = '(?P[^"]+)' -@when(re(f'we run "jrnl {command}" and {input_method}\n{user_input}')) -@when(re(f'we run "jrnl" and {input_method}\n{user_input}')) + + +@when(parse('we run "jrnl {command}" and {input_method}\n{user_input}')) @when(re(f'we run "jrnl {command}" and {input_method} "{user_input}"')) @when(re(f'we run "jrnl" and {input_method} "{user_input}"')) @when(parse('we run "jrnl {command}"')) @@ -36,6 +37,7 @@ def we_run_jrnl(cli_run, capsys, keyring): with ExitStack() as stack: mocks = cli_run["mocks"] factories = cli_run["mock_factories"] + for id in factories: mocks[id] = stack.enter_context(factories[id]())