Files
NHL-Scoreboard/tests/test_scheduler.py
T
josh a88e2edef0
CI / Lint (push) Successful in 5s
CI / Test (push) Successful in 9s
CI / Build & Push (push) Successful in 19s
fix: anchor Day N to each round's first game instead of lazy first sighting
The banner read "Day 1 of ~60" on day 2 of the playoffs because the old
anchor recorded whatever date we first polled a playoff game as Day 1.
Now round start dates come from /v1/schedule/playoff-series, so Day N
is authoritative and resets at each round boundary. Drops the noisy
"of ~60" denominator.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-19 13:03:08 -04:00

112 lines
3.8 KiB
Python

import pytest
from app.scheduler import start_scheduler
def _patch_eager(mocker):
mocker.patch("app.scheduler.refresh_bracket")
mocker.patch("app.scheduler.refresh_round_start_dates")
class TestStartScheduler:
def test_registers_standings_refresh_every_600_seconds(self, mocker):
mock_schedule = mocker.patch("app.scheduler.schedule")
_patch_eager(mocker)
mocker.patch("app.scheduler.time.sleep", side_effect=StopIteration)
with pytest.raises(StopIteration):
start_scheduler()
intervals = [call[0][0] for call in mock_schedule.every.call_args_list]
assert 600 in intervals
def test_registers_score_refresh_every_10_seconds(self, mocker):
mock_schedule = mocker.patch("app.scheduler.schedule")
_patch_eager(mocker)
mocker.patch("app.scheduler.time.sleep", side_effect=StopIteration)
with pytest.raises(StopIteration):
start_scheduler()
intervals = [call[0][0] for call in mock_schedule.every.call_args_list]
assert 10 in intervals
def test_registers_bracket_refresh_every_3600_seconds(self, mocker):
mock_schedule = mocker.patch("app.scheduler.schedule")
_patch_eager(mocker)
mocker.patch("app.scheduler.time.sleep", side_effect=StopIteration)
with pytest.raises(StopIteration):
start_scheduler()
intervals = [call[0][0] for call in mock_schedule.every.call_args_list]
assert 3600 in intervals
def test_registers_round_start_dates_refresh_every_21600_seconds(self, mocker):
mock_schedule = mocker.patch("app.scheduler.schedule")
_patch_eager(mocker)
mocker.patch("app.scheduler.time.sleep", side_effect=StopIteration)
with pytest.raises(StopIteration):
start_scheduler()
intervals = [call[0][0] for call in mock_schedule.every.call_args_list]
assert 21600 in intervals
def test_invokes_bracket_refresh_eagerly_at_startup(self, mocker):
mocker.patch("app.scheduler.schedule")
eager = mocker.patch("app.scheduler.refresh_bracket")
mocker.patch("app.scheduler.refresh_round_start_dates")
mocker.patch("app.scheduler.time.sleep", side_effect=StopIteration)
with pytest.raises(StopIteration):
start_scheduler()
assert eager.called
def test_invokes_round_start_dates_refresh_eagerly_at_startup(self, mocker):
mocker.patch("app.scheduler.schedule")
mocker.patch("app.scheduler.refresh_bracket")
eager = mocker.patch("app.scheduler.refresh_round_start_dates")
mocker.patch("app.scheduler.time.sleep", side_effect=StopIteration)
with pytest.raises(StopIteration):
start_scheduler()
assert eager.called
def test_runs_pending_on_each_tick(self, mocker):
mock_schedule = mocker.patch("app.scheduler.schedule")
_patch_eager(mocker)
call_count = {"n": 0}
def sleep_twice(_):
call_count["n"] += 1
if call_count["n"] >= 2:
raise StopIteration
mocker.patch("app.scheduler.time.sleep", side_effect=sleep_twice)
with pytest.raises(StopIteration):
start_scheduler()
assert mock_schedule.run_pending.call_count >= 2
def test_continues_after_exception_in_run_pending(self, mocker):
mock_schedule = mocker.patch("app.scheduler.schedule")
_patch_eager(mocker)
call_count = {"n": 0}
def raise_then_stop(_):
call_count["n"] += 1
if call_count["n"] >= 2:
raise StopIteration
mock_schedule.run_pending.side_effect = RuntimeError("boom")
mocker.patch("app.scheduler.time.sleep", side_effect=raise_then_stop)
with pytest.raises(StopIteration):
start_scheduler()
assert mock_schedule.run_pending.call_count >= 2