mirror of
https://github.com/kuhyx/screen-locker.git
synced 2026-07-04 14:43:14 +02:00
- Remove all # type: ignore and # noqa comments (banned by no-noqa hook) - Add mypy --disable-error-code flags to pre-commit config for error codes previously suppressed by inline comments - Fix broken imports after ruff auto-removed re-exports: steam_backlog_enforcer, stockfish_analysis, word_frequency, lichess_bot - Re-add re-exports with __all__ in translator.py, screen_lock.py - Split _process_epc_fc.py (524 lines) into _process_epc_fc.py + _process_fc.py - Fix test failures: keyboard_coop, stockfish_analysis, tag_divider - Add per-file-ignores for PLC0415 (deferred imports) in 7 files - Mark shebang scripts as executable - Add __init__.py for generate_images and repo_explorer packages - Fix codespell, eslint, ruff-format, prettier issues - Update copilot-instructions.md with --no-verify ban
372 lines
12 KiB
Python
372 lines
12 KiB
Python
"""Tests for running and strength data verification."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import TYPE_CHECKING
|
|
from unittest.mock import MagicMock
|
|
|
|
from python_pkg.screen_locker.tests.conftest import (
|
|
RunningData,
|
|
StrengthData,
|
|
create_locker,
|
|
setup_running_entries,
|
|
setup_strength_entries,
|
|
)
|
|
|
|
if TYPE_CHECKING:
|
|
from pathlib import Path
|
|
|
|
|
|
class TestVerifyRunningData:
|
|
"""Tests for verify_running_data method."""
|
|
|
|
def test_valid_running_data(
|
|
self,
|
|
mock_tk: MagicMock,
|
|
_mock_sys_exit: MagicMock,
|
|
tmp_path: Path,
|
|
) -> None:
|
|
"""Test valid running data triggers unlock attempt."""
|
|
locker = create_locker(mock_tk, tmp_path)
|
|
setup_running_entries(locker, RunningData("5", "25", "5"))
|
|
locker.log_file = tmp_path / "workout_log.json"
|
|
locker.workout_data = {"type": "running"}
|
|
object.__setattr__(locker, "_attempt_unlock", MagicMock())
|
|
|
|
locker.verify_running_data()
|
|
|
|
locker._attempt_unlock.assert_called_once()
|
|
|
|
def test_invalid_distance_zero(
|
|
self,
|
|
mock_tk: MagicMock,
|
|
_mock_sys_exit: MagicMock,
|
|
tmp_path: Path,
|
|
) -> None:
|
|
"""Test zero distance is rejected."""
|
|
locker = create_locker(mock_tk, tmp_path)
|
|
setup_running_entries(locker, RunningData("0", "25", "5"))
|
|
object.__setattr__(locker, "show_error", MagicMock())
|
|
|
|
locker.verify_running_data()
|
|
|
|
locker.show_error.assert_called_once()
|
|
assert "Distance" in locker.show_error.call_args[0][0]
|
|
|
|
def test_invalid_distance_too_high(
|
|
self,
|
|
mock_tk: MagicMock,
|
|
_mock_sys_exit: MagicMock,
|
|
tmp_path: Path,
|
|
) -> None:
|
|
"""Test distance over max is rejected."""
|
|
locker = create_locker(mock_tk, tmp_path)
|
|
setup_running_entries(locker, RunningData("150", "600", "4"))
|
|
object.__setattr__(locker, "show_error", MagicMock())
|
|
|
|
locker.verify_running_data()
|
|
|
|
locker.show_error.assert_called_once()
|
|
assert "Distance" in locker.show_error.call_args[0][0]
|
|
|
|
def test_invalid_time_zero(
|
|
self,
|
|
mock_tk: MagicMock,
|
|
_mock_sys_exit: MagicMock,
|
|
tmp_path: Path,
|
|
) -> None:
|
|
"""Test zero time is rejected."""
|
|
locker = create_locker(mock_tk, tmp_path)
|
|
setup_running_entries(locker, RunningData("5", "0", "5"))
|
|
object.__setattr__(locker, "show_error", MagicMock())
|
|
|
|
locker.verify_running_data()
|
|
|
|
locker.show_error.assert_called_once()
|
|
assert "Time" in locker.show_error.call_args[0][0]
|
|
|
|
def test_invalid_time_too_high(
|
|
self,
|
|
mock_tk: MagicMock,
|
|
_mock_sys_exit: MagicMock,
|
|
tmp_path: Path,
|
|
) -> None:
|
|
"""Test time over max is rejected."""
|
|
locker = create_locker(mock_tk, tmp_path)
|
|
setup_running_entries(locker, RunningData("5", "700", "5"))
|
|
object.__setattr__(locker, "show_error", MagicMock())
|
|
|
|
locker.verify_running_data()
|
|
|
|
locker.show_error.assert_called_once()
|
|
assert "Time" in locker.show_error.call_args[0][0]
|
|
|
|
def test_invalid_pace_zero(
|
|
self,
|
|
mock_tk: MagicMock,
|
|
_mock_sys_exit: MagicMock,
|
|
tmp_path: Path,
|
|
) -> None:
|
|
"""Test zero pace is rejected."""
|
|
locker = create_locker(mock_tk, tmp_path)
|
|
setup_running_entries(locker, RunningData("5", "25", "0"))
|
|
object.__setattr__(locker, "show_error", MagicMock())
|
|
|
|
locker.verify_running_data()
|
|
|
|
locker.show_error.assert_called_once()
|
|
assert "Pace" in locker.show_error.call_args[0][0]
|
|
|
|
def test_invalid_pace_too_high(
|
|
self,
|
|
mock_tk: MagicMock,
|
|
_mock_sys_exit: MagicMock,
|
|
tmp_path: Path,
|
|
) -> None:
|
|
"""Test pace over max is rejected."""
|
|
locker = create_locker(mock_tk, tmp_path)
|
|
setup_running_entries(locker, RunningData("5", "25", "25"))
|
|
object.__setattr__(locker, "show_error", MagicMock())
|
|
|
|
locker.verify_running_data()
|
|
|
|
locker.show_error.assert_called_once()
|
|
assert "Pace" in locker.show_error.call_args[0][0]
|
|
|
|
def test_pace_mismatch(
|
|
self,
|
|
mock_tk: MagicMock,
|
|
_mock_sys_exit: MagicMock,
|
|
tmp_path: Path,
|
|
) -> None:
|
|
"""Test pace mismatch is rejected."""
|
|
# 5km in 25 min should be 5 min/km, but we say 10 min/km
|
|
locker = create_locker(mock_tk, tmp_path)
|
|
setup_running_entries(locker, RunningData("5", "25", "10"))
|
|
object.__setattr__(locker, "show_error", MagicMock())
|
|
|
|
locker.verify_running_data()
|
|
|
|
locker.show_error.assert_called_once()
|
|
assert "Pace doesn't match" in locker.show_error.call_args[0][0]
|
|
|
|
def test_invalid_number_format(
|
|
self,
|
|
mock_tk: MagicMock,
|
|
_mock_sys_exit: MagicMock,
|
|
tmp_path: Path,
|
|
) -> None:
|
|
"""Test non-numeric input is rejected."""
|
|
locker = create_locker(mock_tk, tmp_path)
|
|
setup_running_entries(locker, RunningData("abc", "25", "5"))
|
|
object.__setattr__(locker, "show_error", MagicMock())
|
|
|
|
locker.verify_running_data()
|
|
|
|
locker.show_error.assert_called_once()
|
|
assert "valid numbers" in locker.show_error.call_args[0][0]
|
|
|
|
|
|
class TestVerifyStrengthData:
|
|
"""Tests for verify_strength_data method."""
|
|
|
|
def test_valid_strength_data(
|
|
self,
|
|
mock_tk: MagicMock,
|
|
_mock_sys_exit: MagicMock,
|
|
tmp_path: Path,
|
|
) -> None:
|
|
"""Test valid strength data triggers unlock attempt."""
|
|
locker = create_locker(mock_tk, tmp_path)
|
|
setup_strength_entries(locker, StrengthData("Squat", "3", "10", "50", "1500"))
|
|
locker.log_file = tmp_path / "workout_log.json"
|
|
locker.workout_data = {"type": "strength"}
|
|
object.__setattr__(locker, "_attempt_unlock", MagicMock())
|
|
|
|
locker.verify_strength_data()
|
|
|
|
locker._attempt_unlock.assert_called_once()
|
|
|
|
def test_valid_multiple_exercises(
|
|
self,
|
|
mock_tk: MagicMock,
|
|
_mock_sys_exit: MagicMock,
|
|
tmp_path: Path,
|
|
) -> None:
|
|
"""Test valid data with multiple exercises."""
|
|
locker = create_locker(mock_tk, tmp_path)
|
|
setup_strength_entries(
|
|
locker,
|
|
StrengthData("Squat, Bench Press", "3, 3", "10, 8", "50, 40", "2460"),
|
|
)
|
|
locker.log_file = tmp_path / "workout_log.json"
|
|
locker.workout_data = {"type": "strength"}
|
|
object.__setattr__(locker, "_attempt_unlock", MagicMock())
|
|
|
|
locker.verify_strength_data()
|
|
|
|
locker._attempt_unlock.assert_called_once()
|
|
|
|
def test_mismatched_list_lengths(
|
|
self,
|
|
mock_tk: MagicMock,
|
|
_mock_sys_exit: MagicMock,
|
|
tmp_path: Path,
|
|
) -> None:
|
|
"""Test mismatched list lengths are rejected."""
|
|
locker = create_locker(mock_tk, tmp_path)
|
|
setup_strength_entries(
|
|
locker,
|
|
StrengthData("Squat, Bench", "3", "10, 8", "50, 40", "2000"),
|
|
)
|
|
object.__setattr__(locker, "show_error", MagicMock())
|
|
|
|
locker.verify_strength_data()
|
|
|
|
locker.show_error.assert_called_once()
|
|
assert "must match" in locker.show_error.call_args[0][0]
|
|
|
|
def test_short_exercise_name(
|
|
self,
|
|
mock_tk: MagicMock,
|
|
_mock_sys_exit: MagicMock,
|
|
tmp_path: Path,
|
|
) -> None:
|
|
"""Test short exercise names are rejected."""
|
|
locker = create_locker(mock_tk, tmp_path)
|
|
setup_strength_entries(locker, StrengthData("Sq", "3", "10", "50", "1500"))
|
|
object.__setattr__(locker, "show_error", MagicMock())
|
|
|
|
locker.verify_strength_data()
|
|
|
|
locker.show_error.assert_called_once()
|
|
assert "too short" in locker.show_error.call_args[0][0]
|
|
|
|
def test_invalid_sets_zero(
|
|
self,
|
|
mock_tk: MagicMock,
|
|
_mock_sys_exit: MagicMock,
|
|
tmp_path: Path,
|
|
) -> None:
|
|
"""Test zero sets is rejected."""
|
|
locker = create_locker(mock_tk, tmp_path)
|
|
setup_strength_entries(locker, StrengthData("Squat", "0", "10", "50", "0"))
|
|
object.__setattr__(locker, "show_error", MagicMock())
|
|
|
|
locker.verify_strength_data()
|
|
|
|
locker.show_error.assert_called_once()
|
|
assert "Sets" in locker.show_error.call_args[0][0]
|
|
|
|
def test_invalid_sets_too_high(
|
|
self,
|
|
mock_tk: MagicMock,
|
|
_mock_sys_exit: MagicMock,
|
|
tmp_path: Path,
|
|
) -> None:
|
|
"""Test sets over max is rejected."""
|
|
locker = create_locker(mock_tk, tmp_path)
|
|
setup_strength_entries(locker, StrengthData("Squat", "25", "10", "50", "12500"))
|
|
object.__setattr__(locker, "show_error", MagicMock())
|
|
|
|
locker.verify_strength_data()
|
|
|
|
locker.show_error.assert_called_once()
|
|
assert "Sets" in locker.show_error.call_args[0][0]
|
|
|
|
def test_invalid_reps_zero(
|
|
self,
|
|
mock_tk: MagicMock,
|
|
_mock_sys_exit: MagicMock,
|
|
tmp_path: Path,
|
|
) -> None:
|
|
"""Test zero reps is rejected."""
|
|
locker = create_locker(mock_tk, tmp_path)
|
|
setup_strength_entries(locker, StrengthData("Squat", "3", "0", "50", "0"))
|
|
object.__setattr__(locker, "show_error", MagicMock())
|
|
|
|
locker.verify_strength_data()
|
|
|
|
locker.show_error.assert_called_once()
|
|
assert "Reps" in locker.show_error.call_args[0][0]
|
|
|
|
def test_invalid_reps_too_high(
|
|
self,
|
|
mock_tk: MagicMock,
|
|
_mock_sys_exit: MagicMock,
|
|
tmp_path: Path,
|
|
) -> None:
|
|
"""Test reps over max is rejected."""
|
|
locker = create_locker(mock_tk, tmp_path)
|
|
setup_strength_entries(locker, StrengthData("Squat", "3", "150", "50", "22500"))
|
|
object.__setattr__(locker, "show_error", MagicMock())
|
|
|
|
locker.verify_strength_data()
|
|
|
|
locker.show_error.assert_called_once()
|
|
assert "Reps" in locker.show_error.call_args[0][0]
|
|
|
|
def test_invalid_weight_negative(
|
|
self,
|
|
mock_tk: MagicMock,
|
|
_mock_sys_exit: MagicMock,
|
|
tmp_path: Path,
|
|
) -> None:
|
|
"""Test negative weight is rejected."""
|
|
locker = create_locker(mock_tk, tmp_path)
|
|
setup_strength_entries(locker, StrengthData("Squat", "3", "10", "-10", "-300"))
|
|
object.__setattr__(locker, "show_error", MagicMock())
|
|
|
|
locker.verify_strength_data()
|
|
|
|
locker.show_error.assert_called_once()
|
|
assert "Weights" in locker.show_error.call_args[0][0]
|
|
|
|
def test_invalid_weight_too_high(
|
|
self,
|
|
mock_tk: MagicMock,
|
|
_mock_sys_exit: MagicMock,
|
|
tmp_path: Path,
|
|
) -> None:
|
|
"""Test weight over max is rejected."""
|
|
locker = create_locker(mock_tk, tmp_path)
|
|
setup_strength_entries(locker, StrengthData("Squat", "3", "10", "600", "18000"))
|
|
object.__setattr__(locker, "show_error", MagicMock())
|
|
|
|
locker.verify_strength_data()
|
|
|
|
locker.show_error.assert_called_once()
|
|
assert "Weights" in locker.show_error.call_args[0][0]
|
|
|
|
def test_total_weight_mismatch(
|
|
self,
|
|
mock_tk: MagicMock,
|
|
_mock_sys_exit: MagicMock,
|
|
tmp_path: Path,
|
|
) -> None:
|
|
"""Test total weight mismatch is rejected."""
|
|
locker = create_locker(mock_tk, tmp_path)
|
|
setup_strength_entries(locker, StrengthData("Squat", "3", "10", "50", "3000"))
|
|
object.__setattr__(locker, "show_error", MagicMock())
|
|
|
|
locker.verify_strength_data()
|
|
|
|
locker.show_error.assert_called_once()
|
|
assert "Total weight doesn't match" in locker.show_error.call_args[0][0]
|
|
|
|
def test_invalid_format(
|
|
self,
|
|
mock_tk: MagicMock,
|
|
_mock_sys_exit: MagicMock,
|
|
tmp_path: Path,
|
|
) -> None:
|
|
"""Test invalid format is rejected."""
|
|
locker = create_locker(mock_tk, tmp_path)
|
|
setup_strength_entries(locker, StrengthData("Squat", "abc", "10", "50", "1500"))
|
|
object.__setattr__(locker, "show_error", MagicMock())
|
|
|
|
locker.verify_strength_data()
|
|
|
|
locker.show_error.assert_called_once()
|
|
assert "valid data" in locker.show_error.call_args[0][0]
|