add WL to tss scoreboards (#1345)

This commit is contained in:
NotSoToothless
2026-06-20 18:55:17 -07:00
committed by GitHub
parent f855e289c8
commit b665eb118f
5 changed files with 327 additions and 26 deletions
+31
View File
@@ -0,0 +1,31 @@
import pathlib
import sys
sys.path.insert(0, str(pathlib.Path(__file__).resolve().parents[1]))
sys.path.insert(0, str(pathlib.Path(__file__).resolve().parents[2] / "SHARED"))
from BOT.transform import build_scoreboard_model
def _game():
return {
"_id": "abc",
"winner": "1",
"mission_name": "Kursk",
"tss": {
"tournament_id": 24965,
"tournament_name": "2x2 RBm Tanks",
"1": {"team_id": "111", "team_name": "A", "players": [{"uid": "1", "pvp_ratio": 1500}]},
"2": {"team_id": "222", "team_name": "B", "players": [{"uid": "2", "pvp_ratio": 1400}]},
},
"players": {
"1": {"name": "alice", "team": "1", "units": [{"unit": "t34", "used": True}]},
"2": {"name": "bob", "team": "2", "units": [{"unit": "pz", "used": True}]},
},
}
def test_model_carries_tournament_id():
model = build_scoreboard_model(_game())
assert model is not None
assert model["tournament_id"] == 24965
+155
View File
@@ -0,0 +1,155 @@
import pathlib
import sqlite3
import sys
sys.path.insert(0, str(pathlib.Path(__file__).resolve().parents[1]))
sys.path.insert(0, str(pathlib.Path(__file__).resolve().parents[2] / "SHARED"))
from BOT import wl
def _make_db(path: str, matches, players):
"""Seed the two real tables with the columns get_tss_standings reads.
matches: list of (session_id, tournament_id)
players: list of (session_id, team_id, vehicle_internal, victor_bool)
"""
conn = sqlite3.connect(path)
conn.execute(
"CREATE TABLE match_summary (session_id TEXT PRIMARY KEY, tournament_id INTEGER)"
)
conn.execute(
"CREATE TABLE player_games_hist ("
" UID TEXT, session_id TEXT, team_id INTEGER,"
" vehicle_internal TEXT, victor_bool TEXT)"
)
conn.executemany("INSERT INTO match_summary VALUES (?, ?)", matches)
conn.executemany(
"INSERT INTO player_games_hist (UID, session_id, team_id, vehicle_internal, victor_bool)"
" VALUES ('u', ?, ?, ?, ?)",
players,
)
conn.commit()
conn.close()
def _point_at(monkeypatch, path):
monkeypatch.setattr(wl, "_db_path", lambda: str(path))
def test_basic_wins_and_losses(tmp_path, monkeypatch):
db = tmp_path / "battles.db"
_make_db(
str(db),
matches=[("s1", 100), ("s2", 100), ("s3", 100)],
players=[
("s1", 7, "t34", "Win"),
("s2", 7, "t34", "Win"),
("s3", 7, "t34", "Loss"),
],
)
_point_at(monkeypatch, db)
assert wl.get_tss_standings(7, 100) == {"wins": 2, "losses": 1}
def test_per_tournament_isolation(tmp_path, monkeypatch):
db = tmp_path / "battles.db"
# Same team_id appears in two tournaments; records must not bleed across.
_make_db(
str(db),
matches=[("a", 100), ("b", 100), ("c", 200)],
players=[
("a", 7, "t34", "Win"),
("b", 7, "t34", "Loss"),
("c", 7, "t34", "Win"),
],
)
_point_at(monkeypatch, db)
assert wl.get_tss_standings(7, 100) == {"wins": 1, "losses": 1}
assert wl.get_tss_standings(7, 200) == {"wins": 1, "losses": 0}
def test_draw_is_loss_for_both_teams(tmp_path, monkeypatch):
db = tmp_path / "battles.db"
# A draw is persisted as victor_bool='Loss' for both participating teams.
_make_db(
str(db),
matches=[("s1", 100)],
players=[
("s1", 7, "t34", "Loss"),
("s1", 9, "pz", "Loss"),
],
)
_point_at(monkeypatch, db)
assert wl.get_tss_standings(7, 100) == {"wins": 0, "losses": 1}
assert wl.get_tss_standings(9, 100) == {"wins": 0, "losses": 1}
def test_vehicle_duplicate_rows_count_once(tmp_path, monkeypatch):
db = tmp_path / "battles.db"
# One player on the team flew two vehicles -> two rows, same session/outcome.
_make_db(
str(db),
matches=[("s1", 100)],
players=[
("s1", 7, "t34", "Win"),
("s1", 7, "is2", "Win"),
],
)
_point_at(monkeypatch, db)
assert wl.get_tss_standings(7, 100) == {"wins": 1, "losses": 0}
def test_string_team_id_is_coerced(tmp_path, monkeypatch):
db = tmp_path / "battles.db"
_make_db(str(db), matches=[("s1", 100)], players=[("s1", 7, "t34", "Win")])
_point_at(monkeypatch, db)
# The render model carries team_id as a string.
assert wl.get_tss_standings("7", 100) == {"wins": 1, "losses": 0}
def test_missing_ids_return_none(tmp_path, monkeypatch):
db = tmp_path / "battles.db"
_make_db(str(db), matches=[("s1", 100)], players=[("s1", 7, "t34", "Win")])
_point_at(monkeypatch, db)
assert wl.get_tss_standings(None, 100) is None
assert wl.get_tss_standings(7, None) is None
assert wl.get_tss_standings("not-a-number", 100) is None
def test_unknown_team_returns_none(tmp_path, monkeypatch):
db = tmp_path / "battles.db"
_make_db(str(db), matches=[("s1", 100)], players=[("s1", 7, "t34", "Win")])
_point_at(monkeypatch, db)
assert wl.get_tss_standings(999, 100) is None
def test_missing_db_returns_none(tmp_path, monkeypatch):
_point_at(monkeypatch, tmp_path / "does_not_exist.db")
assert wl.get_tss_standings(7, 100) is None
def test_reads_wal_mode_db_with_open_writer(tmp_path, monkeypatch):
# The production DB is WAL. Reproduce a live-ingest state: WAL journal, no
# autocheckpoint (so a non-empty -wal/-shm lingers), and a writer connection
# still open while we read — get_tss_standings must still return the record.
db = tmp_path / "battles.db"
_make_db(
str(db),
matches=[("s1", 100), ("s2", 100)],
players=[("s1", 7, "t34", "Win"), ("s2", 7, "t34", "Loss")],
)
writer = sqlite3.connect(str(db))
writer.execute("PRAGMA journal_mode=WAL")
writer.execute("PRAGMA wal_autocheckpoint=0")
writer.execute(
"INSERT INTO player_games_hist (UID, session_id, team_id, vehicle_internal, victor_bool)"
" VALUES ('u', 's3', 7, 't34', 'Win')"
)
writer.execute("INSERT INTO match_summary VALUES ('s3', 100)")
writer.commit() # committed to the WAL, not checkpointed; writer stays open
try:
_point_at(monkeypatch, db)
assert wl.get_tss_standings(7, 100) == {"wins": 2, "losses": 1}
finally:
writer.close()