fix: identical means identical bytes – text parts count, pages and posts only (ruling Q25)
- Fingerprint::content() includes non-whitespace text parts (raw HTML between blocks, inner HTML of core blocks) and opaque blocks with all their bytes; structure() unchanged; find-similar "identical" follows - make-global mode 2 also compares Fingerprint::canonical() bytes of each node - sources and targets: post types page and post only (POST_TYPES) - a rolled-back page N>1 keeps DiviSaver's "Revision X bleibt erhalten" - guide: escaped divi/global-layout re-expanded by Divi's do_blocks in shortcode-module and WooCommerce text output documented as residual risk Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
This commit is contained in:
@@ -490,4 +490,78 @@ final class LibraryMakeGlobalAbilityTest extends TestCase
|
||||
}
|
||||
self::assertSame([], $this->saved);
|
||||
}
|
||||
|
||||
/** @return array<string, array{string}> */
|
||||
public static function visibleExtras(): array
|
||||
{
|
||||
return [
|
||||
'core paragraph' => ['<!-- wp:paragraph --><p>ONLY ON 8</p><!-- /wp:paragraph -->'],
|
||||
'raw text part' => ['<p>ONLY ON 8</p>'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruling Q25 (review of Task 15): a copy with extra visible text – a core paragraph or raw HTML between
|
||||
* blocks – is no identical occurrence; replacing it would swap visible content.
|
||||
*
|
||||
* @dataProvider visibleExtras
|
||||
*/
|
||||
public function testACopyWithExtraVisibleTextIsNoIdenticalOccurrence(string $extra): void
|
||||
{
|
||||
$copy = $this->givenCopiesOf1058();
|
||||
$at = strrpos($copy, '<!-- /wp:divi/column -->');
|
||||
$changed = substr($copy, 0, (int) $at) . $extra . substr($copy, (int) $at);
|
||||
LibraryFixtures::given([
|
||||
LibraryFixtures::item(1058),
|
||||
new WP_Post(['ID' => 8, 'post_type' => 'page', 'post_status' => 'publish', 'post_title' => 'Team',
|
||||
'post_content' => '<!-- wp:divi/placeholder -->' . $changed . '<!-- /wp:divi/placeholder -->']),
|
||||
get_post(9),
|
||||
]);
|
||||
|
||||
$result = $this->ability()->execute(self::targets(['s0'], ['s1'], true));
|
||||
|
||||
self::assertToolError($result, 'validation_failed');
|
||||
self::assertArrayHasKey('targets.0.ids.0', self::errorFields($result));
|
||||
self::assertSame([], $this->saved);
|
||||
}
|
||||
|
||||
/** Scope (ruling Q25): only pages and posts – other Divi-enabled types are neither targets nor sources. */
|
||||
public function testOnlyPagesAndPostsAreTargetsAndSources(): void
|
||||
{
|
||||
$this->givenCopiesOf1058();
|
||||
$project = get_post(8);
|
||||
$project->post_type = 'project';
|
||||
LibraryFixtures::given([LibraryFixtures::item(1058), $project, get_post(9)]);
|
||||
|
||||
$target = $this->ability()->execute(self::targets(['s0'], ['s1'], true));
|
||||
self::assertToolError($target, 'validation_failed');
|
||||
self::assertArrayHasKey('targets.0.post_id', self::errorFields($target));
|
||||
|
||||
$source = $this->ability()->execute(
|
||||
['post_id' => 8, 'tree_rev' => Rev::of((string) $project->post_content), 'id' => 's0', 'title' => 'x']
|
||||
);
|
||||
self::assertToolError($source, 'validation_failed');
|
||||
self::assertArrayHasKey('post_id', self::errorFields($source));
|
||||
self::assertSame([], $this->saved);
|
||||
self::assertSame([], $this->specs);
|
||||
}
|
||||
|
||||
/** A rolled-back page N>1 keeps DiviSaver's note on the revision that stays. */
|
||||
public function testAFailureMidwayKeepsTheRevisionNote(): void
|
||||
{
|
||||
$this->givenCopiesOf1058();
|
||||
$kept = WriteFailed::rolledBack(
|
||||
'Die Divi-Seite konnte nicht gespeichert werden.',
|
||||
state: \LIT\MCP\Abilities\Errors::notSavedKeeping('Revision 812')
|
||||
);
|
||||
|
||||
try {
|
||||
$this->ability([], true, false, [null, $kept])->execute(self::targets(['s0'], ['s1'], true));
|
||||
self::fail('no WriteFailed');
|
||||
} catch (WriteFailed $e) {
|
||||
$message = (string) $e->toError()->get_error_message();
|
||||
self::assertStringContainsString('Revision 812 bleibt erhalten', $message);
|
||||
self::assertStringContainsString('Bereits ersetzt', $message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user