Skip to content

feat(football): make the live screen renderable offline - #267

Merged
ChuckBuilds merged 3 commits into
mainfrom
feat/football-live-testable
Aug 11, 2026
Merged

feat(football): make the live screen renderable offline#267
ChuckBuilds merged 3 commits into
mainfrom
feat/football-live-testable

Conversation

@ChuckBuilds

@ChuckBuilds ChuckBuilds commented Aug 11, 2026

Copy link
Copy Markdown
Owner

The season starts in a couple of weeks and live is the screen that carries it — yet it was the one screen the safety harness never rendered. The fixture said why:

"NFLLiveManager._fetch_data()_fetch_todays_games() is a direct network call with no cache read and no test_mode passthrough in _adapt_config_for_manager, so the live screen can never be fed from mock data."

Both halves of that turned out to be bugs, not gaps.

1. test_mode was unreachable

_adapt_config_for_manager() builds each manager's config from game_limits, display_options, filtering and display_modes — and never passed test_mode through. So SportsLive.test_mode could not be set from config at all, which made unreachable:

  • the fully seeded simulated game already sitting in NFLLiveManager.__init__ — score, Q4 clock, down and distance, possession, timeouts, all of it already written
  • ncaa_fb_managers.py:185's if self.test_mode branch

2. _test_mode_update() was dead code

SportsLive.update() fetched unconditionally, so even with the flag set the seeded game was overwritten on the first tick. FootballLive._test_mode_update() existed and was never called.

baseball-scoreboard had already fixed exactly this — its test_test_mode_live_games.py asserts "test_mode=True must call _test_mode_update(), NOT _fetch_data()" — so the short-circuit is ported from there rather than invented.

Result

