feat: initial MALS implementation — Phase 1

This commit is contained in:
2026-03-20 07:59:43 -05:00
commit dc1258a5cc
28 changed files with 2972 additions and 0 deletions

50
tests/conftest.py Normal file
View File

@@ -0,0 +1,50 @@
"""Test configuration and fixtures.
Tests run against a real PostgreSQL instance (docker-compose test stack).
The DATABASE_URL and MALS_API_KEY are read from environment / .env.test.
If not set, pytest will skip DB-dependent tests gracefully.
"""
from __future__ import annotations
import asyncio
import os
from unittest.mock import AsyncMock, MagicMock, patch
import pytest
from httpx import ASGITransport, AsyncClient
# Set required env vars before importing the app
os.environ.setdefault("DATABASE_URL", "postgresql+asyncpg://mals:mals@localhost:5434/mals")
os.environ.setdefault("MALS_API_KEY", "test-secret-key")
from mals.main import app # noqa: E402
TEST_API_KEY = os.environ["MALS_API_KEY"]
AUTH_HEADERS = {"Authorization": f"Bearer {TEST_API_KEY}"}
# ---------------------------------------------------------------------------
# Async HTTP client fixtures
# ---------------------------------------------------------------------------
@pytest.fixture
async def async_client() -> AsyncClient:
"""Async HTTPX client backed by the ASGI app — no real DB needed for unit tests."""
transport = ASGITransport(app=app)
async with AsyncClient(transport=transport, base_url="http://test") as client:
yield client
# ---------------------------------------------------------------------------
# Mocked DB pool fixture
# ---------------------------------------------------------------------------
@pytest.fixture
def mock_pool():
"""Return a mock asyncpg pool for unit tests that don't need a real DB."""
pool = MagicMock()
conn = AsyncMock()
pool.acquire.return_value.__aenter__ = AsyncMock(return_value=conn)
pool.acquire.return_value.__aexit__ = AsyncMock(return_value=False)
return pool, conn