馃敟 Tests Exhaustivos de APIs"; // Configurar sesi贸n de test $this->setupTestSession(); // Tests de mensajer铆a $this->testSendMessageAPI(); $this->testBroadcastAPI(); // Tests de plantillas $this->testTemplateAPIs(); // Tests de usuarios $this->testUserAPIs(); // Tests de configuraci贸n $this->testConfigurationAPIs(); // Tests de analytics $this->testAnalyticsAPIs(); $this->showAPITestSummary(); } private function setupTestSession() { $_SESSION['admin_logged_in'] = true; $_SESSION['last_activity'] = time(); $_SESSION['login_ip'] = '127.0.0.1'; } private function testSendMessageAPI() { echo "

馃摠 Tests de API send_message.php

"; // Test 1: Verificar que el archivo existe $this->apiTest("Verificar archivo send_message existe", function() { if (!file_exists(__DIR__ . '/../api/send_message.php')) { throw new Exception("Archivo send_message.php no existe"); } return "Archivo send_message.php existe"; }); // Test 2: Verificar contenido b谩sico del archivo $this->apiTest("Verificar estructura de send_message", function() { $content = file_get_contents(__DIR__ . '/../api/send_message.php'); if (strpos($content, 'requireAuthentication()') === false) { throw new Exception("API no incluye verificaci贸n de autenticaci贸n"); } if (strpos($content, 'Content-Type: application/json') === false) { throw new Exception("API no establece Content-Type JSON"); } return "Estructura de send_message correcta"; }); // Test 3: Verificar que usa validaciones $this->apiTest("Verificar validaciones en send_message", function() { $content = file_get_contents(__DIR__ . '/../api/send_message.php'); $validations = [ 'recipient' => strpos($content, 'recipient') !== false, 'type' => strpos($content, 'type') !== false, 'message' => strpos($content, 'message') !== false ]; foreach ($validations as $field => $found) { if (!$found) { throw new Exception("Campo '$field' no est谩 siendo validado"); } } return "Validaciones b谩sicas presentes"; }); // Test 4: Verificar integraci贸n con WhatsApp $this->apiTest("Verificar integraci贸n WhatsApp", function() { $content = file_get_contents(__DIR__ . '/../api/send_message.php'); if (strpos($content, 'WhatsAppService') === false && strpos($content, 'sendMessage') === false) { throw new Exception("No integra con servicio de WhatsApp"); } return "Integraci贸n WhatsApp presente"; }); } private function testBroadcastAPI() { echo "

馃摙 Tests de API send_broadcast.php

"; $this->apiTest("Verificar archivo send_broadcast existe", function() { if (!file_exists(__DIR__ . '/../api/send_broadcast.php')) { throw new Exception("Archivo send_broadcast.php no existe"); } return "Archivo de broadcast existe"; }); // Test de contenido del archivo $this->apiTest("Verificar estructura de broadcast", function() { $content = file_get_contents(__DIR__ . '/../api/send_broadcast.php'); if (strpos($content, 'requireAuthentication()') === false) { throw new Exception("API no requiere autenticaci贸n"); } if (strpos($content, 'recipients') === false && strpos($content, 'users') === false) { throw new Exception("No maneja lista de destinatarios"); } return "Estructura de broadcast correcta"; }); } private function testTemplateAPIs() { echo "

馃摑 Tests de APIs de Plantillas

