from collections.abc import AsyncIterator import pytest import pytest_asyncio from asgi_lifespan import LifespanManager from fastapi import FastAPI from httpx import ASGITransport, AsyncClient from src.config import Settings from src.main import create_app @pytest.fixture def settings() -> Settings: # Every external dependency points at a closed port so unit tests never # reach real infrastructure. For the embedders this matters twice over: # the real defaults are a colleague's Ollama box and OpenAI's paid API, # and ADR-0016 forbids routine runs calling either. Connection-refused is # immediate, so the lifespan's fail-soft warm-up costs nothing here -- # and these tests passing at all is what proves it is fail-soft. return Settings( postgres={"host": "127.0.0.1", "port": 1}, minio={"endpoint": "127.0.0.1:1"}, ingestion={"timeout_seconds": 1.0}, qdrant={"url": "http://127.0.0.1:1"}, app={"readiness_check_timeout_seconds": 0.5}, embedding={ "nomic": {"base_url": "http://127.0.0.1:1/v1", "timeout_seconds": 0.5}, "openai": {"base_url": "http://127.0.0.1:1/v1", "timeout_seconds": 0.5}, }, ) @pytest.fixture def app(settings: Settings) -> FastAPI: return create_app(settings) @pytest_asyncio.fixture async def client(app: FastAPI) -> AsyncIterator[AsyncClient]: async with ( LifespanManager(app) as manager, AsyncClient( transport=ASGITransport(app=manager.app), base_url="http://test" ) as async_client, ): yield async_client