#!/usr/bin/env python """ Manual API Test Script for AMO CRM Service This script tests the API endpoints without requiring Redis/broker. It provides a quick way to verify the service is working. """ import requests import json from datetime import datetime from typing import Dict, Any BASE_URL = "http://localhost:8000" API_BASE = f"{BASE_URL}/api/v1" def print_section(title: str): """Print a formatted section header.""" print(f"\n{'='*60}") print(f" {title}") print(f"{'='*60}\n") def print_result(test_name: str, success: bool, details: str = ""): """Print test result.""" status = "✅ PASS" if success else "❌ FAIL" print(f"{status} - {test_name}") if details: print(f" {details}") def test_health() -> bool: """Test health check endpoint.""" try: response = requests.get(f"{BASE_URL}/health", timeout=5) return response.status_code == 200 and response.json().get("status") == "healthy" except Exception as e: print(f" Error: {e}") return False def test_root() -> bool: """Test root endpoint.""" try: response = requests.get(BASE_URL, timeout=5) data = response.json() return ( response.status_code == 200 and "AMO CRM" in data.get("message", "") ) except Exception as e: print(f" Error: {e}") return False def test_list_entities() -> bool: """Test list entities endpoint.""" try: response = requests.get(f"{API_BASE}/entities/", timeout=5) data = response.json() return ( response.status_code == 200 and "entities" in data and "deals" in data["entities"] ) except Exception as e: print(f" Error: {e}") return False def test_ingest_users() -> bool: """Test user data ingestion.""" try: sample_users = [ { "id": 1, "name": "Test User", "email": "test@example.com", "created_at": int(datetime.now().timestamp()), "updated_at": int(datetime.now().timestamp()), } ] response = requests.post( f"{API_BASE}/data/users", json={"data": sample_users, "sync_mode": "upsert"}, timeout=5 ) return response.status_code == 200 and "Processed" in response.json().get("message", "") except Exception as e: print(f" Error: {e}") return False def test_ingest_deals() -> bool: """Test deal data ingestion.""" try: sample_deals = [ { "id": 1, "name": "Test Deal", "price": 10000, "status_id": 142, "pipeline_id": 1, "responsible_user_id": 1, "created_at": int(datetime.now().timestamp()), "updated_at": int(datetime.now().timestamp()), } ] response = requests.post( f"{API_BASE}/data/deals", json={"data": sample_deals, "sync_mode": "upsert"}, timeout=5 ) return response.status_code == 200 and "Processed" in response.json().get("message", "") except Exception as e: print(f" Error: {e}") return False def test_list_deal_fields() -> bool: """Test listing deal fields.""" try: response = requests.get(f"{API_BASE}/entities/deals/fields", timeout=5) data = response.json() return ( response.status_code == 200 and data.get("entity_type") == "deals" and "fields" in data ) except Exception as e: print(f" Error: {e}") return False def test_create_export_config() -> tuple[bool, int]: """Test creating export configuration.""" try: config = { "name": "Manual Test Export", "sheet_id": "test-sheet-123", "entity_mappings": { "deals": { "sheet_name": "Deals", "is_enabled": True, "field_mapping": [ {"field_name": "name", "column": "A", "order": 1}, {"field_name": "price", "column": "B", "order": 2} ] } } } response = requests.post( f"{API_BASE}/export/configure", json=config, timeout=5 ) if response.status_code == 200: config_id = response.json().get("configuration_id", 0) return True, config_id return False, 0 except Exception as e: print(f" Error: {e}") return False, 0 def test_list_export_configs() -> bool: """Test listing export configurations.""" try: response = requests.get(f"{API_BASE}/export/configurations", timeout=5) data = response.json() return ( response.status_code == 200 and "configurations" in data ) except Exception as e: print(f" Error: {e}") return False def test_amocrm_info() -> bool: """Test AMO CRM connection info (doesn't require valid credentials).""" try: response = requests.get(f"{API_BASE}/amocrm/info", timeout=5) return response.status_code in [200, 401, 500] # Any response means endpoint works except Exception as e: print(f" Error: {e}") return False def main(): """Run all manual tests.""" print(""" ╔══════════════════════════════════════════════════════════════╗ ║ AMO CRM Service - Manual API Test Suite ║ ║ ║ ║ Testing core API functionality without Redis/Worker ║ ╚══════════════════════════════════════════════════════════════╝ """) print("⚙️ Testing API at:", BASE_URL) print("📅 Test Date:", datetime.now().strftime("%Y-%m-%d %H:%M:%S")) # Track results total_tests = 0 passed_tests = 0 # Test 1: Basic Endpoints print_section("1. Basic Service Health") result = test_health() print_result("Health Check", result) total_tests += 1 if result: passed_tests += 1 result = test_root() print_result("Root Endpoint", result) total_tests += 1 if result: passed_tests += 1 # Test 2: Entity Management print_section("2. Entity Management") result = test_list_entities() print_result("List Entities", result) total_tests += 1 if result: passed_tests += 1 result = test_list_deal_fields() print_result("List Deal Fields", result) total_tests += 1 if result: passed_tests += 1 # Test 3: Data Ingestion print_section("3. Data Ingestion") result = test_ingest_users() print_result("Ingest Users", result) total_tests += 1 if result: passed_tests += 1 result = test_ingest_deals() print_result("Ingest Deals", result) total_tests += 1 if result: passed_tests += 1 # Test 4: Export Configuration print_section("4. Export Configuration") result, config_id = test_create_export_config() print_result("Create Export Config", result, f"Config ID: {config_id}" if result else "") total_tests += 1 if result: passed_tests += 1 result = test_list_export_configs() print_result("List Export Configs", result) total_tests += 1 if result: passed_tests += 1 # Test 5: AMO CRM Integration print_section("5. AMO CRM Integration") result = test_amocrm_info() print_result("AMO CRM Info Endpoint", result, "Endpoint responding (credentials may be needed)") total_tests += 1 if result: passed_tests += 1 # Summary print_section("Test Summary") percentage = (passed_tests / total_tests * 100) if total_tests > 0 else 0 print(f"Total Tests: {total_tests}") print(f"Passed: {passed_tests} ✅") print(f"Failed: {total_tests - passed_tests} ❌") print(f"Success Rate: {percentage:.1f}%") if passed_tests == total_tests: print("\n🎉 All tests passed! The service is working correctly.") print("\n📝 Next Steps:") print(" 1. Start Redis server: redis-server") print(" 2. Start worker: python -m workers.broker") print(" 3. Test export jobs and background processing") elif passed_tests >= total_tests * 0.7: print("\n✨ Most tests passed! Core functionality is working.") print(f"\n⚠️ {total_tests - passed_tests} test(s) failed - check if the service is running") else: print("\n❌ Many tests failed. Please check:") print(" 1. Is the service running? (uvicorn app:app)") print(" 2. Is the database initialized? (alembic upgrade head)") print(" 3. Are there any error messages in the service logs?") print("\n" + "="*60) return passed_tests == total_tests if __name__ == "__main__": try: success = main() exit(0 if success else 1) except KeyboardInterrupt: print("\n\n⚠️ Tests interrupted by user") exit(130) except Exception as e: print(f"\n\n❌ Unexpected error: {e}") import traceback traceback.print_exc() exit(1)