diff --git a/tests/bdd/features/override.feature b/tests/bdd/features/override.feature index d4b46e97..ef761d9c 100644 --- a/tests/bdd/features/override.feature +++ b/tests/bdd/features/override.feature @@ -3,7 +3,7 @@ Feature: Implementing Runtime Overrides for Select Configuration Keys Scenario: Override configured editor with built-in input === editor:'' Given we use the config "basic_encrypted.yaml" And we use the password "test" if prompted - When we run "jrnl --config-override editor ''" and enter + When we run "jrnl --config-override editor ''" and pipe This is a journal entry Then the stdin prompt should have been called And the editor should not have been called diff --git a/tests/bdd/features/upgrade.feature b/tests/bdd/features/upgrade.feature index 23628eb7..c092dedb 100644 --- a/tests/bdd/features/upgrade.feature +++ b/tests/bdd/features/upgrade.feature @@ -41,7 +41,7 @@ Feature: Upgrading Journals from 1.x.x to 2.x.x Scenario: Upgrade with missing journal Given we use the config "upgrade_from_195_with_missing_journal.json" When we run "jrnl --list" and enter "Y" - Then the output should contain "Error: features/journals/missing.journal does not exist." + Then the output should contain "features/journals/missing.journal does not exist" And we should get no error Scenario: Upgrade with missing encrypted journal @@ -49,6 +49,6 @@ Feature: Upgrading Journals from 1.x.x to 2.x.x When we run "jrnl --list" and enter Y bad doggie no biscuit - Then the output should contain "features/journals/missing.journal does not exist." + Then the output should contain "features/journals/missing.journal does not exist" And the output should contain "We're all done" And we should get no error diff --git a/tests/lib/fixtures.py b/tests/lib/fixtures.py index 109782ee..7f510585 100644 --- a/tests/lib/fixtures.py +++ b/tests/lib/fixtures.py @@ -6,6 +6,7 @@ import os from pathlib import Path import tempfile +from collections.abc import Iterable from keyring import backend from keyring import errors from pytest import fixture @@ -13,6 +14,7 @@ from unittest.mock import patch from unittest.mock import Mock from .helpers import get_fixture import toml +from rich.console import Console from jrnl.config import load_config from jrnl.os_compat import split_args @@ -86,7 +88,6 @@ def cli_run( mock_editor, mock_user_input, mock_overrides, - mock_piped_input, ): # Check if we need more mocks mock_factories.update(mock_args) @@ -95,7 +96,6 @@ def cli_run( mock_factories.update(mock_editor) mock_factories.update(mock_config_path) mock_factories.update(mock_user_input) - mock_factories.update(mock_piped_input) return { "status": 0, @@ -203,53 +203,72 @@ def should_not(): # @todo is this named properly? does it need to be merged with user_input? does # it only mock piped input? or also user input? -@fixture -def mock_piped_input(request, is_tty): - def _mock_piped_input(): - piped_input = get_fixture(request, "all_input", None) +# @fixture +# def mock_stdin_input(request, is_tty): +# def _mock_stdin_input(): +# stdin_input = get_fixture(request, "all_input", None) - if piped_input is None: - piped_input = Exception("Unexpected call for piped input") - else: - piped_input = [piped_input] +# if stdin_input is None: +# stdin_input = Exception("Unexpected call for piped input") +# else: +# stdin_input = [stdin_input] - if is_tty: - piped_input = [] +# if is_tty: +# stdin_input = [] - return patch("sys.stdin.read", side_effect=piped_input) +# return patch("sys.stdin.read", side_effect=stdin_input) - return {"piped_input": _mock_piped_input} +# return {"stdin_input": _mock_stdin_input} @fixture -def mock_user_input(request): +def mock_user_input(request, password_input, stdin_input): def _mock_user_input(): - from rich.console import Console - + # user_input needs to be here because we don't know it until cli_run starts user_input = get_fixture(request, "all_input", None) - password_input = get_fixture(request, "password", None) - if user_input is None: user_input = Exception("Unexpected call for user input") else: user_input = iter(user_input.splitlines()) - if password_input is None: - password_input = Exception("Unexpected call for password input") - def mock_console_input(**kwargs): - if kwargs["password"]: + # import ipdb; ipdb.sset_trace() + if kwargs["password"] and not isinstance(password_input, Exception): return password_input - else: + + if isinstance(user_input, Iterable): return next(user_input) + # exceptions + return user_input if not kwargs["password"] else password_input + mock_console = Mock(wraps=Console(stderr=True)) - mock_console.input = Mock() - mock_console.input = mock_console_input + mock_console.input = Mock(side_effect=mock_console_input) return patch("jrnl.output._get_console", return_value=mock_console) - return {"user_input": _mock_user_input} + return { + "user_input": _mock_user_input, + "stdin_input": lambda: patch("sys.stdin.read", side_effect=stdin_input), + } + + +@fixture +def password_input(request): + password_input = get_fixture(request, "password", None) + if password_input is None: + password_input = Exception("Unexpected call for password input") + return password_input + + +@fixture +def stdin_input(request, is_tty): + stdin_input = get_fixture(request, "all_input", None) + if stdin_input is None or is_tty: + stdin_input = Exception("Unexpected call for stdin input") + else: + stdin_input = [stdin_input] + return stdin_input @fixture diff --git a/tests/lib/given_steps.py b/tests/lib/given_steps.py index dd7c4720..4b545849 100644 --- a/tests/lib/given_steps.py +++ b/tests/lib/given_steps.py @@ -120,9 +120,9 @@ def config_exists(config_file, temp_dir, working_dir): shutil.copy2(config_source, config_dest) -@given(parse('we use the password "{pw}" if prompted'), target_fixture="password") -def use_password_forever(pw): - return pw +@given(parse('we use the password "{password}" if prompted')) +def use_password_forever(password): + return password @given("we create a cache directory", target_fixture="cache_dir") diff --git a/tests/lib/then_steps.py b/tests/lib/then_steps.py index a3b1c9a7..8abf9c16 100644 --- a/tests/lib/then_steps.py +++ b/tests/lib/then_steps.py @@ -364,7 +364,7 @@ def count_editor_args(num_args, cli_run, editor_state, should_or_should_not): def stdin_prompt_called(cli_run, should_or_should_not): we_should = parse_should_or_should_not(should_or_should_not) - assert cli_run["mocks"]["piped_input"].called == we_should + assert cli_run["mocks"]["stdin_input"].called == we_should @then(parse('the editor filename should end with "{suffix}"'))