""" Pytest configuration and shared fixtures for regression tests """ import pytest import asyncio import os from typing import AsyncGenerator, Dict, Any from unittest.mock import AsyncMock, MagicMock from fastapi.testclient import TestClient from httpx import AsyncClient # Import the FastAPI app from app.app import app @pytest.fixture(scope="session") def event_loop(): """Create an instance of the default event loop for the test session.""" loop = asyncio.get_event_loop_policy().new_event_loop() yield loop loop.close() @pytest.fixture def client(): """Create a test client for the FastAPI app.""" return TestClient(app) @pytest.fixture async def async_client() -> AsyncGenerator[AsyncClient, None]: """Create an async test client for the FastAPI app.""" async with AsyncClient(app=app, base_url="http://test") as ac: yield ac @pytest.fixture def mock_mongodb(): """Mock MongoDB connection.""" mock_db = MagicMock() mock_collection = MagicMock() mock_db.__getitem__.return_value = mock_collection return mock_db @pytest.fixture def mock_redis(): """Mock Redis connection.""" mock_redis = AsyncMock() mock_redis.get.return_value = None mock_redis.set.return_value = True mock_redis.delete.return_value = True return mock_redis @pytest.fixture def sample_merchant_data(): """Sample merchant data for testing.""" return { "_id": "test_merchant_123", "name": "Test Hair Salon", "category": "salon", "subcategory": "hair_salon", "location": { "type": "Point", "coordinates": [-74.0060, 40.7128] # NYC coordinates }, "address": { "street": "123 Test Street", "city": "New York", "state": "NY", "zip_code": "10001" }, "contact": { "phone": "+1-555-0123", "email": "test@testsalon.com" }, "business_hours": { "monday": {"open": "09:00", "close": "18:00"}, "tuesday": {"open": "09:00", "close": "18:00"}, "wednesday": {"open": "09:00", "close": "18:00"}, "thursday": {"open": "09:00", "close": "18:00"}, "friday": {"open": "09:00", "close": "19:00"}, "saturday": {"open": "08:00", "close": "17:00"}, "sunday": {"closed": True} }, "services": [ {"name": "Haircut", "price": 50.0, "duration": 60}, {"name": "Hair Color", "price": 120.0, "duration": 120}, {"name": "Blowout", "price": 35.0, "duration": 45} ], "amenities": ["parking", "wifi", "wheelchair_accessible"], "average_rating": 4.5, "total_reviews": 127, "price_range": "$$", "is_active": True, "created_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-15T12:00:00Z" } @pytest.fixture def sample_search_query(): """Sample search query for testing.""" return { "query": "find the best hair salon near me with parking", "latitude": 40.7128, "longitude": -74.0060, "radius": 5000, # 5km "category": "salon" } @pytest.fixture def mock_nlp_pipeline(): """Mock NLP pipeline for testing.""" mock_pipeline = AsyncMock() mock_pipeline.process_query.return_value = { "query": "test query", "primary_intent": { "intent": "SEARCH_SERVICE", "confidence": 0.85 }, "entities": { "service_types": ["haircut"], "amenities": ["parking"], "location_modifiers": ["near me"] }, "similar_services": [("salon", 0.9)], "search_parameters": { "merchant_category": "salon", "amenities": ["parking"], "radius": 5000 }, "processing_time": 0.123 } return mock_pipeline @pytest.fixture(autouse=True) def setup_test_environment(): """Setup test environment variables.""" os.environ["TESTING"] = "true" os.environ["MONGODB_URL"] = "mongodb://localhost:27017/test_db" os.environ["REDIS_URL"] = "redis://localhost:6379/1" os.environ["ALLOWED_ORIGINS"] = "http://localhost:3000,http://testserver" yield # Cleanup for key in ["TESTING", "MONGODB_URL", "REDIS_URL", "ALLOWED_ORIGINS"]: os.environ.pop(key, None) @pytest.fixture def performance_test_data(): """Data for performance testing.""" return { "queries": [ "find a hair salon", "best spa near me", "gym with parking", "dental clinic open now", "massage therapy luxury", "budget-friendly fitness center", "nail salon walking distance", "pet-friendly grooming", "24/7 pharmacy", "organic restaurant" ], "expected_max_response_time": 2.0, # seconds "expected_min_success_rate": 0.95 # 95% }