"""End-to-End tests configuration and fixtures. E2E tests require: - DB API running - RAG backends (IFT/PSI/PROD) available - mTLS certificates configured - Test user created in DB API """ import os import pytest from fastapi.testclient import TestClient from app.main import app # E2E Test configuration E2E_DB_API_URL = os.getenv("E2E_DB_API_URL", "http://localhost:8081/api/v1") E2E_TEST_LOGIN = os.getenv("E2E_TEST_LOGIN", "88888888") # E2E test user # RAG configuration (should match production .env) E2E_IFT_RAG_HOST = os.getenv("E2E_IFT_RAG_HOST") E2E_PSI_RAG_HOST = os.getenv("E2E_PSI_RAG_HOST") E2E_PROD_RAG_HOST = os.getenv("E2E_PROD_RAG_HOST") @pytest.fixture(scope="session") def check_prerequisites(): """Check that all required services are available.""" import httpx errors = [] # Check DB API try: response = httpx.get(f"{E2E_DB_API_URL.replace('/api/v1', '')}/health", timeout=5.0) if response.status_code != 200: errors.append(f"DB API health check failed: {response.status_code}") except Exception as e: errors.append(f"DB API not available: {e}") # Check RAG hosts configured if not E2E_IFT_RAG_HOST: errors.append("E2E_IFT_RAG_HOST not configured") if not E2E_PSI_RAG_HOST: errors.append("E2E_PSI_RAG_HOST not configured") if not E2E_PROD_RAG_HOST: errors.append("E2E_PROD_RAG_HOST not configured") if errors: pytest.skip(f"E2E prerequisites not met:\n" + "\n".join(f" - {e}" for e in errors)) yield @pytest.fixture(scope="session") def e2e_client(): """FastAPI test client for E2E tests.""" with TestClient(app) as client: yield client @pytest.fixture(scope="function") def e2e_auth_token(e2e_client): """Get authentication token for E2E test user.""" response = e2e_client.post( "/api/v1/auth/login", params={"login": E2E_TEST_LOGIN} ) if response.status_code != 200: pytest.skip(f"Cannot authenticate E2E test user: {response.status_code} - {response.text}") return response.json()["access_token"] @pytest.fixture(scope="function") def e2e_auth_headers(e2e_auth_token): """Authorization headers for E2E tests.""" return {"Authorization": f"Bearer {e2e_auth_token}"} @pytest.fixture(scope="function") def e2e_user_id(e2e_client): """Get E2E test user ID.""" response = e2e_client.post( "/api/v1/auth/login", params={"login": E2E_TEST_LOGIN} ) if response.status_code != 200: pytest.skip(f"Cannot get E2E test user ID: {response.status_code}") return response.json()["user"]["user_id"] @pytest.fixture(scope="function") def setup_test_settings(e2e_client, e2e_auth_headers): """Setup test settings for all environments before tests.""" settings = { "settings": { "ift": { "apiMode": "bench", "bearerToken": os.getenv("E2E_IFT_BEARER_TOKEN", ""), "systemPlatform": os.getenv("E2E_IFT_SYSTEM_PLATFORM", "test-platform"), "systemPlatformUser": os.getenv("E2E_IFT_SYSTEM_USER", "test-user"), "platformUserId": os.getenv("E2E_IFT_PLATFORM_USER_ID", "test-user-id"), "platformId": os.getenv("E2E_IFT_PLATFORM_ID", "test-platform-id"), "withClassify": False, "resetSessionMode": True }, "psi": { "apiMode": "backend", "bearerToken": os.getenv("E2E_PSI_BEARER_TOKEN", ""), "systemPlatform": os.getenv("E2E_PSI_SYSTEM_PLATFORM", "test-platform"), "systemPlatformUser": os.getenv("E2E_PSI_SYSTEM_USER", "test-user"), "platformUserId": os.getenv("E2E_PSI_PLATFORM_USER_ID", "test-user-id"), "platformId": os.getenv("E2E_PSI_PLATFORM_ID", "test-platform-id"), "withClassify": True, "resetSessionMode": False }, "prod": { "apiMode": "bench", "bearerToken": os.getenv("E2E_PROD_BEARER_TOKEN", ""), "systemPlatform": os.getenv("E2E_PROD_SYSTEM_PLATFORM", "test-platform"), "systemPlatformUser": os.getenv("E2E_PROD_SYSTEM_USER", "test-user"), "platformUserId": os.getenv("E2E_PROD_PLATFORM_USER_ID", "test-user-id"), "platformId": os.getenv("E2E_PROD_PLATFORM_ID", "test-platform-id"), "withClassify": False, "resetSessionMode": True } } } response = e2e_client.put( "/api/v1/settings", json=settings, headers=e2e_auth_headers ) if response.status_code != 200: pytest.skip(f"Cannot setup test settings: {response.status_code} - {response.text}") return response.json() @pytest.fixture(scope="function") def cleanup_test_sessions(e2e_client, e2e_auth_headers, e2e_user_id): """Cleanup test sessions after each test.""" yield # Cleanup: delete all test sessions created during test try: # Get all sessions response = e2e_client.get( "/api/v1/analysis/sessions?limit=200", headers=e2e_auth_headers ) if response.status_code == 200: sessions = response.json()["sessions"] # Delete sessions created during test for session in sessions: e2e_client.delete( f"/api/v1/analysis/sessions/{session['session_id']}", headers=e2e_auth_headers ) except Exception: pass # Ignore cleanup errors def pytest_configure(config): """Configure pytest for E2E tests.""" config.addinivalue_line( "markers", "e2e: mark test as end-to-end test (requires full infrastructure)" ) config.addinivalue_line( "markers", "e2e_ift: E2E test for IFT environment" ) config.addinivalue_line( "markers", "e2e_psi: E2E test for PSI environment" ) config.addinivalue_line( "markers", "e2e_prod: E2E test for PROD environment" )