"""Tests for mytoolkit.config.Config (hierarchical get/set/remove/export).""" import pytest from mytoolkit import config as config_mod from mytoolkit.config import Config @pytest.fixture() def fresh_home(tmp_path, monkeypatch): """Give each test its own empty MYTOOLKIT_HOME.""" home = tmp_path / "home" monkeypatch.setattr(config_mod, "CONFIG_PATH", home / "config.json") return home def test_set_get_remove_roundtrip(fresh_home): c = Config() assert c.get("secrets.api_keys.ark") is None c.set("secrets.api_keys.ark", "sk-test") assert c.get("secrets.api_keys.ark") == "sk-test" # Persisted: a fresh instance sees the same value. assert Config().get("secrets.api_keys.ark") == "sk-test" assert c.remove("secrets.api_keys.ark") is True assert c.remove("secrets.api_keys.ark") is False assert c.get("secrets.api_keys.ark") is None def test_nested_set_creates_intermediate_dicts(fresh_home): c = Config() c.set("connections.ssh.workstation.host", "10.0.0.5") assert c.get("connections.ssh.workstation.host") == "10.0.0.5" assert c.get("connections.ssh") == {"workstation": {"host": "10.0.0.5"}} def test_remove_nested_cleans_leaf_but_keeps_parents(fresh_home): c = Config() c.set("a.b.c", 1) assert c.remove("a.b.c") is True assert c.get("a.b.c") is None assert c.get("a.b") == {} def test_get_all_returns_flat_dot_paths(fresh_home): c = Config() c.set("secrets.api_keys.ark", "sk-ark") c.set("paths.cv", "/tmp/cv") assert c.get_all() == { "secrets.api_keys.ark": "sk-ark", "paths.cv": "/tmp/cv", } def test_get_all_returns_copy(fresh_home): c = Config() c.set("k", "v") snapshot = c.get_all() snapshot["k"] = "mutated" assert c.get("k") == "v" def test_export_prefix_and_underscore_replacement(fresh_home): c = Config() c.set("secrets.api_keys.ark", "sk-test") assert c.export() == {"MYCLI_SECRETS_API_KEYS_ARK": "sk-test"} def test_resolve_key_env_overrides_config(fresh_home, monkeypatch): c = Config() c.set("secrets.api_keys.ark", "sk-config") monkeypatch.setenv("ARK_API_KEY", "sk-env") assert c.resolve_key("secrets.api_keys.ark", env_var="ARK_API_KEY") == "sk-env" def test_resolve_key_falls_back_to_config(fresh_home): c = Config() c.set("secrets.api_keys.ark", "sk-config") assert c.resolve_key("secrets.api_keys.ark", env_var="MISSING_VAR") == "sk-config" def test_corrupt_config_falls_back_to_empty(fresh_home): fresh_home.mkdir(parents=True) (fresh_home / "config.json").write_text("{not json") c = Config() assert c.get_all() == {} def test_file_permissions_are_restrictive(fresh_home): c = Config() c.set("k", "v") assert (fresh_home / "config.json").stat().st_mode & 0o777 == 0o600