screen-locker/screen_locker/tests/test_status_view_part5.py
Krzysztof kuhy Rudnicki e5bfdd9a9a Make the Tk locker screens text-free
Every locker screen, the status window and the credit toast now show
glyphs (screen_locker/_glyphs.py) and numbers, coloured by state.
Sentences that carried a reason (verifier message, sync diagnosis,
sick refusal, form rejection) go to the log at warning instead.
New pre-commit hook text-free runs scripts/verify_text_free.py.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 01:20:23 +01:00

75 lines
3.0 KiB
Python

"""Tests for the read-only Tkinter status window's rendering (StatusWindow.render)."""
from __future__ import annotations
from unittest.mock import MagicMock, patch
from screen_locker import _glyphs as g
from screen_locker._status_view_verify import (
PhoneCheckOutcome,
_verify_phone_then_runnerup,
)
class TestVerifyPhoneThenRunnerup:
"""The "Check Phone" worker: StrongLifts first, then RunnerUp as fallback."""
def test_stronglifts_verified_short_circuits(self) -> None:
"""A verified phone workout wins and RunnerUp is never consulted."""
verifier = MagicMock()
verifier._verify_phone_workout.return_value = ("verified", "5x5 done")
result = _verify_phone_then_runnerup(verifier)
assert result == PhoneCheckOutcome(
"phone_verified", "verified", "5x5 done", None
)
verifier._verify_runnerup_workout.assert_not_called()
def test_falls_back_to_runnerup_when_phone_not_verified(self) -> None:
"""StrongLifts miss → a verified run credits as runnerup_verified."""
verifier = MagicMock()
verifier._verify_phone_workout.return_value = ("not_verified", "stale")
verifier._verify_runnerup_workout.return_value = ("verified", "9.8 km")
result = _verify_phone_then_runnerup(verifier)
assert result == PhoneCheckOutcome(
"runnerup_verified", "verified", "stale", "9.8 km"
)
def test_neither_source_verified_nor_backfilled(self) -> None:
"""Neither verified today, nothing to backfill → no credit, no fill message."""
verifier = MagicMock()
verifier._verify_phone_workout.return_value = ("not_verified", "stale")
verifier._verify_runnerup_workout.return_value = ("too_short", "3 km")
verifier._scan_and_fill_week_runnerup.return_value = 0
verifier._try_fill_stronglifts_for_week.return_value = 0
with patch(
"screen_locker._status_view_verify.count_weekly_workouts",
return_value=2,
):
result = _verify_phone_then_runnerup(verifier)
assert result == PhoneCheckOutcome(None, "too_short", "stale", "3 km", None)
def test_falls_back_to_week_scan_backfill(self) -> None:
"""Neither verified today, but the week-scan finds something → fill message."""
verifier = MagicMock()
verifier._verify_phone_workout.return_value = ("not_verified", "stale")
verifier._verify_runnerup_workout.return_value = ("not_verified", "no run")
verifier._scan_and_fill_week_runnerup.return_value = 1
verifier._try_fill_stronglifts_for_week.return_value = 0
with patch(
"screen_locker._status_view_verify.count_weekly_workouts",
return_value=2,
):
result = _verify_phone_then_runnerup(verifier)
assert result.credited_type is None
assert result.week_fill_message == f"{g.RETRY}{g.LIFT} +1"
# The RunnerUp fill is credited by the shared callback, not here.
verifier._adjust_shutdown_time_by.assert_not_called()