fix: tb-create-template rolls back posts Divi inserted before failing (ruling Q19)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,7 @@ use LIT\MCP\Abilities\WriteFailed;
|
||||
use LIT\MCP\Integrations\Divi\Pages\DiviSaver;
|
||||
use LIT\MCP\Integrations\Divi\Pages\SaveScope;
|
||||
use LIT\MCP\Integrations\Divi\ThemeBuilder\DiviThemeBuilder;
|
||||
use LIT\MCP\Integrations\Divi\ThemeBuilder\InsertedBeforeFailure;
|
||||
use LIT\MCP\Integrations\Divi\ThemeBuilder\TbCreateTemplateAbility;
|
||||
use LIT\MCP\Integrations\Divi\ThemeBuilder\Template;
|
||||
use LIT\MCP\Integrations\Divi\ThemeBuilder\TemplateConditions;
|
||||
@@ -32,6 +33,7 @@ final class TbCreateTemplateAbilityTest extends TestCase
|
||||
parent::setUp();
|
||||
// The default template's global header 1061 is a published layout the user may edit (ruling Q8).
|
||||
LibraryFixtures::given([ThemeBuilderFixtures::layout(ThemeBuilderFixtures::HEADER)]);
|
||||
Functions\when('wp_delete_object_term_relationships')->justReturn(null);
|
||||
Functions\when('admin_url')->alias(static fn (string $path): string => 'https://kunde.test/wp-admin/' . $path);
|
||||
}
|
||||
|
||||
@@ -383,4 +385,60 @@ final class TbCreateTemplateAbilityTest extends TestCase
|
||||
self::assertFalse($schema['additionalProperties']);
|
||||
self::assertSame(TbCreateTemplateAbility::SOURCES, $schema['properties']['body']['properties']['source']['enum']);
|
||||
}
|
||||
|
||||
/** Ruling Q19: Divi threw after inserting the template (e.g. a hook's wp_die) – that template goes too. */
|
||||
public function testATemplateInsertedBeforeDiviThrewIsRolledBack(): void
|
||||
{
|
||||
$store = self::store();
|
||||
$store->shouldReceive('insertLayout')->once()->andReturn(2101);
|
||||
$store->shouldReceive('storeTemplate')->once()->andThrow(
|
||||
new InsertedBeforeFailure('Divi called wp_die(): hook', [2100], new RuntimeException('hook'))
|
||||
);
|
||||
$store->shouldReceive('attach')->never();
|
||||
$deleted = [];
|
||||
self::deletions($deleted);
|
||||
|
||||
try {
|
||||
$this->ability($store)->execute(self::input());
|
||||
self::fail('no WriteFailed');
|
||||
} catch (WriteFailed $e) {
|
||||
self::assertTrue($e->rolledBack);
|
||||
}
|
||||
self::assertSame([2100, 2101], $deleted);
|
||||
}
|
||||
|
||||
public function testALayoutInsertedBeforeDiviThrewIsRolledBack(): void
|
||||
{
|
||||
$store = self::store();
|
||||
$store->shouldReceive('insertLayout')->once()->andThrow(
|
||||
new InsertedBeforeFailure('Divi called wp_die(): hook', [2101], new RuntimeException('hook'))
|
||||
);
|
||||
$store->shouldReceive('storeTemplate')->never();
|
||||
$deleted = [];
|
||||
self::deletions($deleted);
|
||||
|
||||
$this->expectException(WriteFailed::class);
|
||||
try {
|
||||
$this->ability($store)->execute(self::input());
|
||||
} finally {
|
||||
self::assertSame([2101], $deleted);
|
||||
}
|
||||
}
|
||||
|
||||
/** Ruling Q19: the default template counts only when the user may edit it (like tb-list, Q8/B11). */
|
||||
public function testTheGlobalHeaderNeedsAnEditableDefaultTemplate(): void
|
||||
{
|
||||
LibraryFixtures::given([ThemeBuilderFixtures::layout(ThemeBuilderFixtures::HEADER)]);
|
||||
Functions\when('current_user_can')->alias(
|
||||
static fn (string $cap, mixed ...$args): bool => ! ($cap === 'edit_post'
|
||||
&& (int) ($args[0] ?? 0) === ThemeBuilderFixtures::DEFAULT_TEMPLATE)
|
||||
);
|
||||
$store = self::store();
|
||||
$store->shouldReceive('insertLayout')->never();
|
||||
|
||||
$result = $this->ability($store)->execute(self::input());
|
||||
|
||||
self::assertToolError($result, 'validation_failed');
|
||||
self::assertArrayHasKey('header.source', self::errorFields($result));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user