Auto merge dev → main (#1353)

* feat(gateway): hashed key store with grant + hot reload

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(gateway): channel registry + aiohttp app (keyed auth, whoami, per-channel ws/proxy)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(gateway): manage_keys CLI (add/list/revoke)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(gateway): retire srebot_external, run relay-gateway under PM2

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(gateway): point ecosystem + README at relay-gateway

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(tss): replay outbox producer for relay gateway

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(tss): forward processed games to relay outbox

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(tss-api): db helpers, app skeleton, info endpoint, fixtures

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(tss-api): player, games, history, search endpoints

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(tss-api): live, match, scoreboard, matches-search, maps

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(tss-api): filter-required leaderboards (players/vehicles/stats)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(tss-api): tournament list/detail/standings/matches

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat: wire tss upstream through gateway + tssbot-api PM2 app

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
NotSoToothless
2026-06-28 03:38:20 -07:00
committed by GitHub
parent f2a1a33c28
commit 24335a2677
18 changed files with 777 additions and 0 deletions
+35
View File
@@ -0,0 +1,35 @@
def test_live_recent_matches(client):
r = client.get("/api/tss/live?limit=10")
assert r.json()["matches"][0]["session_id"] == "sess1"
def test_match_with_rosters(client):
r = client.get("/api/tss/match/sess1")
assert r.status_code == 200
body = r.json()
assert body["match"]["mission_name"].startswith("Gladiators")
slots = {t["team_slot"] for t in body["teams"]}
assert slots == {"1", "2"}
win = next(t for t in body["teams"] if t["team_slot"] == "1")
assert win["is_winner"] is True
assert win["players"][0]["UID"] == "148919027"
def test_match_unknown_404(client):
assert client.get("/api/tss/match/nope").status_code == 404
def test_scoreboard_includes_logs(client):
r = client.get("/api/tss/match/sess1/scoreboard")
assert r.status_code == 200
assert r.json()["logs"]["available"] is True
def test_matches_search_by_player(client):
r = client.get("/api/tss/matches/search?player=148919027")
assert r.json()["matches"][0]["session_id"] == "sess1"
def test_maps_distinct(client):
maps = client.get("/api/tss/maps").json()["maps"]
assert any(m["mission_name"].startswith("Gladiators") for m in maps)