feat: VariableValue prüft Variablenwerte je Typ (numbers, strings, images, links, fonts)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Jan-Niclas Loosen
2026-10-19 13:59:33 +02:00
co-authored by Claude Sonnet 5.5
parent 39a5782562
commit 5bb25e1e8f
2 changed files with 215 additions and 0 deletions
@@ -0,0 +1,115 @@
<?php
declare(strict_types=1);
namespace LIT\MCP\Tests\Unit\Integrations\Divi\Design;
use LIT\MCP\Integrations\Divi\Design\VariableValue;
use PHPUnit\Framework\TestCase;
final class VariableValueTest extends TestCase
{
/** @return array<string, array{string, string}> */
public static function validValues(): array
{
return [
'numbers px' => ['numbers', '8px'],
'numbers clamp' => ['numbers', 'clamp(1.5rem, 4vw, 2.5rem)'],
'numbers calc' => ['numbers', 'calc(100% - var(--gvid-f6yq6mayfy))'],
'strings' => ['strings', 'Handwerk aus Meisterhand – seit 1987'],
'strings with line feed' => ['strings', "Zeile 1\nZeile 2"],
'strings with quotes and markup chars' => ['strings', '"Hallo" & <willkommen>'],
'links https' => ['links', 'https://wordpress.ddev.site:8443/kontakt/'],
'links http' => ['links', 'http://example.com'],
'links relative' => ['links', '/kontakt/#formular'],
'links mailto' => ['links', 'mailto:info@example.com'],
'links tel' => ['links', 'tel:+49221123'],
'images id' => ['images', '1234'],
'images url' => ['images', 'https://example.com/a/600.jpg'],
'fonts' => ['fonts', 'Merriweather'],
'fonts with space and digits' => ['fonts', 'Source Sans 3'],
];
}
/** @dataProvider validValues */
public function testValidValues(string $type, string $value): void
{
self::assertNull(VariableValue::check($type, $value));
}
/** @return array<string, array{string, string}> */
public static function invalidValues(): array
{
return [
'numbers empty' => ['numbers', ''],
'numbers semicolon' => ['numbers', '8px; color: red'],
'numbers braces' => ['numbers', '8px}'],
'numbers angle' => ['numbers', '<8px>'],
'numbers line feed' => ['numbers', "8px\n9px"],
'numbers too long' => ['numbers', str_repeat('1', 201)],
'strings empty' => ['strings', ''],
'strings control' => ['strings', "a\x07b"],
'strings tab' => ['strings', "a\tb"],
'strings carriage return' => ['strings', "a\r\nb"],
'strings too long' => ['strings', str_repeat('ä', 2001)],
'strings invalid utf8' => ['strings', "a\xC3\x28"],
'links empty' => ['links', ''],
'links javascript' => ['links', 'javascript:alert(1)'],
'links data' => ['links', 'data:text/html,x'],
'links anchor only' => ['links', '#kontakt'],
'links relative without slash' => ['links', 'kontakt/'],
'links with space' => ['links', 'https://example.com/a b'],
'links mailto empty' => ['links', 'mailto:'],
'links too long' => ['links', 'https://example.com/' . str_repeat('a', 2000)],
'images negative' => ['images', '-5'],
'images relative path' => ['images', '/wp-content/a.jpg'],
'images text' => ['images', 'Werkstattbild'],
'images javascript' => ['images', 'javascript:alert(1)'],
'fonts empty' => ['fonts', ''],
'fonts semicolon' => ['fonts', 'Lato; color: red'],
'fonts quote' => ['fonts', "Lato'"],
'fonts backslash' => ['fonts', 'Lato\\'],
'fonts too long' => ['fonts', str_repeat('a', 101)],
];
}
/** @dataProvider invalidValues */
public function testInvalidValuesGetAGermanMessage(string $type, string $value): void
{
$message = VariableValue::check($type, $value);
self::assertIsString($message);
self::assertNotSame('', $message);
}
public function testBoundsAreInclusive(): void
{
self::assertNull(VariableValue::check('numbers', str_repeat('1', 200)));
self::assertNull(VariableValue::check('strings', str_repeat('ä', 2000)));
self::assertNull(VariableValue::check('fonts', str_repeat('a', 100)));
self::assertNull(VariableValue::check('links', 'https://example.com/' . str_repeat('a', 1980)));
}
public function testGradientsAndUnknownTypesAreNotCreatable(): void
{
self::assertSame(
'Typ "gradients" ist nicht erlaubt; erlaubt: numbers, strings, images, links, fonts.',
VariableValue::check('gradients', 'linear-gradient(red, blue)')
);
self::assertSame(
'Typ "colors" ist nicht erlaubt; erlaubt: numbers, strings, images, links, fonts.',
VariableValue::check('colors', '#fff')
);
self::assertSame(['numbers', 'strings', 'images', 'links', 'fonts'], VariableValue::TYPES);
}
public function testMessagesNameTheTypeOrTheRule(): void
{
self::assertSame('Wert fehlt (Typ "fonts").', VariableValue::check('fonts', ''));
self::assertStringStartsWith('Zahlenwert:', (string) VariableValue::check('numbers', '1;'));
self::assertStringStartsWith('Link:', (string) VariableValue::check('links', 'x'));
self::assertStringStartsWith('Bild:', (string) VariableValue::check('images', 'x'));
self::assertStringStartsWith('Schrift:', (string) VariableValue::check('fonts', 'a{'));
self::assertStringStartsWith('Textwert:', (string) VariableValue::check('strings', "a\x00"));
}
}