"""Tests targeting remaining screen_lock.py coverage gaps.""" from __future__ import annotations from typing import TYPE_CHECKING from unittest.mock import MagicMock, patch from screen_locker.tests.conftest import create_locker if TYPE_CHECKING: from pathlib import Path class TestCheckNonVerifyExitsExtras: """Tests for _check_non_verify_exits coverage gaps (lines 228, 233, 251-254).""" def test_auto_fill_credits_through_shared_callback( self, mock_tk: MagicMock, mock_sys_exit: MagicMock, tmp_path: Path, ) -> None: """The login-time scan hands every fill to ``_credit_ingested_workout``. It used to compute a weekly-surplus bonus here (+1h per workout above the weekly minimum), which is 0 for most of the week and silently left a synced run uncredited (2026-09-16). No bonus is computed on this path any more; the callback owns the reward. """ locker = create_locker(mock_tk, tmp_path) scan = MagicMock(return_value=2) object.__setattr__(locker, "_scan_and_fill_week_runnerup", scan) # Short-circuit _check_today_state_exits so the test is time-independent. object.__setattr__( locker, "_check_today_state_exits", MagicMock(return_value=False), ) object.__setattr__( locker, "_adjust_shutdown_time_by", MagicMock(return_value=True), ) with ( patch("screen_locker._startup_checks.reset_to_base_if_new_day"), patch( "screen_locker._startup_checks.process_week_transition", return_value=[], ), patch("screen_locker._startup_checks.is_relaxed_day", return_value=False), patch( "screen_locker._startup_checks.has_weekly_minimum", return_value=True ), patch("screen_locker.screen_lock.sys.exit"), ): locker._check_non_verify_exits() scan.assert_called_once_with( locker.log_file, on_ingested=locker._credit_ingested_workout ) locker._adjust_shutdown_time_by.assert_not_called() def test_logs_weekly_reward_message( self, mock_tk: MagicMock, mock_sys_exit: MagicMock, tmp_path: Path, ) -> None: """process_week_transition returning messages → logger.info at line 233.""" locker = create_locker(mock_tk, tmp_path) object.__setattr__( locker, "_scan_and_fill_week_runnerup", MagicMock(return_value=0), ) with ( patch("screen_locker._startup_checks.reset_to_base_if_new_day"), patch( "screen_locker._startup_checks.process_week_transition", return_value=["🎉 +1h shutdown bonus for 5-workout week!"], ), patch("screen_locker._startup_checks.is_relaxed_day", return_value=False), patch( "screen_locker._startup_checks.has_weekly_minimum", return_value=True ), patch("screen_locker.screen_lock.sys.exit"), ): locker._check_non_verify_exits() def test_fresh_day_reset_layers_no_weekly_bonus( self, mock_tk: MagicMock, mock_sys_exit: MagicMock, tmp_path: Path, ) -> None: """A fresh-day reset is the whole shutdown: no weekly bonus on top (2026-10-10).""" locker = create_locker(mock_tk, tmp_path) object.__setattr__( locker, "_scan_and_fill_week_runnerup", MagicMock(return_value=0), ) object.__setattr__( locker, "_adjust_shutdown_time_by", MagicMock(return_value=True), ) with ( patch( "screen_locker._startup_checks.reset_to_base_if_new_day", return_value=True, ), patch( "screen_locker._startup_checks.process_week_transition", return_value=[], ), patch("screen_locker._startup_checks.is_relaxed_day", return_value=False), patch( "screen_locker._startup_checks.has_weekly_minimum", return_value=True ), patch("screen_locker.screen_lock.sys.exit"), ): locker._check_non_verify_exits() locker._adjust_shutdown_time_by.assert_not_called()