model used being carried thru

This commit is contained in:
John Lancaster
2026-06-29 19:04:16 -05:00
parent 9ada09accf
commit 7df687d6f5
27 changed files with 1442 additions and 210 deletions
+68 -23
View File
@@ -1,14 +1,18 @@
"""Tests for transcription.db — schema bootstrap and session factory."""
from sqlalchemy import inspect, text
from sqlmodel import Session, SQLModel, create_engine
import pytest
from sqlalchemy import inspect
from sqlalchemy import text
from sqlalchemy.ext.asyncio import create_async_engine
from sqlmodel import SQLModel
from sqlmodel.ext.asyncio.session import AsyncSession
from sqlmodel.pool import StaticPool
def _in_memory_engine():
"""Create a fresh in-memory SQLite engine for isolated db tests."""
return create_engine(
"sqlite://",
return create_async_engine(
"sqlite+aiosqlite://",
connect_args={"check_same_thread": False},
poolclass=StaticPool,
)
@@ -17,18 +21,21 @@ def _in_memory_engine():
class TestSchemaBootstrap:
"""Verify create_all produces the expected table set."""
def test_create_all_creates_expected_tables(self):
@pytest.mark.asyncio
async def test_create_all_creates_expected_tables(self):
"""After create_all(), document, job, and transcript tables exist."""
engine = _in_memory_engine()
# Ensure models are imported so metadata is populated
from transcription.models import Document, Job, Transcript # noqa: F401
import transcription.db as db_module
from transcription.models import Document # noqa: F401
from transcription.models import Job # noqa: F401
from transcription.models import Transcript # noqa: F401
db_module.create_all(engine=engine)
await db_module.create_all(engine=engine)
inspector = inspect(engine)
table_names = set(inspector.get_table_names())
async with engine.connect() as connection:
table_names = set(await connection.run_sync(lambda conn: inspect(conn).get_table_names()))
await engine.dispose()
assert "document" in table_names
assert "job" in table_names
assert "transcript" in table_names
@@ -37,31 +44,37 @@ class TestSchemaBootstrap:
class TestSessionFactory:
"""Verify get_session yields and cleans up sessions."""
def test_get_session_yields_session(self):
@pytest.mark.asyncio
async def test_get_session_yields_session(self):
"""get_session() yields a usable Session object."""
engine = _in_memory_engine()
SQLModel.metadata.create_all(engine)
async with engine.begin() as connection:
await connection.run_sync(SQLModel.metadata.create_all)
import transcription.db as db_module
with db_module.get_session(engine=engine) as session:
assert isinstance(session, Session)
factory = db_module.async_sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
async with db_module.get_session(session_factory=factory) as session:
assert isinstance(session, AsyncSession)
await engine.dispose()
def test_session_is_closed_after_generator_exit(self):
@pytest.mark.asyncio
async def test_session_is_closed_after_generator_exit(self):
"""After the context manager exits, the session is closed."""
engine = _in_memory_engine()
SQLModel.metadata.create_all(engine)
async with engine.begin() as connection:
await connection.run_sync(SQLModel.metadata.create_all)
import transcription.db as db_module
with db_module.get_session(engine=engine) as session:
factory = db_module.async_sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
async with db_module.get_session(session_factory=factory) as session:
# Session is usable inside the context
session.execute(text("SELECT 1"))
await session.exec(text("SELECT 1"))
captured = session
# After exiting, the session's internal connection is released
# (no active transaction bound to the session)
assert captured._transaction is None
assert captured.sync_session._transaction is None
await engine.dispose()
class TestBootstrapPolicy:
@@ -72,7 +85,11 @@ class TestBootstrapPolicy:
from transcription.config import Settings
from transcription.db import should_bootstrap_schema
settings = Settings(openrouter_api_key="test-key", environment="production")
settings = Settings(
openrouter_api_key="test-key",
environment="production",
bootstrap_schema_on_startup=None,
)
assert should_bootstrap_schema(settings) is False
def test_development_defaults_to_bootstrap(self):
@@ -80,7 +97,11 @@ class TestBootstrapPolicy:
from transcription.config import Settings
from transcription.db import should_bootstrap_schema
settings = Settings(openrouter_api_key="test-key", environment="development")
settings = Settings(
openrouter_api_key="test-key",
environment="development",
bootstrap_schema_on_startup=None,
)
assert should_bootstrap_schema(settings) is True
def test_explicit_override_wins(self):
@@ -94,3 +115,27 @@ class TestBootstrapPolicy:
bootstrap_schema_on_startup=True,
)
assert should_bootstrap_schema(settings) is True
class TestRuntimeSqliteEngineConfig:
"""Verify sqlite runtime engine configuration from settings."""
def test_in_memory_sqlite_uses_static_pool_by_default(self):
"""In-memory sqlite URLs get StaticPool for consistent connections."""
from transcription.config import Settings
from transcription.db.runtime import _build_engine
settings = Settings(openrouter_api_key="test-key", database_url="sqlite://")
engine = _build_engine(settings)
assert engine.sync_engine.pool.__class__.__name__ == "StaticPool"
def test_file_sqlite_does_not_force_static_pool(self):
"""File-backed sqlite URLs keep default pool behavior."""
from transcription.config import Settings
from transcription.db.runtime import _build_engine
settings = Settings(openrouter_api_key="test-key", database_url="sqlite:///./runtime-test.db")
engine = _build_engine(settings)
assert engine.sync_engine.pool.__class__.__name__ != "StaticPool"