88 lines
3.4 KiB
Python
88 lines
3.4 KiB
Python
"""Tests for myagents.commands.uninstall."""
|
|
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
from click.testing import CliRunner
|
|
|
|
from myagents.commands import uninstall as un_mod
|
|
|
|
|
|
@pytest.fixture()
|
|
def fake_home(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> Path:
|
|
home = tmp_path / "home"
|
|
home.mkdir()
|
|
monkeypatch.setattr(Path, "home", staticmethod(lambda: home))
|
|
monkeypatch.setattr(un_mod, "_pip_uninstall", lambda: [])
|
|
monkeypatch.setattr(
|
|
"myagents.commands.completion_install.uninstall_completions",
|
|
lambda progs, **kw: [],
|
|
)
|
|
return home
|
|
|
|
|
|
def _populate(home: Path) -> None:
|
|
local_bin = home / ".local" / "bin"
|
|
(local_bin / "completions").mkdir(parents=True)
|
|
for name in ("xiaohe", "myclaude", "mytoolkit", "metabot", "mb"):
|
|
(local_bin / name).write_text("#!/bin/sh\n")
|
|
(local_bin / "completions" / "metabot").write_text("comp")
|
|
(local_bin / "completions" / "_metabot").write_text("comp")
|
|
(home / ".xiaohe" / "agent").mkdir(parents=True)
|
|
(home / ".xiaohe" / "agent" / "config.json").write_text("{}")
|
|
(home / "workspace").mkdir()
|
|
app = home / "Desktop" / "Xiaohe Agent.app" / "Contents"
|
|
app.mkdir(parents=True)
|
|
|
|
|
|
class TestUninstall:
|
|
def test_removes_cli_layer_keeps_xiaohe_and_workspace(
|
|
self, fake_home: Path
|
|
) -> None:
|
|
_populate(fake_home)
|
|
result = CliRunner().invoke(un_mod.uninstall_cmd, ["--yes"])
|
|
assert result.exit_code == 0
|
|
local_bin = fake_home / ".local" / "bin"
|
|
assert not (local_bin / "xiaohe").exists()
|
|
assert not (local_bin / "myclaude").exists()
|
|
assert not (local_bin / "metabot").exists()
|
|
assert not (local_bin / "completions").exists() # empty dir cleaned
|
|
assert not (fake_home / "Desktop" / "Xiaohe Agent.app").exists()
|
|
assert (fake_home / ".xiaohe" / "agent" / "config.json").is_file()
|
|
assert (fake_home / "workspace").is_dir()
|
|
|
|
def test_all_removes_xiaohe_dir(self, fake_home: Path) -> None:
|
|
_populate(fake_home)
|
|
result = CliRunner().invoke(
|
|
un_mod.uninstall_cmd, ["--all", "--yes"], input="y\ndelete-all\n"
|
|
)
|
|
assert result.exit_code == 0
|
|
assert not (fake_home / ".xiaohe").exists()
|
|
assert (fake_home / "workspace").is_dir() # workspace never touched
|
|
|
|
def test_all_requires_full_chain_even_with_yes(self, fake_home: Path) -> None:
|
|
_populate(fake_home)
|
|
# --yes skips only the first gate; declining the second cancels.
|
|
result = CliRunner().invoke(
|
|
un_mod.uninstall_cmd, ["--all", "--yes"], input="n\n"
|
|
)
|
|
assert result.exit_code == 0
|
|
assert "Cancelled" in result.output
|
|
assert (fake_home / ".xiaohe").exists()
|
|
|
|
def test_all_aborts_on_wrong_phrase(self, fake_home: Path) -> None:
|
|
_populate(fake_home)
|
|
result = CliRunner().invoke(
|
|
un_mod.uninstall_cmd, ["--all", "--yes"], input="y\nnope\n"
|
|
)
|
|
assert result.exit_code == 0
|
|
assert "Cancelled" in result.output
|
|
assert (fake_home / ".xiaohe").exists()
|
|
|
|
def test_cancelled_keeps_everything(self, fake_home: Path) -> None:
|
|
_populate(fake_home)
|
|
result = CliRunner().invoke(un_mod.uninstall_cmd, [], input="n\n")
|
|
assert result.exit_code == 0
|
|
assert "Cancelled" in result.output
|
|
assert (fake_home / ".local" / "bin" / "xiaohe").exists()
|