feat: Fundstellen eines Presets (PresetUsageMatcher, PresetUsageQuery)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
Jan-Niclas Loosen
2026-10-16 17:38:22 +02:00
co-authored by Claude Haiku 5.5
parent 454116851e
commit bfd3840eb1
4 changed files with 280 additions and 0 deletions
@@ -0,0 +1,65 @@
<?php
declare(strict_types=1);
namespace LIT\MCP\Tests\Unit\Integrations\Divi\Design;
use LIT\MCP\Integrations\Divi\Design\PresetScope;
use LIT\MCP\Integrations\Divi\Design\PresetUsageMatcher;
use PHPUnit\Framework\TestCase;
final class PresetUsageMatcherTest extends TestCase
{
private const BUTTON = '<!-- wp:divi/section --><!-- wp:divi/row --><!-- wp:divi/column -->'
. '<!-- wp:divi/button %s /--><!-- /wp:divi/column --><!-- /wp:divi/row --><!-- /wp:divi/section -->';
private static function page(string $buttonAttrs): string
{
return sprintf(self::BUTTON, $buttonAttrs);
}
public function testModulePresetInTheStack(): void
{
$matcher = new PresetUsageMatcher();
$button = new PresetScope('module', 'divi/button');
self::assertTrue($matcher->uses(self::page('{"modulePreset":["aaaaaaaaaa"]}'), $button, 'aaaaaaaaaa', false));
self::assertTrue($matcher->uses(self::page('{"modulePreset":["x","aaaaaaaaaa"]}'), $button, 'aaaaaaaaaa', false));
self::assertTrue($matcher->uses(self::page('{"modulePreset":"aaaaaaaaaa"}'), $button, 'aaaaaaaaaa', false));
self::assertFalse($matcher->uses(self::page('{"modulePreset":["bbbbbbbbbb"]}'), $button, 'aaaaaaaaaa', false));
self::assertFalse(
$matcher->uses(self::page('{"modulePreset":["aaaaaaaaaa"]}'), new PresetScope('module', 'divi/text'), 'aaaaaaaaaa', false),
'an ID of another module does not count'
);
}
public function testDefaultModulePresetReachesModulesWithoutOwnPreset(): void
{
$matcher = new PresetUsageMatcher();
$button = new PresetScope('module', 'divi/button');
self::assertTrue($matcher->uses(self::page('{}'), $button, 'dddddddddd', true));
self::assertTrue($matcher->uses(self::page('{"modulePreset":["default"]}'), $button, 'dddddddddd', true));
self::assertFalse($matcher->uses(self::page('{"modulePreset":["aaaaaaaaaa"]}'), $button, 'dddddddddd', true));
}
public function testGroupPresetById(): void
{
$matcher = new PresetUsageMatcher();
$group = new PresetScope('group', 'divi/font-body');
$attrs = '{"groupPreset":{"content.decoration.bodyFont":{"presetId":["gggggggggg"],"groupName":"divi/font-body"}}}';
self::assertTrue($matcher->uses(self::page($attrs), $group, 'gggggggggg', false));
self::assertFalse($matcher->uses(self::page($attrs), new PresetScope('group', 'divi/spacing'), 'gggggggggg', false));
}
public function testBrokenMarkupCountsAsUse(): void
{
self::assertTrue((new PresetUsageMatcher())->uses(
'<!-- wp:divi/section {"a": --><!-- /wp:divi/row -->',
new PresetScope('module', 'divi/button'),
'aaaaaaaaaa',
false
));
}
}
@@ -0,0 +1,65 @@
<?php
declare(strict_types=1);
namespace LIT\MCP\Tests\Unit\Integrations\Divi\Design;
use LIT\MCP\Integrations\Divi\Design\PresetScope;
use LIT\MCP\Integrations\Divi\Design\PresetUsageQuery;
use LIT\MCP\Tests\Unit\TestCase;
use Mockery;
final class PresetUsageQueryTest extends TestCase
{
public function testCandidatesContainAnIdOrAJsonEscape(): void
{
$db = Mockery::mock(\wpdb::class);
$db->allows('esc_like')->andReturnUsing(static fn (string $text): string => $text);
$db->expects('prepare')
->with(
'(post_content LIKE %s OR post_content LIKE %s OR post_content REGEXP %s)',
'%aaaaaaaaaa%',
'%gggggggggg%',
'\\\\u00[4-7][0-9a-fA-F]'
)
->andReturn('(prepared)');
$query = new PresetUsageQuery([
['scope' => new PresetScope('module', 'divi/button'), 'id' => 'aaaaaaaaaa', 'default' => false],
['scope' => new PresetScope('group', 'divi/font-body'), 'id' => 'gggggggggg', 'default' => false],
]);
self::assertSame('(prepared)', $query->candidateCondition($db));
self::assertTrue($query->matches('<!-- wp:divi/text {"groupPreset":{"content.decoration.bodyFont":'
. '{"presetId":["gggggggggg"],"groupName":"divi/font-body"}}} /-->'));
self::assertFalse($query->matches('<!-- wp:divi/text {} /-->'));
}
public function testADefaultModulePresetLooksForTheModule(): void
{
$db = Mockery::mock(\wpdb::class);
$db->allows('esc_like')->andReturnUsing(static fn (string $text): string => $text);
$db->expects('prepare')
->with(
'(post_content LIKE %s OR post_content LIKE %s OR post_content REGEXP %s)',
'%dddddddddd%',
'%wp:divi/button %',
'\\\\u00[4-7][0-9a-fA-F]'
)
->andReturn('(prepared)');
$query = new PresetUsageQuery([
['scope' => new PresetScope('module', 'divi/button'), 'id' => 'dddddddddd', 'default' => true],
]);
self::assertSame('(prepared)', $query->candidateCondition($db));
self::assertTrue($query->matches('<!-- wp:divi/button {} /-->'));
}
public function testNeedsATarget(): void
{
$this->expectException(\InvalidArgumentException::class);
new PresetUsageQuery([]);
}
}