OpenNIT

Quelltext des aktuellen Standes

Fassung 1.1.1

MdmSyncSafetyTest.php

4 KB
<?php

declare(strict_types=1);

use OpenNIT\Services\MdmSyncDefaults;
use OpenNIT\Services\MdmSyncSafety;

/**
 * Deckt die Schutzmechanismen ab, die Relution- und Intune-Sync gemeinsam nutzen:
 * Plausibilitätsgrenze der Ausmusterung und Vorrang eines von Hand gesetzten Status.
 *
 * Maßgeblich ist, dass die Vorgaben das Verhalten bestehender Installationen
 * nicht verändern – deshalb prüfen die Fälle gezielt die Grenzwerte.
 */
return static function (): void {

    /** Erzeugt ein Testobjekt, das den Trait einbindet und seine Methoden freigibt. */
    $subject = static function (): object {
        return new class {
            use MdmSyncSafety;

            public array $log    = [];
            public array $errors = [];

            public function allow(int $candidates, int $managed, int $maxPercent): bool
            {
                return $this->decommissionAllowed($candidates, $managed, $maxPercent);
            }

            public function mayStatus(array $specs, string $current): bool
            {
                return $this->mayOverwriteStatus($specs, $current);
            }

            public function markTruncated(): void
            {
                $this->truncated = true;
            }
        };
    };

    // ----------------------------------------------------------------
    // Plausibilitätsgrenze der Ausmusterung
    // ----------------------------------------------------------------

    test('Ausmusterung: kleine Stückzahlen bleiben unabhängig vom Prozentsatz erlaubt', function () use ($subject) {
        // 10 von 20 sind 50 %, liegen aber unter der absoluten Untergrenze.
        assertTrue($subject()->allow(10, 20, 20));
    });

    test('Ausmusterung: im Rahmen der Grenze erlaubt', function () use ($subject) {
        assertTrue($subject()->allow(30, 1000, 20));   // 3 %
        assertTrue($subject()->allow(200, 1000, 20));  // exakt 20 %
    });

    test('Ausmusterung: oberhalb der Grenze abgelehnt und protokolliert', function () use ($subject) {
        $s = $subject();
        assertFalse($s->allow(400, 1000, 20));         // 40 %
        assertTrue(count($s->log) === 1);
        assertTrue(str_contains($s->log[0], 'Ausmusterung übersprungen'));
    });

    test('Ausmusterung: Grenze 0 schaltet die Prüfung ab', function () use ($subject) {
        assertTrue($subject()->allow(999, 1000, 0));
    });

    test('Ausmusterung: nichts auszumustern ist immer erlaubt', function () use ($subject) {
        assertTrue($subject()->allow(0, 1000, 20));
    });

    test('Ausmusterung: nach einem abgebrochenen Lauf grundsätzlich abgelehnt', function () use ($subject) {
        $s = $subject();
        $s->markTruncated();
        // Selbst ein winziger, sonst unbedenklicher Umfang bleibt gesperrt.
        assertFalse($s->allow(1, 1000, 20));
        assertTrue(str_contains($s->log[0], 'Laufzeitgrenze'));
    });

    test('Ausmusterung: Vorgabewerte sind die dokumentierten', function () {
        assertSame(20, MdmSyncDefaults::DECOMMISSION_MAX_PERCENT);
        assertSame(25, MdmSyncDefaults::DECOMMISSION_MIN_ABSOLUTE);
    });

    // ----------------------------------------------------------------
    // Vorrang eines von Hand gesetzten Status
    // ----------------------------------------------------------------

    test('Status: ohne Merker schreibt der Sync wie bisher', function () use ($subject) {
        // Bestandsverhalten vor der ersten Ausführung mit Merker.
        assertTrue($subject()->mayStatus([], 'active'));
        assertTrue($subject()->mayStatus(['os_name' => 'iOS'], 'storage'));
    });

    test('Status: unveränderter Wert darf weiter gepflegt werden', function () use ($subject) {
        assertTrue($subject()->mayStatus(['mdm_managed_status' => 'active'], 'active'));
    });

    test('Status: von Hand geänderter Wert bleibt stehen', function () use ($subject) {
        assertFalse($subject()->mayStatus(['mdm_managed_status' => 'active'], 'storage'));
    });

    test('Status: ein zurückkehrendes Gerät wird wieder aktiviert', function () use ($subject) {
        // Die Ausmusterung schreibt den Merker mit – der Sync bleibt zuständig.
        assertTrue($subject()->mayStatus(['mdm_managed_status' => 'decommissioned'], 'decommissioned'));
    });
};