Files
kernalix7--winpodx/tests/test_uninstall_wrapper.py
wehub-resource-sync 3e779be6f3
CI / lint (push) Failing after 13m4s
CI / test (3.11, ubuntu-latest) (push) Failing after 2m4s
CI / test (3.13, ubuntu-latest) (push) Successful in 13m30s
CI / test (3.14, ubuntu-latest) (push) Successful in 17m21s
CI / test (3.12, ubuntu-latest) (push) Successful in 17m55s
CI / discover-apps-ps (push) Successful in 1m56s
CI / test (3.9, ubuntu-latest) (push) Successful in 13m17s
CI / test (3.10, ubuntu-latest) (push) Successful in 26m21s
CI / audit (push) Successful in 13m38s
Deploy site / deploy (push) Has been cancelled
CI / test (3.14, ubuntu-24.04-arm) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:32:37 +08:00

138 lines
4.8 KiB
Python

# SPDX-License-Identifier: MIT
"""Tests for the ``winpodx uninstall`` Python wrapper (#255 consolidation).
The wrapper's only job is to locate ``uninstall.sh`` and ``exec`` it.
Tests verify (1) the candidate paths cover every install topology and
(2) ``os.execvp`` is invoked with the right argv when a script is found.
"""
from __future__ import annotations
import argparse
import sys
from pathlib import Path
from unittest.mock import patch
import pytest
from winpodx.cli.uninstall import _candidate_paths, handle_uninstall
class TestCandidatePaths:
def test_includes_system_share(self):
paths = _candidate_paths()
assert Path("/usr/share/winpodx/uninstall.sh") in paths
assert Path("/usr/local/share/winpodx/uninstall.sh") in paths
def test_includes_curl_bundle(self):
paths = _candidate_paths()
assert Path.home() / ".local" / "bin" / "winpodx-app" / "uninstall.sh" in paths
def test_includes_venv_prefix(self):
paths = _candidate_paths()
assert Path(sys.prefix) / "share" / "winpodx" / "uninstall.sh" in paths
def test_includes_dev_repo_root(self):
paths = _candidate_paths()
# Should include something ending in repo-root / uninstall.sh
assert any(p.name == "uninstall.sh" for p in paths)
class TestHandleUninstall:
def test_exec_invoked_when_script_found(self, tmp_path):
fake_script = tmp_path / "uninstall.sh"
fake_script.write_text("#!/usr/bin/env bash\nexit 0\n")
fake_script.chmod(0o755)
with (
patch(
"winpodx.cli.uninstall._candidate_paths",
return_value=[fake_script],
),
patch("os.execvp") as mock_exec,
):
handle_uninstall(argparse.Namespace(purge=False, yes=False))
mock_exec.assert_called_once_with("bash", ["bash", str(fake_script)])
def test_purge_flag_forwarded(self, tmp_path):
fake_script = tmp_path / "uninstall.sh"
fake_script.write_text("#!/usr/bin/env bash\nexit 0\n")
fake_script.chmod(0o755)
with (
patch(
"winpodx.cli.uninstall._candidate_paths",
return_value=[fake_script],
),
patch("os.execvp") as mock_exec,
):
handle_uninstall(argparse.Namespace(purge=True, yes=False))
args = mock_exec.call_args.args[1]
assert "--purge" in args
def test_yes_flag_forwarded(self, tmp_path):
fake_script = tmp_path / "uninstall.sh"
fake_script.write_text("#!/usr/bin/env bash\nexit 0\n")
fake_script.chmod(0o755)
with (
patch(
"winpodx.cli.uninstall._candidate_paths",
return_value=[fake_script],
),
patch("os.execvp") as mock_exec,
):
handle_uninstall(argparse.Namespace(purge=False, yes=True))
args = mock_exec.call_args.args[1]
assert "--yes" in args
def test_both_flags_forwarded(self, tmp_path):
fake_script = tmp_path / "uninstall.sh"
fake_script.write_text("#!/usr/bin/env bash\nexit 0\n")
fake_script.chmod(0o755)
with (
patch(
"winpodx.cli.uninstall._candidate_paths",
return_value=[fake_script],
),
patch("os.execvp") as mock_exec,
):
handle_uninstall(argparse.Namespace(purge=True, yes=True))
args = mock_exec.call_args.args[1]
assert "--purge" in args
assert "--yes" in args
def test_first_existing_path_wins(self, tmp_path):
first = tmp_path / "first.sh"
second = tmp_path / "second.sh"
second.write_text("#!/usr/bin/env bash\nexit 0\n")
second.chmod(0o755)
# first does NOT exist; should fall through to second
with (
patch(
"winpodx.cli.uninstall._candidate_paths",
return_value=[first, second],
),
patch("os.execvp") as mock_exec,
):
handle_uninstall(argparse.Namespace(purge=False, yes=False))
args = mock_exec.call_args.args[1]
assert str(second) in args
assert str(first) not in args
def test_systemexit_when_no_script_found(self):
with (
patch(
"winpodx.cli.uninstall._candidate_paths",
return_value=[Path("/nonexistent/path/uninstall.sh")],
),
pytest.raises(SystemExit) as exc,
):
handle_uninstall(argparse.Namespace(purge=False, yes=False))
# Error message should mention the search paths so the user can
# diagnose. And the curl one-liner so they can recover.
assert "uninstall.sh not found" in str(exc.value)
assert "curl -fsSL" in str(exc.value)