#!/usr/bin/env python3 """ Integration Test Suite for Site11 Services Tests the interaction between Console, Statistics, and Notification services """ import asyncio import httpx import json from datetime import datetime, timedelta import time BASE_URLS = { "console": "http://localhost:8011", "statistics": "http://localhost:8012", "notifications": "http://localhost:8013", "users": "http://localhost:8001", "oauth": "http://localhost:8003", "images": "http://localhost:8002" } async def test_service_health(): """Test health checks for all services""" print("\nšŸ„ Testing Service Health Checks...") print("=" * 60) async with httpx.AsyncClient() as client: for service, url in BASE_URLS.items(): try: response = await client.get(f"{url}/health") status = "āœ… HEALTHY" if response.status_code == 200 else f"āŒ UNHEALTHY ({response.status_code})" print(f"{service.ljust(15)}: {status}") if response.status_code == 200: data = response.json() if "components" in data: for comp, comp_status in data["components"].items(): print(f" └─ {comp}: {comp_status}") except Exception as e: print(f"{service.ljust(15)}: āŒ ERROR - {str(e)}") print("=" * 60) async def test_notification_to_statistics_flow(): """Test flow from notification creation to statistics recording""" print("\nšŸ“Š Testing Notification → Statistics Flow...") print("=" * 60) async with httpx.AsyncClient() as client: # 1. Send a notification print("1. Sending notification...") notification_data = { "user_id": "integration_test_user", "title": "Integration Test Alert", "message": "Testing integration between services", "channels": ["in_app"], "priority": "high", "category": "system" } try: response = await client.post( f"{BASE_URLS['notifications']}/api/notifications/send", json=notification_data ) result = response.json() print(f" Notification sent: {result}") notification_id = result.get("notification_id") # 2. Wait a moment for processing await asyncio.sleep(2) # 3. Check if statistics recorded the event print("\n2. Checking statistics for notification events...") response = await client.get( f"{BASE_URLS['statistics']}/api/analytics/events", params={"event_type": "notification", "limit": 5} ) if response.status_code == 200: events = response.json() print(f" Found {events.get('count', 0)} notification events in statistics") else: print(f" Statistics check failed: {response.status_code}") # 4. Check analytics overview print("\n3. Getting analytics overview...") response = await client.get( f"{BASE_URLS['statistics']}/api/analytics/overview" ) if response.status_code == 200: overview = response.json() print(f" Total events: {overview.get('total_events', 'N/A')}") print(f" Active users: {overview.get('active_users', 'N/A')}") print(f" System health: {overview.get('system_health', 'N/A')}") except Exception as e: print(f" Error: {e}") print("=" * 60) async def test_user_action_flow(): """Test a complete user action flow across services""" print("\nšŸ‘¤ Testing User Action Flow...") print("=" * 60) async with httpx.AsyncClient() as client: # 1. Create a test user (if Users service supports it) print("1. Creating/verifying test user...") try: # Try to get user first response = await client.get(f"{BASE_URLS['users']}/api/users/test_user_integration") if response.status_code == 404: # Create user if doesn't exist user_data = { "username": "test_user_integration", "email": "integration@test.com", "full_name": "Integration Test User" } response = await client.post( f"{BASE_URLS['users']}/api/users", json=user_data ) print(f" User status: {response.status_code}") except Exception as e: print(f" User service not fully implemented or accessible: {e}") # 2. Record user activity in statistics print("\n2. Recording user activity metrics...") try: metric_data = { "id": f"metric_{int(time.time())}", "metric_type": "user_activity", "value": 1, "timestamp": datetime.now().isoformat(), "labels": { "user_id": "test_user_integration", "action": "login", "source": "web" } } response = await client.post( f"{BASE_URLS['statistics']}/api/metrics", json=metric_data ) print(f" Metric recorded: {response.status_code}") except Exception as e: print(f" Statistics error: {e}") # 3. Send a notification about the user action print("\n3. Sending user action notification...") try: notification_data = { "user_id": "test_user_integration", "title": "Welcome Back!", "message": "Your login was successful", "channels": ["in_app"], "priority": "normal", "category": "system" } response = await client.post( f"{BASE_URLS['notifications']}/api/notifications/send", json=notification_data ) print(f" Notification sent: {response.json()}") except Exception as e: print(f" Notification error: {e}") print("=" * 60) async def test_real_time_metrics(): """Test real-time metrics collection and retrieval""" print("\n⚔ Testing Real-time Metrics...") print("=" * 60) async with httpx.AsyncClient() as client: # 1. Send batch metrics print("1. Sending batch metrics...") metrics = [] for i in range(5): metrics.append({ "id": f"realtime_{int(time.time())}_{i}", "metric_type": "api_request", "value": 100 + i * 10, "timestamp": datetime.now().isoformat(), "labels": { "endpoint": f"/api/test_{i}", "method": "GET", "status": "200" } }) try: response = await client.post( f"{BASE_URLS['statistics']}/api/metrics/batch", json=metrics ) print(f" Batch metrics sent: {response.json()}") except Exception as e: print(f" Error sending metrics: {e}") # 2. Wait and retrieve real-time metrics await asyncio.sleep(1) print("\n2. Retrieving real-time metrics...") try: response = await client.get( f"{BASE_URLS['statistics']}/api/metrics/realtime/api_request", params={"duration": 60} ) if response.status_code == 200: data = response.json() print(f" Metric type: {data.get('metric_type')}") print(f" Duration: {data.get('duration')}s") print(f" Data points: {len(data.get('data', []))}") except Exception as e: print(f" Error retrieving metrics: {e}") print("=" * 60) async def test_notification_preferences(): """Test notification preference management""" print("\nāš™ļø Testing Notification Preferences...") print("=" * 60) async with httpx.AsyncClient() as client: user_id = "pref_test_user" # 1. Set user preferences print("1. Setting user preferences...") preferences = { "user_id": user_id, "channels": { "email": True, "sms": False, "push": True, "in_app": True }, "categories": { "system": True, "marketing": False, "transaction": True, "social": False, "security": True, "update": True }, "email_frequency": "daily", "timezone": "America/New_York", "language": "en" } try: response = await client.put( f"{BASE_URLS['notifications']}/api/preferences/{user_id}", json=preferences ) print(f" Preferences updated: {response.json()}") except Exception as e: print(f" Error setting preferences: {e}") # 2. Test notification with preferences print("\n2. Sending notification respecting preferences...") try: # This should be blocked due to marketing=False notification_data = { "user_id": user_id, "title": "Special Offer!", "message": "Get 50% off today", "channels": ["email", "in_app"], "priority": "normal", "category": "marketing" } response = await client.post( f"{BASE_URLS['notifications']}/api/notifications/send", json=notification_data ) print(f" Marketing notification (should be filtered): {response.json()}") # This should go through due to system=True notification_data["category"] = "system" notification_data["title"] = "System Update" notification_data["message"] = "New features available" response = await client.post( f"{BASE_URLS['notifications']}/api/notifications/send", json=notification_data ) print(f" System notification (should be sent): {response.json()}") except Exception as e: print(f" Error sending notifications: {e}") print("=" * 60) async def main(): """Run all integration tests""" print("=" * 60) print("šŸš€ SITE11 INTEGRATION TEST SUITE") print("=" * 60) print(f"Started at: {datetime.now().isoformat()}") # Run tests await test_service_health() await test_notification_to_statistics_flow() await test_user_action_flow() await test_real_time_metrics() await test_notification_preferences() print("\n" + "=" * 60) print("āœ… Integration tests completed!") print(f"Finished at: {datetime.now().isoformat()}") print("=" * 60) if __name__ == "__main__": asyncio.run(main())