Files
Zhengshou Lai e021aa9dbf fix(backend): 改回全局 ~/.claude/settings.json + 补充测试
- claude_settings: 目标文件改为全局 ~/.claude/settings.json,与 cc-switch 行为一致
- claude_settings: 切回 claude 时保留用户已有的 ANTHROPIC_API_KEY
- backend: 修正 save_project_settings -> save_settings,提示文本同步
- test_backends: 清理未用 import
- test_entrypoints: 新增 backend 命令注册测试
- 新增 test_claude_settings / test_secrets / test_backend_command(共 36 tests)
2026-07-16 20:52:12 +08:00

104 lines
4.1 KiB
Python

"""Tests for myagents.secrets."""
import json
import sys
from pathlib import Path
import pytest
from myagents import secrets as secrets_mod
@pytest.fixture()
def fake_dirs(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> dict[str, Path]:
xiaohe_dir = tmp_path / ".xiaohe" / "agent"
mytoolkit_dir = tmp_path / ".mytoolkit"
monkeypatch.setattr(secrets_mod, "XIAOHE_CONFIG_DIR", xiaohe_dir)
monkeypatch.setattr(secrets_mod, "XIAOHE_CONFIG_PATH", xiaohe_dir / "config.json")
monkeypatch.setattr(secrets_mod, "MYTOOLKIT_CONFIG_PATH", mytoolkit_dir / "config.json")
return {"xiaohe": xiaohe_dir, "mytoolkit": mytoolkit_dir}
class TestGetKey:
def test_returns_xiaohe_key_first(self, fake_dirs: dict[str, Path]) -> None:
xiaohe_path = fake_dirs["xiaohe"] / "config.json"
mytoolkit_path = fake_dirs["mytoolkit"] / "config.json"
xiaohe_path.parent.mkdir(parents=True)
xiaohe_path.write_text(json.dumps({"keys": {"kimi": "xiaohe-key"}}))
mytoolkit_path.parent.mkdir(parents=True)
mytoolkit_path.write_text(json.dumps({"keys": {"kimi": "mtk-key"}}))
assert secrets_mod.get_key("kimi") == "xiaohe-key"
def test_falls_back_to_mytoolkit_key(self, fake_dirs: dict[str, Path]) -> None:
mytoolkit_path = fake_dirs["mytoolkit"] / "config.json"
mytoolkit_path.parent.mkdir(parents=True)
mytoolkit_path.write_text(json.dumps({"keys": {"kimi": "mtk-key"}}))
assert secrets_mod.get_key("kimi") == "mtk-key"
def test_returns_none_when_missing(self, fake_dirs: dict[str, Path]) -> None:
assert secrets_mod.get_key("missing") is None
def test_skips_empty_strings(self, fake_dirs: dict[str, Path]) -> None:
xiaohe_path = fake_dirs["xiaohe"] / "config.json"
xiaohe_path.parent.mkdir(parents=True)
xiaohe_path.write_text(json.dumps({"keys": {"kimi": ""}}))
assert secrets_mod.get_key("kimi") is None
class TestSetKey:
def test_stores_key_in_xiaohe_config(self, fake_dirs: dict[str, Path]) -> None:
secrets_mod.set_key("deepseek", "sk-test")
data = json.loads((fake_dirs["xiaohe"] / "config.json").read_text())
assert data["keys"]["deepseek"] == "sk-test"
def test_rejects_empty_key(self, fake_dirs: dict[str, Path]) -> None:
with pytest.raises(ValueError, match="cannot be empty"):
secrets_mod.set_key("deepseek", "")
def test_preserves_other_keys(self, fake_dirs: dict[str, Path]) -> None:
xiaohe_path = fake_dirs["xiaohe"] / "config.json"
xiaohe_path.parent.mkdir(parents=True)
xiaohe_path.write_text(json.dumps({"keys": {"other": "keep"}}))
secrets_mod.set_key("deepseek", "sk-test")
data = json.loads(xiaohe_path.read_text())
assert data["keys"]["other"] == "keep"
assert data["keys"]["deepseek"] == "sk-test"
class TestRemoveKey:
def test_removes_existing_key(self, fake_dirs: dict[str, Path]) -> None:
xiaohe_path = fake_dirs["xiaohe"] / "config.json"
xiaohe_path.parent.mkdir(parents=True)
xiaohe_path.write_text(json.dumps({"keys": {"deepseek": "sk-test"}}))
assert secrets_mod.remove_key("deepseek") is True
data = json.loads(xiaohe_path.read_text())
assert "deepseek" not in data.get("keys", {})
def test_returns_false_when_missing(self, fake_dirs: dict[str, Path]) -> None:
assert secrets_mod.remove_key("deepseek") is False
class TestPermissions:
@pytest.mark.skipif(sys.platform == "win32", reason="Unix permissions only")
def test_config_file_is_user_readable_only(self, fake_dirs: dict[str, Path]) -> None:
secrets_mod.set_key("kimi", "sk-test")
path = fake_dirs["xiaohe"] / "config.json"
mode = path.stat().st_mode
assert mode & 0o777 == 0o600
class TestHasKey:
def test_true_when_key_exists(self, fake_dirs: dict[str, Path]) -> None:
secrets_mod.set_key("kimi", "sk-test")
assert secrets_mod.has_key("kimi") is True
def test_false_when_missing(self, fake_dirs: dict[str, Path]) -> None:
assert secrets_mod.has_key("missing") is False