import pytest_asyncio from httpx import ASGITransport, AsyncClient from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine from sqlalchemy.pool import StaticPool from app.core.database import Base, get_db from app.crud import role as role_crud from app.crud import user as user_crud from app.main import app from scripts.seed import PERMISSIONS, ROLES @pytest_asyncio.fixture async def db_sessionmaker(): # In-memory SQLite shared across connections for the test's lifetime. engine = create_async_engine( "sqlite+aiosqlite://", connect_args={"check_same_thread": False}, poolclass=StaticPool, ) async with engine.begin() as conn: await conn.run_sync(Base.metadata.create_all) maker = async_sessionmaker(engine, expire_on_commit=False) yield maker await engine.dispose() @pytest_asyncio.fixture async def seeded(db_sessionmaker): """Seed permissions + roles and return ids needed by tests.""" async with db_sessionmaker() as db: perms = {} for name, desc in PERMISSIONS: perms[name] = await role_crud.create_permission( db, name=name, description=desc ) roles = {} for role_name, perm_names in ROLES.items(): roles[role_name] = await role_crud.create( db, name=role_name, permission_ids=[perms[p].id for p in perm_names], ) return {"roles": roles, "perms": perms} @pytest_asyncio.fixture async def client(db_sessionmaker): async def override_get_db(): async with db_sessionmaker() as session: yield session app.dependency_overrides[get_db] = override_get_db transport = ASGITransport(app=app) async with AsyncClient(transport=transport, base_url="http://test") as c: yield c app.dependency_overrides.clear() @pytest_asyncio.fixture async def make_user(db_sessionmaker): async def _make(email, password="secret123", **kwargs): async with db_sessionmaker() as db: return await user_crud.create(db, email=email, password=password, **kwargs) return _make