0, 'failed' => 0, 'warnings' => 0 ]; function test($name, $callback) { global $results; try { echo "Testing: $name... "; $result = $callback(); if ($result === true) { echo "✅ PASS\n"; $results['passed']++; } elseif ($result === null) { echo "⚠️ WARNING\n"; $results['warnings']++; } else { echo "❌ FAIL: $result\n"; $results['failed']++; } } catch (Exception $e) { echo "❌ ERROR: " . $e->getMessage() . "\n"; $results['failed']++; } } // 1. Test Redis Connection test("Redis connection", function() { try { $redis = new Predis\Client([ 'scheme' => getenv('REDIS_SCHEME') ?: 'tcp', 'host' => getenv('REDIS_HOST') ?: '127.0.0.1', 'port' => getenv('REDIS_PORT') ?: 6379, ]); $ping = $redis->ping(); return ($ping === 'PONG' || $ping === true); } catch (Exception $e) { return "No se pudo conectar a Redis: " . $e->getMessage(); } }); // 2. Test RedisQueue - Push test("RedisQueue::push", function() { $queue = new RedisQueue(); $result = $queue->push('test_queue', ['message' => 'test'], 1); return $result; }); // 3. Test RedisQueue - Pop test("RedisQueue::pop", function() { $queue = new RedisQueue(); $message = $queue->pop('test_queue', 1); if (!$message) { return "No se pudo obtener mensaje de la cola"; } if ($message['data']['message'] !== 'test') { return "Mensaje recibido no coincide con el enviado"; } return true; }); // 4. Test RedisQueue - Stats test("RedisQueue::getStats", function() { $queue = new RedisQueue(); $stats = $queue->getStats(); if (!is_array($stats)) { return "Stats no devuelve un array"; } return true; }); // 5. Test ConversationState - Set test("ConversationState::setState", function() { $state = new ConversationState(); $result = $state->setState('test_user_123', 'testing', ['key' => 'value'], 300); return $result; }); // 6. Test ConversationState - Get test("ConversationState::getState", function() { $state = new ConversationState(); $result = $state->getState('test_user_123'); if (!$result) { return "No se pudo obtener estado"; } if ($result['state'] !== 'testing') { return "Estado no coincide"; } if ($result['context']['key'] !== 'value') { return "Contexto no coincide"; } return true; }); // 7. Test ConversationState - Update Context test("ConversationState::updateContext", function() { $state = new ConversationState(); $result = $state->updateContext('test_user_123', ['new_key' => 'new_value']); if (!$result) { return "No se pudo actualizar contexto"; } $current = $state->getState('test_user_123'); if (!isset($current['context']['new_key'])) { return "Contexto no se actualizó correctamente"; } return true; }); // 8. Test ConversationState - Clear test("ConversationState::clearState", function() { $state = new ConversationState(); $state->clearState('test_user_123'); $result = $state->getState('test_user_123'); return $result === null; }); // 9. Test Logger test("LoggerFactory", function() { if (!class_exists('LoggerFactory')) { return "LoggerFactory no existe"; } $logger = LoggerFactory::getLogger('test'); $logger->info("Test message"); // Verificar que el archivo de log existe $logPath = __DIR__ . '/logs/test.log'; if (!file_exists($logPath)) { return "Archivo de log no fue creado"; } // Limpiar @unlink($logPath); return true; }); // 10. Test Database Connection test("Database connection", function() { try { $db = Database::getInstance(); $result = $db->query("SELECT 1 as test")->fetch(); return $result && $result['test'] == 1; } catch (Exception $e) { return "Error de conexión: " . $e->getMessage(); } }); // 11. Test WhatsApp Config test("WhatsApp configuration", function() { if (!function_exists('getWhatsAppConfigFromDB')) { return "Función getWhatsAppConfigFromDB no existe"; } $config = getWhatsAppConfigFromDB(); if (empty($config['token'])) { return null; // Warning, no error crítico } return true; }); // 12. Test file permissions test("Log directory permissions", function() { $logDir = __DIR__ . '/logs'; if (!is_dir($logDir)) { return "Directorio logs no existe"; } if (!is_writable($logDir)) { return "Directorio logs no tiene permisos de escritura"; } return true; }); // 13. Test uploads directory test("Uploads directory permissions", function() { $uploadsDir = __DIR__ . '/uploads'; if (!is_dir($uploadsDir)) { return null; // Warning } if (!is_writable($uploadsDir)) { return "Directorio uploads no tiene permisos de escritura"; } return true; }); // 14. Test Composer autoload test("Composer autoload", function() { if (!file_exists(__DIR__ . '/vendor/autoload.php')) { return "vendor/autoload.php no existe. Ejecuta: composer install"; } // Verificar clases clave if (!class_exists('Predis\Client')) { return "Predis no está instalado"; } if (!class_exists('Monolog\Logger')) { return "Monolog no está instalado"; } return true; }); // 15. Test .env file test(".env configuration", function() { if (!file_exists(__DIR__ . '/.env')) { return "Archivo .env no existe. Copia .env.example"; } $requiredVars = ['DB_HOST', 'DB_NAME', 'REDIS_HOST']; foreach ($requiredVars as $var) { if (!getenv($var)) { return "Variable $var no está configurada en .env"; } } return true; }); // Limpiar test data echo "\n🧹 Limpiando datos de test...\n"; try { $queue = new RedisQueue(); $queue->flush('test_queue'); $state = new ConversationState(); $state->clearState('test_user_123'); echo "✅ Limpieza completada\n"; } catch (Exception $e) { echo "⚠️ Error en limpieza: " . $e->getMessage() . "\n"; } // Resultados finales echo "\n"; echo "================================\n"; echo "📊 RESULTADOS\n"; echo "================================\n"; echo "✅ Pasados: " . $results['passed'] . "\n"; echo "❌ Fallidos: " . $results['failed'] . "\n"; echo "⚠️ Warnings: " . $results['warnings'] . "\n"; echo "================================\n"; if ($results['failed'] > 0) { echo "\n❌ Algunos tests fallaron. Revisa la configuración.\n"; exit(1); } elseif ($results['warnings'] > 0) { echo "\n⚠️ Tests completados con warnings. Algunas funciones pueden no estar completamente configuradas.\n"; exit(0); } else { echo "\n✅ Todos los tests pasaron correctamente!\n"; echo "\n🚀 Tu arquitectura está lista para usarse.\n"; exit(0); }