51029d4a2d
- test_config.py: GeneralConfig defaults, plugin_settings round-trip - test_config_field.py: ConfigField dataclass, BasePlugin.config_fields() no-op, plugin subclass override - test_config_tui.py: _get/_set_nested, _fid/_pfid helpers, GENERAL_FIELDS validity, ConfigApp general tab rendering, save handler, plugins table, plugin tab visibility, q key exit — using Textual run_test() + Pilot - test_cli.py: auto-setup wizard on first run, skip wizard when config exists, /config in _STATIC_COMMANDS Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
90 lines
2.8 KiB
Python
90 lines
2.8 KiB
Python
import pytest
|
|
from pyra.config.schema import PyraConfig, ProviderConfig
|
|
|
|
|
|
def test_config_saves_no_api_key(tmp_pyra_home):
|
|
from pyra.config.manager import save_config, load_config
|
|
|
|
cfg = PyraConfig(ai=ProviderConfig(provider_id="anthropic", model="claude-sonnet-4-6"))
|
|
save_config(cfg)
|
|
|
|
config_text = (tmp_pyra_home / "config.yaml").read_text()
|
|
assert "sk-" not in config_text
|
|
assert "api_key" not in config_text.lower()
|
|
|
|
|
|
def test_config_round_trip(tmp_pyra_home):
|
|
from pyra.config.manager import save_config, load_config
|
|
|
|
cfg = PyraConfig(
|
|
ai=ProviderConfig(
|
|
provider_id="lmstudio",
|
|
model="gemma-4-e4b",
|
|
base_url="http://localhost:1234/v1",
|
|
)
|
|
)
|
|
save_config(cfg)
|
|
loaded = load_config()
|
|
|
|
assert loaded.ai.provider_id == "lmstudio"
|
|
assert loaded.ai.model == "gemma-4-e4b"
|
|
assert loaded.ai.base_url == "http://localhost:1234/v1"
|
|
|
|
|
|
def test_config_file_permissions(tmp_pyra_home):
|
|
import os
|
|
from pyra.config.manager import save_config
|
|
|
|
cfg = PyraConfig(ai=ProviderConfig(provider_id="ollama", model="llama3"))
|
|
save_config(cfg)
|
|
|
|
config_file = tmp_pyra_home / "config.yaml"
|
|
if os.name != "nt":
|
|
mode = oct(config_file.stat().st_mode)[-3:]
|
|
assert mode == "600", f"Expected 600, got {mode}"
|
|
|
|
|
|
def test_load_config_missing_raises(tmp_pyra_home):
|
|
from pyra.config.manager import load_config
|
|
with pytest.raises(FileNotFoundError):
|
|
load_config()
|
|
|
|
|
|
def test_general_config_defaults():
|
|
from pyra.config.schema import GeneralConfig
|
|
g = GeneralConfig()
|
|
assert g.user_name == "User"
|
|
assert g.assistant_name == "Pyra"
|
|
|
|
|
|
def test_pyraconfig_has_general_and_plugin_settings():
|
|
cfg = PyraConfig(ai=ProviderConfig(provider_id="ollama", model="x"))
|
|
assert cfg.general.user_name == "User"
|
|
assert cfg.general.assistant_name == "Pyra"
|
|
assert cfg.plugin_settings == {}
|
|
|
|
|
|
def test_config_round_trip_preserves_general(tmp_pyra_home):
|
|
from pyra.config.manager import save_config, load_config
|
|
|
|
cfg = PyraConfig(ai=ProviderConfig(provider_id="ollama", model="llama3"))
|
|
cfg.general.user_name = "Alice"
|
|
cfg.general.assistant_name = "Aria"
|
|
save_config(cfg)
|
|
|
|
loaded = load_config()
|
|
assert loaded.general.user_name == "Alice"
|
|
assert loaded.general.assistant_name == "Aria"
|
|
|
|
|
|
def test_config_round_trip_preserves_plugin_settings(tmp_pyra_home):
|
|
from pyra.config.manager import save_config, load_config
|
|
|
|
cfg = PyraConfig(ai=ProviderConfig(provider_id="ollama", model="llama3"))
|
|
cfg.plugin_settings["myplugin"] = {"api_url": "http://example.com", "verify_ssl": True}
|
|
save_config(cfg)
|
|
|
|
loaded = load_config()
|
|
assert loaded.plugin_settings["myplugin"]["api_url"] == "http://example.com"
|
|
assert loaded.plugin_settings["myplugin"]["verify_ssl"] is True
|