OpenNIT

Quelltext des aktuellen Standes

Fassung 1.1.1

NavLayoutTest.php

4 KB
<?php

declare(strict_types=1);

use OpenNIT\Controllers\ApiController;

/**
 * Deckt das benutzerdefinierte Menü-Layout ab (Einstellung nav_layout).
 *
 * Schwerpunkte: serverseitige Normalisierung der Editor-Eingabe (nur bekannte
 * Struktur, begrenzte Längen, keine doppelten Menüpunkte) und die Verkabelung
 * von Speicher-Endpunkt, Render-Daten und Frontend-Layout.
 */
return static function (): void {

    $normalize = function (string $raw): ?string {
        $ref = new ReflectionClass(ApiController::class);
        $ctrl = $ref->newInstanceWithoutConstructor();
        $m = $ref->getMethod('normalizeNavLayout');
        $m->setAccessible(true);
        return $m->invoke($ctrl, $raw);
    };

    test('Gültiges Layout wird normalisiert übernommen', function () use ($normalize) {
        $out = $normalize('{"groups":[{"label":" Meine Tools ","items":["tickets","vault"]},{"label":"","items":["topics"]}]}');
        assertTrue($out !== null);
        $decoded = json_decode((string)$out, true);
        assertSame('Meine Tools', $decoded['groups'][0]['label']);
        assertSame(['tickets', 'vault'], $decoded['groups'][0]['items']);
        assertSame('', $decoded['groups'][1]['label']);
        assertSame(['topics'], $decoded['groups'][1]['items']);
    });

    test('Doppelte Menüpunkte werden nur einmal übernommen', function () use ($normalize) {
        $out = $normalize('{"groups":[{"label":"A","items":["tickets"]},{"label":"B","items":["tickets","ipam"]}]}');
        $decoded = json_decode((string)$out, true);
        assertSame(['tickets'], $decoded['groups'][0]['items']);
        assertSame(['ipam'], $decoded['groups'][1]['items']);
    });

    test('Ungültige Strukturen werden abgewiesen', function () use ($normalize) {
        assertTrue($normalize('kein json') === null);
        assertTrue($normalize('{"foo":1}') === null);
        assertTrue($normalize('{"groups":"x"}') === null);
        assertTrue($normalize('{"groups":[1,2]}') === null);
        assertTrue($normalize(str_repeat('a', 9000)) === null);
        // mehr als 20 Gruppen
        $many = ['groups' => array_fill(0, 21, ['label' => 'x', 'items' => []])];
        assertTrue($normalize(json_encode($many)) === null);
    });

    test('Labels werden gekürzt, unbekannte Item-Formen verworfen', function () use ($normalize) {
        $out = $normalize(json_encode(['groups' => [[
            'label' => str_repeat('L', 60),
            'items' => ['tickets', 'BÖSE KEY', '<script>', 123, 'ipam'],
        ]]]));
        $decoded = json_decode((string)$out, true);
        assertSame(40, mb_strlen($decoded['groups'][0]['label']));
        assertSame(['tickets', 'ipam'], $decoded['groups'][0]['items']);
    });

    test('Speicher-Endpunkt erlaubt nav_layout und validiert', function () {
        $src = file_get_contents(dirname(__DIR__) . '/src/Controllers/ApiController.php');
        assertTrue(str_contains($src, "'nav_layout'"));
        assertTrue(str_contains($src, 'normalizeNavLayout'));
    });

    test('Render-Datenfluss und Layout kennen nav_layout', function () {
        $root = dirname(__DIR__);
        assertTrue(str_contains(file_get_contents($root . '/src/Controllers/BaseController.php'), "\$data['nav_layout']"));
        assertTrue(str_contains(file_get_contents($root . '/src/Core/Application.php'), "\$data['nav_layout']"));
        $layout = file_get_contents($root . '/templates/layouts/main.php');
        assertTrue(str_contains($layout, '$navCustomGroups'));
        assertTrue(str_contains($layout, 'navCustomToggle'));
        assertTrue(str_contains($layout, "postSetting('nav_layout'"));
        // Dashboard bleibt außerhalb der konfigurierbaren Bereiche fest verankert
        assertTrue(str_contains($layout, '<!-- Dashboard -->'));
    });
};