Expose game configuration (energy types, card types, rule constants) via /api/config endpoint so frontend can dynamically load game rules without hardcoding values.
111 lines
3.7 KiB
Python
111 lines
3.7 KiB
Python
"""Tests for configuration API endpoints.
|
|
|
|
Tests the config endpoints that provide default game configurations.
|
|
These endpoints are public (no auth required) and return static defaults.
|
|
"""
|
|
|
|
import pytest
|
|
from fastapi import FastAPI
|
|
from fastapi.testclient import TestClient
|
|
|
|
from app.api.config import router as config_router
|
|
from app.core.config import DeckConfig
|
|
|
|
|
|
@pytest.fixture
|
|
def app():
|
|
"""Create a test FastAPI app with config router."""
|
|
test_app = FastAPI()
|
|
test_app.include_router(config_router, prefix="/api")
|
|
return test_app
|
|
|
|
|
|
@pytest.fixture
|
|
def client(app):
|
|
"""Create a test client."""
|
|
return TestClient(app)
|
|
|
|
|
|
class TestGetDefaultDeckConfig:
|
|
"""Tests for GET /api/config/deck endpoint."""
|
|
|
|
def test_returns_default_deck_config(self, client):
|
|
"""
|
|
Test that the endpoint returns the default DeckConfig values.
|
|
|
|
The frontend uses these values for UI display (progress bars, limits)
|
|
before the user has selected a game mode or custom rules.
|
|
"""
|
|
response = client.get("/api/config/deck")
|
|
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
|
|
# Verify it matches DeckConfig defaults
|
|
expected = DeckConfig()
|
|
assert data["min_size"] == expected.min_size
|
|
assert data["max_size"] == expected.max_size
|
|
assert data["max_copies_per_card"] == expected.max_copies_per_card
|
|
assert data["energy_deck_size"] == expected.energy_deck_size
|
|
assert data["min_basic_pokemon"] == expected.min_basic_pokemon
|
|
|
|
def test_returns_all_deck_config_fields(self, client):
|
|
"""
|
|
Test that all DeckConfig fields are included in the response.
|
|
|
|
Frontend may need any of these fields for UI or validation requests,
|
|
so the endpoint should return the complete configuration.
|
|
"""
|
|
response = client.get("/api/config/deck")
|
|
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
|
|
# All DeckConfig fields should be present
|
|
expected_fields = [
|
|
"min_size",
|
|
"max_size",
|
|
"exact_size_required",
|
|
"max_copies_per_card",
|
|
"max_copies_basic_energy",
|
|
"min_basic_pokemon",
|
|
"energy_deck_enabled",
|
|
"energy_deck_size",
|
|
"starting_hand_size",
|
|
]
|
|
for field in expected_fields:
|
|
assert field in data, f"Missing field: {field}"
|
|
|
|
def test_default_values_match_mantimon_rules(self, client):
|
|
"""
|
|
Test that defaults match Mantimon TCG house rules.
|
|
|
|
Mantimon uses a 40-card main deck with 20-card energy deck,
|
|
4-copy limit, and requires at least 1 Basic Pokemon.
|
|
"""
|
|
response = client.get("/api/config/deck")
|
|
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
|
|
# Mantimon TCG defaults (not standard Pokemon TCG)
|
|
assert data["min_size"] == 40, "Main deck should be 40 cards"
|
|
assert data["max_size"] == 40, "Main deck should be exactly 40"
|
|
assert data["energy_deck_size"] == 20, "Energy deck should be 20 cards"
|
|
assert data["max_copies_per_card"] == 4, "4-copy limit per card"
|
|
assert data["min_basic_pokemon"] == 1, "At least 1 Basic Pokemon"
|
|
assert data["energy_deck_enabled"] is True, "Separate energy deck enabled"
|
|
|
|
def test_no_authentication_required(self, client):
|
|
"""
|
|
Test that the endpoint is accessible without authentication.
|
|
|
|
Config endpoints provide public defaults that the frontend needs
|
|
before the user has logged in or selected a game mode.
|
|
"""
|
|
# No auth headers provided
|
|
response = client.get("/api/config/deck")
|
|
|
|
# Should succeed without auth
|
|
assert response.status_code == 200
|