from __future__ import annotations import asyncio import httpx from fastapi import FastAPI from fastapi.testclient import TestClient from services.api import app as api_app from services.game import app as game_app from services.analytics import app as analytics_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: asyncio.get_event_loop().run_until_complete(client.aclose()) except RuntimeError: asyncio.run(client.aclose()) def test_api_game_flow() -> None: with TestClient(api_app.app) as client: created = _install_asgi_clients() response = client.post("/api/auth/register", json={"username": "eve", "password": "secret"}) assert response.status_code == 200 token = response.json()["token"] headers = {"Authorization": f"Bearer {token}"} response = client.post("/api/games", json={"name": "Arena", "max_players": 2}, 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 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 assert response.json()["status"] == "running" _close_clients(created)