diff --git a/services/search/solr-config/conf/solrconfig.xml b/services/search/solr-config/conf/solrconfig.xml index e16dcb7..43c3403 100644 --- a/services/search/solr-config/conf/solrconfig.xml +++ b/services/search/solr-config/conf/solrconfig.xml @@ -146,9 +146,7 @@ - - + - - + \ No newline at end of file diff --git a/services/search/solr-config/conf/stopwords.txt b/services/search/solr-config/conf/stopwords.txt new file mode 100644 index 0000000..3f50366 --- /dev/null +++ b/services/search/solr-config/conf/stopwords.txt @@ -0,0 +1,35 @@ +# Licensed to the Apache Software Foundation (ASF) +# Standard English stop words +a +an +and +are +as +at +be +but +by +for +if +in +into +is +it +no +not +of +on +or +such +that +the +their +then +there +these +they +this +to +was +will +with \ No newline at end of file diff --git a/services/search/solr-config/conf/synonyms.txt b/services/search/solr-config/conf/synonyms.txt new file mode 100644 index 0000000..c167f27 --- /dev/null +++ b/services/search/solr-config/conf/synonyms.txt @@ -0,0 +1,38 @@ +# Synonyms for site11 search +# Format: term1, term2, term3 => all are synonyms +# Or: term1, term2 => term1 is replaced by term2 + +# Technology synonyms +javascript, js +typescript, ts +python, py +golang, go +database, db +kubernetes, k8s +docker, container, containerization + +# Common terms +search, find, query, lookup +upload, import, add +download, export, get +delete, remove, erase +update, modify, edit, change +create, make, new, add + +# File related +document, doc, file +image, picture, photo, img +video, movie, clip +audio, sound, music + +# User related +user, member, account +admin, administrator, moderator +profile, account, user + +# Status +active, enabled, live +inactive, disabled, offline +pending, waiting, processing +complete, done, finished +error, failed, failure \ No newline at end of file diff --git a/test_all_services.py b/test_all_services.py new file mode 100644 index 0000000..7f0147c --- /dev/null +++ b/test_all_services.py @@ -0,0 +1,416 @@ +#!/usr/bin/env python3 +""" +Complete test suite for all backend services +""" +import asyncio +import httpx +import json +from datetime import datetime +import base64 +import os + +# Service endpoints +SERVICES = { + "users": "http://localhost:8001", + "images": "http://localhost:8002", + "oauth": "http://localhost:8003", + "console": "http://localhost:8011", + "statistics": "http://localhost:8012", + "notifications": "http://localhost:8013", + "files": "http://localhost:8014", + "search": "http://localhost:8015" +} + +def print_section(title): + """Print section header""" + print(f"\n{'='*60}") + print(f" {title}") + print(f"{'='*60}") + +def print_test(name, status, details=""): + """Print test result""" + icon = "āœ…" if status else "āŒ" + print(f"{icon} {name}: {details}") + +async def test_health_endpoints(): + """Test all health endpoints""" + print_section("1. HEALTH CHECK ENDPOINTS") + + async with httpx.AsyncClient(timeout=10.0) as client: + results = {} + for service, url in SERVICES.items(): + try: + response = await client.get(f"{url}/health") + if response.status_code == 200: + data = response.json() + status = data.get("status", "unknown") + print_test(f"{service.upper()} Health", True, f"Status: {status}") + results[service] = True + else: + print_test(f"{service.upper()} Health", False, f"HTTP {response.status_code}") + results[service] = False + except Exception as e: + print_test(f"{service.upper()} Health", False, f"Error: {str(e)}") + results[service] = False + return results + +async def test_users_service(): + """Test Users Service API""" + print_section("2. USERS SERVICE TESTS") + + async with httpx.AsyncClient(timeout=10.0) as client: + base_url = SERVICES["users"] + + # Create user + user_data = { + "username": f"testuser_{datetime.now().timestamp()}", + "email": f"test_{datetime.now().timestamp()}@example.com", + "password": "Test123!@#", + "full_name": "Test User" + } + + try: + response = await client.post(f"{base_url}/api/users/register", json=user_data) + if response.status_code == 200: + user = response.json() + print_test("Create User", True, f"User ID: {user.get('id')}") + + # Get user + response = await client.get(f"{base_url}/api/users/{user['id']}") + print_test("Get User", response.status_code == 200, f"Username: {user.get('username')}") + + # List users + response = await client.get(f"{base_url}/api/users") + data = response.json() + print_test("List Users", response.status_code == 200, f"Total: {data.get('total', 0)} users") + + # Update user + update_data = {"bio": "Updated bio"} + response = await client.put(f"{base_url}/api/users/{user['id']}", json=update_data) + print_test("Update User", response.status_code == 200) + + # Delete user + response = await client.delete(f"{base_url}/api/users/{user['id']}") + print_test("Delete User", response.status_code == 200) + else: + print_test("Create User", False, f"HTTP {response.status_code}") + except Exception as e: + print_test("Users Service", False, f"Error: {str(e)}") + +async def test_oauth_service(): + """Test OAuth Service""" + print_section("3. OAUTH SERVICE TESTS") + + async with httpx.AsyncClient(timeout=10.0) as client: + base_url = SERVICES["oauth"] + + try: + # Test OAuth providers + response = await client.get(f"{base_url}/api/oauth/providers") + if response.status_code == 200: + providers = response.json() + print_test("Get OAuth Providers", True, f"Providers: {', '.join(providers.get('providers', []))}") + else: + print_test("Get OAuth Providers", False, f"HTTP {response.status_code}") + + # Test Google OAuth URL + response = await client.get(f"{base_url}/api/oauth/google/authorize") + print_test("Google OAuth URL", response.status_code == 200, "Authorization URL generated") + + # Test GitHub OAuth URL + response = await client.get(f"{base_url}/api/oauth/github/authorize") + print_test("GitHub OAuth URL", response.status_code == 200, "Authorization URL generated") + + except Exception as e: + print_test("OAuth Service", False, f"Error: {str(e)}") + +async def test_images_service(): + """Test Images Service""" + print_section("4. IMAGES SERVICE TESTS") + + async with httpx.AsyncClient(timeout=10.0) as client: + base_url = SERVICES["images"] + + try: + # Create test image (1x1 pixel PNG) + image_data = base64.b64decode( + "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==" + ) + + # Upload image + files = {"file": ("test.png", image_data, "image/png")} + response = await client.post(f"{base_url}/api/images/upload", files=files) + + if response.status_code == 200: + image = response.json() + print_test("Upload Image", True, f"Image ID: {image.get('id')}") + + # Get image metadata + response = await client.get(f"{base_url}/api/images/{image['id']}/metadata") + print_test("Get Image Metadata", response.status_code == 200) + + # List images + response = await client.get(f"{base_url}/api/images") + data = response.json() + print_test("List Images", response.status_code == 200, f"Total: {data.get('total', 0)} images") + + # Delete image + response = await client.delete(f"{base_url}/api/images/{image['id']}") + print_test("Delete Image", response.status_code == 200) + else: + print_test("Upload Image", False, f"HTTP {response.status_code}") + + except Exception as e: + print_test("Images Service", False, f"Error: {str(e)}") + +async def test_files_service(): + """Test Files Service""" + print_section("5. FILES SERVICE TESTS") + + async with httpx.AsyncClient(timeout=30.0) as client: + base_url = SERVICES["files"] + + try: + # Upload test file + test_content = b"Test file content for MinIO storage" + files = {"file": ("test.txt", test_content, "text/plain")} + + response = await client.post(f"{base_url}/api/files/upload", files=files) + + if response.status_code == 200: + file_info = response.json() + print_test("Upload File", True, f"File ID: {file_info.get('file_id')}") + + # Get file info + response = await client.get(f"{base_url}/api/files/{file_info['file_id']}") + print_test("Get File Info", response.status_code == 200) + + # List files + response = await client.get(f"{base_url}/api/files") + data = response.json() + print_test("List Files", response.status_code == 200, f"Total: {data.get('total', 0)} files") + + # Delete file + response = await client.delete(f"{base_url}/api/files/{file_info['file_id']}") + print_test("Delete File", response.status_code == 200) + else: + print_test("Upload File", False, f"HTTP {response.status_code}") + + except Exception as e: + print_test("Files Service", False, f"Error: {str(e)}") + +async def test_notifications_service(): + """Test Notifications Service""" + print_section("6. NOTIFICATIONS SERVICE TESTS") + + async with httpx.AsyncClient(timeout=10.0) as client: + base_url = SERVICES["notifications"] + + try: + # Send email notification + email_data = { + "to": "test@example.com", + "subject": "Test Email", + "body": "This is a test email", + "template": "default" + } + + response = await client.post(f"{base_url}/api/notifications/email", json=email_data) + print_test("Send Email", response.status_code == 200, "Email queued") + + # Send SMS notification + sms_data = { + "to": "+1234567890", + "message": "Test SMS message" + } + + response = await client.post(f"{base_url}/api/notifications/sms", json=sms_data) + print_test("Send SMS", response.status_code == 200, "SMS queued") + + # Send push notification + push_data = { + "user_id": "test_user", + "title": "Test Push", + "body": "Test push notification", + "data": {"key": "value"} + } + + response = await client.post(f"{base_url}/api/notifications/push", json=push_data) + print_test("Send Push", response.status_code == 200, "Push notification queued") + + # Get notification history + response = await client.get(f"{base_url}/api/notifications/history?user_id=test_user") + data = response.json() + print_test("Get History", response.status_code == 200, f"Total: {data.get('total', 0)} notifications") + + except Exception as e: + print_test("Notifications Service", False, f"Error: {str(e)}") + +async def test_statistics_service(): + """Test Statistics Service""" + print_section("7. STATISTICS SERVICE TESTS") + + async with httpx.AsyncClient(timeout=10.0) as client: + base_url = SERVICES["statistics"] + + try: + # Track event + event_data = { + "event_type": "page_view", + "user_id": "test_user", + "metadata": { + "page": "/home", + "referrer": "google.com" + } + } + + response = await client.post(f"{base_url}/api/statistics/events", json=event_data) + print_test("Track Event", response.status_code == 200, "Event tracked") + + # Get user statistics + response = await client.get(f"{base_url}/api/statistics/users/test_user") + print_test("Get User Stats", response.status_code == 200) + + # Get system statistics + response = await client.get(f"{base_url}/api/statistics/system") + if response.status_code == 200: + stats = response.json() + print_test("System Stats", True, f"Total events: {stats.get('total_events', 0)}") + else: + print_test("System Stats", False, f"HTTP {response.status_code}") + + # Get analytics + response = await client.get(f"{base_url}/api/statistics/analytics?period=day") + print_test("Get Analytics", response.status_code == 200, "Daily analytics retrieved") + + except Exception as e: + print_test("Statistics Service", False, f"Error: {str(e)}") + +async def test_search_service(): + """Test Search Service""" + print_section("8. SEARCH SERVICE TESTS") + + async with httpx.AsyncClient(timeout=10.0) as client: + base_url = SERVICES["search"] + + try: + # Index test document + doc = { + "id": f"test_doc_{datetime.now().timestamp()}", + "doc_type": "test", + "title": "Test Document", + "content": "This is a test document for search functionality", + "tags": ["test", "search", "solr"], + "created_at": datetime.utcnow().isoformat() + } + + response = await client.post(f"{base_url}/api/search/index", json=doc) + print_test("Index Document", response.status_code == 200, f"Document ID: {doc['id']}") + + # Wait for indexing + await asyncio.sleep(2) + + # Search documents + response = await client.get(f"{base_url}/api/search", params={"q": "test"}) + if response.status_code == 200: + data = response.json() + print_test("Search Documents", True, f"Found {data.get('total', 0)} results") + else: + print_test("Search Documents", False, f"HTTP {response.status_code}") + + # Get suggestions + response = await client.get(f"{base_url}/api/search/suggest", params={"q": "tes"}) + if response.status_code == 200: + data = response.json() + suggestions = data.get("suggestions", []) + print_test("Get Suggestions", True, f"{len(suggestions)} suggestions") + else: + print_test("Get Suggestions", False, f"HTTP {response.status_code}") + + # Get statistics + response = await client.get(f"{base_url}/api/search/stats") + if response.status_code == 200: + stats = response.json() + print_test("Search Stats", True, f"Total docs: {stats.get('statistics', {}).get('total_documents', 0)}") + else: + print_test("Search Stats", False, f"HTTP {response.status_code}") + + # Delete document + response = await client.delete(f"{base_url}/api/search/document/{doc['id']}") + print_test("Delete Document", response.status_code == 200) + + except Exception as e: + print_test("Search Service", False, f"Error: {str(e)}") + +async def test_console_service(): + """Test Console Service""" + print_section("9. CONSOLE SERVICE TESTS") + + async with httpx.AsyncClient(timeout=10.0) as client: + base_url = SERVICES["console"] + + try: + # Get services status + response = await client.get(f"{base_url}/api/console/services") + if response.status_code == 200: + services = response.json() + print_test("Get Services", True, f"{len(services.get('services', []))} services") + else: + print_test("Get Services", False, f"HTTP {response.status_code}") + + # Get system info + response = await client.get(f"{base_url}/api/console/system") + print_test("System Info", response.status_code == 200, "System information retrieved") + + # Get logs + response = await client.get(f"{base_url}/api/console/logs?service=users&limit=10") + print_test("Get Logs", response.status_code == 200, "Logs retrieved") + + # Get metrics + response = await client.get(f"{base_url}/api/console/metrics") + if response.status_code == 200: + metrics = response.json() + print_test("Get Metrics", True, f"CPU: {metrics.get('metrics', {}).get('cpu_usage', 'N/A')}%") + else: + print_test("Get Metrics", False, f"HTTP {response.status_code}") + + except Exception as e: + print_test("Console Service", False, f"Error: {str(e)}") + +async def main(): + """Run all tests""" + print("="*60) + print(" BACKEND SERVICES COMPREHENSIVE TEST SUITE") + print("="*60) + print(f"Started at: {datetime.now().isoformat()}") + + # Test health endpoints first + health_results = await test_health_endpoints() + + # Test individual services + await test_users_service() + await test_oauth_service() + await test_images_service() + await test_files_service() + await test_notifications_service() + await test_statistics_service() + await test_search_service() + await test_console_service() + + # Summary + print_section("TEST SUMMARY") + healthy_count = sum(1 for v in health_results.values() if v) + total_count = len(health_results) + + print(f"\nšŸ“Š Services Health: {healthy_count}/{total_count} services are healthy") + print(f"āœ… Healthy Services: {', '.join([k for k, v in health_results.items() if v])}") + + if healthy_count < total_count: + unhealthy = [k for k, v in health_results.items() if not v] + print(f"āŒ Unhealthy Services: {', '.join(unhealthy)}") + + print(f"\nšŸŽ‰ Test suite completed at: {datetime.now().isoformat()}") + print("="*60) + +if __name__ == "__main__": + asyncio.run(main()) \ No newline at end of file