feat: lit/divi-colors-set löst {{color:…}} mit relative gegen den geplanten Bestand auf, lehnt Zyklen ab und warnt vor Verwendungen in Presets und relativen Farben
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
337b87b572
commit
2fd03f3900
@@ -7,8 +7,10 @@ namespace LIT\MCP\Tests\Unit\Integrations\Divi\Design;
|
||||
use Brain\Monkey\Functions;
|
||||
use LIT\MCP\Abilities\Annotations;
|
||||
use LIT\MCP\Abilities\WriteFailed;
|
||||
use LIT\MCP\Integrations\Divi\Compose\VariableRef;
|
||||
use LIT\MCP\Integrations\Divi\Design\ColorBook;
|
||||
use LIT\MCP\Integrations\Divi\Design\ColorDiff;
|
||||
use LIT\MCP\Integrations\Divi\Design\ColorValue;
|
||||
use LIT\MCP\Integrations\Divi\Design\DesignChange;
|
||||
use LIT\MCP\Integrations\Divi\Design\DesignSystemWriter;
|
||||
use LIT\MCP\Integrations\Divi\Design\DiviColorsSetAbility;
|
||||
@@ -300,4 +302,140 @@ final class DiviColorsSetAbilityTest extends TestCase
|
||||
}
|
||||
self::assertSame([false, true], $calls, 'the merge failed, the snapshot replaced all colors');
|
||||
}
|
||||
|
||||
/** Ruling V5: {{color:…}} with relative is stored as Divi reference on the named color's ID. */
|
||||
public function testAPlaceholderBecomesARelativeColorOfTheNamedColor(): void
|
||||
{
|
||||
$ability = $this->ability(null, self::snapshots());
|
||||
$input = ['items' => [
|
||||
['label' => 'Holz hell', 'color' => '{{color:Holz dunkel}}', 'relative' => ['lightness' => 30]],
|
||||
]];
|
||||
|
||||
$dry = self::assertToolError($ability->execute($input), 'confirm_required');
|
||||
$ability->execute($input + ['confirm' => true, 'design_rev' => $dry['design_rev']]);
|
||||
|
||||
$created = array_values(array_diff_key($this->stored, ColorAreaTest::stored()));
|
||||
self::assertSame(
|
||||
VariableRef::serialize('color', 'gcid-holz000001', ColorValue::relative(['lightness' => 30])),
|
||||
$created[0]['color']
|
||||
);
|
||||
}
|
||||
|
||||
/** Ruling V5: the placeholder is resolved against the planned inventory, also colors of the same call. */
|
||||
public function testAPlaceholderMayNameAColorOfTheSameCall(): void
|
||||
{
|
||||
$ability = $this->ability(null, self::snapshots());
|
||||
$input = ['items' => [
|
||||
['label' => 'Basis', 'color' => '#112233'],
|
||||
['label' => 'Basis hell', 'color' => '{{color:basis}}', 'relative' => ['lightness' => 20]],
|
||||
]];
|
||||
|
||||
$dry = self::assertToolError($ability->execute($input), 'confirm_required');
|
||||
self::assertSame(['added', 'added'], array_column($dry['diff'], 'action'));
|
||||
$ability->execute($input + ['confirm' => true, 'design_rev' => $dry['design_rev']]);
|
||||
|
||||
$byLabel = [];
|
||||
foreach ($this->stored as $id => $entry) {
|
||||
$byLabel[$entry['label']] = ['id' => $id] + $entry;
|
||||
}
|
||||
self::assertSame(
|
||||
VariableRef::serialize('color', $byLabel['Basis']['id'], ColorValue::relative(['lightness' => 20])),
|
||||
$byLabel['Basis hell']['color']
|
||||
);
|
||||
}
|
||||
|
||||
public function testPlaceholderProblemsAreCollected(): void
|
||||
{
|
||||
$error = $this->ability()->execute(['items' => [
|
||||
['label' => 'A', 'color' => '{{color:Fehlt}}', 'relative' => ['lightness' => 10]],
|
||||
['label' => 'B', 'color' => '#ffffff', 'relative' => ['lightness' => 10]],
|
||||
['id' => 'primary', 'color' => '{{color:Holz dunkel}}', 'relative' => ['lightness' => 10]],
|
||||
['label' => 'C', 'color' => '{{color:Holz dunkel}}', 'relative' => ['farbe' => 10]],
|
||||
['id' => 'Sand', 'relative' => ['lightness' => 10]],
|
||||
['label' => 'D', 'color' => VariableRef::serialize('color', 'gcid-holz000001', [])],
|
||||
['label' => 'E', 'color' => '{{color:Holz dunkel}}'],
|
||||
]]);
|
||||
|
||||
self::assertToolError($error, 'validation_failed');
|
||||
self::assertSame(
|
||||
['items[0].color', 'items[1].relative', 'items[2].color', 'items[3].relative', 'items[4].relative',
|
||||
'items[5].color', 'items[6].relative'],
|
||||
array_keys(self::errorFields($error))
|
||||
);
|
||||
}
|
||||
|
||||
/** Ruling V5: Sand is built on Holz dunkel – Holz dunkel built on Sand would be a cycle. */
|
||||
public function testRelativeColorsMustNotFormACycle(): void
|
||||
{
|
||||
$error = $this->ability()->execute(['items' => [
|
||||
['id' => 'Holz dunkel', 'color' => '{{color:Sand}}', 'relative' => ['lightness' => -40]],
|
||||
]]);
|
||||
|
||||
self::assertToolError($error, 'validation_failed');
|
||||
$fields = self::errorFields($error);
|
||||
self::assertSame(['items'], array_keys($fields));
|
||||
self::assertStringContainsString('Sand', $fields['items']);
|
||||
self::assertSame([], $this->saves);
|
||||
}
|
||||
|
||||
/** Ruling V8: presets and relative colors built on a changed color are warnings, never a block. */
|
||||
public function testChangesWarnAboutPresetsAndRelativeColorsBuiltOnTheColor(): void
|
||||
{
|
||||
$dry = self::assertToolError(
|
||||
$this->ability(null, null, PresetBookTest::storedWithReferences())
|
||||
->execute(['items' => [['id' => 'Holz dunkel', 'color' => '#000000']]]),
|
||||
'confirm_required'
|
||||
);
|
||||
|
||||
self::assertSame([
|
||||
'Die Änderung an Farbe „Holz dunkel“ wirkt auch auf die Presets CTA primär.',
|
||||
'Die relativen Farben Sand bauen auf Farbe „Holz dunkel“ auf und ändern sich mit.',
|
||||
], $dry['warnings']);
|
||||
}
|
||||
|
||||
public function testDeactivatingAUsedColorWarnsAndListsTheUsages(): void
|
||||
{
|
||||
$dry = self::assertToolError(
|
||||
$this->ability(self::usages(self::used()), null, PresetBookTest::storedWithReferences())
|
||||
->execute(['items' => [['id' => 'Holz dunkel', 'status' => 'inactive']]]),
|
||||
'confirm_required'
|
||||
);
|
||||
|
||||
self::assertSame(7, $dry['affected'][0]['post_id']);
|
||||
self::assertSame([
|
||||
'Farbe „Holz dunkel“ wird deaktiviert, aber noch von Presets verwendet: CTA primär.',
|
||||
'Farbe „Holz dunkel“ wird deaktiviert, aber die relativen Farben Sand bauen auf ihr auf.',
|
||||
'Die unter affected genannten Inhalte verweisen auf geänderte oder deaktivierte Farben; deaktivierte '
|
||||
. 'Farben bleiben dort als Verweis stehen.',
|
||||
], $dry['warnings']);
|
||||
}
|
||||
|
||||
public function testNewColorsHaveNoWarnings(): void
|
||||
{
|
||||
$dry = self::assertToolError(
|
||||
$this->ability(null, null, PresetBookTest::storedWithReferences())
|
||||
->execute(['items' => [['label' => 'Weiß', 'color' => 'white']]]),
|
||||
'confirm_required'
|
||||
);
|
||||
|
||||
self::assertSame([], $dry['warnings']);
|
||||
}
|
||||
|
||||
/** Review note: ColorBook::with() replaces, so a changed color keeps usedInPosts and its other fields. */
|
||||
public function testChangingAColorKeepsItsUsedInPostsAndOtherFields(): void
|
||||
{
|
||||
$this->stored['gcid-holz000001']['usedInPosts'] = [7, 9];
|
||||
$ability = $this->ability();
|
||||
$input = ['items' => [['id' => 'Holz dunkel', 'color' => '#000000']]];
|
||||
$dry = self::assertToolError($ability->execute($input), 'confirm_required');
|
||||
$snapshots = Mockery::mock(SnapshotStore::class);
|
||||
$snapshots->allows('save')->andReturn('colors-1');
|
||||
$snapshots->allows('attachLog');
|
||||
|
||||
$this->ability(null, $snapshots)->execute($input + ['confirm' => true, 'design_rev' => $dry['design_rev']]);
|
||||
|
||||
$saved = $this->saves[0][0]['gcid-holz000001'];
|
||||
self::assertSame([7, 9], $saved['usedInPosts']);
|
||||
self::assertSame(['Holz dunkel', '#000000'], [$saved['label'], $saved['color']]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user