OpenNIT

Quelltext des aktuellen Standes

Fassung 1.1.1

workflow-selftest.php

4 KB
<?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);