Refactor code structure for improved readability and maintainability
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
import asyncio
|
||||
import os
|
||||
import sys
|
||||
from collections.abc import AsyncIterator, Iterator
|
||||
from pathlib import Path
|
||||
|
||||
import httpx2
|
||||
import pytest
|
||||
import pytest_asyncio
|
||||
from fastapi import FastAPI
|
||||
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
|
||||
from testcontainers.community.postgres import PostgresContainer
|
||||
from testcontainers.core.container import DockerContainer
|
||||
from testcontainers.core.wait_strategies import LogMessageWaitStrategy
|
||||
|
||||
from app.api import router
|
||||
from app.auth import get_settings
|
||||
from app.config import Settings
|
||||
from app.db import Base, get_session
|
||||
|
||||
PROJECT_ROOT = Path(__file__).parents[2]
|
||||
|
||||
|
||||
async def migrate_to_head(database_url: str) -> None:
|
||||
process = await asyncio.create_subprocess_exec(
|
||||
sys.executable,
|
||||
"-m",
|
||||
"alembic",
|
||||
"upgrade",
|
||||
"head",
|
||||
cwd=PROJECT_ROOT,
|
||||
env={**os.environ, "DATABASE_URL": database_url},
|
||||
)
|
||||
assert await process.wait() == 0
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def postgres_url() -> Iterator[str]:
|
||||
with PostgresContainer("postgres:16-alpine", driver=None) as postgres:
|
||||
url = postgres.get_connection_url(driver=None)
|
||||
yield url.replace("postgresql://", "postgresql+asyncpg://", 1)
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def rabbitmq_url() -> Iterator[str]:
|
||||
rabbitmq = (
|
||||
DockerContainer("rabbitmq:3.13-alpine")
|
||||
.with_exposed_ports(5672)
|
||||
.with_env("RABBITMQ_DEFAULT_USER", "payments")
|
||||
.with_env("RABBITMQ_DEFAULT_PASS", "payments")
|
||||
.waiting_for(LogMessageWaitStrategy("Server startup complete").with_startup_timeout(60))
|
||||
)
|
||||
with rabbitmq:
|
||||
host = rabbitmq.get_container_host_ip()
|
||||
port = rabbitmq.get_exposed_port(5672)
|
||||
yield f"amqp://payments:payments@{host}:{port}/"
|
||||
|
||||
|
||||
@pytest_asyncio.fixture
|
||||
async def database(
|
||||
postgres_url: str,
|
||||
) -> AsyncIterator[async_sessionmaker[AsyncSession]]:
|
||||
engine = create_async_engine(postgres_url)
|
||||
async with engine.begin() as connection:
|
||||
await connection.run_sync(Base.metadata.drop_all)
|
||||
await connection.exec_driver_sql("DROP TABLE IF EXISTS alembic_version")
|
||||
await engine.dispose()
|
||||
|
||||
await migrate_to_head(postgres_url)
|
||||
|
||||
engine = create_async_engine(postgres_url)
|
||||
factory = async_sessionmaker(engine, expire_on_commit=False)
|
||||
try:
|
||||
yield factory
|
||||
finally:
|
||||
await engine.dispose()
|
||||
|
||||
|
||||
@pytest_asyncio.fixture
|
||||
async def db_session(
|
||||
database: async_sessionmaker[AsyncSession],
|
||||
) -> AsyncIterator[AsyncSession]:
|
||||
async with database() as session:
|
||||
yield session
|
||||
|
||||
|
||||
@pytest_asyncio.fixture
|
||||
async def api_client(
|
||||
database: async_sessionmaker[AsyncSession],
|
||||
) -> AsyncIterator[httpx2.AsyncClient]:
|
||||
app = FastAPI()
|
||||
app.include_router(router)
|
||||
|
||||
async def override_session() -> AsyncIterator[AsyncSession]:
|
||||
async with database() as session:
|
||||
yield session
|
||||
|
||||
app.dependency_overrides[get_session] = override_session
|
||||
app.dependency_overrides[get_settings] = lambda: Settings(api_key="test-key")
|
||||
|
||||
transport = httpx2.ASGITransport(app=app)
|
||||
async with httpx2.AsyncClient(
|
||||
transport=transport,
|
||||
base_url="http://testserver",
|
||||
) as client:
|
||||
yield client
|
||||
Reference in New Issue
Block a user