'Landingpage', 'path' => 'landing.php', 'contains' => ['Kaffeeliste', 'Kundenkonto anlegen', 'Mandantenfaehig'], ], [ 'label' => 'Dashboard', 'path' => 'index.php', 'contains' => ['Hallo Test Admin', 'Aktueller Stand'], ], [ 'label' => 'Striche erfassen', 'path' => 'stricheintragen.php', 'contains' => ['Anzahl der Striche'], ], [ 'label' => 'Einzahlungen erfassen', 'path' => 'einzahlung.php', 'contains' => ['Einzahlungen'], ], [ 'label' => 'Kaffeeliste', 'path' => 'kaffeeliste.php', 'contains' => ['Aktive Mitarbeiter'], ], [ 'label' => 'Ledger Preview', 'path' => 'ledger-preview.php', 'contains' => ['Ledger Preview', 'Tenant-Summen', 'Letzte Ledger-Buchungen'], ], [ 'label' => 'Mitgliederverwaltung', 'path' => 'mitarbeiterverwalten.php', 'contains' => ['Mitglieder verwalten', 'PayPal-Name'], ], [ 'label' => 'Letzte Eintraege', 'path' => 'letzteneintraege.php', 'contains' => ['Letzte 100 Einzahlungen'], ], [ 'label' => 'CSV-Upload', 'path' => 'csvupload.php', 'contains' => ['CSV Verarbeitung'], ], [ 'label' => 'Hinweise', 'path' => 'hinweise.php', 'contains' => ['Kaffeeliste - Hinweise'], ], [ 'label' => 'FAQ', 'path' => 'faq.php', 'contains' => ['FAQ - Kaffeeliste'], ], [ 'label' => 'Login', 'path' => 'login.php', 'contains' => ['Login', 'Registrieren', 'Passwort vergessen'], ], [ 'label' => 'Registrierung', 'path' => 'register.php', 'contains' => ['Registrierung', 'Kundenkonto anlegen'], ], [ 'label' => 'Passwort vergessen', 'path' => 'passwort-vergessen.php', 'contains' => ['Passwort vergessen', 'Link vorbereiten'], ], [ 'label' => 'Mandantenauswahl Login-Schutz', 'path' => 'mandant-auswahl.php', 'contains' => ['Login'], ], [ 'label' => 'Passwort zuruecksetzen Invalid', 'path' => 'passwort-zuruecksetzen.php', 'contains' => ['Passwort zuruecksetzen', 'ungueltig oder abgelaufen'], ], [ 'label' => 'E-Mail verifizieren Invalid', 'path' => 'email-verifizieren.php', 'contains' => ['E-Mail verifizieren', 'ungueltig oder abgelaufen'], ], [ 'label' => 'Mandant-Einstellungen Login-Schutz', 'path' => 'mandant-einstellungen.php', 'contains' => ['Login'], ], [ 'label' => 'Namensanpassung', 'path' => 'namenanpassen.php', 'contains' => ['Anzeigenamen aktualisieren'], ], [ 'label' => 'Teilnehmerauswertung', 'path' => 'teilnehmerauswertung.php?user_id=1', 'contains' => ['Auswertung', 'Test Admin'], ], [ 'label' => 'Mailausgabe', 'path' => 'mailausgebe.php', 'contains' => ['admin@test.local'], ], [ 'label' => 'Umfrage', 'path' => 'umfrage.php', 'contains' => ['Kaffeeliste', 'Danke'], ], [ 'label' => 'Umfrageergebnisse', 'path' => 'umfrageergebnisse.php', 'contains' => ['Umfrage', 'Ergebnisse'], ], ]; $knownIssueChecks = [ [ 'label' => 'PDF-Export', 'path' => 'exportKaffeeliste.php', 'expected_issue' => '~TCPDF/include/tcpdf_font_data\.php|Failed opening required .*/TCPDF/include/~i', 'reason' => 'TCPDF ist im Repo nur teilweise vorhanden; das include-Verzeichnis fehlt.', ], ]; $skippedUnsafe = [ [ 'path' => 'mailversenden.php', 'reason' => 'GET kann bei vollstaendiger PHPMailer-Installation E-Mails versenden.', ], [ 'path' => 'jahresauswertung.php', 'reason' => 'GET kann Jahresbuchungen schreiben und E-Mails versenden; PHPMailer-Abhaengigkeit ist zudem unvollstaendig.', ], ]; function smoke_fetch(string $url): array { $context = stream_context_create([ 'http' => [ 'method' => 'GET', 'timeout' => 15, 'ignore_errors' => true, 'header' => "User-Agent: KaffeelisteHttpSmoke/1.0\r\n", ], ]); $body = @file_get_contents($url, false, $context); $headers = $http_response_header ?? []; $status = 0; foreach ($headers as $header) { if (preg_match('~^HTTP/\S+\s+(\d{3})~', $header, $matches) === 1) { $status = (int)$matches[1]; } } if ($body === false) { $error = error_get_last(); return [ 'status' => $status, 'body' => '', 'error' => $error['message'] ?? 'Unknown HTTP error', ]; } return [ 'status' => $status, 'body' => $body, 'error' => null, ]; } function smoke_url(string $baseUrl, string $path): string { return $baseUrl . '/' . ltrim($path, '/'); } $failures = []; $passes = 0; echo "HTTP smoke base URL: {$baseUrl}\n"; foreach ($checks as $check) { $url = smoke_url($baseUrl, $check['path']); $response = smoke_fetch($url); $label = $check['label'] . ' (' . $check['path'] . ')'; if ($response['error'] !== null) { $failures[] = "{$label}: {$response['error']}"; echo "FAIL {$label}\n"; continue; } if ($response['status'] !== 200) { $failures[] = "{$label}: expected HTTP 200, got HTTP {$response['status']}"; echo "FAIL {$label}\n"; continue; } if (preg_match($issuePattern, $response['body'], $matches) === 1) { $failures[] = "{$label}: PHP issue marker found ({$matches[0]})"; echo "FAIL {$label}\n"; continue; } foreach ($check['contains'] as $needle) { if (!str_contains($response['body'], $needle)) { $failures[] = "{$label}: expected text not found: {$needle}"; echo "FAIL {$label}\n"; continue 2; } } $passes++; echo "PASS {$label}\n"; } foreach ($knownIssueChecks as $check) { $url = smoke_url($baseUrl, $check['path']); $response = smoke_fetch($url); $label = $check['label'] . ' (' . $check['path'] . ')'; if ($response['error'] !== null) { echo "KNOWN {$label}: {$check['reason']} ({$response['error']})\n"; continue; } if (preg_match($check['expected_issue'], $response['body']) === 1) { echo "KNOWN {$label}: {$check['reason']}\n"; continue; } if ($response['status'] === 200 && preg_match($issuePattern, $response['body']) !== 1) { echo "RESOLVED {$label}: bitte in die regulaeren Smoke-Checks aufnehmen.\n"; continue; } $failures[] = "{$label}: unexpected response while checking known issue"; echo "FAIL {$label}\n"; } foreach ($skippedUnsafe as $skip) { echo "SKIP {$skip['path']}: {$skip['reason']}\n"; } if ($failures !== []) { echo "\nHTTP smoke failed with " . count($failures) . " failure(s):\n"; foreach ($failures as $failure) { echo "- {$failure}\n"; } exit(1); } echo "\nHTTP smoke passed with {$passes} checked pages.\n";