fix(audit L4): Restore-Planer für Farben, Variablen und Presets berechnen die Fundstellen (affected, P8a blocked_ids) für geänderte, entfernte und deaktivierte Einträge

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Jan-Niclas Loosen
2026-10-20 00:03:28 +02:00
co-authored by Claude Sonnet 5.5
parent 4a8a889f93
commit bd80ab1394
10 changed files with 274 additions and 26 deletions
@@ -8,15 +8,21 @@ use LIT\MCP\Integrations\Divi\Design\DesignPlan;
use LIT\MCP\Integrations\Divi\Design\DesignSystemWriter;
use LIT\MCP\Integrations\Divi\Design\PresetArea;
use LIT\MCP\Integrations\Divi\Design\PresetRestorePlanner;
use LIT\MCP\Integrations\Divi\Design\PresetUsageQuery;
use LIT\MCP\Integrations\Divi\Library\GlobalUsages;
use LIT\MCP\Integrations\Divi\Release\DiviFeature;
use LIT\MCP\Tests\Support\UsageFixture;
use LIT\MCP\Tests\Unit\TestCase;
use Mockery;
final class PresetRestorePlannerTest extends TestCase
{
private static function planner(bool $unfiltered = true): PresetRestorePlanner
private static function planner(bool $unfiltered = true, ?GlobalUsages $usages = null): PresetRestorePlanner
{
return new PresetRestorePlanner(Mockery::mock(DesignSystemWriter::class), static fn (): bool => $unfiltered);
return new PresetRestorePlanner(
Mockery::mock(DesignSystemWriter::class),
$usages ?? UsageFixture::none(),
static fn (): bool => $unfiltered);
}
public function testAreaFeaturesAndDesignArea(): void
@@ -51,4 +57,36 @@ final class PresetRestorePlannerTest extends TestCase
self::assertToolError($plan, 'forbidden');
}
/** Audit L4: removed and changed presets are looked up (spec §5 orphan warning stays); P8a can block. */
public function testReportsThePagesUsingRemovedPresets(): void
{
$older = PresetBookTest::stored();
unset($older['module']['divi/button']['items']['bbbbbbbbbb']);
$older['module']['divi/button']['items']['aaaaaaaaaa']['attrs'] = ['button' => ['x' => 2]];
$usages = Mockery::mock(GlobalUsages::class);
$usages->expects('reportFor')->once()->with(Mockery::on(
static fn (mixed $query): bool => $query instanceof PresetUsageQuery
&& $query->matches('<!-- wp:divi/button {"modulePreset":["bbbbbbbbbb"]} /-->')
&& $query->matches('<!-- wp:divi/button {"modulePreset":["aaaaaaaaaa"]} /-->')
&& ! $query->matches('<!-- wp:divi/button {"modulePreset":["cccccccccc"]} /-->')
))->andReturn(UsageFixture::blockedReport());
$plan = self::planner(true, $usages)->plan(PresetBookTest::stored(), $older, 'presets-1');
self::assertInstanceOf(DesignPlan::class, $plan);
self::assertTrue($plan->usages?->blocks());
self::assertStringContainsString('Standard-Preset', $plan->warnings[0]);
}
public function testNoUsageLookupWithoutChangedOrRemovedPresets(): void
{
$usages = Mockery::mock(GlobalUsages::class);
$usages->expects('reportFor')->never();
$plan = self::planner(true, $usages)->plan(PresetBookTest::stored(), PresetBookTest::stored(), 'presets-1');
self::assertInstanceOf(DesignPlan::class, $plan);
self::assertNull($plan->usages);
}
}