479189ee4e
rigdoctor update assumed a pip/venv install and ran 'python -m pip install', which fails on a .deb (system python has no pip; you can't pip-upgrade a dpkg package). Add updates.install_kind() (dpkg ownership / venv / source-checkout detection, cached) and route apply_update: pip self-updates in place; apt and source installs return guidance instead. CLI and the GUI Update button show the apt/git command. Adds tests/test_updates.py. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
65 lines
2.4 KiB
Python
65 lines
2.4 KiB
Python
"""Tests for the M13 updater: install detection + routing the update to the right method."""
|
|
|
|
import unittest
|
|
from unittest import mock
|
|
|
|
from rigdoctor.core import updates
|
|
|
|
|
|
class InstallKindTests(unittest.TestCase):
|
|
def setUp(self):
|
|
updates.install_kind.cache_clear()
|
|
|
|
def tearDown(self):
|
|
updates.install_kind.cache_clear()
|
|
|
|
def test_apt_when_dpkg_owns_the_package(self):
|
|
with mock.patch.object(updates, "_dpkg_owns", return_value=True):
|
|
self.assertEqual(updates.install_kind(), "apt")
|
|
|
|
def test_pip_when_running_in_a_venv(self):
|
|
with mock.patch.object(updates, "_dpkg_owns", return_value=False), \
|
|
mock.patch.object(updates.sys, "prefix", "/opt/venv"), \
|
|
mock.patch.object(updates.sys, "base_prefix", "/usr"):
|
|
self.assertEqual(updates.install_kind(), "pip")
|
|
|
|
|
|
class ApplyUpdateRoutingTests(unittest.TestCase):
|
|
def test_apt_returns_guidance_and_never_runs_pip(self):
|
|
with mock.patch.object(updates, "install_kind", return_value="apt"), \
|
|
mock.patch("subprocess.run") as run:
|
|
rc, out = updates.apply_update("v9.9.9")
|
|
self.assertEqual(rc, 1)
|
|
self.assertIn("apt install --only-upgrade", out)
|
|
run.assert_not_called()
|
|
|
|
def test_dev_returns_guidance_and_never_runs_pip(self):
|
|
with mock.patch.object(updates, "install_kind", return_value="dev"), \
|
|
mock.patch("subprocess.run") as run:
|
|
rc, out = updates.apply_update("v9.9.9")
|
|
self.assertIn("git pull", out)
|
|
run.assert_not_called()
|
|
|
|
def test_pip_install_runs_pip(self):
|
|
proc = mock.Mock(returncode=0, stdout="Successfully installed", stderr="")
|
|
with mock.patch.object(updates, "install_kind", return_value="pip"), \
|
|
mock.patch.object(updates, "load_token", return_value="TOK"), \
|
|
mock.patch("subprocess.run", return_value=proc) as run:
|
|
rc, _out = updates.apply_update("v1.2.3")
|
|
self.assertEqual(rc, 0)
|
|
cmd = run.call_args[0][0]
|
|
self.assertIn("pip", cmd)
|
|
self.assertIn("install", cmd)
|
|
|
|
|
|
class UpdateHintTests(unittest.TestCase):
|
|
def test_apt_hint_names_the_apt_command(self):
|
|
self.assertIn("apt install --only-upgrade rigdoctor", updates.update_hint("apt"))
|
|
|
|
def test_dev_hint_says_git_pull(self):
|
|
self.assertIn("git pull", updates.update_hint("dev"))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|