The harness now renders nfl_live at every panel size: 16 renders → 24, none blank (verified against the empty-render check from #447). The card draws the parts only this mode has:

Q4 02:35
DAL 17 - 21 TB
1st & 10        [timeouts]

No behaviour change for anyone running it. test_mode defaults to False on both paths, so live fetches exactly as before — the short-circuit is only reachable when a fixture opts in.

Why now

This is the same shape as two bugs already found this month: hockey's display() returned None on every path and hid until the off-season emptied its modes, and this plugin's own has_live_content log flood was — per its test docstring — "dormant only because it was the off-season", with baseball measuring 13,871 lines/minute with nine live games. Live-path bugs don't show up until there are live games. Two weeks out is the time to render that screen in CI rather than on opening Sunday.

Verification

  • Harness: 24 renders, exit 0, zero empty/fill warnings.
  • New test_live_screen.py: 17 checks — the config passthrough exists, update() branches on test_mode before the fetch, the harness actually enables live, and the seeded game carries every field a live scorebug draws (a fixture missing the clock or down-and-distance would render something that passes while covering nothing).
  • Full plugin suite: 11 passed, 1 skipped, 0 failed. Module-collision and display-contract gates clean.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Udr6MfaFLUPhX5Fgo67Jf5

Summary by CodeRabbit

  • New Features
    • Added offline simulation support for live football scoreboard displays.
    • NFL test mode now preserves and advances simulated live-game data without requiring network access.
  • Bug Fixes
    • Fixed league test-mode settings not being passed through to live scoreboard configuration.
    • Preserved seeded game data during updates.
  • Tests
    • Added offline regression coverage for configuration, simulated updates, live rendering, and complete game score details.
  • Chores
    • Updated the football scoreboard plugin to version 2.14.0.

The season starts in weeks and live is the screen that carries it, yet it
was the one screen the safety harness never rendered. The fixture said
why: "_fetch_todays_games() is a direct network call with no cache read
and no test_mode passthrough in _adapt_config_for_manager, so the live
screen can never be fed from mock data."

Both halves of that turned out to be bugs rather than gaps.

_adapt_config_for_manager() never passed test_mode into the per-manager
config, so SportsLive.test_mode could not be set from config at all --
which made the fully seeded simulated game already sitting in
NFLLiveManager.__init__ unreachable, along with everything behind
`if self.test_mode`.

SportsLive.update() then fetched unconditionally, so even with the flag
set the seeded game was overwritten on the first tick.
_test_mode_update() was defined and never called: dead code.
baseball-scoreboard had already fixed exactly this, so the short-circuit
is ported from there rather than invented.

With both fixed the harness renders nfl_live at every panel size, from
16 renders to 24, none of them blank -- the simulated card draws the
score, the quarter and clock, down and distance, possession and
timeouts, which are the parts only this mode has.

No behaviour change for anyone running it: test_mode defaults to False
on both paths, so live fetches exactly as before.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Udr6MfaFLUPhX5Fgo67Jf5
@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@ChuckBuilds, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 56 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 6a3b98d1-f6ad-4167-b03b-c8e5a035a639

📥 Commits

Reviewing files that changed from the base of the PR and between 21099b9 and 1c3003a.

📒 Files selected for processing (2)
  • plugins/football-scoreboard/test/harness.json
  • plugins/football-scoreboard/test_live_screen.py
📝 Walkthrough

Walkthrough

The football scoreboard now propagates league test_mode, advances simulated games before live fetching, enables offline NFL live rendering in the harness, and adds regression checks. Plugin metadata updates to version 2.14.0.

Changes

Football scoreboard test-mode live rendering

Layer / File(s) Summary
Test-mode configuration propagation
plugins/football-scoreboard/manager.py, plugins/football-scoreboard/test_live_screen.py
League test_mode is copied into manager configuration. Regression checks verify the propagation.
Simulated live-game update path
plugins/football-scoreboard/sports.py, plugins/football-scoreboard/test/harness.json, plugins/football-scoreboard/test_live_screen.py
SportsLive.update() advances simulated games before the normal fetch path. The NFL harness enables live rendering and test mode. Checks validate complete seeded scorebug data.
Plugin release metadata
plugins.json, plugins/football-scoreboard/manifest.json
The catalog and manifest update the plugin to version 2.14.0 and record the release history entry.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Harness as Test harness
  participant Manager as manager.py
  participant SportsLive as SportsLive.update
  participant TestMode as _test_mode_update
  Harness->>Manager: Provide NFL test_mode=true
  Manager->>SportsLive: Create scoreboard configuration
  SportsLive->>TestMode: Advance simulated game
  SportsLive-->>Harness: Render updated live game without network fetch
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: enabling offline rendering for the football live screen.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/football-live-testable

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codacy-production

codacy-production Bot commented Aug 11, 2026

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 29 complexity

Metric Results
Complexity 29

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
plugins/football-scoreboard/test_live_screen.py (1)

46-55: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Exercise the runtime contracts.

test_config_passthrough(), test_update_short_circuits_in_test_mode(), and test_seeded_live_game_is_complete() only inspect source text. They do not invoke _adapt_config_for_manager(), SportsLive.update(), or NFLLiveManager. A dead branch or an update that still calls _fetch_data() can pass these checks. Add runtime assertions with an overdue update, a failing fetch stub, and field-level checks on the seeded game.

Also applies to: 57-68, 80-98

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/football-scoreboard/test_live_screen.py` around lines 46 - 55,
Replace the source-text checks in test_config_passthrough(),
test_update_short_circuits_in_test_mode(), and
test_seeded_live_game_is_complete() with runtime tests that invoke
_adapt_config_for_manager(), SportsLive.update(), and NFLLiveManager. Use an
overdue update and a fetch stub that fails if called to verify test-mode
short-circuiting, then assert the seeded game’s required fields and values
directly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@plugins/football-scoreboard/test_live_screen.py`:
- Line 33: Remove the unused deferred imports of manager, sports, and
nfl_managers and eliminate the PLUGIN_DIR sys.path mutation in the affected test
functions. If imports are required for coverage, load them through
plugin-unique, namespaced module paths and assert the resulting module objects;
do not bind bare shared names.

In `@plugins/football-scoreboard/test/harness.json`:
- Around line 2-10: Adjust the test fixture’s live-update setup so the first
render is overdue and executes SportsLive.update(), allowing _test_mode_update()
to run. Replace the effectively infinite live_update_interval with a small
finite interval, or initialize SportsLive.last_update accordingly before
rendering, while preserving the seeded offline live-game behavior.

---

Nitpick comments:
In `@plugins/football-scoreboard/test_live_screen.py`:
- Around line 46-55: Replace the source-text checks in
test_config_passthrough(), test_update_short_circuits_in_test_mode(), and
test_seeded_live_game_is_complete() with runtime tests that invoke
_adapt_config_for_manager(), SportsLive.update(), and NFLLiveManager. Use an
overdue update and a fetch stub that fails if called to verify test-mode
short-circuiting, then assert the seeded game’s required fields and values
directly.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a813d0b5-e502-4a5b-8d3d-ea60a32e4706

📥 Commits

Reviewing files that changed from the base of the PR and between cf3dbd1 and 21099b9.

📒 Files selected for processing (6)
  • plugins.json
  • plugins/football-scoreboard/manager.py
  • plugins/football-scoreboard/manifest.json
  • plugins/football-scoreboard/sports.py
  • plugins/football-scoreboard/test/harness.json
  • plugins/football-scoreboard/test_live_screen.py

Comment thread plugins/football-scoreboard/test_live_screen.py
Comment thread plugins/football-scoreboard/test/harness.json Outdated
claude added 2 commits August 11, 2026 10:36
Vestigial: the checks read the source as text rather than importing the
modules, and importing them here would need the core on the path anyway.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Udr6MfaFLUPhX5Fgo67Jf5
The fixture kept live_update_interval at 9999999999, inherited from when
live mode was disabled and the always-instantiated live manager had to
be stopped from attempting a doomed network fetch. With last_update at 0
and time frozen at 2026-01-15, the first update was therefore never
overdue: the harness rendered the seeded game straight from
NFLLiveManager.__init__ and never ran the short-circuit this change
adds.

test_mode returns before any fetch, so the guard is obsolete. The
interval is a normal 30s and the fixture now exercises the path it
exists to cover.

Adds the behavioural test that was missing alongside the source checks:
drive the real SportsLive.update() with test_mode on and assert
_test_mode_update() ran, no fetch happened, and the seeded game
survived. Deleting the short-circuit makes it fail.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Udr6MfaFLUPhX5Fgo67Jf5
@ChuckBuilds
ChuckBuilds merged commit 8dd8f07 into main Aug 11, 2026
4 checks passed
@ChuckBuilds
ChuckBuilds deleted the feat/football-live-testable branch August 11, 2026 17:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants