"""Tests for app.db.base — Base class, async engine + sessionmaker plumbing. These tests build an isolated in-memory SQLite async engine; they never touch the production MySQL engine defined in app.db.base. """ import sqlalchemy as sa from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine from sqlalchemy.orm import Mapped, mapped_column from app.db.base import Base, async_session_maker def test_base_is_declarative_subclass(): """Base must be a DeclarativeBase subclass (SQLAlchemy 2.0 style).""" from sqlalchemy.orm import DeclarativeBase assert issubclass(Base, DeclarativeBase) def test_async_session_maker_is_async_sessionmaker(): """async_session_maker must be an async_sessionmaker instance.""" assert isinstance(async_session_maker, async_sessionmaker) async def test_round_trip_through_in_memory_sqlite(): """Build a throwaway model, create tables, insert + query a row. Uses an in-memory async SQLite engine built locally inside the test so the production MySQL engine is never exercised here. """ class _Row(Base): __tablename__ = "test_row" id: Mapped[int] = mapped_column(primary_key=True) name: Mapped[str] = mapped_column(sa.String(50)) engine = create_async_engine("sqlite+aiosqlite:///:memory:") try: async with engine.begin() as conn: await conn.run_sync(Base.metadata.create_all) SessionLocal = async_sessionmaker(engine, expire_on_commit=False) async with SessionLocal() as session: session.add(_Row(id=1, name="hello")) await session.commit() fetched = ( await session.execute(sa.select(_Row).where(_Row.id == 1)) ).scalar_one() assert fetched.id == 1 assert fetched.name == "hello" finally: async with engine.begin() as conn: await conn.run_sync(Base.metadata.drop_all) await engine.dispose()