121 lines
3.7 KiB
Python
121 lines
3.7 KiB
Python
"""Shared pytest fixtures and configuration.
|
|
|
|
Environment variables for testing are configured in pytest.ini via pytest-env plugin.
|
|
"""
|
|
|
|
from collections.abc import AsyncGenerator
|
|
|
|
import pytest
|
|
import pytest_asyncio
|
|
from fakeredis import aioredis as fakeredis
|
|
|
|
from capa_de_integracion.config import Settings
|
|
from capa_de_integracion.services.storage import FirestoreService, RedisService
|
|
|
|
# Configure pytest-asyncio
|
|
pytest_plugins = ("pytest_asyncio",)
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def emulator_settings() -> Settings:
|
|
"""Create settings configured for Firestore emulator."""
|
|
# Settings will be loaded from environment variables set at module level
|
|
return Settings.model_validate({})
|
|
|
|
|
|
@pytest_asyncio.fixture
|
|
async def firestore_service(
|
|
emulator_settings: Settings,
|
|
) -> AsyncGenerator[FirestoreService, None]:
|
|
"""Create FirestoreService instance connected to emulator."""
|
|
service = FirestoreService(emulator_settings)
|
|
|
|
yield service
|
|
|
|
# Cleanup: Close the service
|
|
await service.close()
|
|
|
|
|
|
@pytest_asyncio.fixture
|
|
async def clean_firestore(firestore_service: FirestoreService) -> AsyncGenerator[FirestoreService, None]:
|
|
"""Provide a clean Firestore service and cleanup after test."""
|
|
# Cleanup before test
|
|
await _cleanup_collections(firestore_service)
|
|
|
|
yield firestore_service
|
|
|
|
# Cleanup after test
|
|
await _cleanup_collections(firestore_service)
|
|
|
|
|
|
async def _cleanup_collections(service: FirestoreService) -> None:
|
|
"""Delete all documents from test collections."""
|
|
# Clean conversations collection
|
|
conversations_ref = service.db.collection(service.conversations_collection)
|
|
async for doc in conversations_ref.stream():
|
|
# Delete subcollection entries first
|
|
entries_ref = doc.reference.collection(service.entries_subcollection)
|
|
async for entry_doc in entries_ref.stream():
|
|
await entry_doc.reference.delete()
|
|
# Delete session document
|
|
await doc.reference.delete()
|
|
|
|
# Clean notifications collection
|
|
notifications_ref = service.db.collection(service.notifications_collection)
|
|
async for doc in notifications_ref.stream():
|
|
await doc.reference.delete()
|
|
|
|
|
|
@pytest_asyncio.fixture
|
|
async def redis_service(
|
|
emulator_settings: Settings,
|
|
) -> AsyncGenerator[RedisService, None]:
|
|
"""Create RedisService instance with fakeredis for testing."""
|
|
service = RedisService(emulator_settings)
|
|
# Use fakeredis instead of connecting to a real Redis instance
|
|
service.redis = await fakeredis.FakeRedis(decode_responses=True)
|
|
|
|
yield service
|
|
|
|
# Cleanup: Close the service
|
|
await service.close()
|
|
|
|
|
|
@pytest_asyncio.fixture
|
|
async def clean_redis(redis_service: RedisService) -> AsyncGenerator[RedisService, None]:
|
|
"""Provide a clean Redis service and cleanup after test."""
|
|
# Cleanup before test
|
|
await _cleanup_redis(redis_service)
|
|
|
|
yield redis_service
|
|
|
|
# Cleanup after test
|
|
await _cleanup_redis(redis_service)
|
|
|
|
|
|
async def _cleanup_redis(service: RedisService) -> None:
|
|
"""Delete all keys from Redis."""
|
|
if service.redis:
|
|
# Delete all keys matching our patterns
|
|
patterns = [
|
|
"conversation:*",
|
|
"notification:*",
|
|
]
|
|
for pattern in patterns:
|
|
cursor = 0
|
|
while True:
|
|
cursor, keys = await service.redis.scan(cursor, match=pattern, count=100)
|
|
if keys:
|
|
await service.redis.delete(*keys)
|
|
if cursor == 0:
|
|
break
|
|
|
|
|
|
def pytest_recording_configure(config, vcr):
|
|
"""Configure pytest-recording for Firestore emulator."""
|
|
# Don't filter requests to the emulator
|
|
vcr.ignore_hosts = []
|
|
|
|
# Match on method and path for emulator requests
|
|
vcr.match_on = ["method", "path", "body"]
|