"""Tests for transcription.app.""" from contextlib import asynccontextmanager import pytest from fastapi import FastAPI from fastapi.testclient import TestClient from transcription.app import create_app @pytest.mark.unit class TestAppFactory: """Verify FastAPI app factory wiring.""" def test_create_app_returns_fastapi_instance(self): """create_app returns a FastAPI application instance.""" app = create_app() assert isinstance(app, FastAPI) @pytest.mark.integration class TestAppLifespan: """Verify startup and shutdown lifecycle behavior.""" def test_startup_initializes_runtime_dependencies(self, monkeypatch, tmp_path): """Startup initializes logging, schema, directories, and worker resources.""" calls = [] monkeypatch.setattr("transcription.app.configure_logging", lambda _settings: calls.append("logging")) async def _create_all(**_kwargs): calls.append("schema") monkeypatch.setattr("transcription.app.create_all", _create_all) monkeypatch.setattr( "transcription.app.initialize_database_runtime", lambda **_kwargs: type("_Runtime", (), {"engine": object(), "session_factory": object()})(), ) async def _dispose_runtime(): calls.append("dispose_db") monkeypatch.setattr("transcription.app.dispose_database_runtime", _dispose_runtime) async def _recover_stale(_app): calls.append("recover") monkeypatch.setattr("transcription.app._recover_stale_processing_jobs", _recover_stale) @asynccontextmanager async def _worker_lifespan(**_kwargs): calls.append("worker_start") yield object(), object() calls.append("worker_stop") monkeypatch.setattr("transcription.app.worker_consumer_lifespan", _worker_lifespan) class _Settings: should_bootstrap_schema = True upload_dir = tmp_path / "uploads" prompt_dir = tmp_path / "prompts" monkeypatch.setattr("transcription.app.get_settings", lambda: _Settings()) app = create_app() with TestClient(app): pass assert "logging" in calls assert "schema" in calls assert "recover" in calls assert "worker_start" in calls assert "worker_stop" in calls assert "dispose_db" in calls assert _Settings.upload_dir.exists() assert _Settings.prompt_dir.exists() def test_shutdown_stops_worker_resources(self, monkeypatch, tmp_path): """Shutdown signals and stops worker resources cleanly.""" calls = [] monkeypatch.setattr("transcription.app.configure_logging", lambda _settings: calls.append("logging")) async def _create_all(**_kwargs): calls.append("schema") monkeypatch.setattr("transcription.app.create_all", _create_all) monkeypatch.setattr( "transcription.app.initialize_database_runtime", lambda **_kwargs: type("_Runtime", (), {"engine": object(), "session_factory": object()})(), ) async def _dispose_runtime(): calls.append("dispose_db") monkeypatch.setattr("transcription.app.dispose_database_runtime", _dispose_runtime) async def _recover_stale(_app): calls.append("recover") monkeypatch.setattr("transcription.app._recover_stale_processing_jobs", _recover_stale) @asynccontextmanager async def _worker_lifespan(**_kwargs): calls.append("worker_start") yield object(), object() calls.append("worker_stop") monkeypatch.setattr("transcription.app.worker_consumer_lifespan", _worker_lifespan) class _Settings: should_bootstrap_schema = True upload_dir = tmp_path / "uploads" prompt_dir = tmp_path / "prompts" monkeypatch.setattr("transcription.app.get_settings", lambda: _Settings()) app = create_app() with TestClient(app): pass assert calls == ["logging", "schema", "recover", "worker_start", "worker_stop", "dispose_db"]