""" Pytest configuration and fixtures for the City Builder test suite. This provides clean test isolation by resetting the server state before each test. """ import pytest import asyncio import tempfile import os import time from pathlib import Path # Import server components from server.main import initialize_components, game_state, ws_manager, economy_engine, database from server.game_state import GameState from server.economy import EconomyEngine from server.database import Database @pytest.fixture(scope="function") async def fresh_server_state(): """ Fixture that provides fresh server state for each test. This resets the global server components with a clean test database. """ # Create temporary database for this test temp_fd, temp_db_path = tempfile.mkstemp(suffix=".db") os.close(temp_fd) try: # Initialize server components with test database test_game_state, test_ws_manager, test_economy_engine, test_database = initialize_components(temp_db_path) # Initialize the test database test_database.init_db() # Yield the components for the test yield { 'game_state': test_game_state, 'ws_manager': test_ws_manager, 'economy_engine': test_economy_engine, 'database': test_database, 'db_path': temp_db_path } finally: # Clean up temporary database if os.path.exists(temp_db_path): os.unlink(temp_db_path) @pytest.fixture(scope="function") def isolated_game_components(): """ Fixture providing completely isolated game components for unit tests. These are separate from the server's global state. """ # Create temporary database for this test temp_fd, temp_db_path = tempfile.mkstemp(suffix=".db") os.close(temp_fd) try: # Create fresh, isolated components game_state = GameState() economy_engine = EconomyEngine(game_state) database = Database(temp_db_path) database.init_db() yield game_state, economy_engine, database finally: # Clean up temporary database if os.path.exists(temp_db_path): os.unlink(temp_db_path) @pytest.fixture(scope="function") def unique_coordinates(): """ Fixture that provides unique coordinates for each test to avoid conflicts. Uses timestamp-based coordinates to ensure uniqueness. """ base_time = int(time.time() * 1000) % 10000 # Get last 4 digits of timestamp def get_coords(offset=0): """Get unique coordinates with optional offset""" x = (base_time + offset) % 100 y = (base_time + offset * 2) % 100 return x, y return get_coords # Configure asyncio mode for all tests pytest_plugins = ('pytest_asyncio',)