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