Steuerkram an den e2e-runner angebunden (tests/e2e/, 44 Playwright-Tests). Der erste Smoke-Lauf fand zwei Seiten mit HTTP 500: AccountController::create las $_GET['from'] ungeprüft, assets/form.php nutzte $testMode und $defaultKontoId außerhalb des Bearbeiten-Zweigs. Beides war bis zur Fehler-Härtung (#142) nur eine stille Warning. Test 67 räumt sein Belegverzeichnis jetzt mit ab - es blieb als root-eigenes Verzeichnis liegen und blockierte spätere echte Uploads mit HTTP 500. Test 77 (neu) sichert die Löschsperre von Beleg::delete() ab.
105 lines
2.9 KiB
PHP
105 lines
2.9 KiB
PHP
#!/usr/bin/env php
|
||
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
/**
|
||
* Entfernt liegengebliebene E2E-Testdaten.
|
||
*
|
||
* Die E2E-Tests räumen ihre Datensätze selbst wieder ab. Bricht ein Lauf
|
||
* vorzeitig ab, können markierte Reste zurückbleiben — die holt dieses Skript.
|
||
* Erkannt wird ausschließlich der Marker "E2E-TEST" (siehe tests/e2e/helpers/app.js);
|
||
* echte Buchführungsdaten bleiben unangetastet.
|
||
*
|
||
* Verwendung:
|
||
* docker compose exec web php scripts/e2e-cleanup.php # nur anzeigen
|
||
* docker compose exec web php scripts/e2e-cleanup.php --force # wirklich löschen
|
||
*/
|
||
|
||
$projectRoot = dirname(__DIR__);
|
||
if (!file_exists($projectRoot . '/vendor/autoload.php')) {
|
||
fwrite(STDERR, "Fehler: vendor/autoload.php nicht gefunden. Bitte 'composer install' ausführen.\n");
|
||
exit(1);
|
||
}
|
||
|
||
require $projectRoot . '/vendor/autoload.php';
|
||
\Steuerkram\Config::load();
|
||
|
||
use Steuerkram\Database;
|
||
use Steuerkram\Models\Beleg;
|
||
use Steuerkram\Models\Invoice;
|
||
use Steuerkram\Models\Setting;
|
||
|
||
const MARKER = 'E2E-TEST%';
|
||
|
||
$force = in_array('--force', array_slice($argv, 1), true);
|
||
|
||
if (!Setting::isTestMode()) {
|
||
fwrite(STDERR, "Abbruch: Die Instanz läuft nicht im Testmodus – hier wird nichts gelöscht.\n");
|
||
exit(1);
|
||
}
|
||
|
||
$belege = Database::fetchAll(
|
||
'SELECT id, beleg_nr, filename FROM belege WHERE notes LIKE ? OR filename LIKE ?',
|
||
[MARKER, MARKER]
|
||
);
|
||
|
||
$rechnungen = Database::fetchAll(
|
||
'SELECT id, rechnungs_nr, betreff, status FROM invoices WHERE betreff LIKE ?',
|
||
[MARKER]
|
||
);
|
||
|
||
if (!$belege && !$rechnungen) {
|
||
echo "Keine E2E-Testdaten gefunden.\n";
|
||
exit(0);
|
||
}
|
||
|
||
echo 'Gefunden: ' . count($belege) . ' Beleg(e), ' . count($rechnungen) . " Rechnung(en).\n";
|
||
|
||
foreach ($belege as $b) {
|
||
echo " Beleg #{$b['id']} {$b['beleg_nr']} ({$b['filename']})\n";
|
||
}
|
||
foreach ($rechnungen as $r) {
|
||
$nr = $r['rechnungs_nr'] ?: 'Entwurf';
|
||
echo " Rechnung #{$r['id']} {$nr} [{$r['status']}] {$r['betreff']}\n";
|
||
}
|
||
|
||
if (!$force) {
|
||
echo "\nNichts gelöscht. Zum Löschen erneut mit --force aufrufen.\n";
|
||
exit(0);
|
||
}
|
||
|
||
$geloescht = ['belege' => 0, 'rechnungen' => 0];
|
||
$fehler = [];
|
||
|
||
foreach ($rechnungen as $r) {
|
||
try {
|
||
Invoice::delete((int)$r['id']);
|
||
$geloescht['rechnungen']++;
|
||
} catch (\Throwable $e) {
|
||
$fehler[] = "Rechnung #{$r['id']}: " . $e->getMessage();
|
||
}
|
||
}
|
||
|
||
foreach ($belege as $b) {
|
||
$id = (int)$b['id'];
|
||
// Buchungen zuerst – sonst verweigert Beleg::delete() die Löschung.
|
||
Database::execute('DELETE FROM bookings WHERE beleg_id = ?', [$id]);
|
||
Database::execute('UPDATE belege SET locked = 0 WHERE id = ?', [$id]);
|
||
|
||
if (Beleg::delete($id)) {
|
||
$geloescht['belege']++;
|
||
} else {
|
||
$fehler[] = "Beleg #{$id} konnte nicht gelöscht werden.";
|
||
}
|
||
}
|
||
|
||
echo "\nGelöscht: {$geloescht['belege']} Beleg(e), {$geloescht['rechnungen']} Rechnung(en).\n";
|
||
|
||
if ($fehler) {
|
||
echo "Nicht gelöscht:\n";
|
||
foreach ($fehler as $f) {
|
||
echo " - {$f}\n";
|
||
}
|
||
exit(1);
|
||
}
|