"""Shared test fixtures with in-memory SQLite database.""" import pytest from httpx import ASGITransport, AsyncClient from sqlalchemy import create_engine, event from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine from sqlalchemy.orm import sessionmaker from cartsnitch_api.config import settings as cartsnitch_settings from cartsnitch_api.database import get_db from cartsnitch_api.main import create_app from cartsnitch_api.models import Base TEST_DATABASE_URL = "sqlite+aiosqlite:///:memory:" @pytest.fixture(autouse=True) def disable_rate_limiting(): """Disable rate limiting for all tests to prevent 429 interference.""" cartsnitch_settings.rate_limit_enabled = False yield cartsnitch_settings.rate_limit_enabled = True @pytest.fixture def engine(): """Sync in-memory SQLite engine for model unit tests.""" eng = create_engine("sqlite:///:memory:") Base.metadata.create_all(eng) yield eng eng.dispose() @pytest.fixture def session(engine): """Sync SQLAlchemy session for model unit tests.""" factory = sessionmaker(bind=engine) with factory() as sess: yield sess @pytest.fixture async def db_engine(): engine = create_async_engine(TEST_DATABASE_URL, echo=False) @event.listens_for(engine.sync_engine, "connect") def set_sqlite_pragma(dbapi_connection, connection_record): cursor = dbapi_connection.cursor() cursor.execute("PRAGMA foreign_keys=ON") cursor.close() 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.fixture async def db_session(db_engine): factory = async_sessionmaker(db_engine, class_=AsyncSession, expire_on_commit=False) async with factory() as session: yield session @pytest.fixture async def client(db_engine): factory = async_sessionmaker(db_engine, class_=AsyncSession, expire_on_commit=False) async def override_get_db(): async with factory() as session: yield session app = create_app() app.dependency_overrides[get_db] = override_get_db transport = ASGITransport(app=app) async with AsyncClient(transport=transport, base_url="http://test") as ac: yield ac app.dependency_overrides.clear() @pytest.fixture async def auth_headers(client): """Register a test user and return auth headers.""" resp = await client.post( "/auth/register", json={ "email": "test@example.com", "password": "testpass123", "display_name": "Test User", }, ) assert resp.status_code == 201 token = resp.json()["access_token"] return {"Authorization": f"Bearer {token}"}