Refresh web UI and make ML imports optional
All checks were successful
ci / tests (push) Successful in 21s

This commit is contained in:
dan
2025-12-25 09:15:10 +03:00
parent f542747d5e
commit 2499deb071
49 changed files with 4367 additions and 500 deletions

View File

@@ -0,0 +1,86 @@
from __future__ import annotations
import asyncio
from typing import List
import httpx
from fastapi import FastAPI
from fastapi.testclient import TestClient
from services.api import app as api_app
from services.analytics import app as analytics_app
from services.game import app as game_app
def _install_asgi_clients() -> List[httpx.AsyncClient]:
created: List[httpx.AsyncClient] = []
def make_client(app: FastAPI, base_url: str) -> httpx.AsyncClient:
client = httpx.AsyncClient(transport=httpx.ASGITransport(app=app), base_url=base_url)
created.append(client)
return client
api_app.clients["game"] = make_client(game_app.app, "http://game")
api_app.clients["analytics"] = make_client(analytics_app.app, "http://analytics")
dummy_ai = FastAPI()
@dummy_ai.get("/models")
def _models():
return {"models": []}
@dummy_ai.post("/act")
def _act():
return {"action": {"type": "end_turn", "payload": {}}, "debug": {}}
api_app.clients["ai"] = make_client(dummy_ai, "http://ai")
return created
def _close_clients(clients: List[httpx.AsyncClient]) -> None:
for client in clients:
try:
loop = asyncio.get_event_loop()
except RuntimeError:
asyncio.run(client.aclose())
else:
loop.run_until_complete(client.aclose())
def test_full_user_flow() -> None:
with TestClient(api_app.app) as client:
created = _install_asgi_clients()
try:
# Register + login
response = client.post("/api/auth/register", json={"username": "user_flow", "password": "secret"})
assert response.status_code == 200
token = response.json()["token"]
headers = {"Authorization": f"Bearer {token}"}
# Create lobby and seat host
response = client.post("/api/games", json={"name": "Flow", "max_players": 3}, headers=headers)
assert response.status_code == 200
game_id = response.json()["id"]
response = client.post(f"/api/games/{game_id}/join", headers=headers)
assert response.status_code == 200
payload = response.json()
assert payload["players"][0]["name"] == "user_flow"
# Seat AI opponent and start the game
for _ in range(2):
response = client.post(
f"/api/games/{game_id}/add-ai",
json={"ai_type": "random"},
headers=headers,
)
assert response.status_code == 200
response = client.post(f"/api/games/{game_id}/start", headers=headers)
assert response.status_code == 200
state = response.json()
assert state["status"] == "running"
assert state["game"]["phase"] == "setup_round_one"
assert len(state["legal_actions"]) > 0
finally:
_close_clients(created)