| from __future__ import annotations |
|
|
| import json |
| from pathlib import Path |
|
|
| import pytest |
| from fastapi.testclient import TestClient |
|
|
| from world_simulator.api.gradio_app import create_gradio_app |
|
|
|
|
| def test_gradio_app_exposes_game_api(tmp_path: Path) -> None: |
| config_path = _write_config(tmp_path) |
| app = create_gradio_app(config_path=config_path, static_dir=tmp_path / "dist") |
| client = TestClient(app) |
|
|
| health = client.get("/health") |
| assert health.status_code == 200 |
| assert health.json()["status"] == "ok" |
|
|
| snapshot = client.get("/scene/state?warmup=1") |
| assert snapshot.status_code == 200 |
| assert snapshot.json()["terrain"]["kind"] == "plain_green" |
|
|
| tick = client.post("/tick") |
| assert tick.status_code == 200 |
| assert tick.json()["tick"] == 1 |
|
|
|
|
| def test_gradio_app_serves_missing_frontend_page(tmp_path: Path) -> None: |
| config_path = _write_config(tmp_path) |
| app = create_gradio_app(config_path=config_path, static_dir=tmp_path / "missing-dist") |
| client = TestClient(app) |
|
|
| response = client.get("/world") |
|
|
| assert response.status_code == 503 |
| assert "frontend is not built" in response.text |
|
|
| |
| lobby = client.get("/") |
| assert lobby.status_code == 200 |
|
|
|
|
| def test_gradio_app_force_deterministic_disables_modal_runtime( |
| tmp_path: Path, |
| monkeypatch: pytest.MonkeyPatch, |
| ) -> None: |
| monkeypatch.setenv("WORLD_SIMULATOR_FORCE_DETERMINISTIC", "1") |
| config_path = _write_modal_config(tmp_path) |
| app = create_gradio_app(config_path=config_path, static_dir=tmp_path / "dist") |
| client = TestClient(app) |
|
|
| health = client.get("/health") |
| assert health.status_code == 200 |
| assert health.json()["simulator"] == "deterministic" |
|
|
| snapshot = client.get("/scene/state?warmup=1") |
| assert snapshot.status_code == 200 |
| assert snapshot.json()["simulation"]["models"] == [] |
|
|
| god_command = client.post("/god-command", json={"command": "make Ada happy"}) |
| assert god_command.status_code == 404 |
|
|
|
|
| def _write_config(tmp_path: Path) -> Path: |
| config_path = tmp_path / "game.json" |
| config_path.write_text( |
| json.dumps( |
| { |
| "world": { |
| "width": 80, |
| "depth": 80, |
| "terrain": "plain_green", |
| "seed": 42, |
| }, |
| "npcs": {"count": 2}, |
| "simulation": {"tick_ms": 500}, |
| "server": {"host": "127.0.0.1", "port": 8000}, |
| } |
| ), |
| encoding="utf-8", |
| ) |
| return config_path |
|
|
|
|
| def _write_modal_config(tmp_path: Path) -> Path: |
| config_path = tmp_path / "game.modal.json" |
| config_path.write_text( |
| json.dumps( |
| { |
| "world": { |
| "width": 80, |
| "depth": 80, |
| "terrain": "plain_green", |
| "seed": 42, |
| }, |
| "npcs": {"count": 2}, |
| "simulation": {"tick_ms": 500}, |
| "server": {"host": "127.0.0.1", "port": 8000}, |
| "connector": { |
| "type": "openai_compatible", |
| "base_url": "https://workspace--npc-serve.modal.run/v1", |
| "model": "npc-model", |
| }, |
| "god_console": { |
| "type": "openai_compatible", |
| "base_url": "https://workspace--god-serve.modal.run/v1", |
| "model": "god-model", |
| }, |
| } |
| ), |
| encoding="utf-8", |
| ) |
| return config_path |
|
|