Files
aiturk-hermes-ide/tests/tui_gateway/test_config_profile_scope.py
T

114 lines
3.7 KiB
Python

"""config.get / config.set must honor params.profile (issue #95760).
A single dashboard backend in desktop app-global remote mode serves every
profile. projects.* RPCs already bind params.profile via @_profile_scoped;
config.get / config.set did not, so reads and persistent writes used the
launch profile's config.yaml for every focused profile.
"""
from __future__ import annotations
from pathlib import Path
import yaml
import tui_gateway.server as server
LAUNCH_CWD = "/workspace/default"
WORKER_CWD = "/workspace/code"
LAUNCH_ROOTS = ["/workspace/default"]
WORKER_ROOTS = ["/workspace/code"]
def _write_cfg(home: Path, cwd: str, roots: list[str]) -> None:
home.mkdir(parents=True, exist_ok=True)
(home / "config.yaml").write_text(
yaml.safe_dump(
{
"terminal": {"cwd": cwd},
"desktop": {"repo_scan_roots": list(roots)},
"display": {"busy_input_mode": "queue"},
}
),
encoding="utf-8",
)
def _homes(tmp_path: Path) -> tuple[Path, Path]:
launch = tmp_path / "launch"
worker = tmp_path / "profiles" / "code"
_write_cfg(launch, LAUNCH_CWD, LAUNCH_ROOTS)
_write_cfg(worker, WORKER_CWD, WORKER_ROOTS)
return launch, worker
def _reset_cfg_cache() -> None:
server._cfg_cache = None
server._cfg_mtime = None
server._cfg_path = None
def _bind_homes(monkeypatch, launch: Path, worker: Path) -> None:
monkeypatch.setattr(server, "_hermes_home", launch)
monkeypatch.setattr(
server,
"_profile_home",
lambda name: worker if (name or "").strip() == "code" else None,
)
_reset_cfg_cache()
def _get(params: dict) -> dict:
return server._methods["config.get"]("rid-get", params)
def _set(params: dict) -> dict:
return server._methods["config.set"]("rid-set", params)
def _read_yaml(home: Path) -> dict:
return yaml.safe_load((home / "config.yaml").read_text(encoding="utf-8")) or {}
def test_config_get_full_reads_params_profile_yaml_not_launch(tmp_path, monkeypatch):
launch, worker = _homes(tmp_path)
_bind_homes(monkeypatch, launch, worker)
launch_resp = _get({"key": "full"})
assert launch_resp["result"]["config"]["terminal"]["cwd"] == LAUNCH_CWD
assert launch_resp["result"]["config"]["desktop"]["repo_scan_roots"] == LAUNCH_ROOTS
_reset_cfg_cache()
worker_resp = _get({"key": "full", "profile": "code"})
assert worker_resp["result"]["config"]["terminal"]["cwd"] == WORKER_CWD
assert worker_resp["result"]["config"]["desktop"]["repo_scan_roots"] == WORKER_ROOTS
# Launch file must be untouched by the focused-profile read.
assert _read_yaml(launch)["terminal"]["cwd"] == LAUNCH_CWD
def test_config_set_persistent_write_lands_on_params_profile_yaml(tmp_path, monkeypatch):
launch, worker = _homes(tmp_path)
_bind_homes(monkeypatch, launch, worker)
resp = _set({"key": "busy", "value": "steer", "profile": "code"})
assert resp["result"]["value"] == "steer"
worker_cfg = _read_yaml(worker)
launch_cfg = _read_yaml(launch)
assert worker_cfg["display"]["busy_input_mode"] == "steer"
assert launch_cfg["display"]["busy_input_mode"] == "queue"
assert launch_cfg["terminal"]["cwd"] == LAUNCH_CWD
assert worker_cfg["terminal"]["cwd"] == WORKER_CWD
def test_config_set_without_profile_still_writes_launch_home(tmp_path, monkeypatch):
launch, worker = _homes(tmp_path)
_bind_homes(monkeypatch, launch, worker)
resp = _set({"key": "busy", "value": "interrupt"})
assert resp["result"]["value"] == "interrupt"
assert _read_yaml(launch)["display"]["busy_input_mode"] == "interrupt"
assert _read_yaml(worker)["display"]["busy_input_mode"] == "queue"