test: shared Divi fixtures in tests/Support (T1)

- DiviFixtures: markup(), givenPost(), schema(), designSystem(), catalog(),
  dynamicContentRegistry(), maliciousRefs() - moved verbatim out of
  DiviPageLoaderTest, DesignSystemTest, ModuleCatalogTest, DynamicContentMapTest
  and VariableRefTest (its malicious() provider now returns maliciousRefs()).
- ComposeFixture moves to tests/Support.
- DiviWriterFixture: modules(), designReader(), composition(), a recording saver(),
  log() and writer(&$saved, &$failures, unfiltered, loader) for the five tests that
  wired the Divi write stack by hand.
No test cases or assertions changed (1397 / 5834).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-26 17:47:11 +02:00
co-authored by Claude Opus 5.5
parent d2cc8497c9
commit 3d96a41366
24 changed files with 489 additions and 404 deletions
@@ -8,7 +8,7 @@ use LIT\MCP\Integrations\Divi\Design\DesignSystemReader;
use LIT\MCP\Integrations\Divi\Pages\DiviNodeGetAbility;
use LIT\MCP\Integrations\Divi\Pages\DiviOutlineAbility;
use LIT\MCP\Integrations\Divi\Pages\DiviPageLoader;
use LIT\MCP\Tests\Unit\Integrations\Divi\Design\DesignSystemTest;
use LIT\MCP\Tests\Support\DiviFixtures;
use LIT\MCP\Tests\Unit\TestCase;
use Mockery;
use stdClass;
@@ -18,16 +18,16 @@ final class DiviReadAbilitiesTest extends TestCase
private function design(): DesignSystemReader
{
$reader = Mockery::mock(DesignSystemReader::class);
$reader->allows('read')->andReturn(DesignSystemTest::sample());
$reader->allows('read')->andReturn(DiviFixtures::designSystem());
return $reader;
}
public function testOutlineListsNodesWithTreeRevAndPostRev(): void
{
$content = DiviPageLoaderTest::fixture('synthetic-basic.html');
DiviPageLoaderTest::givenPost($content);
$ability = new DiviOutlineAbility(new DiviPageLoader(DiviPageLoaderTest::schema()), $this->design());
$content = DiviFixtures::markup('synthetic-basic.html');
DiviFixtures::givenPost($content);
$ability = new DiviOutlineAbility(new DiviPageLoader(DiviFixtures::schema()), $this->design());
self::assertTrue($ability->permission(['post_id' => 7]));
$result = $ability->execute(['post_id' => 7]);
@@ -46,8 +46,8 @@ final class DiviReadAbilitiesTest extends TestCase
/** Ruling S18: the "limit" input caps children per parent; "truncated" reports the cut. */
public function testOutlineBreadthLimitTruncatesAndReportsIt(): void
{
DiviPageLoaderTest::givenPost(DiviPageLoaderTest::fixture('synthetic-basic.html'));
$ability = new DiviOutlineAbility(new DiviPageLoader(DiviPageLoaderTest::schema()), $this->design());
DiviFixtures::givenPost(DiviFixtures::markup('synthetic-basic.html'));
$ability = new DiviOutlineAbility(new DiviPageLoader(DiviFixtures::schema()), $this->design());
$result = $ability->execute(['post_id' => 7, 'id' => 's0.r0.c1', 'limit' => 2]);
@@ -58,8 +58,8 @@ final class DiviReadAbilitiesTest extends TestCase
public function testOutlineOfASubtreeAndUnknownNode(): void
{
DiviPageLoaderTest::givenPost(DiviPageLoaderTest::fixture('synthetic-basic.html'));
$ability = new DiviOutlineAbility(new DiviPageLoader(DiviPageLoaderTest::schema()), $this->design());
DiviFixtures::givenPost(DiviFixtures::markup('synthetic-basic.html'));
$ability = new DiviOutlineAbility(new DiviPageLoader(DiviFixtures::schema()), $this->design());
$result = $ability->execute(['post_id' => 7, 'id' => 's1', 'depth' => 1]);
self::assertSame(['s1', 's1.r0'], array_column($result['nodes'], 'id'));
@@ -71,8 +71,8 @@ final class DiviReadAbilitiesTest extends TestCase
public function testOutlineValidatesTheSubtreeId(): void
{
DiviPageLoaderTest::givenPost(DiviPageLoaderTest::fixture('synthetic-basic.html'));
$ability = new DiviOutlineAbility(new DiviPageLoader(DiviPageLoaderTest::schema()), $this->design());
DiviFixtures::givenPost(DiviFixtures::markup('synthetic-basic.html'));
$ability = new DiviOutlineAbility(new DiviPageLoader(DiviFixtures::schema()), $this->design());
self::assertSame(
'lit_validation_failed',
@@ -82,11 +82,11 @@ final class DiviReadAbilitiesTest extends TestCase
public function testOutlineHintsForEmptyAndReadOnlyContent(): void
{
DiviPageLoaderTest::givenPost('');
$ability = new DiviOutlineAbility(new DiviPageLoader(DiviPageLoaderTest::schema()), $this->design());
DiviFixtures::givenPost('');
$ability = new DiviOutlineAbility(new DiviPageLoader(DiviFixtures::schema()), $this->design());
self::assertStringContainsString('lit-divi-insert', $ability->execute(['post_id' => 7])['hints'][0]);
DiviPageLoaderTest::givenPost(DiviPageLoaderTest::fixture('synthetic-mixed.html'));
DiviFixtures::givenPost(DiviFixtures::markup('synthetic-mixed.html'));
$hints = $ability->execute(['post_id' => 7])['hints'];
self::assertStringContainsString('nur lesbar', $hints[0]);
self::assertStringContainsString('nur als Ganzes', $hints[0]);
@@ -94,8 +94,8 @@ final class DiviReadAbilitiesTest extends TestCase
public function testNodeGetReturnsFullFormShortformAndPresets(): void
{
DiviPageLoaderTest::givenPost(DiviPageLoaderTest::fixture('synthetic-basic.html'));
$ability = new DiviNodeGetAbility(new DiviPageLoader(DiviPageLoaderTest::schema()), $this->design());
DiviFixtures::givenPost(DiviFixtures::markup('synthetic-basic.html'));
$ability = new DiviNodeGetAbility(new DiviPageLoader(DiviFixtures::schema()), $this->design());
$heading = $ability->execute(['post_id' => 7, 'id' => 's0.r0.c1.m0']);
@@ -117,8 +117,8 @@ final class DiviReadAbilitiesTest extends TestCase
public function testNodeGetValidatesTheId(): void
{
DiviPageLoaderTest::givenPost(DiviPageLoaderTest::fixture('synthetic-basic.html'));
$ability = new DiviNodeGetAbility(new DiviPageLoader(DiviPageLoaderTest::schema()), $this->design());
DiviFixtures::givenPost(DiviFixtures::markup('synthetic-basic.html'));
$ability = new DiviNodeGetAbility(new DiviPageLoader(DiviFixtures::schema()), $this->design());
self::assertSame('lit_validation_failed', $ability->execute(['post_id' => 7, 'id' => 'hero'])->get_error_code());
self::assertSame('lit_not_found', $ability->execute(['post_id' => 7, 'id' => 's5.r0'])->get_error_code());