Files
laya-hook/tests/test_clients.py
richarjiang eae4df7d51 init
2026-09-24 10:04:41 +08:00

100 lines
3.3 KiB
Python

import json
from laya_router.clients.base import read_json
from laya_router.clients.claude import ClaudeClient
from laya_router.clients.codex import CodexClient, hooks_feature_enabled
from laya_router.config import Settings
def _settings(tmp_path) -> Settings:
return Settings(home=tmp_path)
def test_claude_merge_is_idempotent_and_keeps_existing_hooks(tmp_path):
path = tmp_path / "settings.json"
path.write_text(
json.dumps(
{
"env": {"ANTHROPIC_AUTH_TOKEN": "secret-token"},
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [{"type": "command", "command": "rtk hook claude"}],
}
]
},
}
),
encoding="utf-8",
)
client = ClaudeClient(path)
settings = _settings(tmp_path / "runtime")
assert client.install(settings) is True
assert client.install(settings) is False
saved = read_json(path)
assert saved["env"]["ANTHROPIC_AUTH_TOKEN"] == "secret-token"
assert saved["hooks"]["PreToolUse"][0]["matcher"] == "Bash"
commands = [
item["command"]
for group in saved["hooks"]["UserPromptSubmit"]
for item in group["hooks"]
]
assert commands == [f'"{tmp_path / "runtime" / ".venv" / "bin" / "laya-hook"}" --client claude']
assert list(path.parent.glob("settings.json.bak-*"))
assert client.uninstall() is True
removed = read_json(path)
assert "UserPromptSubmit" not in removed["hooks"]
assert removed["hooks"]["PreToolUse"][0]["hooks"][0]["command"] == "rtk hook claude"
assert removed["env"]["ANTHROPIC_AUTH_TOKEN"] == "secret-token"
def test_codex_uninstall_drops_file_when_it_only_contains_our_hook(tmp_path):
codex_dir = tmp_path / ".codex"
client = CodexClient(codex_dir)
settings = _settings(tmp_path / "runtime")
assert client.install(settings) is True
assert client.install(settings) is False
saved = read_json(client.hooks_path)
assert saved["hooks"]["UserPromptSubmit"][0]["hooks"][0]["statusMessage"] == "Laya routing"
assert client.uninstall() is True
assert not client.hooks_path.exists()
def test_codex_uninstall_keeps_foreign_hooks(tmp_path):
codex_dir = tmp_path / ".codex"
hooks = codex_dir / "hooks.json"
hooks.parent.mkdir()
hooks.write_text(
json.dumps(
{
"hooks": {
"UserPromptSubmit": [
{"hooks": [{"type": "command", "command": "other-hook"}]}
]
}
}
),
encoding="utf-8",
)
client = CodexClient(codex_dir)
client.install(_settings(tmp_path / "runtime"))
client.uninstall()
saved = read_json(hooks)
commands = [
item["command"]
for group in saved["hooks"]["UserPromptSubmit"]
for item in group["hooks"]
]
assert commands == ["other-hook"]
def test_hooks_feature_parser():
listing = "hooks stable true\nplugin_hooks removed false\n"
assert hooks_feature_enabled(listing) is True
assert hooks_feature_enabled("hooks experimental false") is False
assert hooks_feature_enabled("no hooks here") is None