Files
bakery-ia/test_data.py
Urtzi Alfaro 592a810762 Fix issues
2025-07-18 11:51:43 +02:00

385 lines
15 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ================================================================
# validate_local.py - Script completo con todos los imports
# ================================================================
import asyncio
import httpx
import json
import sys
import traceback
from datetime import datetime
from typing import Optional, Dict, Any
# Configuración
AUTH_URL = "http://localhost:8001"
DATA_URL = "http://localhost:8004"
GATEWAY_URL = "http://localhost:8000" # Si usas gateway
class DataServiceValidator:
"""Validador completo para el Data Service"""
def __init__(self, use_gateway: bool = False):
self.auth_token: Optional[str] = None
self.use_gateway = use_gateway
self.base_url = GATEWAY_URL if use_gateway else DATA_URL
self.auth_base_url = GATEWAY_URL if use_gateway else AUTH_URL
async def test_service_health(self) -> bool:
"""Verificar que los servicios estén funcionando"""
print("🔍 Checking service health...")
try:
async with httpx.AsyncClient(timeout=10.0) as client:
# Test auth service
auth_response = await client.get(f"{AUTH_URL}/health")
if auth_response.status_code == 200:
print("✅ Auth service is healthy")
else:
print(f"❌ Auth service unhealthy: {auth_response.status_code}")
return False
# Test data service
data_response = await client.get(f"{DATA_URL}/health")
if data_response.status_code == 200:
print("✅ Data service is healthy")
else:
print(f"❌ Data service unhealthy: {data_response.status_code}")
return False
return True
except httpx.ConnectError as e:
print(f"❌ Connection error: {e}")
print("💡 Make sure services are running with: docker-compose up -d")
return False
except Exception as e:
print(f"❌ Health check failed: {e}")
return False
async def authenticate(self) -> bool:
"""Autenticar y obtener token"""
print("🔐 Authenticating...")
try:
async with httpx.AsyncClient(timeout=15.0) as client:
# Datos de usuario de prueba
user_data = {
"email": "test@bakery.es",
"password": "TestPass123",
"full_name": "Test User",
"language": "es"
}
# Intentar registrar usuario (puede fallar si ya existe)
register_endpoint = f"{self.auth_base_url}/api/v1/auth/register"
register_response = await client.post(register_endpoint, json=user_data)
if register_response.status_code == 200:
print("✅ User registered successfully")
elif register_response.status_code == 409:
print(" User already exists, proceeding with login")
else:
print(f"⚠️ Registration response: {register_response.status_code}")
# Login
login_data = {
"email": user_data["email"],
"password": user_data["password"]
}
login_endpoint = f"{self.auth_base_url}/api/v1/auth/login"
login_response = await client.post(login_endpoint, json=login_data)
if login_response.status_code == 200:
response_data = login_response.json()
self.auth_token = response_data["access_token"]
print("✅ Authentication successful")
return True
else:
print(f"❌ Login failed: {login_response.status_code}")
print(f"Response: {login_response.text}")
return False
except Exception as e:
print(f"❌ Authentication failed: {e}")
return False
def get_headers(self) -> Dict[str, str]:
"""Obtener headers con token de autenticación"""
if not self.auth_token:
raise ValueError("No authentication token available")
return {"Authorization": f"Bearer {self.auth_token}"}
async def test_weather_endpoints(self) -> bool:
"""Probar endpoints de clima"""
print("🌤️ Testing weather endpoints...")
try:
headers = self.get_headers()
madrid_coords = {"latitude": 40.4168, "longitude": -3.7038}
async with httpx.AsyncClient(timeout=20.0) as client:
# Current weather
current_endpoint = f"{self.base_url}/api/v1/weather/current" if not self.use_gateway else f"{self.base_url}/api/v1/data/weather/current"
current_response = await client.get(
current_endpoint,
params=madrid_coords,
headers=headers
)
if current_response.status_code == 200:
weather = current_response.json()
print(f"✅ Current weather: {weather.get('temperature')}°C, {weather.get('description')}")
else:
print(f"❌ Current weather failed: {current_response.status_code}")
print(f"Response: {current_response.text}")
return False
# Weather forecast
forecast_endpoint = f"{self.base_url}/api/v1/weather/forecast" if not self.use_gateway else f"{self.base_url}/api/v1/data/weather/forecast"
forecast_response = await client.get(
forecast_endpoint,
params={**madrid_coords, "days": 3},
headers=headers
)
if forecast_response.status_code == 200:
forecast = forecast_response.json()
print(f"✅ Weather forecast: {len(forecast)} days")
else:
print(f"❌ Weather forecast failed: {forecast_response.status_code}")
return False
return True
except Exception as e:
print(f"❌ Weather tests failed: {e}")
return False
async def test_traffic_endpoints(self) -> bool:
"""Probar endpoints de tráfico"""
print("🚦 Testing traffic endpoints...")
try:
headers = self.get_headers()
madrid_coords = {"latitude": 40.4168, "longitude": -3.7038}
async with httpx.AsyncClient(timeout=20.0) as client:
# Current traffic
current_endpoint = f"{self.base_url}/api/v1/traffic/current" if not self.use_gateway else f"{self.base_url}/api/v1/data/traffic/current"
current_response = await client.get(
current_endpoint,
params=madrid_coords,
headers=headers
)
if current_response.status_code == 200:
traffic = current_response.json()
print(f"✅ Current traffic: {traffic.get('traffic_volume')} vehicles, {traffic.get('congestion_level')} congestion")
return True
else:
print(f"❌ Current traffic failed: {current_response.status_code}")
print(f"Response: {current_response.text}")
return False
except Exception as e:
print(f"❌ Traffic tests failed: {e}")
return False
async def test_sales_endpoints(self) -> bool:
"""Probar endpoints de ventas"""
print("📊 Testing sales endpoints...")
try:
headers = self.get_headers()
# Datos de prueba
sales_data = {
"tenant_id": "123e4567-e89b-12d3-a456-426614174000",
"date": datetime.now().isoformat(),
"product_name": "Pan Integral Test",
"quantity_sold": 25,
"revenue": 37.50,
"location_id": "madrid_centro",
"source": "test"
}
async with httpx.AsyncClient(timeout=20.0) as client:
# Create sales record
create_endpoint = f"{self.base_url}/api/v1/sales/" if not self.use_gateway else f"{self.base_url}/api/v1/data/sales/"
create_response = await client.post(
create_endpoint,
json=sales_data,
headers=headers
)
if create_response.status_code == 200:
record = create_response.json()
print(f"✅ Sales record created: ID {record.get('id')}")
else:
print(f"❌ Sales creation failed: {create_response.status_code}")
print(f"Response: {create_response.text}")
return False
# Test import template
template_endpoint = f"{self.base_url}/api/v1/sales/import/template/csv" if not self.use_gateway else f"{self.base_url}/api/v1/data/sales/import/template/csv"
template_response = await client.get(
template_endpoint,
headers=headers
)
if template_response.status_code == 200:
print("✅ Import template generated successfully")
else:
print(f"❌ Template generation failed: {template_response.status_code}")
return False
return True
except Exception as e:
print(f"❌ Sales tests failed: {e}")
return False
async def test_import_functionality(self) -> bool:
"""Probar funcionalidad de importación"""
print("📄 Testing import functionality...")
try:
headers = self.get_headers()
# Crear CSV de prueba
csv_content = """fecha,producto,cantidad,ingresos
15/01/2024,Pan Integral,25,37.50
15/01/2024,Croissant,15,22.50
15/01/2024,Café con Leche,10,20.00"""
# Test CSV import
import_data = {
"tenant_id": "123e4567-e89b-12d3-a456-426614174000",
"data_format": "csv",
"data": csv_content
}
async with httpx.AsyncClient(timeout=30.0) as client:
import_endpoint = f"{self.base_url}/api/v1/sales/import/json" if not self.use_gateway else f"{self.base_url}/api/v1/data/sales/import/json"
import_response = await client.post(
import_endpoint,
json=import_data,
headers=headers
)
if import_response.status_code == 200:
result = import_response.json()
if result.get("success"):
print(f"✅ CSV import successful: {result.get('records_created')} records created")
return True
else:
print(f"❌ CSV import failed: {result.get('error')}")
return False
else:
print(f"❌ Import request failed: {import_response.status_code}")
print(f"Response: {import_response.text}")
return False
except Exception as e:
print(f"❌ Import tests failed: {e}")
return False
async def main():
"""Función principal de validación"""
print("🚀 Starting Data Service Validation")
print("=" * 50)
# Preguntar si usar gateway
use_gateway_input = input("Use API Gateway? (y/N): ").lower()
use_gateway = use_gateway_input == 'y'
if use_gateway:
print("📡 Testing via API Gateway")
else:
print("🔗 Testing direct service connections")
validator = DataServiceValidator(use_gateway=use_gateway)
try:
# 1. Health checks
if not await validator.test_service_health():
print("\n❌ Health checks failed. Ensure services are running.")
return False
# 2. Authentication
if not await validator.authenticate():
print("\n❌ Authentication failed.")
return False
# 3. Weather tests
if not await validator.test_weather_endpoints():
print("\n❌ Weather endpoint tests failed.")
return False
# 4. Traffic tests
if not await validator.test_traffic_endpoints():
print("\n❌ Traffic endpoint tests failed.")
return False
# 5. Sales tests
if not await validator.test_sales_endpoints():
print("\n❌ Sales endpoint tests failed.")
return False
# 6. Import tests
if not await validator.test_import_functionality():
print("\n❌ Import functionality tests failed.")
return False
print("\n" + "=" * 50)
print("🎉 ALL TESTS PASSED! Data Service is working correctly!")
print("=" * 50)
return True
except KeyboardInterrupt:
print("\n⚠️ Tests interrupted by user")
return False
except Exception as e:
print(f"\n❌ Unexpected error: {e}")
print("Traceback:")
traceback.print_exc()
return False
def check_dependencies():
"""Verificar que las dependencias estén instaladas"""
try:
import httpx
print("✅ httpx is available")
except ImportError:
print("❌ httpx not found. Install with: pip install httpx")
return False
return True
if __name__ == "__main__":
print("🔧 Checking dependencies...")
if not check_dependencies():
print("\n💡 Install dependencies with:")
print("pip install httpx")
sys.exit(1)
print("✅ All dependencies available")
print()
# Ejecutar validación
success = asyncio.run(main())
if success:
print("\n🎯 Next steps:")
print("1. Check logs: docker-compose logs -f data-service")
print("2. Connect to DB: docker-compose exec data-db psql -U data_user -d data_db")
print("3. Test with real data imports")
sys.exit(0)
else:
print("\n🔧 Troubleshooting:")
print("1. Check services: docker-compose ps")
print("2. Restart services: docker-compose restart")
print("3. Check logs: docker-compose logs data-service")
sys.exit(1)