oclaw/tests/test_oclaw_hooks_runtime.py
oliver 420abac9f1 refactor: root-package imports (svc/runtime/interfaces) and fix PYTHONPATH
- Rename platform/ to svc/ to avoid shadowing stdlib platform.
- Replace from oclaw.* with from svc/runtime/interfaces; update -m CLI paths.
- tests/conftest: prepend repo root to sys.path (no parent-folder package name).
- CI: paths and offline_eval script under repo root.
- Ops scripts: PYTHONPATH must be repo root for python -m runtime.* (fixes gateway/WhatsApp sidecar startup).
- Fix default oclaw.json path in tabular/file attachment limits; stabilize attachment test config.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-13 14:51:17 +08:00

105 lines
4.1 KiB
Python

from __future__ import annotations
import json
from pathlib import Path
from runtime.hooks.eligibility_from_metadata import hook_eligibility_from_message_metadata
from runtime.hooks_runtime import (
_reset_hooks_runtime_state_for_test,
initialize_hooks_runtime,
resolve_runtime_config,
)
def test_resolve_runtime_config_from_env_json(monkeypatch) -> None:
monkeypatch.setenv(
"OCLAW_RUNTIME_CONFIG_JSON",
json.dumps({"hooks": {"internal": {"enabled": False, "entries": {"x": {"enabled": False}}}}}),
)
monkeypatch.delenv("OCLAW_CONFIG_PATH", raising=False)
cfg = resolve_runtime_config()
assert ((cfg.get("hooks") or {}).get("internal") or {}).get("enabled") is False
assert ((cfg.get("hooks") or {}).get("internal") or {}).get("entries", {}).get("x", {}).get("enabled") is False
def test_resolve_runtime_config_from_config_path(monkeypatch, tmp_path: Path) -> None:
cfg_path = tmp_path / "oclaw.custom.json"
cfg_path.write_text(
json.dumps({"hooks": {"internal": {"enabled": True, "entries": {"session-memory": {"messages": 99}}}}}),
encoding="utf-8",
)
monkeypatch.delenv("OCLAW_RUNTIME_CONFIG_JSON", raising=False)
monkeypatch.setenv("OCLAW_CONFIG_PATH", str(cfg_path))
cfg = resolve_runtime_config()
assert ((cfg.get("hooks") or {}).get("internal") or {}).get("enabled") is True
assert (
((cfg.get("hooks") or {}).get("internal") or {}).get("entries", {}).get("session-memory", {}).get("messages")
== 99
)
def test_initialize_hooks_runtime_passes_remote_eligibility(monkeypatch, tmp_path: Path) -> None:
_reset_hooks_runtime_state_for_test()
empty_bundled = tmp_path / "empty-bundled"
empty_bundled.mkdir(parents=True, exist_ok=True)
monkeypatch.setattr("runtime.hooks_runtime.runtime_hooks_bundled_root", lambda: str(empty_bundled))
monkeypatch.setattr("runtime.hooks.merge_skill_hook_dirs.discover_workspace_skill_manifests", lambda: ())
ws = tmp_path / "workspace"
hook_dir = ws / "hooks" / "demo"
hook_dir.mkdir(parents=True, exist_ok=True)
(hook_dir / "HOOK.md").write_text(
"---\n"
"name: demo\n"
"description: demo\n"
"metadata:\n"
" oclaw:\n"
" events: [\"command:new\"]\n"
" requires:\n"
" bins: [\"git\"]\n"
"---\n",
encoding="utf-8",
)
(hook_dir / "handler.py").write_text("def handle(event):\n return None\n", encoding="utf-8")
cfg = {"hooks": {"internal": {"enabled": True, "entries": {"demo": {"enabled": True}}}}}
loaded = initialize_hooks_runtime(
cfg=cfg,
workspace_dir=str(ws),
eligibility={"remote": {"hasBin": lambda _bin: False, "hasAnyBin": lambda _bins: False}},
)
assert loaded == 0
def test_initialize_hooks_runtime_loads_when_metadata_bins_present_reports_requirement(
monkeypatch, tmp_path: Path
) -> None:
_reset_hooks_runtime_state_for_test()
empty_bundled = tmp_path / "empty-bundled"
empty_bundled.mkdir(parents=True, exist_ok=True)
monkeypatch.setattr("runtime.hooks_runtime.runtime_hooks_bundled_root", lambda: str(empty_bundled))
monkeypatch.setattr("runtime.hooks.merge_skill_hook_dirs.discover_workspace_skill_manifests", lambda: ())
ws = tmp_path / "workspace"
hook_dir = ws / "hooks" / "demo"
hook_dir.mkdir(parents=True, exist_ok=True)
(hook_dir / "HOOK.md").write_text(
"---\n"
"name: demo\n"
"description: demo\n"
"metadata:\n"
" oclaw:\n"
" events: [\"command:new\"]\n"
" requires:\n"
" bins: [\"oclaw_fake_hook_bin\"]\n"
"---\n",
encoding="utf-8",
)
(hook_dir / "handler.py").write_text("def handle(event):\n return None\n", encoding="utf-8")
cfg = {"hooks": {"internal": {"enabled": True, "entries": {"demo": {"enabled": True}}}}}
elig = hook_eligibility_from_message_metadata(
{"hookEligibility": {"remote": {"binsPresent": ["oclaw_fake_hook_bin"]}}},
)
assert elig is not None
loaded = initialize_hooks_runtime(cfg=cfg, workspace_dir=str(ws), eligibility=elig)
assert loaded == 1