mirror of
https://github.com/chidiwilliams/buzz.git
synced 2026-03-14 14:45:46 +01:00
202 lines
8.6 KiB
Python
202 lines
8.6 KiB
Python
import platform
|
|
from datetime import datetime, timedelta
|
|
from unittest.mock import patch
|
|
|
|
import pytest
|
|
from pytestqt.qtbot import QtBot
|
|
|
|
from buzz.__version__ import VERSION
|
|
from buzz.settings.settings import Settings
|
|
from buzz.update_checker import UpdateChecker, UpdateInfo
|
|
from tests.mock_qt import MockNetworkAccessManager, MockNetworkReply
|
|
|
|
|
|
VERSION_INFO = {
|
|
"version": "99.0.0",
|
|
"release_notes": "Some fixes.",
|
|
"download_urls": {
|
|
"windows_x64": ["https://example.com/Buzz-99.0.0.exe"],
|
|
"macos_arm": ["https://example.com/Buzz-99.0.0-arm.dmg"],
|
|
"macos_x86": ["https://example.com/Buzz-99.0.0-x86.dmg"],
|
|
},
|
|
}
|
|
|
|
|
|
@pytest.fixture()
|
|
def checker(settings: Settings) -> UpdateChecker:
|
|
reply = MockNetworkReply(data=VERSION_INFO)
|
|
manager = MockNetworkAccessManager(reply=reply)
|
|
return UpdateChecker(settings=settings, network_manager=manager)
|
|
|
|
|
|
class TestShouldCheckForUpdates:
|
|
def test_returns_false_on_linux(self, checker: UpdateChecker):
|
|
with patch.object(platform, "system", return_value="Linux"):
|
|
assert checker.should_check_for_updates() is False
|
|
|
|
def test_returns_true_on_windows_first_run(self, checker: UpdateChecker, settings: Settings):
|
|
settings.set_value(Settings.Key.LAST_UPDATE_CHECK, "")
|
|
with patch.object(platform, "system", return_value="Windows"):
|
|
assert checker.should_check_for_updates() is True
|
|
|
|
def test_returns_true_on_macos_first_run(self, checker: UpdateChecker, settings: Settings):
|
|
settings.set_value(Settings.Key.LAST_UPDATE_CHECK, "")
|
|
with patch.object(platform, "system", return_value="Darwin"):
|
|
assert checker.should_check_for_updates() is True
|
|
|
|
def test_returns_false_when_checked_recently(
|
|
self, checker: UpdateChecker, settings: Settings
|
|
):
|
|
recent = (datetime.now() - timedelta(days=2)).isoformat()
|
|
settings.set_value(Settings.Key.LAST_UPDATE_CHECK, recent)
|
|
|
|
with patch.object(platform, "system", return_value="Windows"):
|
|
assert checker.should_check_for_updates() is False
|
|
|
|
def test_returns_true_when_check_is_overdue(
|
|
self, checker: UpdateChecker, settings: Settings
|
|
):
|
|
old = (datetime.now() - timedelta(days=10)).isoformat()
|
|
settings.set_value(Settings.Key.LAST_UPDATE_CHECK, old)
|
|
|
|
with patch.object(platform, "system", return_value="Windows"):
|
|
assert checker.should_check_for_updates() is True
|
|
|
|
def test_returns_true_on_invalid_date_in_settings(
|
|
self, checker: UpdateChecker, settings: Settings
|
|
):
|
|
settings.set_value(Settings.Key.LAST_UPDATE_CHECK, "not-a-date")
|
|
|
|
with patch.object(platform, "system", return_value="Windows"):
|
|
assert checker.should_check_for_updates() is True
|
|
|
|
|
|
class TestIsNewerVersion:
|
|
def test_newer_major(self, checker: UpdateChecker):
|
|
with patch("buzz.update_checker.VERSION", "1.0.0"):
|
|
assert checker._is_newer_version("2.0.0") is True
|
|
|
|
def test_newer_minor(self, checker: UpdateChecker):
|
|
with patch("buzz.update_checker.VERSION", "1.0.0"):
|
|
assert checker._is_newer_version("1.1.0") is True
|
|
|
|
def test_newer_patch(self, checker: UpdateChecker):
|
|
with patch("buzz.update_checker.VERSION", "1.0.0"):
|
|
assert checker._is_newer_version("1.0.1") is True
|
|
|
|
def test_same_version(self, checker: UpdateChecker):
|
|
with patch("buzz.update_checker.VERSION", "1.0.0"):
|
|
assert checker._is_newer_version("1.0.0") is False
|
|
|
|
def test_older_version(self, checker: UpdateChecker):
|
|
with patch("buzz.update_checker.VERSION", "2.0.0"):
|
|
assert checker._is_newer_version("1.9.9") is False
|
|
|
|
def test_different_segment_count(self, checker: UpdateChecker):
|
|
with patch("buzz.update_checker.VERSION", "1.0"):
|
|
assert checker._is_newer_version("1.0.1") is True
|
|
|
|
def test_invalid_version_returns_false(self, checker: UpdateChecker):
|
|
with patch("buzz.update_checker.VERSION", "1.0.0"):
|
|
assert checker._is_newer_version("not-a-version") is False
|
|
|
|
|
|
class TestGetDownloadUrl:
|
|
def test_windows_returns_windows_urls(self, checker: UpdateChecker):
|
|
with patch.object(platform, "system", return_value="Windows"):
|
|
urls = checker._get_download_url(VERSION_INFO["download_urls"])
|
|
assert urls == ["https://example.com/Buzz-99.0.0.exe"]
|
|
|
|
def test_macos_arm_returns_arm_urls(self, checker: UpdateChecker):
|
|
with patch.object(platform, "system", return_value="Darwin"), \
|
|
patch.object(platform, "machine", return_value="arm64"):
|
|
urls = checker._get_download_url(VERSION_INFO["download_urls"])
|
|
assert urls == ["https://example.com/Buzz-99.0.0-arm.dmg"]
|
|
|
|
def test_macos_x86_returns_x86_urls(self, checker: UpdateChecker):
|
|
with patch.object(platform, "system", return_value="Darwin"), \
|
|
patch.object(platform, "machine", return_value="x86_64"):
|
|
urls = checker._get_download_url(VERSION_INFO["download_urls"])
|
|
assert urls == ["https://example.com/Buzz-99.0.0-x86.dmg"]
|
|
|
|
def test_linux_returns_empty(self, checker: UpdateChecker):
|
|
with patch.object(platform, "system", return_value="Linux"):
|
|
urls = checker._get_download_url(VERSION_INFO["download_urls"])
|
|
assert urls == []
|
|
|
|
def test_wraps_plain_string_in_list(self, checker: UpdateChecker):
|
|
with patch.object(platform, "system", return_value="Windows"):
|
|
urls = checker._get_download_url({"windows_x64": "https://example.com/a.exe"})
|
|
assert urls == ["https://example.com/a.exe"]
|
|
|
|
|
|
class TestCheckForUpdates:
|
|
def _make_checker(self, settings: Settings, version_data: dict) -> UpdateChecker:
|
|
settings.set_value(Settings.Key.LAST_UPDATE_CHECK, "")
|
|
reply = MockNetworkReply(data=version_data)
|
|
manager = MockNetworkAccessManager(reply=reply)
|
|
return UpdateChecker(settings=settings, network_manager=manager)
|
|
|
|
def test_emits_update_available_when_newer_version(self, settings: Settings):
|
|
received = []
|
|
checker = self._make_checker(settings, VERSION_INFO)
|
|
checker.update_available.connect(lambda info: received.append(info))
|
|
|
|
with patch.object(platform, "system", return_value="Windows"), \
|
|
patch.object(platform, "machine", return_value="x86_64"), \
|
|
patch("buzz.update_checker.VERSION", "1.0.0"):
|
|
checker.check_for_updates()
|
|
|
|
assert len(received) == 1
|
|
update_info: UpdateInfo = received[0]
|
|
assert update_info.version == "99.0.0"
|
|
assert update_info.release_notes == "Some fixes."
|
|
assert update_info.download_urls == ["https://example.com/Buzz-99.0.0.exe"]
|
|
|
|
def test_does_not_emit_when_version_is_current(self, settings: Settings):
|
|
received = []
|
|
checker = self._make_checker(settings, {**VERSION_INFO, "version": VERSION})
|
|
checker.update_available.connect(lambda info: received.append(info))
|
|
|
|
with patch.object(platform, "system", return_value="Windows"):
|
|
checker.check_for_updates()
|
|
|
|
assert received == []
|
|
|
|
def test_skips_network_call_on_linux(self, settings: Settings):
|
|
received = []
|
|
checker = self._make_checker(settings, VERSION_INFO)
|
|
checker.update_available.connect(lambda info: received.append(info))
|
|
|
|
with patch.object(platform, "system", return_value="Linux"):
|
|
checker.check_for_updates()
|
|
|
|
assert received == []
|
|
|
|
def test_stores_last_check_date_after_reply(self, settings: Settings):
|
|
checker = self._make_checker(settings, {**VERSION_INFO, "version": VERSION})
|
|
|
|
with patch.object(platform, "system", return_value="Windows"):
|
|
checker.check_for_updates()
|
|
|
|
stored = settings.value(Settings.Key.LAST_UPDATE_CHECK, "")
|
|
assert stored != ""
|
|
datetime.fromisoformat(stored) # should not raise
|
|
|
|
def test_stores_available_version_when_update_found(self, settings: Settings):
|
|
checker = self._make_checker(settings, VERSION_INFO)
|
|
|
|
with patch.object(platform, "system", return_value="Windows"), \
|
|
patch("buzz.update_checker.VERSION", "1.0.0"):
|
|
checker.check_for_updates()
|
|
|
|
assert settings.value(Settings.Key.UPDATE_AVAILABLE_VERSION, "") == "99.0.0"
|
|
|
|
def test_clears_available_version_when_up_to_date(self, settings: Settings):
|
|
settings.set_value(Settings.Key.UPDATE_AVAILABLE_VERSION, "99.0.0")
|
|
checker = self._make_checker(settings, {**VERSION_INFO, "version": VERSION})
|
|
|
|
with patch.object(platform, "system", return_value="Windows"):
|
|
checker.check_for_updates()
|
|
|
|
assert settings.value(Settings.Key.UPDATE_AVAILABLE_VERSION, "") == ""
|