115 lines
3.7 KiB
Python
115 lines
3.7 KiB
Python
"""Persistent TUI user config tests."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from unittest.mock import patch
|
|
|
|
from omnigent_ui_sdk.terminal import (
|
|
DEFAULT_USER_CONFIG,
|
|
UserConfig,
|
|
UserConfigError,
|
|
load_user_config,
|
|
save_user_config,
|
|
state_dir,
|
|
update_user_config,
|
|
user_config_path,
|
|
)
|
|
|
|
|
|
def test_user_config_path_uses_shared_state_dir(tmp_path, monkeypatch) -> None:
|
|
monkeypatch.setattr("pathlib.Path.home", lambda: tmp_path)
|
|
|
|
assert state_dir() == tmp_path / ".omnigent"
|
|
assert user_config_path() == tmp_path / ".omnigent" / "config.yaml"
|
|
|
|
|
|
def test_user_config_path_accepts_explicit_state_dir(tmp_path) -> None:
|
|
assert user_config_path(tmp_path) == tmp_path / "config.yaml"
|
|
|
|
|
|
def test_load_missing_config_returns_default(tmp_path) -> None:
|
|
assert load_user_config(tmp_path / "config.yaml") == DEFAULT_USER_CONFIG
|
|
|
|
|
|
def test_save_and_load_user_config_round_trips_yaml(tmp_path) -> None:
|
|
path = tmp_path / "state" / "config.yaml"
|
|
|
|
written = save_user_config(UserConfig(theme="dark"), path)
|
|
|
|
assert written == path
|
|
assert path.read_text(encoding="utf-8") == (
|
|
"# Omnigent user configuration\ntui:\n theme: dark\n"
|
|
)
|
|
assert load_user_config(path) == UserConfig(theme="dark")
|
|
|
|
|
|
def test_save_preserves_sibling_cli_keys(tmp_path) -> None:
|
|
"""TUI writes must not clobber top-level CLI keys (default_agent, profile, …)."""
|
|
path = tmp_path / "config.yaml"
|
|
path.write_text("default_agent: foo\nprofile: bar\n", encoding="utf-8")
|
|
|
|
save_user_config(UserConfig(theme="dark"), path)
|
|
|
|
assert path.read_text(encoding="utf-8") == (
|
|
"# Omnigent user configuration\ndefault_agent: foo\nprofile: bar\ntui:\n theme: dark\n"
|
|
)
|
|
|
|
|
|
def test_save_default_removes_tui_but_keeps_siblings(tmp_path) -> None:
|
|
"""Resetting to DEFAULT drops ``tui:`` while preserving sibling keys."""
|
|
path = tmp_path / "config.yaml"
|
|
path.write_text(
|
|
"default_agent: foo\ntui:\n theme: dark\n",
|
|
encoding="utf-8",
|
|
)
|
|
|
|
save_user_config(DEFAULT_USER_CONFIG, path)
|
|
|
|
assert path.read_text(encoding="utf-8") == (
|
|
"# Omnigent user configuration\ndefault_agent: foo\n"
|
|
)
|
|
|
|
|
|
def test_load_invalid_theme_fails_loud(tmp_path) -> None:
|
|
path = tmp_path / "config.yaml"
|
|
path.write_text("tui:\n theme: sepia\n", encoding="utf-8")
|
|
|
|
try:
|
|
load_user_config(path)
|
|
except UserConfigError as exc:
|
|
assert "must be one of dark, light" in str(exc)
|
|
else: # pragma: no cover - defensive assertion
|
|
raise AssertionError("load_user_config accepted an invalid theme")
|
|
|
|
|
|
def test_update_user_config_normalizes_and_persists(tmp_path) -> None:
|
|
path = tmp_path / "config.yaml"
|
|
|
|
config = update_user_config(path, theme=" LIGHT ")
|
|
|
|
assert config == UserConfig(theme="light")
|
|
assert load_user_config(path) == UserConfig(theme="light")
|
|
|
|
|
|
def test_save_default_user_config_round_trips_without_tui_table(tmp_path) -> None:
|
|
path = tmp_path / "config.yaml"
|
|
|
|
save_user_config(DEFAULT_USER_CONFIG, path)
|
|
|
|
assert path.read_text(encoding="utf-8") == "# Omnigent user configuration\n"
|
|
assert load_user_config(path) == DEFAULT_USER_CONFIG
|
|
|
|
|
|
def test_save_user_config_cleans_up_temp_file_when_replace_fails(tmp_path) -> None:
|
|
path = tmp_path / "config.yaml"
|
|
|
|
with patch("pathlib.Path.replace", side_effect=OSError("rename failed")):
|
|
try:
|
|
save_user_config(UserConfig(theme="dark"), path)
|
|
except UserConfigError as exc:
|
|
assert "Failed to write TUI user config" in str(exc)
|
|
else: # pragma: no cover - defensive assertion
|
|
raise AssertionError("save_user_config swallowed replace failure")
|
|
|
|
assert not list(tmp_path.glob("config.yaml.tmp.*"))
|