test: file-based editor byte-identity regression; filters fixture with JSON escapes (P20)
synthetic-divi-filters.html now stores its paragraph as Divi does (unicode escapes, bytes built with chr(92) and checked with od). A data-provider test inserts a section as a user without unfiltered_html into every Divi 5 fixture page read from disk and asserts that every other byte stays. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1 +1 @@
|
|||||||
<!-- wp:divi/placeholder --><!-- wp:divi/section {"module":{"meta":{"adminLabel":{"desktop":{"value":"Eigene Felder"}}}},"builderVersion":"5.2.1"} --><!-- wp:divi/row {"module":{"meta":{"adminLabel":{"desktop":{"value":"Eigene Felder – Zeile"}}}},"builderVersion":"5.2.1"} --><!-- wp:divi/column {"module":{"decoration":{"sizing":{"desktop":{"value":{"flexType":"24_24"}}}}},"builderVersion":"5.2.1"} --><!-- wp:divi/text {"module":{"meta":{"adminLabel":{"desktop":{"value":"Eigene Felder – Artikel"}}},"advanced":{"html":{"elementType":{"desktop":{"value":"article"}}}},"decoration":{"attributes":{"desktop":{"value":{"attributes":[{"id":"lit-attr-1","name":"data-track","value":"hero","targetElement":""}]}}}}},"content":{"innerContent":{"desktop":{"value":"<p>Text mit eigenem Element und Attribut.</p>"}}},"builderVersion":"5.2.1"} --><!-- /wp:divi/text --><!-- wp:divi/heading {"title":{"innerContent":{"desktop":{"value":"Eigene Felder bleiben"}},"decoration":{"font":{"font":{"desktop":{"value":{"headingLevel":"h2"}}}}}},"module":{"meta":{"adminLabel":{"desktop":{"value":"Eigene Felder – Überschrift"}}}},"builderVersion":"5.2.1"} --><!-- /wp:divi/heading --><!-- wp:divi/button {"button":{"innerContent":{"desktop":{"value":{"text":"Kontakt","linkUrl":"/kontakt"}}}},"module":{"meta":{"adminLabel":{"desktop":{"value":"Eigene Felder – Button"}}}},"builderVersion":"5.2.1"} --><!-- /wp:divi/button --><!-- /wp:divi/column --><!-- /wp:divi/row --><!-- /wp:divi/section --><!-- /wp:divi/placeholder -->
|
<!-- wp:divi/placeholder --><!-- wp:divi/section {"module":{"meta":{"adminLabel":{"desktop":{"value":"Eigene Felder"}}}},"builderVersion":"5.2.1"} --><!-- wp:divi/row {"module":{"meta":{"adminLabel":{"desktop":{"value":"Eigene Felder – Zeile"}}}},"builderVersion":"5.2.1"} --><!-- wp:divi/column {"module":{"decoration":{"sizing":{"desktop":{"value":{"flexType":"24_24"}}}}},"builderVersion":"5.2.1"} --><!-- wp:divi/text {"module":{"meta":{"adminLabel":{"desktop":{"value":"Eigene Felder – Artikel"}}},"advanced":{"html":{"elementType":{"desktop":{"value":"article"}}}},"decoration":{"attributes":{"desktop":{"value":{"attributes":[{"id":"lit-attr-1","name":"data-track","value":"hero","targetElement":""}]}}}}},"content":{"innerContent":{"desktop":{"value":"\u003cp\u003eText mit eigenem Element und Attribut.\u003c/p\u003e"}}},"builderVersion":"5.2.1"} --><!-- /wp:divi/text --><!-- wp:divi/heading {"title":{"innerContent":{"desktop":{"value":"Eigene Felder bleiben"}},"decoration":{"font":{"font":{"desktop":{"value":{"headingLevel":"h2"}}}}}},"module":{"meta":{"adminLabel":{"desktop":{"value":"Eigene Felder – Überschrift"}}}},"builderVersion":"5.2.1"} --><!-- /wp:divi/heading --><!-- wp:divi/button {"button":{"innerContent":{"desktop":{"value":{"text":"Kontakt","linkUrl":"/kontakt"}}}},"module":{"meta":{"adminLabel":{"desktop":{"value":"Eigene Felder – Button"}}}},"builderVersion":"5.2.1"} --><!-- /wp:divi/button --><!-- /wp:divi/column --><!-- /wp:divi/row --><!-- /wp:divi/section --><!-- /wp:divi/placeholder -->
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace LIT\MCP\Tests\Unit\Integrations\Divi\Pages;
|
||||||
|
|
||||||
|
use Brain\Monkey\Functions;
|
||||||
|
use LIT\MCP\Abilities\Rev;
|
||||||
|
use LIT\MCP\Integrations\Divi\BlockTree\NodeIndex;
|
||||||
|
use LIT\MCP\Integrations\Divi\BlockTree\Parser;
|
||||||
|
use LIT\MCP\Integrations\Divi\BlockTree\Serializer;
|
||||||
|
use LIT\MCP\Integrations\Divi\Pages\DiviInsertAbility;
|
||||||
|
use LIT\MCP\Tests\Support\DiviFixtures;
|
||||||
|
use LIT\MCP\Tests\Support\DiviWriterFixture;
|
||||||
|
use LIT\MCP\Tests\Unit\TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ruling P20 (regression): a user without unfiltered_html (editor) changes one place of a real page;
|
||||||
|
* every other byte stays (JSON unicode escapes of markup, CRLF, empty block pairs, instances, foreign
|
||||||
|
* blocks). The pages are read from the fixture files only (never written inline), so no tool in
|
||||||
|
* between can decode an escape sequence.
|
||||||
|
*/
|
||||||
|
final class DiviEditorByteIdentityTest extends TestCase
|
||||||
|
{
|
||||||
|
/** @return array<string, array{string}> */
|
||||||
|
public static function pages(): array
|
||||||
|
{
|
||||||
|
$pages = [];
|
||||||
|
foreach (['', 'stage3/'] as $dir) {
|
||||||
|
foreach (glob(dirname(__DIR__, 4) . '/Fixtures/divi/' . $dir . '*.html') ?: [] as $file) {
|
||||||
|
$name = $dir . basename($file);
|
||||||
|
if ($name !== 'divi4-shortcodes.html') {
|
||||||
|
$pages[$name] = [$name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $pages;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @dataProvider pages */
|
||||||
|
public function testAnEditorInsertKeepsEveryOtherByte(string $fixture): void
|
||||||
|
{
|
||||||
|
$original = DiviFixtures::markup($fixture);
|
||||||
|
self::assertNotSame('', $original, $fixture);
|
||||||
|
DiviFixtures::givenPost($original);
|
||||||
|
Functions\when('get_preview_post_link')->justReturn('https://kunde.test/?page_id=7&preview=true');
|
||||||
|
$saved = [];
|
||||||
|
|
||||||
|
$result = (new DiviInsertAbility(DiviWriterFixture::writer($saved, unfiltered: false)))->execute([
|
||||||
|
'post_id' => 7,
|
||||||
|
'tree_rev' => Rev::of($original),
|
||||||
|
'nodes' => [['type' => 'section']],
|
||||||
|
]);
|
||||||
|
|
||||||
|
self::assertTrue($result['ok'] ?? false, $fixture . ': ' . json_encode($result));
|
||||||
|
self::assertCount(1, $saved);
|
||||||
|
$node = NodeIndex::build((new Parser())->parse($saved[0]))->find($result['changed'][0]['id']);
|
||||||
|
self::assertNotNull($node, $fixture);
|
||||||
|
$inserted = Serializer::block($node);
|
||||||
|
$at = strpos($saved[0], $inserted);
|
||||||
|
self::assertNotFalse($at, $fixture);
|
||||||
|
self::assertSame(
|
||||||
|
$original,
|
||||||
|
substr($saved[0], 0, (int) $at) . substr($saved[0], (int) $at + strlen($inserted)),
|
||||||
|
$fixture . ': only the new section was added'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user