rentcache/tests/conftest.py
Ryan Malloy dde8bd04de Add cache attribution and fix broken DB session methods
- Add fetched_by_key_hash column to CacheEntry model for tracking
  which Rentcast API key originally fetched each cached response
- Fix broken self.db references in SQLiteCacheBackend methods:
  - delete() now properly creates session from SessionLocal
  - clear_pattern() fixed with proper session management
  - health_check() fixed with proper session management
- Add SQL injection protection in clear_pattern() by escaping
  LIKE wildcards (%, _) before pattern conversion
- Update proxy_to_rentcast to hash and store the client's
  Rentcast API key on cache miss
- Fix httpx test client to use ASGITransport (required for httpx 0.27+)
2026-01-18 18:09:47 -07:00

81 lines
2.0 KiB
Python

"""
Pytest configuration for RentCache tests.
"""
import asyncio
import pytest
import pytest_asyncio
from httpx import AsyncClient, ASGITransport
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker
from sqlalchemy.pool import StaticPool
from rentcache.models import Base
from rentcache.server import app, get_db
# Test database URL
TEST_DATABASE_URL = "sqlite+aiosqlite:///:memory:"
@pytest.fixture(scope="session")
def event_loop():
"""Create an instance of the default event loop for the test session."""
loop = asyncio.new_event_loop()
yield loop
loop.close()
@pytest_asyncio.fixture(scope="function")
async def test_engine():
"""Create a test database engine."""
engine = create_async_engine(
TEST_DATABASE_URL,
echo=False,
poolclass=StaticPool,
connect_args={"check_same_thread": False},
)
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
yield engine
await engine.dispose()
@pytest_asyncio.fixture(scope="function")
async def test_session(test_engine):
"""Create a test database session."""
SessionLocal = async_sessionmaker(
bind=test_engine,
class_=AsyncSession,
expire_on_commit=False
)
async with SessionLocal() as session:
yield session
@pytest_asyncio.fixture(scope="function")
async def test_client(test_session):
"""Create a test HTTP client with database override."""
def override_get_db():
yield test_session
app.dependency_overrides[get_db] = override_get_db
transport = ASGITransport(app=app)
async with AsyncClient(transport=transport, base_url="http://test") as client:
yield client
app.dependency_overrides.clear()
@pytest.fixture
def sample_api_key_data():
"""Sample data for creating API keys in tests."""
return {
"key_name": "test_key",
"rentcast_api_key": "test_rentcast_key_123",
"daily_limit": 1000,
"monthly_limit": 10000
}