Steuerkram/tests/76_DatenverzeichnisUebernahmeTest.php

113 lines
5.1 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
declare(strict_types=1);
/**
* Test 76: Übernahme des Altbestands aus uploads/ nach data/belege.
*
* Der Umzug lief früher über "mv uploads/2026 data/belege/". Existierte im Ziel
* bereits ein Jahresverzeichnis, scheiterte das Verschieben (bzw. legte den Baum
* als data/belege/2026/2026 ab) – und weil die Fehler mit "2>/dev/null || true"
* unterdrückt wurden, meldete die Migration trotzdem Erfolg. Ergebnis: eine
* Installation, in der die Belege nicht mehr auffindbar waren.
*
* Der Test führt scripts/intern/uploads-uebernahme.sh real aus und prüft, dass es
* zusammenführt statt zu verschachteln und keine vorhandene Zieldatei überschreibt.
*/
class DatenverzeichnisUebernahmeTest extends TestCase
{
protected string $testName = 'Test 76: Übernahme Altbestand uploads/ -> data/belege';
public function run(): void
{
$skript = dirname(__DIR__) . '/scripts/intern/uploads-uebernahme.sh';
$this->assert(file_exists($skript), 'scripts/intern/uploads-uebernahme.sh existiert');
exec('sh -n ' . escapeshellarg($skript) . ' 2>&1', $syntax, $syntaxExit);
$this->assertEquals(0, $syntaxExit, 'sh-Syntax ist gültig (' . implode(' ', $syntax) . ')');
$inhalt = (string)file_get_contents($skript);
$this->assert(
!preg_match('/\bmv\b[^\n]*2>\/dev\/null\s*\|\|\s*true/', $inhalt),
'Fehler beim Verschieben werden nicht unterdrückt'
);
// Der manuelle Umzug muss dieselbe Logik verwenden wie der Container-Start –
// sonst driftet beides auseinander. docker-entrypoint.sh wird hier bewusst
// nicht geprüft: Die Datei ist nicht als Volume gemountet, im Container läge
// also immer der Stand des Images vor und der Test schlüge nur an, wenn ein
// Rebuild aussteht.
$migration = dirname(__DIR__) . '/scripts/migrate-datenverzeichnis.sh';
$this->assert(
str_contains((string)file_get_contents($migration), 'uploads-uebernahme.sh'),
'migrate-datenverzeichnis.sh verwendet scripts/intern/uploads-uebernahme.sh'
);
// ── Funktionaler Lauf: Ziel enthält bereits ein Jahresverzeichnis ──────
$basis = $this->tempPath();
$alt = $basis . '/uploads';
$neu = $basis . '/belege';
$logo = $basis . '/logo';
mkdir($alt . '/2026/BLG-2026-0001', 0777, true);
mkdir($alt . '/2026/BLG-2026-0099', 0777, true);
mkdir($alt . '/logo', 0777, true);
mkdir($neu . '/2026/BLG-2026-0001', 0777, true);
mkdir($logo, 0777, true);
file_put_contents($alt . '/2026/BLG-2026-0001/original.pdf', 'ALT');
file_put_contents($alt . '/2026/BLG-2026-0099/original.pdf', 'NEU-IM-ALTBESTAND');
file_put_contents($alt . '/logo/logo.png', 'LOGO');
file_put_contents($neu . '/2026/BLG-2026-0001/original.pdf', 'BESTEHEND');
$befehl = 'sh ' . escapeshellarg($skript) . ' '
. escapeshellarg($alt) . ' ' . escapeshellarg($neu) . ' ' . escapeshellarg($logo) . ' 2>&1';
exec($befehl, $ausgabe, $exitCode);
$ausgabeText = implode("\n", $ausgabe);
$this->assert(
is_file($neu . '/2026/BLG-2026-0099/original.pdf'),
'Beleg aus dem Altbestand landet im bestehenden Jahresverzeichnis'
);
$this->assertEquals(
'NEU-IM-ALTBESTAND',
(string)file_get_contents($neu . '/2026/BLG-2026-0099/original.pdf'),
'Übernommener Beleg ist inhaltlich unverändert'
);
$this->assert(
!is_dir($neu . '/2026/2026'),
'Der Baum wird nicht als data/belege/2026/2026 verschachtelt'
);
$this->assertEquals(
'LOGO',
(string)file_get_contents($logo . '/logo.png'),
'Das Logo wandert nach data/logo und nicht in die Belege'
);
$this->assert(
!is_file($neu . '/logo/logo.png'),
'Das Logo liegt nicht zusätzlich als Beleg vor'
);
// Kollision: bestehende Zieldatei bleibt, Quelldatei geht nicht verloren.
$this->assertEquals(
'BESTEHEND',
(string)file_get_contents($neu . '/2026/BLG-2026-0001/original.pdf'),
'Vorhandene Zieldatei wird nicht überschrieben'
);
$this->assert(
is_file($alt . '/2026/BLG-2026-0001/original.pdf'),
'Kollidierende Quelldatei bleibt zur Prüfung liegen statt verloren zu gehen'
);
$this->assert(
str_contains($ausgabeText, 'übersprungen'),
'Die Kollision wird gemeldet und nicht stillschweigend übergangen'
);
$this->assertEquals(1, $exitCode, 'Verbliebene Reste melden einen Fehler-Exitcode');
// ── Zweiter Lauf ohne Altbestand: nichts zu tun, sauberer Exitcode ────
$leer = $basis . '/leer';
mkdir($leer, 0777, true);
exec('sh ' . escapeshellarg($skript) . ' ' . escapeshellarg($leer) . ' '
. escapeshellarg($neu) . ' ' . escapeshellarg($logo) . ' 2>&1', $zweite, $zweiterExit);
$this->assertEquals(0, $zweiterExit, 'Lauf ohne Altbestand endet mit Exitcode 0');
}
}