From 91da48edab2320dbe72b3523c615d6df8e21cfa1 Mon Sep 17 00:00:00 2001 From: Kegan Maher Date: Fri, 22 Mar 2024 17:05:18 +0000 Subject: [PATCH] fix(config): ensure .current file exists before usage before this change, only the _get_current_path() helper ensured .current existed with this change, both _get_current_path() and _update_current_path() ensure .current exists --- littlepay/config.py | 19 ++++++++++++++++--- tests/test_config.py | 35 ++++++++++++++++++++++++++++++----- 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/littlepay/config.py b/littlepay/config.py index 833646b..579202c 100644 --- a/littlepay/config.py +++ b/littlepay/config.py @@ -21,14 +21,26 @@ CONFIG_TYPES = list(DEFAULT_ACTIVE.keys()) +def _ensure_current_exists() -> bool: + """ + Creates the CONFIG_FILE_CURRENT file if it doesn't already exist. + + Returns (bool): + A flag indicating if the file existed or not. + """ + exists = CONFIG_FILE_CURRENT.exists() + if not exists: + CONFIG_FILE_CURRENT.parent.mkdir(parents=True, exist_ok=True) + CONFIG_FILE_CURRENT.touch() + return exists + + def _get_current_path() -> Path: """ Returns (Path): The path to the config file currently in-use, or the default. """ - CONFIG_FILE_CURRENT.parent.mkdir(parents=True, exist_ok=True) - if not CONFIG_FILE_CURRENT.exists(): - CONFIG_FILE_CURRENT.touch() + if not _ensure_current_exists(): _update_current_path(DEFAULT_CONFIG_FILE) current = CONFIG_FILE_CURRENT.read_text().strip() return Path(current) @@ -38,6 +50,7 @@ def _update_current_path(new_path: str | Path): """Saves new_path as the path to the current config file.""" if isinstance(new_path, Path): new_path = str(new_path.expanduser().absolute()) + _ensure_current_exists() CONFIG_FILE_CURRENT.write_text(new_path) diff --git a/tests/test_config.py b/tests/test_config.py index 17abd6f..c777c66 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -6,6 +6,7 @@ from littlepay.config import ( DEFAULT_CONFIG, DEFAULT_CREDENTIALS, + _ensure_current_exists, _get_current_path, _read_config, _write_config, @@ -15,45 +16,69 @@ from tests.conftest import CUSTOM_CONFIG_FILE -def test_get_current_path_default(custom_config_file: Path): +@pytest.fixture +def spy_ensure_current_exists(mocker): + return mocker.spy(littlepay.config, "_ensure_current_exists") + + +def test_ensure_current_exists(): + # reminder: the module-level variable littlepay.config.CONFIG_FILE_CURRENT + # is overwritten by the autouse fixture custom_current_file + + # the .current file should not exist to begin with + assert not littlepay.config.CONFIG_FILE_CURRENT.exists() + assert _ensure_current_exists() is False + + # now having ensured, the current file should exist + assert littlepay.config.CONFIG_FILE_CURRENT.exists() + # subsequent calls to ensure should indicate that it already exists + assert _ensure_current_exists() + + +def test_get_current_path_default(custom_config_file: Path, spy_ensure_current_exists): result = _get_current_path() assert isinstance(result, Path) assert result.absolute() == custom_config_file.absolute() + assert spy_ensure_current_exists.call_count > 0 -def test_get_current_path_custom(custom_current_file: Path): +def test_get_current_path_custom(custom_current_file: Path, spy_ensure_current_exists): expected = "." custom_current_file.write_text(expected) result = _get_current_path() assert result == Path(expected) + assert spy_ensure_current_exists.call_count > 0 -def test_get_current_path_newline(custom_current_file: Path): +def test_get_current_path_newline(custom_current_file: Path, spy_ensure_current_exists): expected = "." custom_current_file.write_text(".\n") result = _get_current_path() assert result == Path(expected) + assert spy_ensure_current_exists.call_count > 0 -def test_update_current_path_str(custom_current_file: Path): +def test_update_current_path_str(custom_current_file: Path, spy_ensure_current_exists): assert not custom_current_file.exists() _update_current_path("/the/path") assert custom_current_file.read_text() == "/the/path" + assert spy_ensure_current_exists.call_count > 0 -def test_update_current_path_Path(custom_current_file: Path): +def test_update_current_path_Path(custom_current_file: Path, spy_ensure_current_exists): assert not custom_current_file.exists() _update_current_path(Path("/the/path")) assert custom_current_file.read_text() == "/the/path" + assert spy_ensure_current_exists.call_count > 0 def test_read_config(custom_config_file: Path):