Files
deskhub/DeskHub-Webseite/tests/mail_design.php
T
2026-11-05 21:21:55 +00:00

67 lines
4.7 KiB
PHP

<?php
declare(strict_types=1);
/**
* Prüft das E-Mail-Design (includes/mailer.php): Aufbau für Outlook und Handys, Knopf mit Outlook-Ersatz, Platzhalter, Escaping von Name und Logo
* und dass keine Layout-Mittel benutzt werden, die Outlook ignoriert (Flexbox, Grid, position, <style>-Blöcke).
*/
putenv('DESKHUB_TESTING=1');
putenv('DESKHUB_SQLITE_PATH=:memory:');
require_once dirname(__DIR__) . '/includes/bootstrap.php';
$failures = [];
$total = 0;
$check = function (bool $ok, string $what) use (&$failures, &$total): void {
$total++;
if (!$ok) $failures[] = $what;
};
set_setting('display_name', 'Muster <b>Support</b> & Co');
set_setting('site_url', 'https://support.example.de');
set_setting('logo_path', '');
$html = email_wrap(email_p('Hallo') . email_badge('Ticket', '#123') . email_button('Ticket ansehen', 'https://support.example.de/t?n=1&x=2'));
$check(str_contains($html, 'width="600"') && str_contains($html, 'max-width:600px'), 'feste Breite 600 für Outlook, auf kleinen Bildschirmen schrumpfend');
$check(substr_count($html, 'role="presentation"') >= 4, 'Layout besteht aus Tabellen');
$check(!preg_match('/display\s*:\s*(flex|grid)|position\s*:\s*(absolute|fixed)|<style|@media|float\s*:/i', $html), 'keine Layout-Mittel, die Outlook ignoriert');
$check(str_contains($html, 'Muster &lt;b&gt;Support&lt;/b&gt; &amp; Co') && !str_contains($html, '<b>Support</b>'), 'Name der Seite wird maskiert');
$check(str_contains($html, '<!--[if mso]><v:roundrect') && str_contains($html, 'href="https://support.example.de/t?n=1&x=2"'), 'Knopf hat einen Ersatz für Outlook (VML) und den Link');
$check(preg_match('/<a href="[^"]+" style="display:inline-block;padding:14px 30px/', $html) === 1, 'Knopf ist sonst ein Link mit Innenabstand');
$check(preg_match('#<table[^>]*width="100%"[^>]*>\s*<tr>\s*<td width="5"#', $html) === 1, 'Ticketkarte nutzt die volle Breite mit Farbbalken');
$check(str_contains($html, 'bgcolor="#0f6f6a"'), 'Farben stehen auch als bgcolor (für ältere Clients)');
$check(!str_contains($html, 'src='), 'ohne Logo kein Bild');
// Logo
set_setting('logo_path', '/uploads/logo.png');
$withLogo = email_wrap('x');
$check(str_contains($withLogo, '<img src="https://support.example.de/uploads/logo.png"') && str_contains($withLogo, 'Muster &lt;b&gt;'), 'Logo mit absoluter Adresse, daneben der Name');
set_setting('logo_hide_name', '1');
$logoOnly = email_wrap('x');
$check(str_contains($logoOnly, '<img src=') && !str_contains($logoOnly, 'Muster &lt;b&gt;Support&lt;/b&gt; &amp; Co</span>'), 'Nur das Logo, wenn der Name ausgeblendet ist');
set_setting('logo_path', 'javascript:alert(1)');
$bad = email_wrap('x');
$check(!str_contains($bad, 'javascript:') && !str_contains($bad, '<img'), 'Ungültige Logo-Adresse wird ignoriert');
set_setting('logo_path', ''); set_setting('logo_hide_name', '0');
// Standardvorlagen: Platzhalter werden ersetzt, auch im Outlook-Ersatz des Knopfes
$vars = ['ticket_number' => 'T-1', 'subject' => 'Betreff', 'customer_name' => 'Erika', 'customer_email' => 'e@example.org', 'department_name' => 'Technik', 'ticket_url' => 'https://support.example.de/x?n=T-1',
'lookup_url' => 'https://support.example.de/l', 'message' => '<p>Antwort</p>', 'close_note' => '', 'transcript' => ''];
foreach ([
'ticket_created' => email_ticket_created_default_body(), 'new_reply' => email_new_reply_default_body(), 'new_ticket_department' => email_new_ticket_department_default_body(),
'ticket_overdue' => email_ticket_overdue_default_body(), 'live_chat_transcript' => email_live_chat_transcript_default_body(), 'customer_reminder' => email_customer_reminder_default_body(),
] as $key => $default) {
[$subject, $body] = render_email_template($key, $vars, 'x', $default);
$full = email_wrap($body);
$check(!preg_match('/\{[a-z_]+\}/', $full), "Vorlage {$key}: alle Platzhalter ersetzt");
$check(substr_count($full, 'https://support.example.de/x?n=T-1') >= 2 || $key === 'ticket_overdue' || str_contains($full, 'x?n=T-1'), "Vorlage {$key}: Knopf-Link enthalten");
$check(preg_match('/<h2 /', $full) === 1, "Vorlage {$key}: hat eine Überschrift");
}
$reset = email_password_reset_body('https://support.example.de/reset?t=abc');
$check(str_contains($reset, 'Passwort zurücksetzen') && str_contains($reset, 'reset?t=abc') && str_contains($reset, 'width="600"'), 'Passwort-Mail im neuen Rahmen mit Knopf');
$check(str_contains(email_ticket_overdue_default_body(), '#b91c1c') && str_contains(email_ticket_overdue_default_body(), '#dc2626'), 'Überfällig-Mail bleibt rot');
echo $failures ? "FEHLGESCHLAGEN:\n - " . implode("\n - ", $failures) . "\n" : '';
echo "Mail-Design-Test: " . ($total - count($failures)) . " von {$total} Prüfungen in Ordnung.\n";
exit($failures ? 1 : 0);