"; // Test get_templates.php $this->apiTest("API get_templates existe y estructura", function() { if (!file_exists(__DIR__ . '/../api/get_templates.php')) { throw new Exception("get_templates.php no existe"); } $content = file_get_contents(__DIR__ . '/../api/get_templates.php'); if (strpos($content, 'requireAuthentication()') === false) { throw new Exception("get_templates no requiere autenticaci贸n"); } if (strpos($content, 'message_templates') === false) { throw new Exception("No consulta tabla message_templates"); } return "API get_templates correcta"; }); // Test save_template.php $this->apiTest("API save_template existe y validaciones", function() { if (!file_exists(__DIR__ . '/../api/save_template.php')) { throw new Exception("save_template.php no existe"); } $content = file_get_contents(__DIR__ . '/../api/save_template.php'); $validations = [ 'autenticaci贸n' => strpos($content, 'requireAuthentication()') !== false, 'name' => strpos($content, 'name') !== false, 'template_name' => strpos($content, 'template_name') !== false, 'language_code' => strpos($content, 'language_code') !== false ]; foreach ($validations as $check => $found) { if (!$found) { throw new Exception("Validaci贸n '$check' faltante"); } } return "API save_template completa"; }); // Test update_template_status.php $this->apiTest("API update_template_status existe", function() { if (!file_exists(__DIR__ . '/../api/update_template_status.php')) { throw new Exception("update_template_status.php no existe"); } $content = file_get_contents(__DIR__ . '/../api/update_template_status.php'); if (strpos($content, 'requireAuthentication()') === false) { throw new Exception("update_template_status no requiere autenticaci贸n"); } if (strpos($content, 'status') === false) { throw new Exception("No maneja campo status"); } return "API update_template_status correcta"; }); // Test de integraci贸n con base de datos $this->apiTest("Verificar tablas de plantillas", function() { $db = Database::getInstance(); // Verificar que la tabla existe $result = $db->fetchAll("SHOW TABLES LIKE 'message_templates'"); $tables = $result ? $result : []; if (empty($tables)) { throw new Exception("Tabla message_templates no existe"); } // Verificar estructura de la tabla $columns = $db->fetchAll("DESCRIBE message_templates"); if (!$columns || empty($columns)) { throw new Exception("No se puede obtener estructura de message_templates"); } $requiredColumns = ['id', 'name', 'template_name', 'status', 'created_at']; $existingColumns = array_map(function($col) { return $col['Field']; }, $columns); foreach ($requiredColumns as $required) { if (!in_array($required, $existingColumns)) { throw new Exception("Columna '$required' faltante en message_templates"); } } return "Estructura de tabla message_templates correcta"; }); } private function testUserAPIs() { echo "

馃懃 Tests de APIs de Usuarios

"; // Test get_users.php $this->apiTest("API get_users existe y estructura", function() { if (!file_exists(__DIR__ . '/../api/get_users.php')) { throw new Exception("get_users.php no existe"); } $content = file_get_contents(__DIR__ . '/../api/get_users.php'); if (strpos($content, 'requireAuthentication()') === false) { throw new Exception("get_users no requiere autenticaci贸n"); } if (strpos($content, 'users') === false && strpos($content, 'conversations') === false) { throw new Exception("No consulta tablas de usuarios"); } return "API get_users correcta"; }); // Test export_users.php $this->apiTest("API export_users existe", function() { if (!file_exists(__DIR__ . '/../api/export_users.php')) { throw new Exception("export_users.php no existe"); } $content = file_get_contents(__DIR__ . '/../api/export_users.php'); if (strpos($content, 'requireAuthentication()') === false) { throw new Exception("export_users no requiere autenticaci贸n"); } if (strpos($content, 'CSV') === false && strpos($content, 'header') === false) { throw new Exception("No implementa exportaci贸n CSV"); } return "API export_users correcta"; }); // Verificar tabla de usuarios $this->apiTest("Verificar estructura tabla usuarios", function() { $db = Database::getInstance(); // Verificar tabla conversations (usuarios) $result = $db->fetchAll("SHOW TABLES LIKE 'conversations'"); if (!$result || empty($result)) { throw new Exception("Tabla conversations no existe"); } return "Estructura de usuarios correcta"; }); } private function testConfigurationAPIs() { echo "

鈿欙笍 Tests de APIs de Configuraci贸n

"; // Test get_settings.php $this->apiTest("API get_settings existe", function() { if (!file_exists(__DIR__ . '/../api/get_settings.php')) { throw new Exception("get_settings.php no existe"); } $content = file_get_contents(__DIR__ . '/../api/get_settings.php'); if (strpos($content, 'requireAuthentication()') === false) { throw new Exception("get_settings no requiere autenticaci贸n"); } return "API get_settings correcta"; }); // Test save_settings.php $this->apiTest("API save_settings existe", function() { if (!file_exists(__DIR__ . '/../api/save_settings.php')) { throw new Exception("save_settings.php no existe"); } $content = file_get_contents(__DIR__ . '/../api/save_settings.php'); if (strpos($content, 'requireAuthentication()') === false) { throw new Exception("save_settings no requiere autenticaci贸n"); } $fields = ['business_name', 'whatsapp_token', 'phone_number_id']; foreach ($fields as $field) { if (strpos($content, $field) === false) { throw new Exception("Campo '$field' no est谩 siendo procesado"); } } return "API save_settings completa"; }); // Verificar tabla settings $this->apiTest("Verificar tabla configuraci贸n", function() { $db = Database::getInstance(); $result = $db->fetchAll("SHOW TABLES LIKE 'settings'"); if (!$result || empty($result)) { throw new Exception("Tabla settings no existe"); } return "Tabla de configuraci贸n existe"; }); } private function testAnalyticsAPIs() { echo "

馃搳 Tests de APIs de Analytics

