zapretgui/tests/test_paired_run_page.py
loop-uh 0fdb937526
All checks were successful
Zapret source guards / validate (push) Successful in 10s
Windows-сборка / Dev Dev 21.1.7.191 опубликован
BlockCheck: кнопка «С обходом и без» — две проверки подряд с переключением Zapret
Проверяет как сейчас, переключает Zapret (выключает, если работал, или включает), ждёт смены состояния, проверяет ещё раз и возвращает Zapret как был; сравнение «С Zapret и без» строится по двум записям истории. «Стоп» между проверками и любой сбой возвращают Zapret в исходное состояние. Экскурсия описывает кнопку и подсвечивает её.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 12:44:25 -04:00

133 lines
4.6 KiB
Python

"""Кнопка «С обходом и без» на странице BlockCheck: переключение Zapret между двумя проверками."""
from __future__ import annotations
import os
import unittest
from unittest.mock import patch
os.environ.setdefault("QT_QPA_PLATFORM", "offscreen")
from PyQt6.QtWidgets import QApplication
from blockcheck import paired_run
from blockcheck.ui.page import BlockcheckPage
class _Feature:
pass
class _Bypass:
def __init__(self, running: bool) -> None:
self.running = running
self.calls: list[str] = []
def is_running(self) -> bool:
return self.running
def start(self) -> bool:
self.calls.append("start")
self.running = True
return True
def stop(self) -> bool:
self.calls.append("stop")
self.running = False
return True
REPORT = {"scope": "main", "elapsed": 3.0, "problems": [], "services": [], "working": []}
class PairedPageTests(unittest.TestCase):
@classmethod
def setUpClass(cls) -> None:
cls.app = QApplication.instance() or QApplication([])
def _page(self, bypass: _Bypass | None = None):
kwargs = {}
if bypass is not None:
kwargs = {"zapret_is_running": bypass.is_running, "start_zapret": bypass.start, "stop_zapret": bypass.stop}
with patch.object(BlockcheckPage, "_request_page_initial_state_load", lambda self: None):
page = BlockcheckPage(
blockcheck_feature=_Feature(), dns_feature=_Feature(), create_strategy_scan_worker=lambda *_a, **_k: None, **kwargs
)
self.addCleanup(page.deleteLater)
return page
def test_button_is_there_but_off_without_zapret_control(self) -> None:
page = self._page()
self.assertFalse(page._paired_btn.isEnabled())
page._on_start_paired()
self.assertIsNone(page._paired)
def test_full_pair_runs_two_checks_switches_zapret_and_puts_it_back(self) -> None:
bypass = _Bypass(True)
page = self._page(bypass)
starts: list[str] = []
page._on_start = lambda: starts.append("run")
with patch("blockcheck.ui.page.QTimer.singleShot", lambda _ms, callback: callback()):
page._on_start_paired()
self.assertEqual((starts, page._paired.phase), (["run"], paired_run.PHASE_FIRST))
self.assertFalse(page._paired_btn.isEnabled())
page._paired_after(REPORT)
self.assertEqual((bypass.calls, page._paired.phase), (["stop"], paired_run.PHASE_SWITCHING))
page._paired_tick()
self.assertEqual((starts, page._paired.phase), (["run", "run"], paired_run.PHASE_SECOND))
page._paired_after(REPORT)
self.assertEqual(bypass.calls, ["stop", "start"])
self.assertTrue(bypass.running)
self.assertFalse(page._paired.active)
self.assertTrue(page._paired_btn.isEnabled())
self.assertIn("Готово", page._status_label.text())
def test_stopping_the_first_check_leaves_zapret_alone(self) -> None:
bypass = _Bypass(True)
page = self._page(bypass)
page._on_start = lambda: None
page._on_start_paired()
page._paired_after(None)
self.assertEqual(bypass.calls, [])
self.assertFalse(page._paired.active)
self.assertIn("остановлена", page._status_label.text())
def test_stopping_between_the_checks_returns_zapret(self) -> None:
bypass = _Bypass(True)
page = self._page(bypass)
page._on_start = lambda: None
page._on_start_paired()
page._paired_after(REPORT)
self.assertFalse(bypass.running)
page._on_stop()
self.assertTrue(bypass.running)
self.assertEqual(bypass.calls, ["stop", "start"])
self.assertFalse(page._paired.active)
def test_zapret_that_never_changes_ends_the_pair_after_the_wait(self) -> None:
bypass = _Bypass(True)
bypass.stop = lambda: bypass.calls.append("stop") or True # команда принята, процесс остался
page = self._page(bypass)
page._paired = paired_run.PairedRun(is_running=bypass.is_running, start=bypass.start, stop=bypass.stop)
page._on_start = lambda: None
page._on_start_paired()
page._paired_after(REPORT)
page._paired_waited = paired_run.SETTLE_WAIT_SECONDS
page._paired_tick()
self.assertFalse(page._paired.active)
self.assertIn("не сменил состояние", page._status_label.text())
if __name__ == "__main__":
unittest.main()