provider = new AuditSearchResourceProvider(); } public function testResourcesReturnsBothAuditKeys(): void { $resources = $this->provider->resources(); $this->assertArrayHasKey('api-audit', $resources); $this->assertArrayHasKey('system-audit', $resources); $this->assertCount(2, $resources); } public function testResourcesContainRequiredSqlKeys(): void { foreach ($this->provider->resources() as $key => $resource) { $this->assertArrayHasKey('label', $resource, "Resource '{$key}' missing label"); $this->assertArrayHasKey('permission', $resource, "Resource '{$key}' missing permission"); $this->assertArrayHasKey('count_sql', $resource, "Resource '{$key}' missing count_sql"); $this->assertArrayHasKey('preview_sql', $resource, "Resource '{$key}' missing preview_sql"); $this->assertArrayHasKey('result_sql', $resource, "Resource '{$key}' missing result_sql"); } } public function testResourcePermissionKeys(): void { $resources = $this->provider->resources(); $this->assertSame('audit.api.view', $resources['api-audit']['permission']); $this->assertSame('audit.system.view', $resources['system-audit']['permission']); } public function testMapApiAuditItem(): void { $row = [ 'id' => 42, 'method' => 'POST', 'path' => '/api/v1/users', 'status_code' => 201, 'request_id' => 'req-abc', 'created_at' => '2026-03-15 10:30:00', ]; $result = $this->provider->mapResultItem('api-audit', $row); $this->assertNotNull($result); $this->assertSame('POST /api/v1/users', $result['title']); $this->assertStringContains('201', $result['subtitle']); $this->assertStringContains('2026-03-15 10:30:00', $result['subtitle']); $this->assertSame('bi-shield-check', $result['icon']); $this->assertStringContainsString('admin/api-audit/view/42', $result['url']); } public function testMapApiAuditItemFallsBackToRequestId(): void { $row = ['id' => 1, 'method' => '', 'path' => '', 'status_code' => 0, 'request_id' => 'req-fallback']; $result = $this->provider->mapResultItem('api-audit', $row); $this->assertNotNull($result); $this->assertSame('req-fallback', $result['title']); } public function testMapApiAuditItemReturnsNullWhenEmpty(): void { $row = ['id' => 1, 'method' => '', 'path' => '', 'status_code' => 0, 'request_id' => '']; $result = $this->provider->mapResultItem('api-audit', $row); $this->assertNull($result); } public function testMapSystemAuditItem(): void { $row = [ 'id' => 99, 'event_type' => 'admin.settings.update', 'outcome' => 'success', 'request_id' => 'req-xyz', 'created_at' => '2026-03-15 11:00:00', ]; $result = $this->provider->mapResultItem('system-audit', $row); $this->assertNotNull($result); $this->assertSame('admin.settings.update', $result['title']); $this->assertStringContains('SUCCESS', $result['subtitle']); $this->assertStringContains('2026-03-15 11:00:00', $result['subtitle']); $this->assertSame('bi-journal-lock', $result['icon']); $this->assertStringContainsString('admin/system-audit/view/99', $result['url']); } public function testMapSystemAuditItemFallsBackToRequestId(): void { $row = ['id' => 1, 'event_type' => '', 'outcome' => '', 'request_id' => 'req-fallback']; $result = $this->provider->mapResultItem('system-audit', $row); $this->assertNotNull($result); $this->assertSame('req-fallback', $result['title']); } public function testMapSystemAuditItemReturnsNullWhenEmpty(): void { $row = ['id' => 1, 'event_type' => '', 'outcome' => '', 'request_id' => '']; $result = $this->provider->mapResultItem('system-audit', $row); $this->assertNull($result); } public function testMapResultItemReturnsNullForUnknownKey(): void { $result = $this->provider->mapResultItem('unknown', ['id' => 1]); $this->assertNull($result); } public function testListUrlForApiAudit(): void { $url = $this->provider->listUrl('api-audit', 'test%20query'); $this->assertStringContainsString('admin/api-audit', $url); $this->assertStringContainsString('search=test%20query', $url); } public function testListUrlForSystemAudit(): void { $url = $this->provider->listUrl('system-audit', 'test'); $this->assertStringContainsString('admin/system-audit', $url); $this->assertStringContainsString('search=test', $url); } public function testListUrlReturnsEmptyForUnknownKey(): void { $url = $this->provider->listUrl('unknown', 'test'); $this->assertSame('', $url); } /** * Helper to check string containment (mirrors assertStringContainsString for readability). */ private static function assertStringContains(string $needle, string $haystack): void { self::assertStringContainsString($needle, $haystack); } }