79 lines
4.4 KiB
PHP
79 lines
4.4 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
/**
|
|
* Prüft, dass der Administrator eine Mail bekommt, wenn ein Plugin Fehler wirft oder wegen Fehlern abgeschaltet wird, und wenn ein
|
|
* Hintergrundjob scheitert, mit Drosselung und Ausschalter.
|
|
*/
|
|
|
|
$pluginDir = sys_get_temp_dir() . '/deskhub-pm-' . bin2hex(random_bytes(4));
|
|
mkdir($pluginDir, 0755, true);
|
|
putenv('DESKHUB_PLUGINS_DIR=' . $pluginDir);
|
|
putenv('DESKHUB_TESTING=1');
|
|
putenv('DESKHUB_CATALOG_DEFAULTS=' . __DIR__ . '/fixtures/no-catalog.php');
|
|
putenv('DESKHUB_SQLITE_PATH=:memory:');
|
|
require_once dirname(__DIR__) . '/includes/bootstrap.php';
|
|
|
|
$failures = [];
|
|
$check = function (bool $ok, string $what) use (&$failures): void {
|
|
if (!$ok) $failures[] = $what;
|
|
};
|
|
$pdo = get_db();
|
|
set_setting('admin_email', 'admin@firma.example');
|
|
$mails = [];
|
|
$GLOBALS['error_alert_send'] = function (string $to, string $subject, string $html) use (&$mails): bool { $mails[] = compact('to', 'subject', 'html'); return true; };
|
|
|
|
$zipPath = sys_get_temp_dir() . '/pm-' . bin2hex(random_bytes(3)) . '.zip';
|
|
$zip = new ZipArchive();
|
|
$zip->open($zipPath, ZipArchive::CREATE);
|
|
$zip->addFromString('mailprobe/plugin.json', json_encode(['slug' => 'mailprobe', 'name' => 'Mail-Probe', 'version' => '1.0.0', 'permissions' => ['hooks.cron']]));
|
|
$zip->addFromString('mailprobe/plugin.php', "<?php\nplugin_add_hook('cron.run', function () { throw new RuntimeException('Spalte fehlt: first_fail_at'); });\n");
|
|
$zip->close();
|
|
$check(plugin_install_zip($pdo, $zipPath)['ok'] && plugin_set_active($pdo, 'mailprobe', true, ['hooks.cron'])['ok'], 'Test-Plugin installiert und aktiv');
|
|
$state = &plugin_state();
|
|
$state['booted'] = false;
|
|
plugins_boot();
|
|
|
|
// 1. Fehler: Mail „meldet einen Fehler“
|
|
plugin_hook('cron.run');
|
|
$check(count($mails) === 1 && $mails[0]['to'] === 'admin@firma.example' && str_contains($mails[0]['subject'], 'Plugin „Mail-Probe“ meldet einen Fehler'), 'erster Fehler: Mail an den Administrator: ' . json_encode(array_column($mails, 'subject'), JSON_UNESCAPED_UNICODE));
|
|
$h = $mails[0]['html'] ?? '';
|
|
$check(str_contains($h, 'Spalte fehlt: first_fail_at') && str_contains($h, 'Fehler 1 von ' . PLUGIN_FAIL_LIMIT) && str_contains($h, 'plugins/mailprobe') && !str_contains($h, 'Zeile 0') && !str_contains($h, 'Die aufgerufene Seite konnte nicht angezeigt werden'), 'Inhalt nennt Plugin, Fehlertext und Zähler, ohne die Seiten-Formulierung');
|
|
// 2. Derselbe Fehler noch einmal: gedrosselt
|
|
plugin_hook('cron.run');
|
|
$check(count($mails) === 1, 'derselbe Fehler wird nicht noch einmal gemailt (höchstens einmal pro Stunde)');
|
|
// 3. Abschaltung nach dem dritten Fehler: eigene Mail
|
|
plugin_hook('cron.run');
|
|
$row = plugins_installed($pdo)['mailprobe'];
|
|
$check((int) $row['is_active'] === 0 && (int) $row['fail_count'] >= PLUGIN_FAIL_LIMIT, 'Plugin ist nach den Fehlern deaktiviert');
|
|
$off = array_values(array_filter($mails, fn($m) => str_contains($m['subject'], 'wurde wegen Fehlern deaktiviert')));
|
|
$check(count($off) === 1 && str_contains($off[0]['html'], 'automatisch deaktiviert') && str_contains($off[0]['html'], 'mailprobe'), 'Mail „wegen Fehlern deaktiviert“ kommt trotz Drosselung (eigener Betreff)');
|
|
|
|
// Ausschalter
|
|
set_setting('error_alert', '0');
|
|
$before = count($mails);
|
|
plugin_record_failure('mailprobe', 'Ein ganz anderer Fehler');
|
|
$check(count($mails) === $before, 'bei ausgeschalteter Fehler-Mail wird nichts gesendet');
|
|
set_setting('error_alert', '1');
|
|
|
|
// Hintergrundjob: Meldung
|
|
error_alert_notice('Hintergrundjob „x“ ist fehlgeschlagen', 'Der Hintergrundjob „x“ hat einen Fehler gemeldet.', 'cron/x.php', 'Verbindung abgelehnt');
|
|
$last = end($mails);
|
|
$check(str_contains($last['subject'], 'Hintergrundjob „x“ ist fehlgeschlagen') && str_contains($last['html'], 'Verbindung abgelehnt'), 'fehlgeschlagene Hintergrundjobs werden gemeldet');
|
|
// Wirkt auch im eingebauten Hintergrund-Betrieb
|
|
$pc = (string) file_get_contents(dirname(__DIR__) . '/includes/pseudo_cron.php');
|
|
$check(str_contains($pc, 'error_alert_notice('), 'der eingebaute Hintergrund-Betrieb meldet fehlgeschlagene Jobs');
|
|
|
|
unset($GLOBALS['error_alert_send']);
|
|
foreach (scandir($pluginDir) ?: [] as $entry) {
|
|
if ($entry === '.' || $entry === '..') continue;
|
|
is_dir($pluginDir . '/' . $entry) ? plugin_rmdir($pluginDir . '/' . $entry) : @unlink($pluginDir . '/' . $entry);
|
|
}
|
|
@rmdir($pluginDir);
|
|
@unlink($zipPath);
|
|
if ($failures) {
|
|
fwrite(STDERR, "Fehlgeschlagen:\n - " . implode("\n - ", $failures) . "\n");
|
|
exit(1);
|
|
}
|
|
echo 'Plugin error mail checks passed.' . "\n";
|