import pytest from app.playoff import ( is_pinned, is_playoff_game, is_playoff_ot, ot_label, series_badges, series_blurb, series_state, series_summary, today_meta, ) from tests.conftest import make_game, make_playoff_game class TestSeriesState: def test_empty_returns_defaults(self): state = series_state({}) assert state["is_opener"] is True assert state["game_number"] == 1 assert state["round"] == 1 assert state["leader"] is None @pytest.mark.parametrize( "top,bot,expected_game", [(0, 0, 1), (1, 0, 2), (1, 1, 3), (2, 1, 4), (2, 2, 5), (3, 2, 6), (3, 3, 7)], ) def test_game_number_computation(self, top, bot, expected_game): state = series_state({"round": 1, "topSeedWins": top, "bottomSeedWins": bot}) assert state["game_number"] == expected_game def test_game7_predicate(self): state = series_state({"round": 1, "topSeedWins": 3, "bottomSeedWins": 3}) assert state["is_game7"] is True assert state["is_clincher"] is False assert state["is_pivotal"] is False def test_clincher_predicate(self): state = series_state({"round": 1, "topSeedWins": 3, "bottomSeedWins": 1}) assert state["is_clincher"] is True assert state["is_elimination"] is True assert state["is_game7"] is False def test_pivotal_predicate(self): state = series_state({"round": 2, "topSeedWins": 2, "bottomSeedWins": 2}) assert state["is_pivotal"] is True assert state["is_game7"] is False assert state["is_clincher"] is False def test_opener_predicate(self): state = series_state({"round": 1, "topSeedWins": 0, "bottomSeedWins": 0}) assert state["is_opener"] is True def test_leader_top(self): state = series_state({"round": 1, "topSeedWins": 2, "bottomSeedWins": 1}) assert state["leader"] == "top" assert state["hi"] == 2 and state["lo"] == 1 def test_leader_bottom(self): state = series_state({"round": 1, "topSeedWins": 1, "bottomSeedWins": 2}) assert state["leader"] == "bottom" def test_no_leader_when_tied(self): state = series_state({"round": 1, "topSeedWins": 1, "bottomSeedWins": 1}) assert state["leader"] is None class TestSeriesBlurb: def test_opener_blurb(self): game = make_playoff_game(top_wins=0, bottom_wins=0) assert series_blurb(game) == "Series opener" def test_game7_blurb(self): game = make_playoff_game(top_wins=3, bottom_wins=3) assert series_blurb(game) == "Win-or-go-home \u2014 Game 7." def test_clincher_blurb_names_leader(self): game = make_playoff_game( top_wins=3, bottom_wins=1, top_abbrev="TOR", bottom_abbrev="BOS", top_is_home=True, ) blurb = series_blurb(game) assert "Top Seeds" in blurb assert "close it out" in blurb assert "Game 5" in blurb def test_pivotal_blurb(self): game = make_playoff_game(top_wins=2, bottom_wins=2) assert "pivotal" in series_blurb(game).lower() assert "Game 5" in series_blurb(game) def test_leader_trailer_blurb(self): game = make_playoff_game(top_wins=2, bottom_wins=1) blurb = series_blurb(game) assert "lead" in blurb assert "2\u20111" in blurb def test_tied_mid_series_blurb(self): game = make_playoff_game(top_wins=1, bottom_wins=1) blurb = series_blurb(game) assert "1" in blurb assert "Game 3" in blurb class TestSeriesBadges: def test_round_1_always_first(self): game = make_playoff_game(round_num=1, top_wins=1, bottom_wins=0) assert series_badges(game)[0] == "R1" def test_cup_final_label(self): game = make_playoff_game(round_num=4, top_wins=0, bottom_wins=0) assert series_badges(game)[0] == "CUP FINAL" def test_conf_final_label(self): game = make_playoff_game(round_num=3, top_wins=0, bottom_wins=0) assert series_badges(game)[0] == "CONF FINAL" def test_game7_badge(self): game = make_playoff_game(top_wins=3, bottom_wins=3) assert "GAME 7" in series_badges(game) def test_clincher_badge(self): game = make_playoff_game(top_wins=3, bottom_wins=1) assert "CLINCHER" in series_badges(game) def test_pivotal_badge(self): game = make_playoff_game(top_wins=2, bottom_wins=2) assert "PIVOTAL" in series_badges(game) def test_opener_has_no_stake_badge(self): badges = series_badges(make_playoff_game(top_wins=0, bottom_wins=0)) assert badges == ["R1"] class TestSeriesSummary: def test_opener_summary(self): game = make_playoff_game(top_wins=0, bottom_wins=0, round_num=1) assert series_summary(game) == "Game 1 of 7" def test_leader_summary(self): game = make_playoff_game(top_wins=2, bottom_wins=1) assert series_summary(game) == "Game 4 of 7" def test_tied_mid_series_summary(self): game = make_playoff_game(top_wins=1, bottom_wins=1) assert series_summary(game) == "Game 3 of 7" def test_finished_game_keeps_its_own_number(self): # seriesStatus has advanced to 2-0 after this game finished, but the # raw gameNumber pins the card to the game it actually represents. game = make_playoff_game(top_wins=2, bottom_wins=0, game_number=2) assert series_summary(game) == "Game 2 of 7" class TestIsPinned: def test_game7_live_is_pinned(self): game = make_playoff_game(top_wins=3, bottom_wins=3, game_state="LIVE") assert is_pinned(game) is True def test_game7_pre_is_pinned(self): game = make_playoff_game(top_wins=3, bottom_wins=3, game_state="FUT") assert is_pinned(game) is True def test_game7_final_not_pinned(self): game = make_playoff_game(top_wins=3, bottom_wins=3, game_state="OFF") assert is_pinned(game) is False def test_non_game7_not_pinned(self): game = make_playoff_game(top_wins=2, bottom_wins=1) assert is_pinned(game) is False def test_regular_season_not_pinned(self): game = make_game() # game_type=2, no series assert is_pinned(game) is False class TestIsPlayoffOt: def test_playoff_period_4_live(self): game = make_playoff_game(period=4, game_state="LIVE") assert is_playoff_ot(game) is True def test_playoff_period_5_live(self): game = make_playoff_game(period=5, game_state="LIVE") assert is_playoff_ot(game) is True def test_playoff_period_3_not_ot(self): game = make_playoff_game(period=3, game_state="LIVE") assert is_playoff_ot(game) is False def test_regular_season_ot_not_playoff_ot(self): game = make_game(period=4, game_state="LIVE", game_type=2) assert is_playoff_ot(game) is False def test_crit_state_counts_as_live(self): game = make_playoff_game(period=4, game_state="CRIT") assert is_playoff_ot(game) is True def test_final_state_not_playoff_ot(self): game = make_playoff_game(period=4, game_state="OFF") assert is_playoff_ot(game) is False class TestOtLabel: def test_period_4_is_ot(self): assert ot_label(4) == "OT" def test_period_5_is_2ot(self): assert ot_label(5) == "2OT" def test_period_6_is_3ot(self): assert ot_label(6) == "3OT" def test_pre_ot_returns_empty(self): assert ot_label(3) == "" assert ot_label(0) == "" class TestIsPlayoffGame: def test_playoff_raw_shape(self): assert is_playoff_game(make_playoff_game()) is True def test_regular_raw_shape(self): assert is_playoff_game(make_game(game_type=2)) is False def test_parsed_shape(self): # parse_games produces {"Game Type": 3} — is_playoff_game should handle both assert is_playoff_game({"Game Type": 3}) is True assert is_playoff_game({"Game Type": 2}) is False class TestTodayMeta: def test_no_playoff_games_off_mode(self): meta = today_meta([make_game(game_type=2)]) assert meta["playoff_mode"] is False assert meta["round_label"] is None def test_playoff_games_on_mode(self): games = [ make_playoff_game(series_letter="A"), make_playoff_game(series_letter="B"), ] meta = today_meta(games) assert meta["playoff_mode"] is True assert meta["series_active"] == 2 assert meta["round_label"] == "First Round" def test_counts_game7(self): games = [ make_playoff_game(top_wins=3, bottom_wins=3, series_letter="A"), make_playoff_game(top_wins=1, bottom_wins=0, series_letter="B"), ] meta = today_meta(games) assert meta["game7_count"] == 1 assert meta["elimination_count"] == 0 def test_counts_elimination_games(self): games = [ make_playoff_game(top_wins=3, bottom_wins=1, series_letter="A"), make_playoff_game(top_wins=3, bottom_wins=2, series_letter="B"), ] meta = today_meta(games) assert meta["elimination_count"] == 2 assert meta["game7_count"] == 0 def test_round_label_reflects_highest_active_round(self): games = [ make_playoff_game(round_num=1, series_letter="A"), make_playoff_game(round_num=2, series_letter="I"), ] meta = today_meta(games) assert meta["round_label"] == "Second Round" def test_cup_final_label(self): games = [make_playoff_game(round_num=4, series_letter="P")] meta = today_meta(games) assert meta["round_label"] == "Stanley Cup Final"