fix(tests): sin pdo_sqlite — db() falso en PHP puro
El servidor no trae el driver de SQLite y el arnes reventaba al arrancar. NormalBot solo hace dos consultas —el endpoint por clave y el perfil por numero— asi que dos mapas en memoria alcanzan y el arnes deja de depender de cualquier driver de PDO. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
1f7d33b40d
commit
9ae4b0dee3
+59
-16
@@ -4,8 +4,8 @@ declare(strict_types=1);
|
||||
/**
|
||||
* Arnés para ejecutar NormalBot de verdad, sin MySQL ni WhatsApp:
|
||||
*
|
||||
* db() -> SQLite en memoria, con los endpoints del seed
|
||||
* reescritos hacia el servidor de fixtures
|
||||
* db() -> falso en PHP puro (sin drivers), con los endpoints
|
||||
* del seed reescritos hacia el servidor de fixtures
|
||||
* ConversationContext -> estado en memoria, un contexto por teléfono
|
||||
* WhatsAppSender -> captura los envíos directos en ::$enviados
|
||||
* AiBot -> respuestas guionadas en ::$respuestas
|
||||
@@ -15,28 +15,71 @@ declare(strict_types=1);
|
||||
|
||||
const FIXTURE_BASE = 'http://127.0.0.1:8973/fixtures_api.php';
|
||||
|
||||
// ── db(): SQLite con los endpoints reales del seed ───────────────────────────
|
||||
function db(): PDO
|
||||
// ── db(): falso en PHP puro ──────────────────────────────────────────────────
|
||||
// Sin SQLite: los servidores no siempre traen pdo_sqlite. NormalBot solo hace
|
||||
// dos consultas —el endpoint por clave y el perfil por número— así que un par
|
||||
// de mapas en memoria alcanza y no dependemos de ningún driver.
|
||||
|
||||
class FakeStmt
|
||||
{
|
||||
static $pdo = null;
|
||||
if ($pdo !== null) return $pdo;
|
||||
private $row = false;
|
||||
public function __construct(private string $sql) {}
|
||||
|
||||
$pdo = new PDO('sqlite::memory:', null, null, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
|
||||
$pdo->exec("CREATE TABLE company_endpoints (
|
||||
company_id INT, endpoint_key TEXT, direction TEXT, url TEXT,
|
||||
method TEXT DEFAULT 'GET', params TEXT DEFAULT NULL, is_active INT DEFAULT 1)");
|
||||
$pdo->exec("CREATE TABLE company_phones (
|
||||
company_id INT, wa_number TEXT, label TEXT, permission_type INT,
|
||||
tercero_id INT NULL, modulos_json TEXT NULL, es_supervisor INT DEFAULT 0, is_active INT DEFAULT 1)");
|
||||
public function execute(array $p = []): bool
|
||||
{
|
||||
if (str_contains($this->sql, 'company_endpoints')) {
|
||||
$key = $p[1] ?? '';
|
||||
$url = FakeDb::$endpoints[$key] ?? null;
|
||||
$this->row = $url === null ? false
|
||||
: ['url' => $url, 'method' => 'GET', 'params' => null];
|
||||
} elseif (str_contains($this->sql, 'company_phones')) {
|
||||
$this->row = FakeDb::$phones[$p[1] ?? ''] ?? false;
|
||||
} else {
|
||||
$this->row = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function fetch() { return $this->row; }
|
||||
public function fetchColumn() { return $this->row ? array_values($this->row)[0] : false; }
|
||||
public function fetchAll(): array { return $this->row ? [$this->row] : []; }
|
||||
}
|
||||
|
||||
class FakeDb
|
||||
{
|
||||
/** endpoint_key => url absoluta hacia el servidor de fixtures */
|
||||
public static array $endpoints = [];
|
||||
/** wa_number => fila de company_phones */
|
||||
public static array $phones = [];
|
||||
|
||||
public function prepare(string $sql): FakeStmt { return new FakeStmt($sql); }
|
||||
public function query(string $sql): FakeStmt { $s = new FakeStmt($sql); $s->execute(); return $s; }
|
||||
public function exec(string $sql): int { return 0; }
|
||||
}
|
||||
|
||||
function db(): FakeDb
|
||||
{
|
||||
static $db = null;
|
||||
if ($db !== null) return $db;
|
||||
|
||||
$db = new FakeDb();
|
||||
// Los endpoints salen del seed real: mismas claves y placeholders, otra base.
|
||||
$seed = file_get_contents(dirname(__DIR__) . '/seed_palmas.php');
|
||||
preg_match_all("/\['key' => '([^']+)',\s*'dir' => '([^']+)',\s*'url' => \\\$BASE \. '([^']*)'/", $seed, $m);
|
||||
$ins = $pdo->prepare("INSERT INTO company_endpoints (company_id, endpoint_key, direction, url) VALUES (1, ?, ?, ?)");
|
||||
foreach ($m[1] as $i => $key) {
|
||||
$ins->execute([$key, $m[2][$i], FIXTURE_BASE . $m[3][$i]]);
|
||||
FakeDb::$endpoints[$key] = FIXTURE_BASE . $m[3][$i];
|
||||
}
|
||||
return $pdo;
|
||||
return $db;
|
||||
}
|
||||
|
||||
/** Registra un número con perfil para los escenarios de trabajador/supervisor. */
|
||||
function fakePhone(string $wa, ?int $tercero, int $esSupervisor): void
|
||||
{
|
||||
FakeDb::$phones[$wa] = [
|
||||
'tercero_id' => $tercero,
|
||||
'modulos_json' => null,
|
||||
'es_supervisor' => $esSupervisor,
|
||||
];
|
||||
}
|
||||
|
||||
// ── ConversationContext en memoria ───────────────────────────────────────────
|
||||
|
||||
@@ -84,9 +84,8 @@ check('y la trazabilidad', $post['body']['telefono'] ?? null, '57300AUSEN');
|
||||
// ════ 3. Ausentismo según el perfil del número ═══════════════════════════════
|
||||
echo "\nPerfil — trabajador vinculado y supervisor\n";
|
||||
|
||||
db()->exec("INSERT INTO company_phones (company_id, wa_number, label, permission_type, tercero_id, es_supervisor)
|
||||
VALUES (1, '57300TRABAJADOR', 'Julio', 1, 412, 0),
|
||||
(1, '57300JEFE', 'Sup', 3, 412, 1)");
|
||||
fakePhone('57300TRABAJADOR', 412, 0);
|
||||
fakePhone('57300JEFE', 412, 1);
|
||||
|
||||
$ctx = contexto('57300TRABAJADOR');
|
||||
$r = NormalBot::processInteractive($co, $ctx, 'registrar_ausentismo');
|
||||
|
||||
Reference in New Issue
Block a user