from collections.abc import AsyncGenerator import pytest_asyncio from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine from fiscal_svc.core.config import settings from fiscal_svc.core.db import Base # Ported verbatim from `auto/backend/tests/conftest.py` (Task 1). Note: # pytest-asyncio >=0.23 runs the whole test session on a single event loop # when asyncio_default_fixture_loop_scope/asyncio_default_test_loop_scope are # set to "session" (see pyproject.toml [tool.pytest.ini_options]) -- that # replaces the old pattern of redefining the `event_loop` fixture, which no # longer controls fixture/test loop assignment on pytest-asyncio 1.x and # caused a "Future attached to a different loop" RuntimeError when the # session-scoped `test_engine` below was created on a different loop than # each test. @pytest_asyncio.fixture(scope="session") async def test_engine(): engine = create_async_engine(settings.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(test_engine) -> AsyncGenerator[AsyncSession, None]: session_maker = async_sessionmaker(test_engine, expire_on_commit=False) async with session_maker() as session: yield session await session.rollback()