OpenNIT

Quelltext des aktuellen Standes

Fassung 1.1.1

SchemaInspectorTest.php

3 KB
<?php

declare(strict_types=1);

use OpenNIT\Core\SchemaInspector;

/**
 * Prüft den (DB-freien) Schema-Parser des SchemaInspector gegen die echten
 * Migrationsdateien. Fängt u. a. die „ticket_email_templates.body"-Klasse ab
 * (TEXT-Spalte, die von außen verkleinert zum Migrationsabbruch führt).
 */
return static function (): void {

    $migrationsDir = dirname(__DIR__) . '/database/migrations';

    // Ohne DB konstruieren (inspect() braucht die DB nicht – expectedSchema() liest nur Dateien)
    $ref  = new ReflectionClass(SchemaInspector::class);
    $insp = $ref->newInstanceWithoutConstructor();
    $prop = $ref->getProperty('migrationsDir');
    $prop->setAccessible(true);
    $prop->setValue($insp, $migrationsDir);

    $method = $ref->getMethod('expectedSchema');
    $method->setAccessible(true);
    /** @var array{tables:string[],wide_columns:array<string,array{type:string,cap:int}>} $exp */
    $exp = $method->invoke($insp);

    test('expectedSchema: erkennt viele Tabellen', function () use ($exp) {
        assertTrue(count($exp['tables']) > 100, 'Es sollten >100 Tabellen erkannt werden, erkannt: ' . count($exp['tables']));
    });

    test('expectedSchema: ticket_email_templates ist bekannt', function () use ($exp) {
        assertTrue(in_array('ticket_email_templates', $exp['tables'], true), 'ticket_email_templates fehlt in der Tabellenliste');
    });

    test('expectedSchema: ticket_email_templates.body = TEXT (Incident-Spalte)', function () use ($exp) {
        $col = $exp['wide_columns']['ticket_email_templates.body'] ?? null;
        assertTrue($col !== null, 'body-Spalte wird nicht überwacht');
        assertSame('text', $col['type']);
        assertSame(65535, $col['cap']);
    });

    test('expectedSchema: ALTER MODIFY wird berücksichtigt (ticket_replies.body = LONGTEXT)', function () use ($exp) {
        $col = $exp['wide_columns']['ticket_replies.body'] ?? null;
        assertTrue($col !== null, 'ticket_replies.body wird nicht überwacht');
        assertSame('longtext', $col['type'], 'Die spätere ALTER … MODIFY LONGTEXT muss gewinnen');
    });

    test('expectedSchema: BLOB-Spalten werden überwacht (vault_entry_files.data_enc = MEDIUMBLOB)', function () use ($exp) {
        $col = $exp['wide_columns']['vault_entry_files.data_enc'] ?? null;
        assertTrue($col !== null, 'data_enc wird nicht überwacht');
        assertSame('mediumblob', $col['type']);
    });

    test('expectedSchema: per DROP TABLE entfernte Tabelle gilt NICHT als erwartet (ai_context_keywords)', function () use ($exp) {
        assertFalse(in_array('ai_context_keywords', $exp['tables'], true),
            'ai_context_keywords wird in 001 erstellt und später gedroppt – darf nicht als erwartet/fehlend gelten');
    });

    test('expectedSchema: schmale Spalten werden NICHT überwacht (kein VARCHAR(50))', function () use ($exp) {
        foreach ($exp['wide_columns'] as $key => $col) {
            assertTrue($col['cap'] >= 65535, "Nur TEXT/BLOB+ überwachen, aber {$key} hat cap={$col['cap']}");
        }
    });
};