feat: change log tab with filters, revision links and clear button
ChangeLog gains query()/abilities()/clear() (filters: ability, user, result, date range - all optional and additive). LogTab/LogListTable render the "Protokoll" admin tab: WP_List_Table with pagination, links to the post/attachment/nav_menu edit screen by object_type, a revision link shown only when the user may edit the revision's parent post, and a nonce+manage_options-gated "Protokoll leeren" with a JS confirmation and highlighted 'partial' rows. 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:
@@ -126,4 +126,70 @@ final class ChangeLogTest extends TestCase
|
||||
|
||||
self::assertSame(3, (new ChangeLog($db))->purgeOlderThan(90));
|
||||
}
|
||||
|
||||
public function testQueryFiltersAndPaginatesNewestFirst(): void
|
||||
{
|
||||
$db = Mockery::mock(\wpdb::class)->makePartial();
|
||||
$db->expects('get_var')
|
||||
->with(Mockery::on(static fn (string $sql): bool => $sql
|
||||
=== "SELECT COUNT(*) FROM wp_lit_mcp_log WHERE 1 = 1 AND ability = 'lit/content-update'"
|
||||
. " AND user_id = 3"))
|
||||
->andReturn('12');
|
||||
$db->expects('get_results')
|
||||
->with(
|
||||
Mockery::on(static fn (string $sql): bool => str_ends_with($sql, 'ORDER BY id DESC LIMIT 50 OFFSET 50')),
|
||||
'ARRAY_A'
|
||||
)
|
||||
->andReturn([['id' => '7', 'ability' => 'lit/content-update']]);
|
||||
|
||||
$result = (new ChangeLog($db))->query(['ability' => 'lit/content-update', 'user_id' => 3], 50, 50);
|
||||
|
||||
self::assertSame(12, $result['total']);
|
||||
self::assertSame('7', $result['rows'][0]['id']);
|
||||
}
|
||||
|
||||
public function testQueryFiltersByResultAndDateRange(): void
|
||||
{
|
||||
$db = Mockery::mock(\wpdb::class)->makePartial();
|
||||
$db->expects('get_var')
|
||||
->with(Mockery::on(static fn (string $sql): bool => $sql
|
||||
=== "SELECT COUNT(*) FROM wp_lit_mcp_log WHERE 1 = 1 AND result = 'partial'"
|
||||
. " AND created_at >= '2026-09-01 00:00:00' AND created_at <= '2026-09-25 23:59:59'"))
|
||||
->andReturn('2');
|
||||
$db->expects('get_results')->andReturn([]);
|
||||
|
||||
$result = (new ChangeLog($db))->query(
|
||||
['result' => 'partial', 'date_from' => '2026-09-01', 'date_to' => '2026-09-25'],
|
||||
50,
|
||||
0
|
||||
);
|
||||
|
||||
self::assertSame(2, $result['total']);
|
||||
self::assertSame([], $result['rows']);
|
||||
}
|
||||
|
||||
public function testQueryWithoutFiltersUsesTheBaseCondition(): void
|
||||
{
|
||||
$db = Mockery::mock(\wpdb::class)->makePartial();
|
||||
$db->expects('get_var')
|
||||
->with('SELECT COUNT(*) FROM wp_lit_mcp_log WHERE 1 = 1')
|
||||
->andReturn('0');
|
||||
$db->expects('get_results')->andReturn(null);
|
||||
|
||||
$result = (new ChangeLog($db))->query([], 50, 0);
|
||||
|
||||
self::assertSame(0, $result['total']);
|
||||
self::assertSame([], $result['rows']);
|
||||
}
|
||||
|
||||
public function testAbilitiesAndClear(): void
|
||||
{
|
||||
$db = Mockery::mock(\wpdb::class)->makePartial();
|
||||
$db->expects('get_col')->with('SELECT DISTINCT ability FROM wp_lit_mcp_log ORDER BY ability')->andReturn(['lit/a']);
|
||||
$db->expects('query')->with('DELETE FROM wp_lit_mcp_log')->andReturn(4);
|
||||
$log = new ChangeLog($db);
|
||||
|
||||
self::assertSame(['lit/a'], $log->abilities());
|
||||
$log->clear();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user