OpenNIT

Quelltext des aktuellen Standes

Fassung 1.1.1

NetdiagramSchemaTest.php

3 KB
<?php

declare(strict_types=1);

/**
 * Deckt ab, dass die Netzwerkplan-Spalten jede Instanz erreichen.
 *
 * `001_initial_schema.sql` gilt einer bestehenden Instanz als angewendet und
 * läuft dort nie erneut. Eine Spalte, die ausschließlich dort angelegt wird,
 * entsteht deshalb nur auf Neuinstallationen – auf allen übrigen fehlt sie
 * dauerhaft, und jeder Zugriff darauf endet im internen Fehler. Nachgezogen
 * wird so etwas über eine eigene, höher nummerierte Migration.
 */
return static function (): void {

    $migrationsDir = __DIR__ . '/../database/migrations';

    /** Inhalt aller Migrationen außer der Baseline. */
    $ausserhalbBaseline = static function () use ($migrationsDir): string {
        $text = '';
        foreach ((array)glob($migrationsDir . '/*.sql') as $datei) {
            if (str_starts_with(basename((string)$datei), '001_')) {
                continue;
            }
            $text .= (string)file_get_contents((string)$datei);
        }
        return $text;
    };

    $spalten = ['drawio_xml', 'diagram_format', 'preview_svg'];

    test('Die Netzwerkplan-Spalten werden ausserhalb der Baseline nachgezogen', function () use ($spalten, $ausserhalbBaseline) {
        $text = $ausserhalbBaseline();
        foreach ($spalten as $spalte) {
            assertTrue(
                preg_match('/ADD COLUMN\s+`?' . preg_quote($spalte, '/') . '`?/i', $text) === 1,
                'Die Spalte "' . $spalte . '" entsteht nur in der Baseline und erreicht damit keine bestehende Instanz'
            );
        }
    });

    test('Jede Spalte steht in einer eigenen Anweisung', function () use ($migrationsDir) {
        // Fasst eine Anweisung mehrere Spalten zusammen, verhindert eine
        // bereits vorhandene Spalte das Anlegen der übrigen: der Duplicate-
        // Fehler lässt die gesamte Anweisung scheitern.
        $datei = $migrationsDir . '/244_netdiagram_drawio_columns.sql';
        assertTrue(is_file($datei), 'Die nachziehende Migration fehlt');

        $sql = (string)file_get_contents($datei);
        foreach (explode("\n", $sql) as $zeile) {
            $zeile = trim($zeile);
            if (!str_starts_with(strtoupper($zeile), 'ALTER TABLE')) {
                continue;
            }
            assertSame(1, substr_count(strtoupper($zeile), 'ADD COLUMN'),
                'Diese Anweisung legt mehr als eine Spalte an: ' . $zeile);
        }
    });

    test('Die Migration bleibt bei wiederholtem Lauf harmlos', function () use ($migrationsDir) {
        $sql = strtoupper((string)file_get_contents($migrationsDir . '/244_netdiagram_drawio_columns.sql'));
        // Ein zweiter Lauf darf keine Daten anfassen.
        foreach (['TRUNCATE', 'DROP TABLE', 'DELETE FROM', 'AUTO_INCREMENT ='] as $verboten) {
            assertFalse(str_contains($sql, $verboten), 'Die Migration enthält "' . $verboten . '"');
        }
    });

    test('Code und Schema nennen dieselben Spalten', function () use ($spalten, $migrationsDir) {
        $controller = (string)file_get_contents(__DIR__ . '/../src/Controllers/NetworkDiagramController.php');
        $schema = '';
        foreach ((array)glob($migrationsDir . '/*.sql') as $datei) {
            $schema .= (string)file_get_contents((string)$datei);
        }

        foreach ($spalten as $spalte) {
            assertTrue(str_contains($controller, $spalte), 'Der Controller nutzt "' . $spalte . '" nicht mehr');
            assertTrue(str_contains($schema, '`' . $spalte . '`'), 'Die Spalte "' . $spalte . '" fehlt im Schema');
        }
    });
};