from types import SimpleNamespace from syncvito.main_window import UPDATE_CHECK_INTERVAL_MS, UPDATE_RETRY_INTERVAL_MS, MainWindow class FakeTimer: def __init__(self, *, active: bool = False) -> None: self.active = active self.start_calls: list[int | None] = [] self.stop_calls = 0 def isActive(self) -> bool: # noqa: N802 - Qt API return self.active def start(self, interval: int | None = None) -> None: self.active = True self.start_calls.append(interval) def stop(self) -> None: self.active = False self.stop_calls += 1 class FakeStyle: def __init__(self) -> None: self.unpolished = False self.polished = False def unpolish(self, _button: object) -> None: self.unpolished = True def polish(self, _button: object) -> None: self.polished = True class FakeButton: def __init__(self) -> None: self.text = "" self.properties: dict[str, object] = {} self.tooltip = "" self.accessible_description = "" self.button_style = FakeStyle() self.updated = False def setText(self, text: str) -> None: # noqa: N802 - Qt API self.text = text def setProperty(self, name: str, value: object) -> None: # noqa: N802 - Qt API self.properties[name] = value def setToolTip(self, text: str) -> None: # noqa: N802 - Qt API self.tooltip = text def setAccessibleDescription(self, text: str) -> None: # noqa: N802 - Qt API self.accessible_description = text def style(self) -> FakeStyle: return self.button_style def update(self) -> None: self.updated = True def _window(*, sync_running: bool = False, updater_busy: bool = False) -> SimpleNamespace: checks: list[bool] = [] return SimpleNamespace( config=SimpleNamespace(settings=SimpleNamespace(check_updates_on_start=True)), coordinator=SimpleNamespace(is_running=sync_running), updater=SimpleNamespace(busy=updater_busy), update_check_timer=FakeTimer(active=True), update_retry_timer=FakeTimer(), _check_updates=lambda manual: checks.append(manual), checks=checks, ) def test_automatic_update_check_runs_without_daily_throttle() -> None: window = _window() MainWindow._automatic_update_check(window) assert window.checks == [False] assert window.update_check_timer.start_calls == [UPDATE_CHECK_INTERVAL_MS] assert window.update_retry_timer.stop_calls == 1 def test_automatic_update_check_retries_while_sync_is_running() -> None: window = _window(sync_running=True) MainWindow._automatic_update_check(window) assert window.checks == [] assert window.update_retry_timer.start_calls == [None] assert UPDATE_RETRY_INTERVAL_MS == 60_000 def test_periodic_update_interval_is_thirty_minutes() -> None: assert UPDATE_CHECK_INTERVAL_MS == 30 * 60 * 1000 def test_update_indicator_uses_text_and_accessible_description() -> None: button = FakeButton() window = SimpleNamespace(settings_nav_button=button) MainWindow._set_update_indicator(window, "1.0.5") assert button.text == "Einstellungen • UPDATE" assert button.properties["updateAvailable"] is True assert button.tooltip == "SyncVito 1.0.5 ist verfügbar" assert button.accessible_description == button.tooltip assert button.button_style.unpolished and button.button_style.polished assert button.updated