Quelltext des aktuellen Standes
<?php
/**
* Smoke-Test für das Workflow-Modul (manuell ausführbar):
*
* php bin/workflow-selftest.php
*
* Legt eine temporäre Vorlage (1 Feld, 1 Genehmigungs-Station) an, stellt einen
* Antrag, genehmigt ihn und prüft, dass der Antrag den Status "approved" erreicht.
* Räumt anschließend wieder auf. Gibt bei Erfolg Exit-Code 0 zurück, sonst 1.
*
* Hinweis: Erzeugt dabei reale Benachrichtigungen an den Testnutzer.
*/
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
require_once __DIR__ . '/../bootstrap.php';
use OpenNIT\Cron\Bootstrap;
use OpenNIT\Workflows\WorkflowFactory;
$rootDir = dirname(__DIR__);
if (class_exists(\Dotenv\Dotenv::class) && is_file($rootDir . '/.env')) {
\Dotenv\Dotenv::createImmutable($rootDir)->safeLoad();
}
function fail(string $msg): never
{
fwrite(STDERR, "[selftest] FEHLER: $msg" . PHP_EOL);
exit(1);
}
try {
$ctx = Bootstrap::init($rootDir);
} catch (\Throwable $e) {
fail('Bootstrap fehlgeschlagen: ' . $e->getMessage());
}
$db = $ctx->db;
$mgr = WorkflowFactory::fromContext($ctx);
$user = $db->fetchOne('SELECT id, display_name FROM users WHERE is_active = 1 ORDER BY id LIMIT 1');
if (!$user) {
fail('Kein aktiver Benutzer vorhanden.');
}
$uid = (int)$user['id'];
$wfId = null;
$reqId = null;
try {
// 1) Temporäre Vorlage
$wfId = $db->insert('workflows', ['name' => '__SELFTEST__ ' . date('H:i:s'), 'enabled' => 1, 'created_by' => $uid]);
$db->insert('workflow_fields', [
'workflow_id' => $wfId, 'field_key' => 'grund', 'label' => 'Grund',
'field_type' => 'text', 'is_required' => 1, 'sort_order' => 1,
]);
$db->insert('workflow_steps', [
'workflow_id' => $wfId, 'stage_no' => 1, 'sort_order' => 1, 'name' => 'Freigabe',
'step_type' => 'approval',
'resolver_json' => json_encode([['type' => 'fixed_user', 'value' => (string)$uid]]),
'decision_rule' => 'single', 'required_count' => 1, 'on_reject' => 'stop',
]);
echo "[selftest] Vorlage #$wfId angelegt." . PHP_EOL;
// 2) Antrag starten
$reqId = $mgr->startRequest($wfId, $uid, 'Selftest-Antrag', ['type' => 'none'], ['grund' => 'Automatischer Test']);
$r = $mgr->getRequest($reqId);
if (($r['status'] ?? '') !== 'pending') {
fail("Antrag nicht 'pending' nach Start (ist: " . ($r['status'] ?? '?') . ').');
}
echo "[selftest] Antrag #$reqId gestartet (pending)." . PHP_EOL;
// 3) Aktive Station finden + genehmigen
$active = null;
foreach ($mgr->getStepStates($reqId) as $s) {
if ($s['status'] === 'active') { $active = $s; break; }
}
if ($active === null) {
fail('Keine aktive Station gefunden.');
}
// 3b) Erinnerung an die aktive Station auslösen (darf nicht fehlschlagen)
$mgr->remindStep((int)$active['id']);
echo "[selftest] Erinnerung für aktive Station ausgelöst." . PHP_EOL;
$mgr->decideAsUser((int)$active['id'], $uid, 'approve', '', 'Selftest-Zustimmung');
// 4) Ergebnis prüfen
$r2 = $mgr->getRequest($reqId);
if (($r2['status'] ?? '') !== 'approved') {
fail("Antrag nicht 'approved' nach Genehmigung (ist: " . ($r2['status'] ?? '?') . ').');
}
echo "[selftest] Antrag #$reqId erfolgreich genehmigt (approved)." . PHP_EOL;
} catch (\Throwable $e) {
// Aufräumen versuchen, dann Fehler melden
if ($reqId) { @$db->delete('workflow_requests', 'id = ?', [$reqId]); }
if ($wfId) { @$db->delete('workflows', 'id = ?', [$wfId]); }
fail($e->getMessage());
}
// Aufräumen
if ($reqId) { $db->delete('workflow_requests', 'id = ?', [$reqId]); }
if ($wfId) { $db->delete('workflows', 'id = ?', [$wfId]); }
echo "[selftest] OK – End-to-End-Durchlauf erfolgreich, temporäre Daten entfernt." . PHP_EOL;
exit(0);