77 lines
4.7 KiB
PHP
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";
|