Files
NHL-Scoreboard/tests/conftest.py
T
josh e908139323
CI / Lint (push) Successful in 10s
CI / Test (push) Successful in 10s
CI / Build & Push (push) Successful in 23s
fix: pin playoff card to its own gameNumber so the header doesn't tick forward after a final
series_state derives game_number from topSeedWins + bottomSeedWins + 1, which becomes the *next* game's number once the API advances seriesStatus post-final. The card for the just-finished game would then read "Game N+1 of 7". Prefer the raw gameNumber on the game payload, falling back to the derived value when it's missing.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-19 18:41:04 -04:00

154 lines
4.5 KiB
Python

import json
import sqlite3
import pytest
def make_game(
game_state="LIVE",
home_name="Maple Leafs",
away_name="Bruins",
home_score=2,
away_score=1,
period=3,
seconds_remaining=300,
in_intermission=False,
start_time_utc="2024-04-10T23:00:00Z",
home_record="40-25-10",
away_record="38-27-09",
game_type=2,
situation=None,
series_status=None,
home_abbrev="TOR",
away_abbrev="BOS",
):
clock = {
"timeRemaining": f"{seconds_remaining // 60:02d}:{seconds_remaining % 60:02d}",
"secondsRemaining": seconds_remaining,
"running": game_state == "LIVE",
"inIntermission": in_intermission,
}
return {
"gameState": game_state,
"startTimeUTC": start_time_utc,
"periodDescriptor": {"number": period},
"clock": clock,
"homeTeam": {
"name": {"default": home_name},
"abbrev": home_abbrev,
"score": home_score,
"sog": 15,
"logo": "https://example.com/home.png",
"record": home_record,
},
"awayTeam": {
"name": {"default": away_name},
"abbrev": away_abbrev,
"score": away_score,
"sog": 12,
"logo": "https://example.com/away.png",
"record": away_record,
},
"gameOutcome": {"lastPeriodType": "REG"},
"gameType": game_type,
**({"situation": situation} if situation is not None else {}),
**({"seriesStatus": series_status} if series_status is not None else {}),
}
def make_playoff_game(
top_wins=0,
bottom_wins=0,
round_num=1,
series_letter="A",
top_abbrev="TOR",
bottom_abbrev="BOS",
top_is_home=True,
game_state="LIVE",
game_number=None,
**kwargs,
):
"""Convenience wrapper around make_game for playoff fixtures.
`top_is_home` controls which side of the matchup hosts this game, so tests
for the blurb copy (leader vs. trailer names) don't have to juggle raw dicts.
"""
series_status = {
"round": round_num,
"topSeedWins": top_wins,
"bottomSeedWins": bottom_wins,
"seriesLetter": series_letter,
"topSeedTeamAbbrev": top_abbrev,
"bottomSeedTeamAbbrev": bottom_abbrev,
}
if top_is_home:
home_abbrev, away_abbrev = top_abbrev, bottom_abbrev
home_name, away_name = "Top Seeds", "Bottom Seeds"
else:
home_abbrev, away_abbrev = bottom_abbrev, top_abbrev
home_name, away_name = "Bottom Seeds", "Top Seeds"
game = make_game(
game_state=game_state,
game_type=3,
series_status=series_status,
home_abbrev=kwargs.pop("home_abbrev", home_abbrev),
away_abbrev=kwargs.pop("away_abbrev", away_abbrev),
home_name=kwargs.pop("home_name", home_name),
away_name=kwargs.pop("away_name", away_name),
**kwargs,
)
if game_number is not None:
game["gameNumber"] = game_number
return game
LIVE_GAME = make_game()
PRE_GAME = make_game(
game_state="FUT", home_score=0, away_score=0, period=0, seconds_remaining=1200
)
FINAL_GAME = make_game(game_state="OFF", period=3, seconds_remaining=0)
SAMPLE_SCOREBOARD = {"games": [LIVE_GAME, PRE_GAME, FINAL_GAME]}
@pytest.fixture()
def sample_scoreboard():
return SAMPLE_SCOREBOARD
@pytest.fixture()
def flask_client(tmp_path, monkeypatch):
data_dir = tmp_path / "data"
data_dir.mkdir()
# Write sample scoreboard JSON
scoreboard_file = data_dir / "scoreboard_data.json"
scoreboard_file.write_text(json.dumps(SAMPLE_SCOREBOARD))
# Create minimal SQLite DB so get_team_standings doesn't crash
db_path = data_dir / "nhl_standings.db"
conn = sqlite3.connect(str(db_path))
conn.execute(
"CREATE TABLE standings "
"(team_common_name TEXT, league_sequence INTEGER, league_l10_sequence INTEGER, "
"division_abbrev TEXT, conference_abbrev TEXT, games_played INTEGER, wildcard_sequence INTEGER)"
)
conn.commit()
conn.close()
# Patch module-level path constants so no reloads are needed
import app.routes as routes
import app.games as games
import app.playoff_cache as playoff_cache
monkeypatch.setattr(routes, "SCOREBOARD_DATA_FILE", str(scoreboard_file))
monkeypatch.setattr(games, "DB_PATH", str(db_path))
monkeypatch.setattr(playoff_cache, "DB_PATH", str(db_path))
from app import app as flask_app
flask_app.config["TESTING"] = True
with flask_app.test_client() as client:
yield client