"; // Test get_stats.php $this->apiTest("API get_stats existe y estructura", function() { if (!file_exists(__DIR__ . '/../api/get_stats.php')) { throw new Exception("get_stats.php no existe"); } $content = file_get_contents(__DIR__ . '/../api/get_stats.php'); if (strpos($content, 'requireAuthentication()') === false) { throw new Exception("get_stats no requiere autenticaci贸n"); } $stats = ['total_users', 'messages_today', 'active_users', 'total_messages']; foreach ($stats as $stat) { if (strpos($content, $stat) === false) { throw new Exception("Estad铆stica '$stat' no est谩 implementada"); } } return "API get_stats completa"; }); // Test get_chart_data.php $this->apiTest("API get_chart_data existe", function() { if (!file_exists(__DIR__ . '/../api/get_chart_data.php')) { throw new Exception("get_chart_data.php no existe"); } $content = file_get_contents(__DIR__ . '/../api/get_chart_data.php'); if (strpos($content, 'requireAuthentication()') === false) { throw new Exception("get_chart_data no requiere autenticaci贸n"); } return "API get_chart_data correcta"; }); // Test get_recent_messages.php $this->apiTest("API get_recent_messages existe", function() { if (!file_exists(__DIR__ . '/../api/get_recent_messages.php')) { throw new Exception("get_recent_messages.php no existe"); } $content = file_get_contents(__DIR__ . '/../api/get_recent_messages.php'); if (strpos($content, 'requireAuthentication()') === false) { throw new Exception("get_recent_messages no requiere autenticaci贸n"); } if (strpos($content, 'messages') === false && strpos($content, 'conversations') === false) { throw new Exception("No consulta mensajes"); } return "API get_recent_messages correcta"; }); // Test de integridad de datos $this->apiTest("Verificar tablas de analytics", function() { $db = Database::getInstance(); $tables = ['messages', 'conversations']; foreach ($tables as $table) { $result = $db->fetchAll("SHOW TABLES LIKE '$table'"); if (!$result || empty($result)) { throw new Exception("Tabla '$table' necesaria para analytics no existe"); } } return "Tablas para analytics existen"; }); } private function callAPI($endpoint, $method = 'GET', $data = null) { // Configurar el entorno para la llamada $_SERVER['REQUEST_METHOD'] = $method; if ($method === 'POST' && $data) { $_POST = $data; // Simular php://input para APIs que lo usan $GLOBALS['HTTP_RAW_POST_DATA'] = json_encode($data); } ob_start(); try { // Cambiar al directorio padre temporalmente para que las rutas relativas funcionen $originalDir = getcwd(); chdir(__DIR__ . '/..'); include "api/$endpoint"; // Restaurar directorio original chdir($originalDir); $output = ob_get_clean(); // Intentar decodificar como JSON $decoded = json_decode($output, true); if ($decoded === null && json_last_error() !== JSON_ERROR_NONE) { // Si no es JSON v谩lido, retornar el output raw return ['raw_output' => $output]; } return $decoded; } catch (Exception $e) { ob_end_clean(); // Restaurar directorio en caso de excepci贸n if (isset($originalDir)) { chdir($originalDir); } throw $e; } finally { // Restaurar directorio y limpiar variables globales if (isset($originalDir)) { chdir($originalDir); } unset($_POST); unset($GLOBALS['HTTP_RAW_POST_DATA']); } } private function apiTest($name, $callable) { try { $result = $callable(); echo "
$name: $result
"; $this->testResults[] = ['name' => $name, 'status' => 'passed', 'message' => $result]; } catch (Exception $e) { echo "
$name: " . $e->getMessage() . "
"; $this->testResults[] = ['name' => $name, 'status' => 'failed', 'message' => $e->getMessage()]; } } private function showAPITestSummary() { $total = count($this->testResults); $passed = count(array_filter($this->testResults, function($r) { return $r['status'] === 'passed'; })); $failed = $total - $passed; $successRate = $total > 0 ? ($passed / $total) * 100 : 0; $alertClass = $successRate === 100.0 ? 'success' : ($successRate >= 80 ? 'warning' : 'danger'); echo "
"; echo "

Resumen Tests de APIs

"; echo "

Total de tests API: $total | "; echo "Pasaron: $passed | "; echo "Fallaron: $failed | "; echo "脡xito: " . number_format($successRate, 1) . "%

"; echo "
"; } } // No ejecutar si es incluido por el runner principal if (basename($_SERVER['PHP_SELF']) === 'api_tests.php') { $configPath = __DIR__ . '/../config/config.php'; if (file_exists($configPath)) { require_once $configPath; } $suite = new APITestSuite(); $suite->runAllAPITests(); } ?>