refactor: ChangeLog::recordPartial and column-size truncation

recordPartial() replaces the partial-log FollowUp blocks in content-create,
content-update and post-replace-with-copy; record() truncates ability,
object_type and object_id to their column sizes.

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:
2026-09-26 01:15:13 +02:00
co-authored by Claude Opus 5.5
parent 46a445fe9d
commit 0c4da28855
8 changed files with 94 additions and 47 deletions
+47
View File
@@ -67,6 +67,53 @@ final class ChangeLogTest extends TestCase
unlink($log);
}
public function testRecordTruncatesObjectIdAndAbilityToTheColumnSizes(): void
{
Functions\when('current_time')->justReturn('2026-09-25 08:00:00');
Functions\when('get_current_user_id')->justReturn(3);
$db = Mockery::mock(\wpdb::class)->makePartial();
$db->expects('insert')
->with('wp_lit_mcp_log', Mockery::on(static function (array $row): bool {
return $row['object_id'] === str_repeat('ä', 191) && $row['ability'] === str_repeat('ö', 100);
}), Mockery::type('array'))
->andReturn(1);
(new ChangeLog($db))->record(str_repeat('ö', 150), 'option', str_repeat('ä', 300), 'x');
}
public function testRecordPartialStoresResultPartial(): void
{
Functions\when('current_time')->justReturn('2026-09-25 08:00:00');
Functions\when('get_current_user_id')->justReturn(3);
$db = Mockery::mock(\wpdb::class)->makePartial();
$db->expects('insert')
->with('wp_lit_mcp_log', Mockery::on(static function (array $row): bool {
return $row['result'] === 'partial' && $row['revision_id'] === 7 && $row['object_id'] === '12';
}), Mockery::type('array'))
->andReturn(1);
(new ChangeLog($db))->recordPartial('lit/content-update', 'page', '12', 'teilweise', 7);
}
public function testRecordPartialNeverThrows(): void
{
Functions\when('current_time')->justReturn('2026-09-25 08:00:00');
Functions\when('get_current_user_id')->justReturn(3);
$db = Mockery::mock(\wpdb::class)->makePartial();
$db->allows('insert')->andThrow(new \RuntimeException('db gone'));
$log = (string) tempnam(sys_get_temp_dir(), 'lit-mcp-log');
$previous = ini_set('error_log', $log);
try {
(new ChangeLog($db))->recordPartial('lit/menu-set-items', 'nav_menu', '4', 'teilweise');
} finally {
ini_set('error_log', (string) $previous);
}
self::assertStringContainsString('db gone', (string) file_get_contents($log));
unlink($log);
}
public function testPurgeDeletesRowsOlderThanTheRetention(): void
{
$db = Mockery::mock(\wpdb::class)->makePartial();
@@ -134,8 +134,8 @@ final class ContentCreateAbilityTest extends TestCase
Functions\when('wp_insert_post')->justReturn(42);
Functions\when('wp_delete_post')->justReturn(false);
$log = Mockery::mock(ChangeLog::class);
$log->expects('record')
->with('lit/content-create', 'lit_person', '42', Mockery::type('string'), null, null, 'partial')
$log->expects('recordPartial')
->with('lit/content-create', 'lit_person', '42', Mockery::type('string'))
->andReturn(9);
$failure = $this->execute($writer, $log);
@@ -153,7 +153,7 @@ final class ContentCreateAbilityTest extends TestCase
Functions\when('wp_insert_post')->justReturn(42);
Functions\when('wp_delete_post')->justReturn(new WP_Post(['ID' => 42]));
$log = Mockery::mock(ChangeLog::class);
$log->expects('record')->andReturn(9);
$log->expects('recordPartial');
$failure = $this->execute($writer, $log);
@@ -168,8 +168,8 @@ final class ContentCreateAbilityTest extends TestCase
throw new RuntimeException('save_post hook kaputt');
});
$log = Mockery::mock(ChangeLog::class);
$log->expects('record')
->with('lit/content-create', 'lit_person', '', Mockery::type('string'), null, null, 'partial')
$log->expects('recordPartial')
->with('lit/content-create', 'lit_person', '', Mockery::type('string'))
->andReturn(9);
$failure = $this->execute($writer, $log);
@@ -261,8 +261,8 @@ final class ContentUpdateAbilityTest extends TestCase
$this->captureUpdates($updates);
Functions\when('wp_revisions_enabled')->justReturn(false);
$log = Mockery::mock(ChangeLog::class);
$log->expects('record')
->with('lit/content-update', 'page', '5', Mockery::type('string'), 811, null, 'partial')
$log->expects('recordPartial')
->with('lit/content-update', 'page', '5', Mockery::type('string'), 811)
->andReturn(12);
$failure = $this->executeExpectingFailure($writer, $input, $log);
@@ -228,8 +228,8 @@ final class PostReplaceWithCopyAbilityTest extends TestCase
$cloner->expects('restore')->with($this->original, self::SNAPSHOT, PostCloner::PARTS)->andThrow(new RuntimeException('Restore incomplete: terms'));
Functions\expect('wp_trash_post')->never();
$log = Mockery::mock(ChangeLog::class);
$log->expects('record')
->with('lit/post-replace-with-copy', 'page', '5', Mockery::type('string'), 900, null, 'partial')
$log->expects('recordPartial')
->with('lit/post-replace-with-copy', 'page', '5', Mockery::type('string'), 900)
->andReturn(12);
try {