Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
104 lines
4.1 KiB
PHP
104 lines
4.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace LIT\MCP\Tests\Unit\Integrations\Divi\BlockTree;
|
|
|
|
use LIT\MCP\Integrations\Divi\BlockTree\Block;
|
|
use LIT\MCP\Integrations\Divi\BlockTree\GlobalInstance;
|
|
use LIT\MCP\Integrations\Divi\BlockTree\LibraryContent;
|
|
use LIT\MCP\Integrations\Divi\BlockTree\NodeIndex;
|
|
use LIT\MCP\Integrations\Divi\BlockTree\Parser;
|
|
use LIT\MCP\Integrations\Divi\BlockTree\Serializer;
|
|
use LIT\MCP\Tests\Support\DiviFixtures;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
final class LibraryContentTest extends TestCase
|
|
{
|
|
/** @return array<string, array{string, string}> */
|
|
public static function savedNodes(): array
|
|
{
|
|
return [
|
|
'section' => ['s1', 'library--library-abschnitt.html'],
|
|
'row' => ['s1.r0', 'library--library-zeile.html'],
|
|
'module' => ['s1.r0.c0.m0', 'library--library-modul.html'],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* The builder's "add to library" wraps the node in divi/placeholder (F4); the fixtures only
|
|
* differ by the CRLF of the form upload (finding 9).
|
|
*
|
|
* @dataProvider savedNodes
|
|
*/
|
|
public function testWrapMatchesTheBuilderEntry(string $id, string $file): void
|
|
{
|
|
$index = NodeIndex::build((new Parser())->parse(DiviFixtures::markup('stage3/page--globale-instanzen.html')));
|
|
|
|
self::assertSame(
|
|
str_replace("\r\n", "\n", DiviFixtures::markup('stage3/' . $file)),
|
|
LibraryContent::wrap($index->find($id))
|
|
);
|
|
}
|
|
|
|
public function testLoadUnifiesLineBreaksAndRootsSkipThePlaceholder(): void
|
|
{
|
|
$document = LibraryContent::load(new Parser(), DiviFixtures::markup('stage3/library--layout-ganze-seite.html'));
|
|
|
|
self::assertStringNotContainsString("\r", Serializer::document($document));
|
|
self::assertSame(
|
|
['divi/section', 'divi/section', 'divi/section'],
|
|
array_map(static fn (Block $block): string => $block->name(), LibraryContent::roots($document))
|
|
);
|
|
self::assertSame(
|
|
['divi/text'],
|
|
array_map(
|
|
static fn (Block $block): string => $block->name(),
|
|
LibraryContent::roots((new Parser())->parse('<!-- wp:divi/text /-->'))
|
|
)
|
|
);
|
|
}
|
|
|
|
public function testContainsGlobal(): void
|
|
{
|
|
$index = NodeIndex::build((new Parser())->parse(DiviFixtures::markup('stage3/page--globale-instanzen.html')));
|
|
|
|
self::assertTrue(LibraryContent::containsGlobal($index->find('s0')));
|
|
self::assertFalse(LibraryContent::containsGlobal($index->find('s1')));
|
|
}
|
|
|
|
public function testShapeViolations(): void
|
|
{
|
|
$section = Block::create('divi/section');
|
|
$row = Block::create('divi/row');
|
|
$instance = GlobalInstance::of(Block::create('divi/text'), 9);
|
|
$withInstance = Block::create('divi/section', [], [Block::create('divi/row', [], [
|
|
Block::create('divi/column', [], [$instance]),
|
|
])]);
|
|
|
|
self::assertNull(LibraryContent::shapeViolation([$section], [$section], 'section', false));
|
|
self::assertStringContainsString(
|
|
'nicht leer',
|
|
(string) LibraryContent::shapeViolation([$section], [], 'section', false)
|
|
);
|
|
self::assertStringContainsString(
|
|
'genau ein divi/section',
|
|
(string) LibraryContent::shapeViolation([$section], [$section, $section], 'section', false)
|
|
);
|
|
self::assertStringContainsString(
|
|
'genau ein divi/section',
|
|
(string) LibraryContent::shapeViolation([$section], [$row], null, false)
|
|
);
|
|
self::assertNull(LibraryContent::shapeViolation([$section, $section], [$section], 'layout', false));
|
|
self::assertStringContainsString(
|
|
'nur Abschnitte',
|
|
(string) LibraryContent::shapeViolation([$section, $section], [$section, $row], 'layout', false)
|
|
);
|
|
self::assertNull(LibraryContent::shapeViolation([$section], [$withInstance], 'section', false));
|
|
self::assertStringContainsString(
|
|
'keine globalen Module',
|
|
(string) LibraryContent::shapeViolation([$section], [$withInstance], 'section', true)
|
|
);
|
|
}
|
|
}
|