"""Tests for transcription.db — schema bootstrap and session factory.""" from sqlalchemy import inspect from sqlalchemy import text from sqlmodel import Session from sqlmodel import SQLModel from sqlmodel import create_engine from sqlmodel.pool import StaticPool def _in_memory_engine(): """Create a fresh in-memory SQLite engine for isolated db tests.""" return create_engine( "sqlite://", connect_args={"check_same_thread": False}, poolclass=StaticPool, ) class TestSchemaBootstrap: """Verify create_all produces the expected table set.""" def test_create_all_creates_expected_tables(self): """After create_all(), core V1 tables exist.""" engine = _in_memory_engine() # Ensure models are imported so metadata is populated 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 from transcription.models import TranscriptRevision # noqa: F401 db_module.create_all(engine=engine) inspector = inspect(engine) table_names = set(inspector.get_table_names()) assert "document" in table_names assert "job" in table_names assert "transcript" in table_names assert "transcriptrevision" in table_names def test_validate_schema_compatibility_returns_no_issues_for_fresh_schema(self): """validate_schema_compatibility reports no issues on fresh schema.""" engine = _in_memory_engine() import transcription.db as db_module db_module.create_all(engine=engine) issues = db_module.validate_schema_compatibility(engine=engine) assert issues == [] class TestSessionFactory: """Verify get_session yields and cleans up sessions.""" def test_get_session_yields_session(self): """get_session() yields a usable Session object.""" engine = _in_memory_engine() SQLModel.metadata.create_all(engine) import transcription.db as db_module with db_module.get_session(engine=engine) as session: assert isinstance(session, Session) 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) import transcription.db as db_module with db_module.get_session(engine=engine) as session: # Session is usable inside the context session.execute(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 class TestBootstrapPolicy: """Verify schema bootstrap policy defaults and overrides.""" def test_production_defaults_to_no_bootstrap(self): """Production defaults to explicit non-bootstrap startup behavior.""" from transcription.config import Settings from transcription.db import should_bootstrap_schema settings = Settings(openrouter_api_key="test-key", environment="production") assert should_bootstrap_schema(settings) is False def test_development_defaults_to_bootstrap(self): """Development defaults to schema bootstrap for local workflows.""" from transcription.config import Settings from transcription.db import should_bootstrap_schema settings = Settings(openrouter_api_key="test-key", environment="development") assert should_bootstrap_schema(settings) is True def test_explicit_override_wins(self): """Explicit bootstrap_schema_on_startup overrides environment default.""" from transcription.config import Settings from transcription.db import should_bootstrap_schema settings = Settings( openrouter_api_key="test-key", environment="production", bootstrap_schema_on_startup=True, ) assert should_bootstrap_schema(settings) is True