OpenNIT

Quelltext des aktuellen Standes

Fassung 1.1.1

PersonSearchTest.php

4 KB
<?php

declare(strict_types=1);

/**
 * Hält die Verzeichnis-Personensuche als eine Komponente zusammen.
 *
 * Die Suche lebt zentral in person-search.js/.css (Prefix `psx-`). Templates
 * dürfen sie nur einbinden, nicht nachbauen: Ein eigener Nachbau driftet im
 * Aussehen auseinander und verliert bei Änderungen an der Komponente den
 * Anschluss.
 */
return static function (): void {

    $tplDir = dirname(__DIR__) . '/templates';

    /** @return string[] Alle Template-Pfade */
    $templates = static function (string $dir): array {
        $out = [];
        $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));
        foreach ($it as $f) {
            if ($f->getExtension() === 'php') {
                $out[] = $f->getPathname();
            }
        }
        sort($out);
        return $out;
    };

    test('Kein Template definiert eigene Personensuche-Klassen', function () use ($templates, $tplDir) {
        // Nachbauten erkennt man an CSS-Regeln für Dropdown, Treffer oder Plakette
        // unter beliebigem Prefix, z. B. `.ps-dropdown` oder `.atm-ps-item`.
        $muster = '/^\s*\.[a-z0-9-]*ps-(dropdown|drop|item|badge|input|no-results|nores)[a-z0-9-]*\s*[,{:]/mi';
        $treffer = [];
        foreach ($templates($tplDir) as $file) {
            if (preg_match_all($muster, file_get_contents($file), $m)) {
                $treffer[] = basename($file) . ': ' . trim($m[0][0]);
            }
        }
        assertSame([], $treffer, 'Eigene Personensuche-Styles: ' . implode(' | ', $treffer));
    });

    test('Jede Seite mit Personensuche lädt die zentrale Komponente', function () use ($templates, $tplDir) {
        // Nur vollständige Seiten (mit Layout-Aufruf) binden Assets ein. Fragmente
        // ohne Layout erben sie von der Seite, die sie nachlädt.
        $fehlend = [];
        foreach ($templates($tplDir) as $file) {
            $src = file_get_contents($file);
            if (!str_contains($src, 'data-person-search') || !str_contains($src, '$this->layout(')) {
                continue;
            }
            if (!str_contains($src, '/assets/js/person-search.js')
                || !str_contains($src, '/assets/css/person-search.css')) {
                $fehlend[] = basename($file);
            }
        }
        assertSame([], $fehlend, 'Komponente nicht eingebunden: ' . implode(', ', $fehlend));
    });

    test('Die Komponente kennt Plakette und Aufheben-Verhalten', function () {
        $js  = file_get_contents(dirname(__DIR__) . '/public/assets/js/person-search.js');
        $css = file_get_contents(dirname(__DIR__) . '/public/assets/css/person-search.css');

        assertTrue(str_contains($js, "getAttribute('data-ps-badge')"));
        assertTrue(str_contains($js, "getAttribute('data-ps-clear')"));
        assertTrue(str_contains($css, '.psx-selected'));
        assertTrue(str_contains($css, '.psx-selected-clear'));
    });

    test('Personensuche-Felder tragen eine gestylte Eingabeklasse', function () use ($templates, $tplDir) {
        // Ein Suchfeld ohne Eingabeklasse fällt auf das Browser-Aussehen zurück –
        // .psx-wrap liefert nur die Positionierung, keine Feldoptik.
        $ohneKlasse = [];
        foreach ($templates($tplDir) as $file) {
            $src = file_get_contents($file);
            if (!str_contains($src, 'data-person-search')) {
                continue;
            }
            // Jedes <input …>-Tag mit dem Attribut prüfen
            preg_match_all('/<input\b[^>]*data-person-search[^>]*>/is', $src, $m);
            foreach ($m[0] as $tag) {
                if (!preg_match('/class\s*=\s*"([^"]*)"/i', $tag, $cm)) {
                    $ohneKlasse[] = basename($file) . ' (kein class-Attribut)';
                    continue;
                }
                $klassen = preg_split('/\s+/', trim($cm[1])) ?: [];
                $gestylt = array_filter($klassen, static fn($c) => $c !== '' && $c !== 'psx-wrap');
                if ($gestylt === []) {
                    $ohneKlasse[] = basename($file) . ' (nur Hilfsklassen)';
                }
            }
        }
        assertSame([], $ohneKlasse, 'Ungestylte Suchfelder: ' . implode(', ', $ohneKlasse));
    });
};