107 lines
2.9 KiB
Python
107 lines
2.9 KiB
Python
"""
|
|
©AngelaMos | 2026
|
|
conftest.py
|
|
|
|
Shared pytest fixtures for in-memory SQLite database and
|
|
HTTPX async test client setup
|
|
|
|
test_settings overrides Settings for the test environment
|
|
with an in-memory SQLite URL and dummy paths. db_engine
|
|
creates a StaticPool aiosqlite engine with all tables via
|
|
SQLModel.metadata.create_all. db_session yields an
|
|
AsyncSession bound to the shared engine. db_client builds
|
|
a full HTTPX AsyncClient with ASGITransport wrapping the
|
|
FastAPI app, overriding get_session to use the in-memory
|
|
database with auto-commit
|
|
|
|
Connects to:
|
|
app/config - Settings override
|
|
app/factory - create_app for ASGI transport
|
|
app/api/deps - get_session dependency override
|
|
"""
|
|
|
|
from collections.abc import AsyncIterator
|
|
|
|
import pytest
|
|
from httpx import ASGITransport, AsyncClient
|
|
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
|
|
from sqlalchemy.pool import StaticPool
|
|
from sqlmodel import SQLModel
|
|
|
|
from app.api.deps import get_session
|
|
from app.config import Settings
|
|
from app.factory import create_app
|
|
|
|
|
|
@pytest.fixture
|
|
def test_settings() -> Settings:
|
|
"""
|
|
Override settings for test environment.
|
|
"""
|
|
return Settings(
|
|
env="testing",
|
|
debug=False,
|
|
database_url="sqlite+aiosqlite://",
|
|
redis_url="redis://localhost:6379/1",
|
|
nginx_log_path="/tmp/test-access.log",
|
|
geoip_db_path="/tmp/nonexistent.mmdb",
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
async def db_engine():
|
|
"""
|
|
In-memory SQLite engine shared across all sessions via StaticPool.
|
|
"""
|
|
from app.models.threat_event import ThreatEvent # noqa: F401
|
|
|
|
engine = create_async_engine(
|
|
"sqlite+aiosqlite://",
|
|
connect_args={"check_same_thread": False},
|
|
poolclass=StaticPool,
|
|
)
|
|
async with engine.begin() as conn:
|
|
await conn.run_sync(SQLModel.metadata.create_all)
|
|
yield engine
|
|
await engine.dispose()
|
|
|
|
|
|
@pytest.fixture
|
|
async def db_session(db_engine) -> AsyncIterator[AsyncSession]:
|
|
"""
|
|
Async session bound to the shared in-memory DB.
|
|
"""
|
|
factory = async_sessionmaker(
|
|
db_engine,
|
|
class_=AsyncSession,
|
|
expire_on_commit=False,
|
|
)
|
|
async with factory() as session:
|
|
yield session
|
|
|
|
|
|
@pytest.fixture
|
|
async def db_client(db_engine) -> AsyncIterator[AsyncClient]:
|
|
"""
|
|
HTTPX async client with DB dependency overridden to use in-memory SQLite.
|
|
"""
|
|
factory = async_sessionmaker(
|
|
db_engine,
|
|
class_=AsyncSession,
|
|
expire_on_commit=False,
|
|
)
|
|
|
|
test_app = create_app()
|
|
|
|
async def override_get_session() -> AsyncIterator[AsyncSession]:
|
|
async with factory() as session:
|
|
yield session
|
|
await session.commit()
|
|
|
|
test_app.dependency_overrides[get_session] = override_get_session
|
|
|
|
transport = ASGITransport(app=test_app)
|
|
async with AsyncClient(transport=transport,
|
|
base_url="http://test") as client:
|
|
yield client
|