feat: SnapshotStore – Snapshots des Designsystems je Bereich
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Haiku 5.5
parent
388b52ea76
commit
5ba52b98b3
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace LIT\MCP\Tests\Unit\Integrations\Divi\Design;
|
||||
|
||||
use Brain\Monkey\Functions;
|
||||
use InvalidArgumentException;
|
||||
use LIT\MCP\Integrations\Divi\Design\SnapshotStore;
|
||||
use LIT\MCP\Integrations\Divi\Design\SnapshotTooLarge;
|
||||
use LIT\MCP\Tests\Unit\TestCase;
|
||||
use RuntimeException;
|
||||
|
||||
final class SnapshotStoreTest extends TestCase
|
||||
{
|
||||
/** @var array<string, mixed> */
|
||||
private array $options = [];
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->options = [];
|
||||
Functions\when('get_option')->alias(fn (string $name, mixed $default = false): mixed => $this->options[$name] ?? $default);
|
||||
Functions\when('update_option')->alias(function (string $name, mixed $value, mixed $autoload = null): bool {
|
||||
self::assertFalse($autoload, 'snapshots are never autoloaded');
|
||||
$this->options[$name] = $value;
|
||||
|
||||
return true;
|
||||
});
|
||||
Functions\when('get_current_user_id')->justReturn(7);
|
||||
}
|
||||
|
||||
public function testSavesListsAndReturnsTheNewestFirst(): void
|
||||
{
|
||||
$store = new SnapshotStore();
|
||||
$first = $store->save('presets', ['module' => ['a' => 1]], 'lit/divi-presets-set');
|
||||
$second = $store->save('presets', ['module' => ['a' => 2]], 'lit/divi-presets-set');
|
||||
$store->attachLog('presets', $second, 42);
|
||||
|
||||
self::assertSame('lit_mcp_snapshots_presets', SnapshotStore::option('presets'));
|
||||
self::assertMatchesRegularExpression('/^presets-\d{8}T\d{6}Z-[0-9a-f]{6}$/', $first);
|
||||
$list = $store->list('presets');
|
||||
self::assertSame([$second, $first], array_column($list, 'id'));
|
||||
self::assertSame(42, $list[0]['log_id']);
|
||||
self::assertSame(7, $list[0]['user_id']);
|
||||
self::assertArrayNotHasKey('data', $list[0]);
|
||||
self::assertSame(['module' => ['a' => 1]], $store->get('presets', $first)['data']);
|
||||
self::assertNull($store->get('presets', 'presets-unknown'));
|
||||
self::assertSame([], $store->list('colors'));
|
||||
}
|
||||
|
||||
public function testKeepsAtMostTwentyPerArea(): void
|
||||
{
|
||||
$store = new SnapshotStore();
|
||||
$ids = [];
|
||||
for ($i = 0; $i < 22; ++$i) {
|
||||
$ids[] = $store->save('presets', ['n' => $i], 'lit/divi-presets-set');
|
||||
}
|
||||
|
||||
$list = $store->list('presets');
|
||||
self::assertCount(SnapshotStore::LIMIT, $list);
|
||||
self::assertSame($ids[21], $list[0]['id']);
|
||||
self::assertNull($store->get('presets', $ids[0]));
|
||||
self::assertNull($store->get('presets', $ids[1]));
|
||||
}
|
||||
|
||||
public function testRefusesSnapshotsAboveTheLimit(): void
|
||||
{
|
||||
$this->expectException(SnapshotTooLarge::class);
|
||||
|
||||
(new SnapshotStore())->save('presets', ['x' => str_repeat('a', SnapshotStore::MAX_BYTES)], 'lit/divi-presets-set');
|
||||
}
|
||||
|
||||
public function testUnknownAreaIsAProgrammingError(): void
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
SnapshotStore::option('pages');
|
||||
}
|
||||
|
||||
public function testAFailedOptionWriteThrows(): void
|
||||
{
|
||||
Functions\when('update_option')->justReturn(false);
|
||||
$this->expectException(RuntimeException::class);
|
||||
$this->expectExceptionMessage('snapshot presets could not be stored');
|
||||
|
||||
(new SnapshotStore())->save('presets', ['a' => 1], 'lit/divi-presets-set');
|
||||
}
|
||||
|
||||
public function testCorruptOptionReadsAsEmpty(): void
|
||||
{
|
||||
$this->options['lit_mcp_snapshots_presets'] = 'kaputt';
|
||||
|
||||
self::assertSame([], (new SnapshotStore())->list('presets'));
|
||||
}
|
||||
}
|
||||
@@ -55,6 +55,8 @@ final class UninstallTest extends TestCase
|
||||
$own = [
|
||||
Access::OPTION, ExposurePolicy::OPTION, Limits::OPTION, ChangeLogInstaller::VERSION_OPTION,
|
||||
ReleaseStore::OPTION, CheckReportStore::OPTION, DiviCheckRoute::LOCK,
|
||||
'lit_mcp_snapshots_colors', 'lit_mcp_snapshots_variables', 'lit_mcp_snapshots_presets',
|
||||
'lit_mcp_snapshots_theme_options',
|
||||
];
|
||||
self::assertSame(array_merge($own, $own), $deleted);
|
||||
self::assertNotContains('mcp_jwt_secret', $deleted);
|
||||
|
||||
@@ -61,6 +61,8 @@ final class UninstallerTest extends TestCase
|
||||
[
|
||||
Access::OPTION, ExposurePolicy::OPTION, Limits::OPTION, ChangeLogInstaller::VERSION_OPTION,
|
||||
ReleaseStore::OPTION, CheckReportStore::OPTION, DiviCheckRoute::LOCK,
|
||||
'lit_mcp_snapshots_colors', 'lit_mcp_snapshots_variables', 'lit_mcp_snapshots_presets',
|
||||
'lit_mcp_snapshots_theme_options',
|
||||
],
|
||||
$deleted
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user