DiviThemeBuilder wraps Divi's Theme Builder: reads through Divi's functions, writes layouts/templates through insert_layout/store_template behind a wp_die guard (edit_others_posts and function checks first, every handler filter and output buffer restored in finally), list/conditions/enabled mirrored from Divi's own save. Template: live = attached and enabled, whatever the post status (ruling Q8/B8). ThemeBuilderAccess: edit_others_posts plus Divi's theme_builder role, hidden IDs answer like missing ones, canEditTemplate (B11) and layoutsRefusal (B10). DiviCompatibility checks the Theme Builder functions and post types (E15). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
96 lines
4.4 KiB
PHP
96 lines
4.4 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
namespace LIT\MCP\Tests\Unit\Integrations\Divi\ThemeBuilder;
|
||
|
||
use LIT\MCP\Integrations\Divi\ThemeBuilder\Template;
|
||
use LIT\MCP\Tests\Support\ThemeBuilderFixtures;
|
||
use PHPUnit\Framework\TestCase;
|
||
|
||
final class TemplateTest extends TestCase
|
||
{
|
||
public function testReadsDivisTemplateArray(): void
|
||
{
|
||
$template = ThemeBuilderFixtures::template();
|
||
|
||
self::assertSame(1066, $template->id);
|
||
self::assertFalse($template->enabled);
|
||
self::assertSame(['id' => 1062, 'enabled' => true], $template->layouts['body']);
|
||
self::assertSame(['singular:post_type:page:id:1053'], $template->useOn);
|
||
self::assertSame(['page'], $template->postTypes());
|
||
self::assertFalse($template->isLive());
|
||
}
|
||
|
||
/** Ruling Q8/B8: Divi renders every listed, enabled template whatever its post status – fail closed. */
|
||
public function testLiveMeansAttachedAndEnabledWhateverThePostStatus(): void
|
||
{
|
||
self::assertTrue(ThemeBuilderFixtures::template(1066, ['enabled' => true])->isLive());
|
||
self::assertFalse(ThemeBuilderFixtures::template(1066, ['enabled' => true, 'attached' => false])->isLive());
|
||
self::assertFalse(ThemeBuilderFixtures::template(1066, ['attached' => true])->isLive());
|
||
self::assertTrue(ThemeBuilderFixtures::template(1066, ['enabled' => true, 'status' => 'trash'])->isLive());
|
||
self::assertTrue(ThemeBuilderFixtures::template(1066, ['enabled' => true, 'status' => 'draft'])->isLive());
|
||
self::assertTrue(ThemeBuilderFixtures::template(1066, ['enabled' => true])->showsLayout('body', 1062));
|
||
$hiddenBody = ThemeBuilderFixtures::template(1066, [
|
||
'enabled' => true,
|
||
'layouts' => [
|
||
'header' => ['id' => 1061, 'enabled' => true],
|
||
'body' => ['id' => 1062, 'enabled' => false],
|
||
'footer' => ['id' => 1063, 'enabled' => true],
|
||
],
|
||
]);
|
||
self::assertFalse($hiddenBody->showsLayout('body', 1062));
|
||
self::assertFalse(ThemeBuilderFixtures::template()->showsLayout('body', 1062), 'disabled template');
|
||
}
|
||
|
||
/** Stored as Divi stores it (stage3b/tb-template--person.json): layout IDs and flags as strings. */
|
||
public function testReadsDivisStorageTypes(): void
|
||
{
|
||
$template = Template::fromDivi([
|
||
'id' => '2394',
|
||
'title' => '[Fixture 3b] Person',
|
||
'default' => false,
|
||
'enabled' => false,
|
||
'layouts' => [
|
||
'header' => ['id' => '1061', 'enabled' => true, 'override' => true, 'global' => false],
|
||
'body' => ['id' => '2391', 'enabled' => true],
|
||
'footer' => ['id' => '0', 'enabled' => true],
|
||
],
|
||
'use_on' => ['singular:post_type:lit_fixture_person:all'],
|
||
'exclude_from' => [],
|
||
], 'publish', true, '2026-09-27 12:47:02');
|
||
|
||
self::assertSame(2394, $template->id);
|
||
self::assertSame(['id' => 1061, 'enabled' => true], $template->layouts['header']);
|
||
self::assertSame(['id' => 0, 'enabled' => true], $template->layouts['footer']);
|
||
self::assertSame(['lit_fixture_person'], $template->postTypes());
|
||
self::assertSame('2026-09-27 12:47:02', $template->toArray()['marked_unused']);
|
||
}
|
||
|
||
public function testRevChangesWithEveryField(): void
|
||
{
|
||
$rev = ThemeBuilderFixtures::template()->rev();
|
||
|
||
self::assertSame($rev, ThemeBuilderFixtures::template()->rev());
|
||
self::assertNotSame($rev, ThemeBuilderFixtures::template(1066, ['enabled' => true])->rev());
|
||
self::assertNotSame($rev, ThemeBuilderFixtures::template(1066, ['use_on' => ['homepage']])->rev());
|
||
self::assertNotSame($rev, ThemeBuilderFixtures::template(1066, ['attached' => false])->rev());
|
||
}
|
||
|
||
public function testOverlapsNameOtherLiveTemplatesWithSharedConditions(): void
|
||
{
|
||
$other = ThemeBuilderFixtures::template(1070, [
|
||
'enabled' => true,
|
||
'title' => 'Seiten',
|
||
'use_on' => ['singular:post_type:page:all', 'homepage'],
|
||
]);
|
||
$disabled = ThemeBuilderFixtures::template(1071, ['use_on' => ['homepage']]);
|
||
|
||
self::assertSame(
|
||
[['id' => 1070, 'title' => 'Seiten', 'conditions' => ['homepage']]],
|
||
Template::overlaps([$other, $disabled], 1066, ['homepage', 'search'])
|
||
);
|
||
self::assertSame([], Template::overlaps([$other], 1070, ['homepage']));
|
||
}
|
||
}
|