feat: write results warn about sections built like a library section (spec §5.5)

SimilarSections compares inserted sections (not global instances) with
at most 200 editable library section entries by structure fingerprint,
read lazily once per request, only while library IDs may be named (P13).
lit/library-insert is not asked.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-27 21:16:16 +02:00
co-authored by Claude Opus 5.5
parent f82964f617
commit 4f70886006
6 changed files with 260 additions and 6 deletions
@@ -10,8 +10,10 @@ use LIT\MCP\Abilities\WriteFailed;
use LIT\MCP\ChangeLog\ChangeLog;
use LIT\MCP\Integrations\Divi\BlockTree\AttrMap;
use LIT\MCP\Integrations\Divi\Design\DesignSystemReader;
use LIT\MCP\Integrations\Divi\Library\SimilarSections;
use LIT\MCP\Integrations\Divi\Pages\DiviChange;
use LIT\MCP\Integrations\Divi\Pages\DiviComposition;
use LIT\MCP\Integrations\Divi\Pages\DiviInsertAbility;
use LIT\MCP\Integrations\Divi\Pages\DiviPage;
use LIT\MCP\Integrations\Divi\Pages\DiviPageLoader;
use LIT\MCP\Integrations\Divi\Pages\DiviSaver;
@@ -245,4 +247,48 @@ final class DiviWriterTest extends TestCase
$log->assertRecorded();
$log->assertPartials();
}
/** Spec §5.5: the writer adds the similar-section warnings to every write result. */
public function testWriteResultsCarryTheSimilarSectionWarning(): void
{
$content = DiviFixtures::markup('synthetic-basic.html');
DiviFixtures::givenPost($content);
Functions\when('get_preview_post_link')->justReturn('https://kunde.test/?page_id=7&preview=true');
$similar = Mockery::mock(SimilarSections::class);
$similar->allows('warnings')->andReturn(['Ein gleich aufgebauter Abschnitt liegt in der Divi-Bibliothek.']);
$saved = [];
$failures = [];
$writer = DiviWriterFixture::writer($saved, $failures, false, null, null, null, $similar);
$result = (new DiviInsertAbility($writer))->execute([
'post_id' => 7,
'tree_rev' => \LIT\MCP\Abilities\Rev::of($content),
'nodes' => [['type' => 'section', 'modules' => [['type' => 'text', 'content' => 'Neu']]]],
]);
self::assertContains('Ein gleich aufgebauter Abschnitt liegt in der Divi-Bibliothek.', $result['warnings']);
}
/** What lit/library-insert inserts comes from the library – no advice to use the library. */
public function testLibraryInsertIsNotAskedForTheSimilarSectionWarning(): void
{
$content = DiviFixtures::markup('synthetic-basic.html');
DiviFixtures::givenPost($content);
Functions\when('get_preview_post_link')->justReturn('https://kunde.test/?page_id=7&preview=true');
Functions\when('do_action')->justReturn(null);
$similar = Mockery::mock(SimilarSections::class);
$similar->expects('warnings')->never();
$saved = [];
$failures = [];
$writer = DiviWriterFixture::writer($saved, $failures, false, null, null, null, $similar);
$input = ['post_id' => 7, 'tree_rev' => Rev::of($content)];
$page = $writer->page($input);
$section = $page->index->find('s1')->copy();
$page->document->children()[0]->removeChild($page->index->find('s1'));
$change = (new DiviChange('eingefügt'))->record($section, 'inserted');
$result = $writer->save('lit/library-insert', $page, $change, $input);
self::assertSame(811, $result['revision_id']);
}
}