""" Pytest configuration and fixtures for Cockatrice Web Application tests. """ import pytest import pytest_asyncio from httpx import AsyncClient, ASGITransport from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine, async_sessionmaker from sqlalchemy.orm import sessionmaker from sqlalchemy.pool import StaticPool from app.main import app from app.core.database import Base, get_db from app.core.security import hash_password from app.models.models import User # Test database URL (in-memory SQLite for tests) TEST_DATABASE_URL = "sqlite+aiosqlite:///:memory:" # Create test engine and session test_engine = create_async_engine( TEST_DATABASE_URL, connect_args={"check_same_thread": False}, poolclass=StaticPool, ) TestSessionLocal = async_sessionmaker( bind=test_engine, class_=AsyncSession, expire_on_commit=False, ) @pytest.fixture(scope="session") def event_loop(): """Create an instance of the default event loop for the test session.""" import asyncio loop = asyncio.new_event_loop() yield loop loop.close() @pytest_asyncio.fixture(scope="function") async def db_session(): """Create a new database session for each test.""" async with test_engine.begin() as conn: await conn.run_sync(Base.metadata.create_all) async with TestSessionLocal() as session: yield session async with test_engine.begin() as conn: await conn.run_sync(Base.metadata.drop_all) @pytest_asyncio.fixture(scope="function") async def client(db_session): """Create a test client with database dependency override.""" async def override_get_db(): try: yield db_session finally: pass app.dependency_overrides[get_db] = override_get_db async with AsyncClient( transport=ASGITransport(app=app), base_url="http://test", ) as ac: yield ac app.dependency_overrides.clear() @pytest_asyncio.fixture(scope="function") async def test_user(db_session): """Create a test user.""" user = User( username="testuser", password_sha512=hash_password("testpassword123"), salt="test_salt", email="test@example.com", country="US", privlevel="User", ) db_session.add(user) await db_session.flush() return user @pytest_asyncio.fixture(scope="function") async def admin_user(db_session): """Create an admin test user.""" user = User( username="adminuser", password_sha512=hash_password("adminpassword123"), salt="admin_salt", email="admin@example.com", country="US", privlevel="Admin", ) db_session.add(user) await db_session.flush() return user @pytest_asyncio.fixture(scope="function") async def auth_headers(client, test_user): """Get authentication headers for test user.""" from app.core.security import create_access_token, create_refresh_token access_token = create_access_token(str(test_user.id)) return {"Authorization": f"Bearer {access_token}"} @pytest_asyncio.fixture(scope="function") async def admin_headers(client, admin_user): """Get authentication headers for admin user.""" from app.core.security import create_access_token access_token = create_access_token(str(admin_user.id)) return {"Authorization": f"Bearer {access_token}"}