Files
deskhub/DeskHub-Webseite/tests/mail_fetch_manual.php
T
2026-11-04 07:55:36 +00:00

77 lines
4.7 KiB
PHP

<?php
declare(strict_types=1);
/**
* Prüft den E-Mail-Abruf von Hand (Knopf in der Ticketliste, includes/mail_fetch_manual.php): ohne Postfach eine Meldung, mit Postfach
* läuft der Abruf genau einmal, ein zweiter Klick innerhalb der Sperrzeit startet keinen zweiten Lauf, und das Ergebnis (neue Tickets,
* Antworten, Fehler) wird verständlich zusammengefasst.
*/
putenv('DESKHUB_TESTING=1');
putenv('DESKHUB_SQLITE_PATH=:memory:');
require_once dirname(__DIR__) . '/includes/bootstrap.php';
require_once dirname(__DIR__) . '/includes/mail_fetch_manual.php';
$failures = [];
$check = function (bool $ok, string $what) use (&$failures): void {
if (!$ok) $failures[] = $what;
};
$pdo = get_db();
$calls = 0;
$runner = function (array $out) use (&$calls): callable {
return function () use (&$calls, $out): array { $calls++; return $out; };
};
$reset = fn() => $pdo->exec("DELETE FROM settings WHERE setting_key = 'cron_fetch_emails_last_run'");
// Kein Postfach
$check(!mail_fetch_available($pdo), 'ohne Postfach nicht verfügbar');
$r = mail_fetch_manual($pdo, $runner(['processed' => 0, 'log' => []]));
$check(!$r['ok'] && $calls === 0 && str_contains($r['message'], 'kein aktives Postfach'), 'ohne Postfach: verständliche Meldung, kein Lauf: ' . $r['message']);
// Mit Postfach
$pdo->exec("INSERT INTO imap_accounts (label, host, port, encryption, username, password_enc, folder, is_active) VALUES ('Test','mail.example.test',993,'ssl','u','x','INBOX',1)");
$check(mail_fetch_available($pdo), 'mit aktivem Postfach verfügbar');
$reset();
$r = mail_fetch_manual($pdo, $runner(['processed' => 0, 'log' => ['[Test] Keine neuen E-Mails.']]));
$check($r['ok'] && $r['level'] === 'info' && $calls === 1 && str_contains($r['message'], 'Keine neuen E-Mails'), 'keine neuen Mails: Hinweis: ' . $r['message']);
// Sperrzeit: ein zweiter Klick direkt danach läuft nicht
$r = mail_fetch_manual($pdo, $runner(['processed' => 9, 'log' => []]));
$check(!$r['ok'] && $r['level'] === 'info' && $calls === 1 && str_contains($r['message'], 'gerade eben'), 'zweiter Klick innerhalb der Sperrzeit startet keinen zweiten Lauf');
// Auch ein laufender Zeitgeber (Zeitstempel gerade gesetzt) sperrt den manuellen Abruf
$check(pseudo_cron_try_claim($pdo, 'cron_fetch_emails_last_run', 3600) === false, 'Zeitstempel ist gerade beansprucht');
// Nach der Sperrzeit wieder möglich; Ergebnis mit neuen Tickets, Antworten, ignorierten Mails
$pdo->prepare("UPDATE settings SET setting_value = ? WHERE setting_key = 'cron_fetch_emails_last_run'")->execute([date('Y-m-d H:i:s', time() - 60)]);
$r = mail_fetch_manual($pdo, $runner(['processed' => 5, 'log' => [
'[Test] Neues Ticket #260301-0001 erstellt (von a@example.de).',
'[Test] Neues Ticket #260301-0002 erstellt (von b@example.de).',
'[Test] Antwort zu Ticket #260101-0005 hinzugefügt (von c@example.de).',
'[Test] → Anhang übernommen: a.pdf',
'[Test] Mail von noreply@example.de ignoriert (eigene Systemmail, würde sonst ein Ticket erzeugen): x',
'[Test] → Anhang nicht übernommen: gross.pdf (zu groß)',
]]));
$check($r['ok'] && $r['level'] === 'success' && $calls === 2 && $r['new_tickets'] === 2 && $r['replies'] === 1 && $r['processed'] === 5, 'Ergebnis wird gezählt: ' . json_encode($r));
$check(str_contains($r['message'], '2 neue(s) Ticket(s)') && str_contains($r['message'], '1 Antwort(en)') && str_contains($r['message'], '2 weitere'), 'Zusammenfassung nennt Tickets, Antworten und Übriges: ' . $r['message']);
$check($r['errors'] === [], 'ein nicht übernommener Anhang ist kein Fehler des Abrufs');
// Fehler: Verbindung zum Postfach schlägt fehl
$pdo->prepare("UPDATE settings SET setting_value = ? WHERE setting_key = 'cron_fetch_emails_last_run'")->execute([date('Y-m-d H:i:s', time() - 60)]);
$r = mail_fetch_manual($pdo, $runner(['processed' => 0, 'log' => ['[Test] IMAP-Verbindung fehlgeschlagen: Login failed (Authentication failure)']]));
$check(!$r['ok'] && $r['level'] === 'error' && str_contains($r['message'], 'Login failed') && !str_contains($r['message'], '[Test]'), 'Verbindungsfehler wird gezeigt: ' . $r['message']);
// Ausnahme im Abruf
$pdo->prepare("UPDATE settings SET setting_value = ? WHERE setting_key = 'cron_fetch_emails_last_run'")->execute([date('Y-m-d H:i:s', time() - 60)]);
$r = mail_fetch_manual($pdo, function () { throw new RuntimeException('Datenbank weg'); });
$check(!$r['ok'] && str_contains($r['message'], 'Datenbank weg'), 'Ausnahme wird als Meldung gezeigt, nicht als Absturz');
// Deaktiviertes Postfach zählt nicht
$pdo->exec('UPDATE imap_accounts SET is_active = 0');
$check(!mail_fetch_available($pdo), 'deaktivierte Postfächer zählen nicht');
if ($failures) {
fwrite(STDERR, "Fehlgeschlagen:\n - " . implode("\n - ", $failures) . "\n");
exit(1);
}
echo "Manual mail fetch checks passed.\n";