Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
169 lines
6.9 KiB
PHP
169 lines
6.9 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
namespace LIT\MCP\Tests\Unit\Integrations\Divi\Design;
|
||
|
||
use LIT\MCP\Integrations\Divi\Design\GlobalVariablesAdapter;
|
||
use LIT\MCP\Integrations\Divi\Design\VariableArea;
|
||
use LIT\MCP\Integrations\Divi\Design\VariableBook;
|
||
use LIT\MCP\Integrations\Divi\Release\DiviFeature;
|
||
use LIT\MCP\Tests\Unit\TestCase;
|
||
use Mockery;
|
||
|
||
final class VariableAreaTest extends TestCase
|
||
{
|
||
/**
|
||
* GlobalVariablesAdapter::read() (stored form, V7): Eckenradius (numbers), Slogan, the archived Alter Slogan
|
||
* and the archived empty Leer (strings), and Verlauf (gradients, only passed through).
|
||
*
|
||
* @return array<string, array<string, array<string, mixed>>>
|
||
*/
|
||
public static function stored(): array
|
||
{
|
||
$entry = static fn (string $type, string $id, string $label, string $value, string $order, string $status)
|
||
: array => ['id' => $id, 'label' => $label, 'value' => $value, 'order' => $order, 'status' => $status,
|
||
'lastUpdated' => '2026-10-01T10:00:00.000Z', 'variableType' => $type];
|
||
|
||
return [
|
||
'numbers' => [
|
||
'gvid-radius0001' => $entry('numbers', 'gvid-radius0001', 'Eckenradius', '8px', '1', 'active'),
|
||
],
|
||
'strings' => [
|
||
'gvid-slogan0001' => $entry('strings', 'gvid-slogan0001', 'Slogan', 'Holz mit Herz', '1', 'active'),
|
||
'gvid-alt0000001' => $entry('strings', 'gvid-alt0000001', 'Alter Slogan', 'Früher', '', 'archived'),
|
||
'gvid-leer000001' => $entry('strings', 'gvid-leer000001', 'Leer', '', '', 'archived'),
|
||
],
|
||
'gradients' => [
|
||
'gvid-verlauf001' => $entry(
|
||
'gradients',
|
||
'gvid-verlauf001',
|
||
'Verlauf',
|
||
'linear-gradient(#fff, #000)',
|
||
'1',
|
||
'active'
|
||
),
|
||
],
|
||
];
|
||
}
|
||
|
||
/**
|
||
* A GlobalVariablesAdapter over $stored: save() replaces the inventory like set_global_variables() and notes each
|
||
* call (data, expected) in $saves.
|
||
*
|
||
* @param array<string, array<string, array<string, mixed>>> $stored
|
||
* @param list<array{0: array<string, mixed>, 1: array<string, mixed>}> $saves
|
||
*/
|
||
public static function adapter(array &$stored, array &$saves, bool $manage = true): GlobalVariablesAdapter
|
||
{
|
||
$variables = Mockery::mock(GlobalVariablesAdapter::class);
|
||
$variables->allows('canManage')->andReturn($manage);
|
||
$variables->allows('read')->andReturnUsing(static function () use (&$stored): array {
|
||
return $stored;
|
||
});
|
||
$variables->allows('save')->andReturnUsing(
|
||
static function (array $data, array $expected) use (&$stored, &$saves): void {
|
||
$saves[] = [$data, $expected];
|
||
$stored = $data;
|
||
}
|
||
);
|
||
|
||
return $variables;
|
||
}
|
||
|
||
public function testAreaReadsThroughTheAdapter(): void
|
||
{
|
||
$stored = self::stored();
|
||
$saves = [];
|
||
$area = new VariableArea(self::adapter($stored, $saves));
|
||
|
||
self::assertSame(['variables', 'Variablen'], [$area->name(), $area->label()]);
|
||
self::assertSame(DiviFeature::VariableWrite, $area->feature());
|
||
self::assertSame(VariableBook::fromDivi($stored)->data(), $area->raw());
|
||
self::assertSame(VariableBook::fromDivi($stored)->rev(), $area->rev($stored));
|
||
}
|
||
|
||
/** Ruling V7: the whole planned inventory, with the inventory read before for Divi's stale check. */
|
||
public function testWriteSavesThePlannedInventoryAgainstTheLiveOne(): void
|
||
{
|
||
$stored = self::stored();
|
||
$saves = [];
|
||
$area = new VariableArea(self::adapter($stored, $saves));
|
||
$planned = self::stored();
|
||
$planned['numbers']['gvid-radius0001']['value'] = '12px';
|
||
|
||
$saved = $area->write($planned, false);
|
||
|
||
self::assertSame([[VariableBook::fromDivi($planned)->data(), self::stored()]], $saves);
|
||
self::assertSame('12px', $saved['numbers']['gvid-radius0001']['value']);
|
||
}
|
||
|
||
/** Ruling V1b: Divi refuses an inventory without a stored ID – later variables stay, archived. */
|
||
public function testRestoreKeepsVariablesCreatedAfterTheSnapshotArchived(): void
|
||
{
|
||
$stored = self::stored();
|
||
$stored['numbers']['gvid-neu0000001'] = ['id' => 'gvid-neu0000001', 'label' => 'Neu', 'value' => '4px',
|
||
'order' => '2', 'status' => 'active', 'lastUpdated' => '2026-10-19T09:00:00.000Z',
|
||
'variableType' => 'numbers'];
|
||
$live = $stored;
|
||
$saves = [];
|
||
$area = new VariableArea(self::adapter($stored, $saves));
|
||
|
||
$area->restore(VariableBook::fromDivi(self::stored())->data());
|
||
|
||
self::assertCount(1, $saves);
|
||
self::assertSame(
|
||
VariableBook::fromDivi($live)->restoredFrom(VariableBook::fromDivi(self::stored()))->data(),
|
||
$saves[0][0]
|
||
);
|
||
self::assertSame($live, $saves[0][1]);
|
||
self::assertSame('archived', $saves[0][0]['numbers']['gvid-neu0000001']['status']);
|
||
}
|
||
|
||
public function testVerifyInsistsOnTheSameVariablesStatusAndValues(): void
|
||
{
|
||
$stored = self::stored();
|
||
$saves = [];
|
||
$area = new VariableArea(self::adapter($stored, $saves));
|
||
$expected = self::stored();
|
||
$sanitized = $expected;
|
||
$sanitized['strings']['gvid-slogan0001']['value'] = 'Holz mit Herz ';
|
||
$missing = $expected;
|
||
unset($missing['numbers']['gvid-radius0001']);
|
||
$archived = $expected;
|
||
$archived['numbers']['gvid-radius0001']['status'] = 'archived';
|
||
$emptied = $expected;
|
||
$emptied['numbers']['gvid-radius0001']['value'] = '';
|
||
|
||
$relabeled = $expected;
|
||
$relabeled['numbers']['gvid-radius0001']['label'] = 'Anders';
|
||
|
||
self::assertTrue($area->verify($expected, $sanitized));
|
||
self::assertFalse($area->verify($expected, $relabeled));
|
||
self::assertFalse($area->verify($expected, $missing));
|
||
self::assertFalse($area->verify($expected, $archived));
|
||
self::assertFalse($area->verify($expected, $emptied));
|
||
}
|
||
|
||
public function testDifferencesNameTheVariablesDiviChanged(): void
|
||
{
|
||
$stored = self::stored();
|
||
$saves = [];
|
||
$area = new VariableArea(self::adapter($stored, $saves));
|
||
$expected = self::stored();
|
||
$sanitized = $expected;
|
||
$sanitized['strings']['gvid-slogan0001']['value'] = 'Holz mit Herz ';
|
||
|
||
self::assertSame([], $area->differences($expected, $expected));
|
||
self::assertSame(
|
||
['Divi hat den Wert der Variablen „Slogan“ beim Speichern bereinigt.'],
|
||
$area->differences($expected, $sanitized)
|
||
);
|
||
$sanitized['strings']['gvid-slogan0001']['label'] = 'Slogan neu';
|
||
self::assertSame(
|
||
['Divi hat den Namen und den Wert der Variablen „Slogan neu“ beim Speichern bereinigt.'],
|
||
$area->differences($expected, $sanitized)
|
||
);
|
||
}
|
||
}
|