Files
hermes-agent/tests/hermes_cli/test_desktop_profile_launch.py

141 lines
4.8 KiB
Python

"""hermes desktop forwards an explicit profile into the packaged Electron launch.
Electron boots from active-profile.json. ``hermes -p <name> desktop`` used to
set only the CLI HERMES_HOME, so the packaged app still started the stored
profile. A launch with no ``-p`` / ``--profile`` must not invent a flag.
"""
from __future__ import annotations
import os
import subprocess
import sys
from argparse import Namespace
from pathlib import Path
import pytest
from hermes_cli import main as cli_main
from hermes_cli import main_desktop
def _ns(**kwargs):
defaults = dict(
skip_build=True,
build_only=False,
force_build=False,
source=False,
fake_boot=False,
ignore_existing=False,
hermes_root=None,
cwd=None,
setup_tcc_identity=False,
identity=None,
local=False,
)
defaults.update(kwargs)
return Namespace(**defaults)
def _named_profiles(argv: list[str]) -> set[str]:
names: set[str] = set()
for index, arg in enumerate(argv):
if arg in {"-p", "--profile"} and index + 1 < len(argv):
names.add(argv[index + 1].strip().casefold())
elif arg.startswith("--profile="):
names.add(arg.split("=", 1)[1].strip().casefold())
names.discard("default")
return names
def _packaged_exe(root: Path) -> Path:
desktop_dir = root / "apps" / "desktop"
if sys.platform == "darwin":
exe = desktop_dir / "release" / "mac-arm64" / "Hermes.app" / "Contents" / "MacOS" / "Hermes"
elif sys.platform == "win32":
exe = desktop_dir / "release" / "win-unpacked" / "Hermes.exe"
else:
exe = desktop_dir / "release" / "linux-unpacked" / "hermes"
exe.parent.mkdir(parents=True, exist_ok=True)
(exe.parent / "chrome-sandbox").write_text("", encoding="utf-8")
exe.parent.mkdir(parents=True, exist_ok=True)
exe.write_text("", encoding="utf-8")
return exe
def _live_profile(root: Path, name: str) -> None:
profile = root / "profiles" / name
profile.mkdir(parents=True, exist_ok=True)
(profile / "config.yaml").write_text("{}\n", encoding="utf-8")
def _launch_command(tmp_path, monkeypatch, argv: list[str], *, active_profile: str | None = None) -> list[str]:
hermes_root = tmp_path / ".hermes"
hermes_root.mkdir()
if active_profile and active_profile != "default":
_live_profile(hermes_root, active_profile)
(hermes_root / "active_profile").write_text(active_profile + "\n", encoding="utf-8")
for name in _named_profiles(argv):
_live_profile(hermes_root, name)
project = tmp_path / "hermes-agent"
(project / "apps" / "desktop").mkdir(parents=True)
(project / "apps" / "desktop" / "package.json").write_text("{}", encoding="utf-8")
exe = _packaged_exe(project)
monkeypatch.setattr(Path, "home", lambda: tmp_path)
monkeypatch.delenv("HERMES_HOME", raising=False)
monkeypatch.setenv("XDG_DATA_HOME", str(tmp_path / "xdg"))
monkeypatch.setenv("GNOME_KEYRING_CONTROL", "/run/user/1000/keyring")
for var in (
"HERMES_SUPERVISED_CHILD",
"HERMES_S6_SUPERVISED_CHILD",
"INVOCATION_ID",
"HERMES_GATEWAY_EXTERNAL_SUPERVISOR",
"KDE_SESSION_VERSION",
"KDE_FULL_SESSION",
):
monkeypatch.delenv(var, raising=False)
monkeypatch.setattr(sys, "argv", argv)
monkeypatch.setattr(cli_main, "PROJECT_ROOT", project)
monkeypatch.setattr(main_desktop, "_desktop_exe_integrity_error", lambda _path: None)
# Module global: restore it so a later cmd_gui test does not inherit a flag.
monkeypatch.setattr(cli_main, "_explicit_cli_profile", None)
cli_main._apply_profile_override()
calls: list[list[str]] = []
def _run(cmd, **_kwargs):
calls.append(list(cmd))
return subprocess.CompletedProcess(cmd, 0)
monkeypatch.setattr(subprocess, "run", _run)
with pytest.raises(SystemExit) as exc:
cli_main.cmd_gui(_ns())
assert exc.value.code == 0
launches = [cmd for cmd in calls if cmd and cmd[0] == str(exe)]
assert len(launches) == 1
return launches[0]
def test_dash_p_desktop_appends_profile_to_packaged_launch(tmp_path, monkeypatch):
launched = _launch_command(tmp_path, monkeypatch, ["hermes", "-p", "desktop", "desktop"])
assert launched[-2:] == ["--profile", "desktop"]
def test_profile_equals_spelling_is_forwarded(tmp_path, monkeypatch):
launched = _launch_command(tmp_path, monkeypatch, ["hermes", "desktop", "--profile=work"])
assert launched[-2:] == ["--profile", "work"]
def test_missing_flag_does_not_forward_sticky_profile(tmp_path, monkeypatch):
launched = _launch_command(
tmp_path, monkeypatch, ["hermes", "desktop"], active_profile="coder"
)
assert "--profile" not in launched
assert os.environ.get("HERMES_HOME", "").endswith(f"{os.sep}profiles{os.sep}coder")