import pytest from fastapi.testclient import TestClient from tft.api import app as app_mod from tft.constants.loader import load_constants from tft.model import artifact as artifact_mod from tests.test_sim import make_static @pytest.fixture def client(monkeypatch): static = make_static() static["meta"]["patch"] = "test" art = artifact_mod.build(static) cfg = load_constants(17) monkeypatch.setattr(app_mod, "_load_game_deps", lambda: (art, cfg)) return TestClient(app_mod.app) def test_full_game_via_api(client): state = client.post("/api/game", params={"seed": 3}).json() game_id = state["game_id"] assert state["round"]["label"] == "1-1" assert state["player"]["hp"] == 100 assert len(state["opponents"]) == 7 steps = 0 while not state["over"]: if state["augment_offer"]: client.post(f"/api/game/{game_id}/action", json={"action": "pick_augment", "choice": 0}) affordable = [i for i, s in enumerate(state["shop"]) if s and s["cost"] <= state["player"]["gold"]] if affordable: client.post(f"/api/game/{game_id}/action", json={"action": "buy", "slot": affordable[0]}) resp = client.post(f"/api/game/{game_id}/action", json={"action": "next"}) assert resp.status_code == 200 state = resp.json() steps += 1 assert steps < 100 assert 1 <= state["placement"] <= 8 def test_invalid_action_is_400(client): game_id = client.post("/api/game", params={"seed": 1}).json()["game_id"] resp = client.post(f"/api/game/{game_id}/action", json={"action": "sell", "where": "bench", "idx": 99}) assert resp.status_code == 400 resp = client.post(f"/api/game/{game_id}/action", json={"action": "dance"}) assert resp.status_code == 400 assert client.post("/api/game/nope/action", json={"action": "next"}).status_code == 404 def test_state_shape(client): state = client.post("/api/game", params={"seed": 5}).json() for key in ("round", "player", "board", "bench", "shop", "traits", "opponents", "items", "over", "log", "shop_odds", "shop_locked"): assert key in state assert sum(state["shop_odds"]) == 100 assert state["player"]["score"] == 0.0 assert all(o["board"] is not None for o in state["opponents"]) def test_upgrade_hint(): from tft.api.app import upgrade_hint from tft.sim.game import Game static = make_static() static["meta"]["patch"] = "t" game = Game(artifact_mod.build(static), load_constants(17), seed=1) assert upgrade_hint(game, "U1_0") == 0 game.bench = [{"api_name": "U1_0", "stars": 1, "items": []} for _ in range(2)] assert upgrade_hint(game, "U1_0") == 2 game.bench = [{"api_name": "U1_0", "stars": 2, "items": []} for _ in range(2)] + \ [{"api_name": "U1_0", "stars": 1, "items": []} for _ in range(2)] assert upgrade_hint(game, "U1_0") == 3 game.bench = [{"api_name": "U1_0", "stars": 3, "items": []}] assert upgrade_hint(game, "U1_0") == 0