feat(css): globales CSS bearbeiten (lit/divi-custom-css-get und -update)
WordPress „Zusätzliches CSS“ (in Divi „Eigenes CSS“) über die Design-Pipeline: Probelauf mit Zeilen-Diff, design_rev, Bestätigung, Snapshot, Rollback und Wiederherstellen (Bereich custom_css). Der Guard lehnt </style, <script, expression(, javascript: und neue @import ab und warnt bei fremden Hosts; nur Neues zählt, Bestehendes blockiert keine Änderung. Erfordert edit_css und die Divi-Rolle Theme-Anpassung. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
96fa58188b
commit
ac333a164c
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace LIT\MCP\Tests\Unit\Integrations\Divi\Design;
|
||||
|
||||
use Brain\Monkey\Functions;
|
||||
use LIT\MCP\Integrations\Divi\Design\CustomCssArea;
|
||||
use LIT\MCP\Integrations\Divi\Design\CustomCssRestorePlanner;
|
||||
use LIT\MCP\Integrations\Divi\Design\DesignPlan;
|
||||
use LIT\MCP\Integrations\Divi\Design\ThemeOptionsAdapter;
|
||||
use LIT\MCP\Integrations\Divi\Release\DiviFeature;
|
||||
use LIT\MCP\Tests\Support\FakeCustomCssStore;
|
||||
use LIT\MCP\Tests\Unit\TestCase;
|
||||
use Mockery;
|
||||
|
||||
final class CustomCssRestorePlannerTest extends TestCase
|
||||
{
|
||||
private function planner(bool $customize = true): CustomCssRestorePlanner
|
||||
{
|
||||
$options = Mockery::mock(ThemeOptionsAdapter::class);
|
||||
$options->allows('canCustomize')->andReturn($customize);
|
||||
|
||||
return new CustomCssRestorePlanner(new FakeCustomCssStore(), $options);
|
||||
}
|
||||
|
||||
public function testDescribesItsAreaRightsAndFeatures(): void
|
||||
{
|
||||
Functions\when('current_user_can')->justReturn(true);
|
||||
$planner = $this->planner();
|
||||
|
||||
self::assertSame('custom_css', $planner->area());
|
||||
self::assertInstanceOf(CustomCssArea::class, $planner->designArea());
|
||||
self::assertSame([DiviFeature::ThemeOptionRead, DiviFeature::ThemeOptionWrite], $planner->features());
|
||||
self::assertNull($planner->rights());
|
||||
|
||||
Functions\when('current_user_can')->alias(static fn (string $cap): bool => $cap !== 'edit_css');
|
||||
self::assertToolError($planner->rights(), 'forbidden');
|
||||
}
|
||||
|
||||
public function testThePlanReplacesTheWholeTextWithTheSnapshots(): void
|
||||
{
|
||||
$plan = $this->planner()->plan(
|
||||
['stylesheet' => 'Divi', 'css' => ".new{}\n.keep{}"],
|
||||
['stylesheet' => 'Divi', 'css' => ".old{}\n.keep{}"],
|
||||
'custom_css-20261105T100000Z-abc123'
|
||||
);
|
||||
|
||||
self::assertInstanceOf(DesignPlan::class, $plan);
|
||||
self::assertSame(['stylesheet' => 'Divi', 'css' => ".old{}\n.keep{}"], $plan->raw);
|
||||
self::assertTrue($plan->mayRemove);
|
||||
self::assertSame([
|
||||
['action' => 'removed', 'line' => '.new{}'],
|
||||
['action' => 'added', 'line' => '.old{}'],
|
||||
], $plan->diff);
|
||||
self::assertStringStartsWith('Snapshot custom_css-20261105T100000Z-abc123 wiederherstellen', $plan->summary);
|
||||
self::assertSame([CustomCssArea::SITE_WIDE], $plan->warnings);
|
||||
}
|
||||
|
||||
public function testAnUnchangedTextIsAnEmptyPlan(): void
|
||||
{
|
||||
$plan = $this->planner()->plan(
|
||||
['stylesheet' => 'Divi', 'css' => '.a{}'],
|
||||
['stylesheet' => 'Divi', 'css' => '.a{}'],
|
||||
'custom_css-x'
|
||||
);
|
||||
|
||||
self::assertInstanceOf(DesignPlan::class, $plan);
|
||||
self::assertTrue($plan->isEmpty());
|
||||
self::assertSame([], $plan->warnings);
|
||||
}
|
||||
|
||||
/** A snapshot of another theme would land in this theme's CSS. */
|
||||
public function testASnapshotOfAnotherThemeIsRefused(): void
|
||||
{
|
||||
$result = $this->planner()->plan(
|
||||
['stylesheet' => 'Divi', 'css' => '.a{}'],
|
||||
['stylesheet' => 'Child', 'css' => '.b{}'],
|
||||
'custom_css-x'
|
||||
);
|
||||
|
||||
$error = self::assertToolError($result, 'validation_failed');
|
||||
self::assertStringContainsString('Theme „Child“, aktiv ist „Divi“', $error['message']);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user