test: flujos ejecutados de punta a punta contra un ERP falso
setup/tests/ corre NormalBot de verdad —no un espejo—: SQLite en memoria con los endpoints del seed reescritos hacia fixtures_api.php servido con php -S, asi el curl real se ejecuta y los POST capturados se comparan contra el contrato del procesador. ConversationContext, WhatsAppSender y AiBot son falsos en memoria; el resto es el codigo de produccion. 51 casos: finca restringida que entra sola, ausentismo completo con rango invertido rechazado, perfiles trabajador/supervisor, ciclos con multi-select paginado, mantenimiento con requires/resolver, labores con cuadrilla, y NLU que resuelve "plateo" por entity hasta el informe. Destaparon dos errores reales: - registrar_mantenimiento posteaba a labores_up sin novedad_id ni empleados, que el procesador exige: el ERP lo habria rechazado siempre. Ahora pide la labor del grupo elegido (endpoint nuevo novedades_mant_dn) y la cuadrilla. - resolverPorCampos reventaba con warning al sustituir arreglos en la URL. Uso: bash setup/tests/run.sh Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
6df1d482cc
commit
1f7d33b40d
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
/**
|
||||
* ERP falso para los tests unitarios. Se sirve con `php -S` y responde los
|
||||
* catálogos con datos fijos; los POST se capturan en un log JSONL para que el
|
||||
* test verifique el payload exacto que armó el bot.
|
||||
*/
|
||||
|
||||
$peticion = $_GET['peticion'] ?? '';
|
||||
$capture = getenv('CAPTURE_LOG') ?: sys_get_temp_dir() . '/bot_test_capture.jsonl';
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
// ── POST: capturar y responder como el ERP real ──────────────────────────────
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$body = json_decode(file_get_contents('php://input'), true);
|
||||
file_put_contents($capture, json_encode([
|
||||
'peticion' => $peticion,
|
||||
'query' => $_GET,
|
||||
'body' => $body,
|
||||
], JSON_UNESCAPED_UNICODE) . "\n", FILE_APPEND);
|
||||
|
||||
// Mismo shape que BotEntradaProcesador para que el bot repita el detalle
|
||||
echo json_encode([
|
||||
'status' => 'ok',
|
||||
'mensaje' => 'capturado:' . $peticion,
|
||||
], JSON_UNESCAPED_UNICODE);
|
||||
exit;
|
||||
}
|
||||
|
||||
// ── GET: catálogos fijos ──────────────────────────────────────────────────────
|
||||
$fincas = [
|
||||
['id' => '0', 'label' => '🌐 Todas las fincas'],
|
||||
['id' => '4', 'label' => 'REPOSO'],
|
||||
['id' => '7', 'label' => 'ROSA BLANCA'],
|
||||
];
|
||||
// El ERP acota por número: este wa solo tiene una finca asignada
|
||||
if (($_GET['wa'] ?? '') === '57300RESTRINGIDO') {
|
||||
$fincas = [['id' => '4', 'label' => 'REPOSO']];
|
||||
}
|
||||
|
||||
$novedades17 = [];
|
||||
foreach (range(1, 17) as $i) $novedades17[] = ['id' => (string)(100 + $i), 'nombre' => "NOVEDAD {$i}"];
|
||||
|
||||
$lotes12 = [];
|
||||
foreach (range(1, 12) as $i) $lotes12[] = ['id' => (string)$i, 'label' => "REPOSO {$i}A (" . (50 - $i) . "d)"];
|
||||
|
||||
$fixtures = [
|
||||
'fincas' => $fincas,
|
||||
'empleados' => [
|
||||
['id' => '412', 'nombre' => 'JULIO PEREZ GOMEZ'],
|
||||
['id' => '415', 'nombre' => 'JULIO CESAR RAMIREZ'],
|
||||
['id' => '418', 'nombre' => 'MARIA GOMEZ RUIZ'],
|
||||
],
|
||||
'novedades_ausentismo_dn' => $novedades17,
|
||||
'novedades_labor_dn' => !empty($_GET['grupo'])
|
||||
? [['id' => '77', 'nombre' => 'PLATEO MANUAL']]
|
||||
: [
|
||||
['id' => '42', 'nombre' => 'TRACTORISTA'],
|
||||
['id' => '43', 'nombre' => 'HORAS EXTRA'],
|
||||
],
|
||||
'lotes_apertura_dn' => $lotes12,
|
||||
'lotes_abiertos_dn' => array_slice($lotes12, 0, 3),
|
||||
'lotes_x_finca' => [
|
||||
['id' => '4', 'label' => 'REPOSO 1A'],
|
||||
['id' => '9', 'label' => 'REPOSO 2A'],
|
||||
],
|
||||
'grupos_mantenimiento' => [
|
||||
['id' => '5', 'label' => 'PLATEO'],
|
||||
['id' => '6', 'label' => 'CORONA'],
|
||||
],
|
||||
'lotes_mantenimiento_dn' => [
|
||||
['id' => '4', 'label' => 'REPOSO 1A (falta 12)', 'faltante' => 12],
|
||||
],
|
||||
'productos_fertilizacion_dn' => [
|
||||
['id' => '30', 'nombre' => 'UREA (falta 120)', 'dosis' => 120],
|
||||
],
|
||||
];
|
||||
|
||||
// Los informes de texto responden {status, message}
|
||||
if (str_contains($peticion, '_texto_bot')) {
|
||||
file_put_contents($capture, json_encode(['peticion' => $peticion, 'query' => $_GET]) . "\n", FILE_APPEND);
|
||||
echo json_encode(['status' => '1', 'message' => 'informe-de-prueba']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (isset($fixtures[$peticion])) {
|
||||
// La paginación del ERP: los catálogos cortos devuelven 10 salvo &todos=1
|
||||
$datos = $fixtures[$peticion];
|
||||
if (in_array($peticion, ['lotes_apertura_dn', 'lotes_abiertos_dn'], true) && empty($_GET['todos'])) {
|
||||
$datos = array_slice($datos, 0, 10);
|
||||
}
|
||||
echo json_encode(['status' => '1', 'datos' => $datos], JSON_UNESCAPED_UNICODE);
|
||||
exit;
|
||||
}
|
||||
|
||||
http_response_code(404);
|
||||
echo json_encode(['status' => 'error', 'mensaje' => "sin fixture: {$peticion}"]);
|
||||
Reference in New Issue
Block a user