Files
clinicpro/tests/Admin/AdminLogsTest.php
T

84 lines
3.1 KiB
PHP

<?php
namespace App\Tests\Admin;
use App\Tests\ApiTestCase;
/**
* GET /api/v1/admin/logs — admin-only, paginated, filterable by level.
*/
class AdminLogsTest extends ApiTestCase
{
private function seedLog(string $level, string $message): void
{
$this->em->getConnection()->insert('app_log', [
'level' => $level,
'message' => $message,
'channel' => 'app',
'path' => '/test',
'created_at' => time(),
]);
}
public function testNonAdminForbidden(): void
{
$user = $this->createUser(['ROLE_USER']);
$this->authJson('GET', '/api/v1/admin/logs', $user);
self::assertSame(403, $this->responseCode());
}
public function testAdminSeesLogsFilteredByLevel(): void
{
$marker = 'ADMINLOGTEST_' . bin2hex(random_bytes(5));
$this->seedLog('error', $marker . '_err');
$this->seedLog('warning', $marker . '_warn');
$admin = $this->createUser(['ROLE_ADMIN']);
$body = $this->authJson('GET', '/api/v1/admin/logs?level=error&search=' . $marker, $admin);
self::assertSame(200, $this->responseCode());
self::assertTrue($body['success']);
self::assertCount(1, $body['data']);
self::assertSame('error', $body['data'][0]['level']);
self::assertSame($marker . '_err', $body['data'][0]['message']);
self::assertArrayHasKey('totalRecords', $body['meta']);
$this->em->getConnection()->executeStatement('DELETE FROM app_log WHERE message LIKE ?', [$marker . '%']);
}
public function testExportNonAdminForbidden(): void
{
$user = $this->createUser(['ROLE_USER']);
$this->authJson('GET', '/api/v1/admin/logs/export', $user);
self::assertSame(403, $this->responseCode());
}
public function testAdminExportsCsvFilteredByLevel(): void
{
$marker = 'ADMINLOGEXPORT_' . bin2hex(random_bytes(5));
$this->seedLog('error', $marker . '_err');
$this->seedLog('warning', $marker . '_warn');
$admin = $this->createUser(['ROLE_ADMIN']);
$this->client->request(
'GET',
'/api/v1/admin/logs/export?level=error&search=' . $marker,
server: ['HTTP_AUTHORIZATION' => 'Bearer ' . $this->jwtFor($admin)],
);
$response = $this->client->getResponse();
self::assertSame(200, $response->getStatusCode());
self::assertStringContainsString('text/csv', (string) $response->headers->get('Content-Type'));
self::assertStringContainsString('attachment', (string) $response->headers->get('Content-Disposition'));
// StreamedResponse body is captured by BrowserKit into the internal response.
$csv = $this->client->getInternalResponse()->getContent();
self::assertStringContainsString('id,level,message', $csv);
self::assertStringContainsString($marker . '_err', $csv);
self::assertStringNotContainsString($marker . '_warn', $csv);
$this->em->getConnection()->executeStatement('DELETE FROM app_log WHERE message LIKE ?', [$marker . '%']);
}
}