106 lines
3.6 KiB
Python
106 lines
3.6 KiB
Python
"""Tests for services.update_service — no GUI dependency."""
|
|||
|
|
import json
|
||
|
|
import shutil
|
||
|
|
import sys
|
||
|
|
import tempfile
|
||
|
|
import unittest
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
sys.path.insert(0, str(Path(__file__).parent.parent / "src"))
|
||
|
|
|
||
|
|
from services.update_service import (
|
||
|
|
UpdateInfo,
|
||
|
|
check_for_update,
|
||
|
|
is_newer,
|
||
|
|
parse_version,
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
class TestVersionCompare(unittest.TestCase):
|
||
|
|
def test_parse_basic(self):
|
||
|
|
self.assertEqual(parse_version("1.2.3"), (1, 2, 3))
|
||
|
|
|
||
|
|
def test_parse_pads_missing_parts(self):
|
||
|
|
self.assertEqual(parse_version("1"), (1, 0, 0))
|
||
|
|
self.assertEqual(parse_version("1.5"), (1, 5, 0))
|
||
|
|
|
||
|
|
def test_parse_tolerates_suffix(self):
|
||
|
|
self.assertEqual(parse_version("1.2.3rc1"), (1, 2, 3))
|
||
|
|
self.assertEqual(parse_version("v"), (0, 0, 0))
|
||
|
|
|
||
|
|
def test_is_newer(self):
|
||
|
|
self.assertTrue(is_newer("1.1.0", "1.0.0"))
|
||
|
|
self.assertTrue(is_newer("1.0.1", "1.0.0"))
|
||
|
|
self.assertTrue(is_newer("2.0.0", "1.9.9"))
|
||
|
|
|
||
|
|
def test_is_not_newer(self):
|
||
|
|
self.assertFalse(is_newer("1.0.0", "1.0.0"))
|
||
|
|
self.assertFalse(is_newer("1.0.0", "1.1.0"))
|
||
|
|
self.assertFalse(is_newer("0.9.9", "1.0.0"))
|
||
|
|
|
||
|
|
|
||
|
|
class TestCheckForUpdate(unittest.TestCase):
|
||
|
|
def setUp(self):
|
||
|
|
self.tmp = Path(tempfile.mkdtemp())
|
||
|
|
|
||
|
|
def tearDown(self):
|
||
|
|
shutil.rmtree(str(self.tmp), ignore_errors=True)
|
||
|
|
|
||
|
|
def _write_manifest(self, data):
|
||
|
|
with open(str(self.tmp / "manifest.json"), "w", encoding="utf-8") as f:
|
||
|
|
json.dump(data, f)
|
||
|
|
|
||
|
|
def test_no_source_returns_none(self):
|
||
|
|
self.assertIsNone(check_for_update("", "1.0.0"))
|
||
|
|
|
||
|
|
def test_missing_manifest_returns_none(self):
|
||
|
|
# tmp exists but has no manifest.json
|
||
|
|
self.assertIsNone(check_for_update(str(self.tmp), "1.0.0"))
|
||
|
|
|
||
|
|
def test_unreachable_source_returns_none(self):
|
||
|
|
self.assertIsNone(check_for_update(str(self.tmp / "nope"), "1.0.0"))
|
||
|
|
|
||
|
|
def test_malformed_manifest_returns_none(self):
|
||
|
|
with open(str(self.tmp / "manifest.json"), "w", encoding="utf-8") as f:
|
||
|
|
f.write("{ not valid json")
|
||
|
|
self.assertIsNone(check_for_update(str(self.tmp), "1.0.0"))
|
||
|
|
|
||
|
|
def test_non_object_manifest_returns_none(self):
|
||
|
|
self._write_manifest(["1.1.0"])
|
||
|
|
self.assertIsNone(check_for_update(str(self.tmp), "1.0.0"))
|
||
|
|
|
||
|
|
def test_newer_version_returns_info(self):
|
||
|
|
self._write_manifest({
|
||
|
|
"version": "1.1.0",
|
||
|
|
"source": r"\\nas\cmbot\releases\CMBot-1.1.0",
|
||
|
|
"notes": "fix batch export",
|
||
|
|
"mandatory": False,
|
||
|
|
})
|
||
|
|
info = check_for_update(str(self.tmp), "1.0.0")
|
||
|
|
self.assertIsInstance(info, UpdateInfo)
|
||
|
|
self.assertEqual(info.version, "1.1.0")
|
||
|
|
self.assertEqual(info.source, r"\\nas\cmbot\releases\CMBot-1.1.0")
|
||
|
|
self.assertEqual(info.notes, "fix batch export")
|
||
|
|
self.assertFalse(info.mandatory)
|
||
|
|
|
||
|
|
def test_same_version_returns_none(self):
|
||
|
|
self._write_manifest({"version": "1.0.0"})
|
||
|
|
self.assertIsNone(check_for_update(str(self.tmp), "1.0.0"))
|
||
|
|
|
||
|
|
def test_older_version_returns_none(self):
|
||
|
|
self._write_manifest({"version": "0.9.0"})
|
||
|
|
self.assertIsNone(check_for_update(str(self.tmp), "1.0.0"))
|
||
|
|
|
||
|
|
def test_missing_version_field_returns_none(self):
|
||
|
|
self._write_manifest({"notes": "no version here"})
|
||
|
|
self.assertIsNone(check_for_update(str(self.tmp), "1.0.0"))
|
||
|
|
|
||
|
|
def test_source_falls_back_to_update_source(self):
|
||
|
|
self._write_manifest({"version": "2.0.0"}) # no "source" field
|
||
|
|
info = check_for_update(str(self.tmp), "1.0.0")
|
||
|
|
self.assertEqual(info.source, str(self.tmp))
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
unittest.main()
|