Files
WP-LIT-MCP/tests/Unit/Integrations/Divi/Design/DesignSystemTest.php
T
janniclas.loosenandClaude Opus 5.5 8688a02402 fix: Task 3 review round 1 - strip control chars before the sanitizer (S32a), S34 minors
Control characters now go on the raw value in AttrWriter::cleanNode and
VariableRef::setting; after the sanitizer only rejection remains ('<' + VT/FF
no longer turns into a tag). VALUE_KEY anchored with D, exact column-width
fractions, nested rows in columns, specialty columns refused, fullwidth by
catalog category, preset ambiguity in DesignSystem::modulePresetId().

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
2026-09-26 14:26:18 +02:00

110 lines
5.4 KiB
PHP

<?php
declare(strict_types=1);
namespace LIT\MCP\Tests\Unit\Integrations\Divi\Design;
use LIT\MCP\Integrations\Divi\Design\DesignSystem;
use PHPUnit\Framework\TestCase;
final class DesignSystemTest extends TestCase
{
/** Shapes as GlobalData / GlobalPreset return them (Divi 5.2.1, verified in DDEV). */
public static function sample(): DesignSystem
{
return DesignSystem::fromDivi(
[
'gcid-primary-color' => ['color' => '#2ea3f2', 'label' => 'Primärfarbe', 'status' => 'active'],
'gcid-body-color' => ['color' => '#666666', 'label' => 'Fließtextfarbe', 'status' => 'active'],
'gcid-a1b2' => ['color' => '#0b3d59', 'label' => 'Nachtblau', 'status' => 'active'],
'gcid-old' => ['color' => '#ff0000', 'label' => 'Alt', 'status' => 'inactive'],
],
[
'numbers' => ['gvid-r1' => ['id' => 'gvid-r1', 'label' => 'Radius', 'value' => '8px', 'status' => 'active']],
'strings' => ['gvid-s1' => ['id' => 'gvid-s1', 'label' => 'Telefon', 'value' => '0221 123', 'status' => 'active']],
// Divi returns every variable type as stdClass (verified in DDEV).
'fonts' => (object) [
'--et_global_heading_font' => ['id' => '--et_global_heading_font', 'label' => 'Überschrift', 'value' => 'Open Sans', 'status' => 'active'],
'--et_global_body_font' => ['id' => '--et_global_body_font', 'label' => 'Fließtext', 'value' => 'Lato', 'status' => 'active'],
],
'links' => new \stdClass(),
],
[
'module' => ['divi/button' => ['default' => 'p-1', 'items' => [
'p-1' => ['id' => 'p-1', 'name' => 'Standard', 'moduleName' => 'divi/button'],
'p-2' => ['id' => 'p-2', 'name' => 'CTA primär', 'moduleName' => 'divi/button'],
]]],
'group' => ['divi/font' => ['default' => '', 'items' => [
'g-1' => ['id' => 'g-1', 'name' => 'Fließtext groß', 'groupName' => 'divi/font'],
]]],
],
['body_font_size' => '16']
);
}
public function testReadsColorsVariablesFontsSizesAndPresets(): void
{
$design = self::sample();
self::assertSame(
['id' => 'gcid-a1b2', 'label' => 'Nachtblau', 'value' => '#0b3d59'],
$design->colors()[2]
);
self::assertCount(3, $design->colors());
self::assertSame(['heading' => 'Open Sans', 'body' => 'Lato'], $design->fonts());
self::assertSame(
[['id' => 'gvid-r1', 'type' => 'numbers', 'label' => 'Radius', 'value' => '8px'],
['id' => 'gvid-s1', 'type' => 'strings', 'label' => 'Telefon', 'value' => '0221 123']],
$design->variables()
);
self::assertSame('16', $design->sizes()['body_font_size']);
self::assertSame('30', $design->sizes()['body_header_size']);
self::assertSame(
['kind' => 'module', 'module' => 'divi/button', 'id' => 'p-1', 'name' => 'Standard', 'default' => true],
$design->presets()[0]
);
self::assertSame(['p-1' => 'Standard', 'p-2' => 'CTA primär', 'g-1' => 'Fließtext groß'], $design->presetNames());
}
public function testLooksUpByAliasLabelOrId(): void
{
$design = self::sample();
self::assertSame('gcid-primary-color', $design->colorId('primary'));
self::assertSame('gcid-a1b2', $design->colorId('nachtblau'));
self::assertSame('gcid-a1b2', $design->colorId('gcid-a1b2'));
self::assertNull($design->colorId('secondary'));
self::assertNull($design->colorId('Alt'));
self::assertSame('gvid-s1', $design->variable('telefon')['id'] ?? null);
self::assertSame('p-2', $design->modulePresetId('divi/button', 'cta PRIMÄR'));
self::assertNull($design->modulePresetId('divi/text', 'Standard'));
self::assertSame(['Standard', 'CTA primär'], $design->modulePresetNames('divi/button'));
self::assertSame('{{color:primary}}', DesignSystem::colorPlaceholder('gcid-primary-color', 'Primärfarbe'));
self::assertSame('{{color:Nachtblau}}', DesignSystem::colorPlaceholder('gcid-a1b2', 'Nachtblau'));
}
/** Ruling S13a/S34: a preset name several presets of the module share fails with their ids. */
public function testAmbiguousPresetNamesFail(): void
{
$design = DesignSystem::fromDivi([], [], ['module' => ['divi/button' => ['default' => 'p-1', 'items' => [
'p-1' => ['id' => 'p-1', 'name' => 'Standard', 'moduleName' => 'divi/button'],
'p-3' => ['id' => 'p-3', 'name' => 'standard', 'moduleName' => 'divi/button'],
]]]], []);
self::assertSame('p-3', $design->modulePresetId('divi/button', 'p-3'));
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('p-1, p-3');
$design->modulePresetId('divi/button', 'STANDARD');
}
public function testToleratesEmptyOrOddInput(): void
{
$design = DesignSystem::fromDivi([], ['fonts' => 'x'], ['module' => 'y'], []);
self::assertSame([], $design->colors());
self::assertSame(['heading' => '', 'body' => ''], $design->fonts());
self::assertSame([], $design->presets());
self::assertSame('14', $design->sizes()['body_font_size']);
}
}