feat: Divi-Adapter sperren je Fähigkeit – ReleaseGate::feature/assertFeature(s), DiviLocked und Ablehnung nennen die betroffenen Fähigkeiten (D6), DiviSaver prüft Seiten schreiben und die Fähigkeit des Speicherbereichs (D5), DesignArea::feature; Test-Standard alle Fähigkeiten freigegeben

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Jan-Niclas Loosen
2026-10-18 22:10:41 +02:00
co-authored by Claude Opus 5.5
parent c4efeb3ba4
commit e387d8d29e
20 changed files with 525 additions and 65 deletions
@@ -11,12 +11,14 @@ use LIT\MCP\Integrations\Divi\Design\DesignPlan;
use LIT\MCP\Integrations\Divi\Design\SnapshotStore;
use LIT\MCP\Integrations\Divi\Design\SnapshotTooLarge;
use LIT\MCP\Integrations\Divi\Library\UsageReport;
use LIT\MCP\Integrations\Divi\Release\DiviFeature;
use LIT\MCP\Integrations\Divi\Release\DiviLocked;
use LIT\MCP\Integrations\Divi\Release\ReleaseGate;
use LIT\MCP\Integrations\Divi\Release\ReleaseState;
use LIT\MCP\Integrations\Divi\Release\ReleaseStatus;
use LIT\MCP\Abilities\WriteFailed;
use LIT\MCP\Tests\Support\FakeChangeLog;
use LIT\MCP\Tests\Support\ReleaseMatrices;
use LIT\MCP\Tests\Unit\TestCase;
use Brain\Monkey\Functions;
use Mockery;
@@ -80,6 +82,11 @@ final class DesignChangeTest extends TestCase
return 'Presets';
}
public function feature(): DiviFeature
{
return DiviFeature::PresetWrite;
}
public function raw(): array
{
return $this->stored;
@@ -383,6 +390,41 @@ final class DesignChangeTest extends TestCase
);
}
public function testTheLockFollowsTheFeatureOfTheArea(): void
{
$others = array_values(array_filter(
DiviFeature::cases(),
static fn (DiviFeature $feature): bool => $feature !== DiviFeature::PresetWrite
));
ReleaseGate::useResolver(static fn (): ReleaseStatus => ReleaseMatrices::status($others));
$stored = ['v' => 1];
$area = self::area($stored);
$snapshots = Mockery::mock(SnapshotStore::class);
$snapshots->expects('save')->andReturn('s1');
$snapshots->expects('attachLog');
$written = (new DesignChange($snapshots, new FakeChangeLog(9)))->run(
'lit/divi-presets-set',
$area,
['confirm' => true, 'design_rev' => $area->rev($stored)],
self::plan(['v' => 2])
);
self::assertTrue($written['ok'], 'every other feature locked: presets are still written');
ReleaseGate::useResolver(static fn (): ReleaseStatus => ReleaseMatrices::status([DiviFeature::PresetWrite]));
try {
(new DesignChange(Mockery::mock(SnapshotStore::class), FakeChangeLog::forbidden()))->run(
'lit/divi-presets-set',
$area,
['confirm' => true, 'design_rev' => $area->rev($stored)],
self::plan(['v' => 3])
);
self::fail('preset-write locked must refuse');
} catch (DiviLocked $locked) {
self::assertSame([DiviFeature::PresetWrite], $locked->features);
}
}
public function testTooLargeSnapshotRefusesTheChange(): void
{
$stored = ['v' => 1];
@@ -7,6 +7,7 @@ namespace LIT\MCP\Tests\Unit\Integrations\Divi\Design;
use LIT\MCP\Integrations\Divi\Design\DesignSystemWriter;
use LIT\MCP\Integrations\Divi\Design\PresetArea;
use LIT\MCP\Integrations\Divi\Design\PresetBook;
use LIT\MCP\Integrations\Divi\Release\DiviFeature;
use LIT\MCP\Tests\Unit\TestCase;
use Mockery;
@@ -23,6 +24,7 @@ final class PresetAreaTest extends TestCase
$area = new PresetArea($writer);
self::assertSame(['presets', 'Presets'], [$area->name(), $area->label()]);
self::assertSame(DiviFeature::PresetWrite, $area->feature());
self::assertSame(PresetBook::fromDivi($stored)->data(), $area->raw());
self::assertSame(PresetBook::fromDivi($stored)->rev(), $area->rev($stored));
self::assertSame(PresetBook::fromDivi($stored)->data(), $area->write($stored, true));