97 lines
3.0 KiB
Python
97 lines
3.0 KiB
Python
from __future__ import annotations
|
|
|
|
import json
|
|
import tomllib
|
|
from pathlib import Path
|
|
|
|
from typer.testing import CliRunner
|
|
|
|
from opensquilla.cli.main import app
|
|
from opensquilla.onboarding.config_store import load_config
|
|
|
|
runner = CliRunner()
|
|
|
|
|
|
def _write_hermes_home(root: Path) -> Path:
|
|
source = root / ".hermes"
|
|
source.mkdir(parents=True)
|
|
(source / "config.yaml").write_text(
|
|
"model:\n provider: openrouter\n model: openai/gpt-4o-mini\n",
|
|
encoding="utf-8",
|
|
)
|
|
(source / "SOUL.md").write_text("Hermes soul\n", encoding="utf-8")
|
|
return source
|
|
|
|
|
|
def test_cli_hermes_dry_run_json_does_not_write(tmp_path: Path, monkeypatch) -> None:
|
|
source = _write_hermes_home(tmp_path)
|
|
home = tmp_path / "opensquilla-home"
|
|
config_path = tmp_path / "opensquilla.toml"
|
|
monkeypatch.setenv("OPENSQUILLA_STATE_DIR", str(home))
|
|
|
|
result = runner.invoke(
|
|
app,
|
|
["migrate", "hermes", "--source", str(source), "--config", str(config_path), "--json"],
|
|
)
|
|
|
|
assert result.exit_code == 0, result.stdout
|
|
report = json.loads(result.stdout)
|
|
assert report["apply"] is False
|
|
assert not config_path.exists()
|
|
assert not (home / "workspace" / "SOUL.md").exists()
|
|
|
|
|
|
def test_cli_hermes_apply_preserves_existing_config_and_redacts_report(
|
|
tmp_path: Path, monkeypatch
|
|
) -> None:
|
|
source = _write_hermes_home(tmp_path)
|
|
(source / ".env").write_text(
|
|
"OPENROUTER_API_KEY=sk-or-secret\nTELEGRAM_BOT_TOKEN=tg-secret\n",
|
|
encoding="utf-8",
|
|
)
|
|
(source / "config.yaml").write_text(
|
|
"""
|
|
model:
|
|
provider: openrouter
|
|
model: anthropic/claude-3.5-sonnet
|
|
telegram:
|
|
default_chat_id: "123"
|
|
""",
|
|
encoding="utf-8",
|
|
)
|
|
home = tmp_path / "opensquilla-home"
|
|
config_path = tmp_path / "opensquilla.toml"
|
|
config_path.write_text('host = "127.0.0.9"\nport = 19999\n', encoding="utf-8")
|
|
monkeypatch.setenv("OPENSQUILLA_STATE_DIR", str(home))
|
|
|
|
result = runner.invoke(
|
|
app,
|
|
[
|
|
"migrate",
|
|
"hermes",
|
|
"--source",
|
|
str(source),
|
|
"--config",
|
|
str(config_path),
|
|
"--apply",
|
|
"--migrate-secrets",
|
|
"--json",
|
|
],
|
|
)
|
|
|
|
assert result.exit_code == 0, result.stdout
|
|
report = json.loads(result.stdout)
|
|
assert "sk-or-secret" not in result.stdout
|
|
assert "tg-secret" not in result.stdout
|
|
config = tomllib.loads(config_path.read_text(encoding="utf-8"))
|
|
assert config["host"] == "127.0.0.9"
|
|
assert config["port"] == 19999
|
|
# Sparse persistence omits values equal to the built-in default
|
|
# (provider "openrouter"); the effective provider must still resolve
|
|
# to the migrated value.
|
|
assert config["llm"].get("provider", "openrouter") == "openrouter"
|
|
assert load_config(config_path).llm.provider == "openrouter"
|
|
assert config["llm"]["model"] == "anthropic/claude-3.5-sonnet"
|
|
assert config["channels"]["channels"][0]["type"] == "telegram"
|
|
assert (Path(report["output_dir"]) / "report.json").is_file()
|