from app.bracket_view import build_bracket_view def _series( letter, top_abbrev, top_id, top_wins, bot_abbrev, bot_id, bot_wins, rnd=1, winning_id=None, top_seed="D1", bot_seed="WC1", ): return { "seriesLetter": letter, "playoffRound": rnd, "topSeedWins": top_wins, "bottomSeedWins": bot_wins, "topSeedRankAbbrev": top_seed, "bottomSeedRankAbbrev": bot_seed, "winningTeamId": winning_id, "topSeedTeam": { "id": top_id, "abbrev": top_abbrev, "name": {"default": f"{top_abbrev} Team"}, "commonName": {"default": top_abbrev}, "darkLogo": f"http://example.com/{top_abbrev}_dark.svg", }, "bottomSeedTeam": { "id": bot_id, "abbrev": bot_abbrev, "name": {"default": f"{bot_abbrev} Team"}, "commonName": {"default": bot_abbrev}, "darkLogo": f"http://example.com/{bot_abbrev}_dark.svg", }, } class TestEmptyBracket: def test_empty_payload_returns_all_placeholders(self): view = build_bracket_view(2026, {"series": []}) assert len(view["east_r1"]) == 4 assert len(view["west_r1"]) == 4 assert len(view["east_r2"]) == 2 assert len(view["west_r2"]) == 2 assert len(view["east_cf"]) == 1 assert len(view["west_cf"]) == 1 assert len(view["cup"]) == 1 for slot in view["east_r1"]: assert slot["empty"] is True assert slot["series_id"].startswith("2026-") def test_none_payload_is_safe(self): view = build_bracket_view(2026, None) assert all(s["empty"] for s in view["east_r1"]) class TestMatchupStates: def test_complete_series_marks_winner(self): s = _series("A", "TOR", 10, 4, "OTT", 9, 2, winning_id=10) view = build_bracket_view(2026, {"series": [s]}) a = view["east_r1"][0] assert a["empty"] is False assert a["state"] == "complete" assert a["winner_abbrev"] == "TOR" assert a["top_wins"] == 4 assert a["bottom_wins"] == 2 def test_active_series_has_wins_but_no_winner(self): s = _series("B", "FLA", 13, 2, "TBL", 14, 1) view = build_bracket_view(2026, {"series": [s]}) b = view["east_r1"][1] assert b["state"] == "active" assert b["winner_abbrev"] is None def test_upcoming_series_zero_zero(self): s = _series("C", "WSH", 15, 0, "MTL", 8, 0) view = build_bracket_view(2026, {"series": [s]}) c = view["east_r1"][2] assert c["state"] == "upcoming" class TestRoutingToRounds: def test_round_1_east_vs_west_by_letter(self): series = [ _series("A", "T1", 1, 1, "T2", 2, 0), _series("E", "T3", 3, 1, "T4", 4, 0), ] view = build_bracket_view(2026, {"series": series}) assert view["east_r1"][0]["top"]["abbrev"] == "T1" assert view["west_r1"][0]["top"]["abbrev"] == "T3" def test_round_2_routing(self): series = [ _series("I", "T1", 1, 0, "T2", 2, 0, rnd=2), _series("K", "T3", 3, 0, "T4", 4, 0, rnd=2), ] view = build_bracket_view(2026, {"series": series}) assert view["east_r2"][0]["top"]["abbrev"] == "T1" assert view["west_r2"][0]["top"]["abbrev"] == "T3" def test_conf_finals_routing(self): series = [ _series("M", "T1", 1, 0, "T2", 2, 0, rnd=3), _series("N", "T3", 3, 0, "T4", 4, 0, rnd=3), ] view = build_bracket_view(2026, {"series": series}) assert view["east_cf"][0]["top"]["abbrev"] == "T1" assert view["west_cf"][0]["top"]["abbrev"] == "T3" def test_cup_final_routing(self): series = [_series("O", "T1", 1, 2, "T2", 2, 4, rnd=4, winning_id=2)] view = build_bracket_view(2026, {"series": series}) assert view["cup"][0]["bottom"]["abbrev"] == "T2" assert view["cup"][0]["winner_abbrev"] == "T2" class TestSeriesIdLink: def test_series_id_format(self): s = _series("A", "TOR", 10, 0, "OTT", 9, 0) view = build_bracket_view(2026, {"series": [s]}) assert view["east_r1"][0]["series_id"] == "2026-A" class TestRoundsAccordionBundle: def test_rounds_has_four_entries(self): view = build_bracket_view(2026, {"series": []}) assert len(view["rounds"]) == 4 assert view["rounds"][0]["label"] == "First Round" assert view["rounds"][3]["label"] == "Stanley Cup Final" assert "east" in view["rounds"][0] assert "cup" in view["rounds"][3]