"""Pytest fixtures for Hub tests.""" import asyncio from collections.abc import AsyncGenerator from typing import Generator import pytest import pytest_asyncio from httpx import ASGITransport, AsyncClient from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine from app.config import settings from app.db import get_db from app.main import app from app.models import Base # Use SQLite for testing TEST_DATABASE_URL = "sqlite+aiosqlite:///:memory:" @pytest.fixture(scope="session") def event_loop() -> Generator[asyncio.AbstractEventLoop, None, None]: """Create event loop for async tests.""" loop = asyncio.get_event_loop_policy().new_event_loop() yield loop loop.close() @pytest_asyncio.fixture async def db_engine(): """Create test database engine.""" engine = create_async_engine( TEST_DATABASE_URL, echo=False, ) async with engine.begin() as conn: await conn.run_sync(Base.metadata.create_all) yield engine async with engine.begin() as conn: await conn.run_sync(Base.metadata.drop_all) await engine.dispose() @pytest_asyncio.fixture async def db_session(db_engine) -> AsyncGenerator[AsyncSession, None]: """Create test database session.""" async_session = async_sessionmaker( db_engine, class_=AsyncSession, expire_on_commit=False, ) async with async_session() as session: yield session @pytest_asyncio.fixture async def client(db_session: AsyncSession) -> AsyncGenerator[AsyncClient, None]: """Create test HTTP client.""" async def override_get_db(): yield db_session 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.fixture def admin_headers() -> dict[str, str]: """Return admin authentication headers.""" return {"X-Admin-Api-Key": settings.ADMIN_API_KEY}