fix: show correct "Game X of 7" for future playoff dates
Enrich raw score-endpoint games with gameNumber from the series cache before parsing. The score API omits gameNumber and its seriesStatus reflects current wins, so all future games in a series computed the same number. Now we cross-reference by game id against the cached series-detail endpoint which includes the correct gameNumber per game. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -273,3 +273,98 @@ class TestSchema:
|
||||
playoff_cache._put("k", {"v": 2})
|
||||
cached, _ = playoff_cache._get("k")
|
||||
assert cached == {"v": 2}
|
||||
|
||||
|
||||
def _raw_playoff_game(game_id, series_letter="A", game_number=None):
|
||||
"""Minimal raw score-endpoint playoff game for enrichment tests."""
|
||||
game = {
|
||||
"id": game_id,
|
||||
"gameType": 3,
|
||||
"gameState": "FUT",
|
||||
"startTimeUTC": "2026-04-25T23:00:00Z",
|
||||
"seriesStatus": {"seriesLetter": series_letter, "round": 1},
|
||||
}
|
||||
if game_number is not None:
|
||||
game["gameNumber"] = game_number
|
||||
return game
|
||||
|
||||
|
||||
class TestEnrichGameNumbers:
|
||||
def test_basic_enrichment(self, tmp_db, monkeypatch):
|
||||
games = [_raw_playoff_game(101), _raw_playoff_game(102)]
|
||||
series_payload = {
|
||||
"games": [
|
||||
{"id": 101, "gameNumber": 3},
|
||||
{"id": 102, "gameNumber": 4},
|
||||
]
|
||||
}
|
||||
monkeypatch.setattr(
|
||||
"app.playoff_cache.requests.get",
|
||||
lambda *a, **kw: _Resp(series_payload),
|
||||
)
|
||||
playoff_cache.enrich_game_numbers(games)
|
||||
assert games[0]["gameNumber"] == 3
|
||||
assert games[1]["gameNumber"] == 4
|
||||
|
||||
def test_skips_games_with_existing_game_number(self, tmp_db, monkeypatch):
|
||||
games = [_raw_playoff_game(101, game_number=2)]
|
||||
called = []
|
||||
monkeypatch.setattr(
|
||||
"app.playoff_cache.requests.get",
|
||||
lambda *a, **kw: called.append(1) or _Resp({"games": []}),
|
||||
)
|
||||
playoff_cache.enrich_game_numbers(games)
|
||||
assert games[0]["gameNumber"] == 2
|
||||
assert len(called) == 0
|
||||
|
||||
def test_skips_non_playoff_games(self, tmp_db, monkeypatch):
|
||||
games = [{"id": 101, "gameType": 2, "gameState": "FUT"}]
|
||||
called = []
|
||||
monkeypatch.setattr(
|
||||
"app.playoff_cache.requests.get",
|
||||
lambda *a, **kw: called.append(1) or _Resp({"games": []}),
|
||||
)
|
||||
playoff_cache.enrich_game_numbers(games)
|
||||
assert "gameNumber" not in games[0]
|
||||
assert len(called) == 0
|
||||
|
||||
def test_graceful_on_cache_miss(self, tmp_db, monkeypatch):
|
||||
import requests as req
|
||||
|
||||
games = [_raw_playoff_game(101)]
|
||||
monkeypatch.setattr(
|
||||
"app.playoff_cache.requests.get",
|
||||
lambda *a, **kw: (_ for _ in ()).throw(req.ConnectionError("x")),
|
||||
)
|
||||
playoff_cache.enrich_game_numbers(games)
|
||||
assert "gameNumber" not in games[0]
|
||||
|
||||
def test_handles_missing_id(self, tmp_db, monkeypatch):
|
||||
game = {
|
||||
"gameType": 3,
|
||||
"gameState": "FUT",
|
||||
"startTimeUTC": "2026-04-25T23:00:00Z",
|
||||
"seriesStatus": {"seriesLetter": "A", "round": 1},
|
||||
}
|
||||
monkeypatch.setattr(
|
||||
"app.playoff_cache.requests.get",
|
||||
lambda *a, **kw: _Resp({"games": [{"id": 101, "gameNumber": 3}]}),
|
||||
)
|
||||
playoff_cache.enrich_game_numbers([game])
|
||||
assert "gameNumber" not in game
|
||||
|
||||
def test_multiple_series(self, tmp_db, monkeypatch):
|
||||
games = [_raw_playoff_game(101, "A"), _raw_playoff_game(201, "B")]
|
||||
payloads = {
|
||||
"a": {"games": [{"id": 101, "gameNumber": 2}]},
|
||||
"b": {"games": [{"id": 201, "gameNumber": 5}]},
|
||||
}
|
||||
|
||||
def fake_get(url, *a, **kw):
|
||||
letter = url.rstrip("/").rsplit("/", 1)[-1]
|
||||
return _Resp(payloads[letter])
|
||||
|
||||
monkeypatch.setattr("app.playoff_cache.requests.get", fake_get)
|
||||
playoff_cache.enrich_game_numbers(games)
|
||||
assert games[0]["gameNumber"] == 2
|
||||
assert games[1]["gameNumber"] == 5
|
||||
|
||||
Reference in New Issue
Block a user