fix: lit/divi-presets-set – name und rename schließen sich aus, Namensprüfung vorziehen

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Jan-Niclas Loosen
2026-10-16 17:48:43 +02:00
co-authored by Claude Sonnet 5.5
parent b3c3e69a53
commit 25720ad086
2 changed files with 40 additions and 3 deletions
@@ -236,6 +236,17 @@ final class DiviPresetsSetAbility implements Ability
return null;
}
if ($existing === null && isset($item['rename'])) {
$errors[$field . '.rename'] = 'nur zusammen mit preset; für ein neues Preset name verwenden';
return null;
}
if ($existing !== null && isset($item['name'])) {
$errors[$field . '.name'] = 'zum Umbenennen rename verwenden';
return null;
}
foreach (['name' => $existing === null, 'rename' => $existing !== null] as $key => $applies) {
if (! $applies || ! is_string($item[$key] ?? null)) {
continue;
@@ -269,10 +280,12 @@ final class DiviPresetsSetAbility implements Ability
/** Plain text of 1 to 100 characters, or null (ruling: preset names). */
private function cleanName(string $name): ?string
{
if (strlen($name) > self::NAME_MAX * 4) {
return null;
}
$clean = sanitize_text_field($name);
$length = function_exists('mb_strlen') ? mb_strlen($clean) : strlen($clean);
return $clean === '' || $length > self::NAME_MAX || strlen($name) > self::NAME_MAX * 4 ? null : $clean;
return $clean === '' || mb_strlen($clean) > self::NAME_MAX ? null : $clean;
}
/**
@@ -192,6 +192,29 @@ final class DiviPresetsSetAbilityTest extends TestCase
self::assertStringContainsString('1–100 Zeichen', $empty['fields']['items[0].rename']);
}
public function testNameAndRenameAreExclusive(): void
{
$ability = $this->ability();
$new = self::assertToolError($ability->execute(['items' => [
['module' => 'button', 'name' => 'Neu', 'rename' => '<b>x</b>'],
]]), 'validation_failed');
self::assertStringContainsString('nur zusammen mit preset', $new['fields']['items[0].rename']);
$change = self::assertToolError($ability->execute(['items' => [
['module' => 'button', 'preset' => 'CTA primär', 'name' => 'CTA primär'],
]]), 'validation_failed');
self::assertStringContainsString('rename', $change['fields']['items[0].name']);
}
public function testRenameToAnotherPresetsNameIsRefused(): void
{
$result = self::assertToolError($this->ability()->execute(['items' => [
['module' => 'button', 'preset' => 'CTA primär', 'rename' => 'Doppelt'],
]]), 'validation_failed');
self::assertStringContainsString('bbbbbbbbbb', $result['fields']['items[0].rename']);
}
public function testNothingIsWrittenWhenOneItemHasErrors(): void
{
$writer = Mockery::mock(DesignSystemWriter::class);
@@ -202,7 +225,8 @@ final class DiviPresetsSetAbilityTest extends TestCase
$ability = $this->ability(true, null, null, $writer);
$result = $ability->execute(['items' => [
['module' => 'button', 'name' => 'Gut'],
['module' => 'button', 'name' => 'Gut',
'attrs' => ['button.decoration.background' => ['desktop' => ['color' => '#333333']]]],
['module' => 'button', 'name' => 'Schlecht', 'attrs' => ['button.innerContent' => ['desktop' => ['text' => 'Hallo']]]],
], 'confirm' => true, 'design_rev' => 'egal']);