OpenNIT

Quelltext des aktuellen Standes

Fassung 1.1.1

ModuleListLayoutTest.php

4 KB
<?php

declare(strict_types=1);

/**
 * Der Aufbau der Modul-Übersichtsseiten.
 *
 * Der Styleguide gibt eine Reihenfolge vor – Content Header, KPI-Kacheln,
 * Filterleiste, Tabelle – und **eine** Komponentenbibliothek für alles darin.
 * Die Abstände kommen von diesen Komponenten; wo eine Seite sie einzeln
 * nachjustiert, sieht sie anders aus als die daneben, und niemand merkt es,
 * bis jemand beide nebeneinander aufruft.
 *
 * Geprüft wird deshalb, dass keine Übersichtsseite den Seitenkörper zerlegt
 * oder sein Polster überschreibt, und dass die Filterleiste überall denselben
 * Abstand zur Tabelle hält.
 */

return static function (): void {

    $wurzel = dirname(__DIR__);

    /** @return array<string,string> Modulname => Inhalt der Übersichtsseite */
    $seiten = static function () use ($wurzel): array {
        $alle = [];
        foreach ((array)glob($wurzel . '/templates/*/index.php') as $datei) {
            $modul = basename(dirname((string)$datei));
            $alle[$modul] = (string)file_get_contents((string)$datei);
        }
        return $alle;
    };

    test('Es gibt Übersichtsseiten zu prüfen', function () use ($seiten) {
        assertTrue(count($seiten()) > 15, 'Es wurden kaum Übersichtsseiten gefunden');
    });

    test('Eine Seite hat einen Seitenkörper, nicht mehrere', function () use ($seiten) {
        // Zwei Körper übereinander ergeben zwischen ihnen das doppelte Polster;
        // wer das ausgleicht, setzt es an beiden von Hand – und damit anders
        // als jede andere Seite.
        foreach ($seiten() as $modul => $inhalt) {
            $anzahl = substr_count($inhalt, 'class="page-body');
            assertTrue(
                $anzahl <= 1,
                'Die Übersicht von ' . $modul . ' hat ' . $anzahl . ' Seitenkörper'
            );
        }
    });

    test('Der Seitenkörper behält sein Polster', function () use ($seiten) {
        foreach ($seiten() as $modul => $inhalt) {
            assertFalse(
                (bool)preg_match('/class="page-body[^"]*"\s+style="[^"]*padding/', $inhalt),
                'Die Übersicht von ' . $modul . ' überschreibt das Polster des Seitenkörpers'
            );
        }
    });

    test('Die Filterleiste hält überall denselben Abstand zur Tabelle', function () use ($seiten) {
        // `mb-3` ist der Abstand, den die Übersichtsseiten gemeinsam führen.
        // Ein kleinerer rückt die Tabelle enger heran als überall sonst.
        $engere = ['mb-0', 'mb-1', 'mb-2'];

        foreach ($seiten() as $modul => $inhalt) {
            if (!preg_match_all('/class="card card-outline card-primary([^"]*)"/', $inhalt, $treffer)) {
                continue;
            }
            foreach ($treffer[1] as $zusatz) {
                foreach ($engere as $klasse) {
                    assertFalse(
                        (bool)preg_match('/\b' . preg_quote($klasse, '/') . '\b/', $zusatz),
                        'Die Filterleiste von ' . $modul . ' rückt mit ' . $klasse . ' näher an die Tabelle als die übrigen'
                    );
                }
            }
        }
    });

    test('Die Reihenfolge stimmt: erst Kacheln, dann Filter, dann Tabelle', function () use ($seiten) {
        foreach ($seiten() as $modul => $inhalt) {
            // Gemessen wird im Seitenkörper. Davor kann eine Seite eine eigene
            // Karte führen – etwa den Abo-Link eines Kalenders –, die dieselbe
            // Polsterung nutzt, aber keine Filterleiste ist.
            $koerper = strpos($inhalt, 'class="page-body');
            if ($koerper === false) {
                continue;
            }

            $kpi    = strpos($inhalt, 'class="kpi-row', $koerper);
            $filter = strpos($inhalt, 'class="filter-card-body', $koerper);
            $tabs   = strpos($inhalt, 'class="table-wrapper', $koerper);

            if ($kpi !== false && $filter !== false) {
                assertTrue($kpi < $filter, 'Bei ' . $modul . ' steht die Filterleiste vor den Kacheln');
            }
            if ($filter !== false && $tabs !== false) {
                assertTrue($filter < $tabs, 'Bei ' . $modul . ' steht die Tabelle vor der Filterleiste');
            }
        }
    });
};