fedi-feed-router/backend/tests/Feature/Http/Controllers/Api/V1/LogsControllerTest.php

259 lines
8.3 KiB
PHP
Raw Permalink Normal View History

2025-08-05 21:53:49 +02:00
<?php
namespace Tests\Feature\Http\Controllers\Api\V1;
2025-08-15 16:39:18 +02:00
use Domains\Logging\Enums\LogLevelEnum;
use Domains\Logging\Models\Log;
2025-08-05 21:53:49 +02:00
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class LogsControllerTest extends TestCase
{
use RefreshDatabase;
2025-08-14 22:01:15 +02:00
protected function setUp(): void
{
parent::setUp();
// Clear any logs that may have been created during application startup
Log::query()->delete();
}
2025-08-05 21:53:49 +02:00
public function test_index_returns_successful_response(): void
{
Log::factory()->count(5)->create();
$response = $this->getJson('/api/v1/logs');
$response->assertStatus(200)
->assertJsonStructure([
'success',
'message',
'data' => [
'logs' => [
'*' => [
'id',
'level',
'message',
'context',
'created_at',
'updated_at',
]
],
'pagination' => [
'current_page',
'last_page',
'per_page',
'total',
'from',
'to',
]
]
])
->assertJson([
'success' => true,
'message' => 'Logs retrieved successfully.'
]);
}
public function test_index_orders_logs_by_created_at_desc(): void
{
$oldLog = Log::factory()->create(['created_at' => now()->subDays(2)]);
$newLog = Log::factory()->create(['created_at' => now()->subDay()]);
$newestLog = Log::factory()->create(['created_at' => now()]);
$response = $this->getJson('/api/v1/logs');
$response->assertStatus(200);
$logs = $response->json('data.logs');
$this->assertEquals($newestLog->id, $logs[0]['id']);
$this->assertEquals($newLog->id, $logs[1]['id']);
$this->assertEquals($oldLog->id, $logs[2]['id']);
}
public function test_index_filters_by_level(): void
{
Log::factory()->create(['level' => LogLevelEnum::ERROR]);
Log::factory()->create(['level' => LogLevelEnum::WARNING]);
Log::factory()->create(['level' => LogLevelEnum::INFO]);
$response = $this->getJson('/api/v1/logs?level=error');
$response->assertStatus(200);
$logs = $response->json('data.logs');
$this->assertCount(1, $logs);
$this->assertEquals('error', $logs[0]['level']);
}
public function test_index_respects_per_page_parameter(): void
{
Log::factory()->count(15)->create();
$response = $this->getJson('/api/v1/logs?per_page=5');
$response->assertStatus(200);
$logs = $response->json('data.logs');
$pagination = $response->json('data.pagination');
$this->assertCount(5, $logs);
$this->assertEquals(5, $pagination['per_page']);
$this->assertEquals(15, $pagination['total']);
$this->assertEquals(3, $pagination['last_page']);
}
public function test_index_limits_per_page_to_maximum(): void
{
Log::factory()->count(10)->create();
$response = $this->getJson('/api/v1/logs?per_page=150');
$response->assertStatus(200);
$pagination = $response->json('data.pagination');
// Should be limited to 100 as per controller logic
$this->assertEquals(100, $pagination['per_page']);
}
public function test_index_uses_default_per_page_when_not_specified(): void
{
Log::factory()->count(25)->create();
$response = $this->getJson('/api/v1/logs');
$response->assertStatus(200);
$pagination = $response->json('data.pagination');
// Should use default of 20
$this->assertEquals(20, $pagination['per_page']);
}
public function test_index_handles_empty_logs(): void
{
$response = $this->getJson('/api/v1/logs');
$response->assertStatus(200)
->assertJson([
'success' => true,
'message' => 'Logs retrieved successfully.',
'data' => [
'logs' => [],
'pagination' => [
'total' => 0,
'current_page' => 1,
'last_page' => 1,
]
]
]);
}
public function test_index_pagination_works_correctly(): void
{
Log::factory()->count(25)->create();
// Test first page
$response = $this->getJson('/api/v1/logs?per_page=10&page=1');
$response->assertStatus(200);
$pagination = $response->json('data.pagination');
$this->assertEquals(1, $pagination['current_page']);
$this->assertEquals(3, $pagination['last_page']);
$this->assertEquals(1, $pagination['from']);
$this->assertEquals(10, $pagination['to']);
// Test second page
$response = $this->getJson('/api/v1/logs?per_page=10&page=2');
$response->assertStatus(200);
$pagination = $response->json('data.pagination');
$this->assertEquals(2, $pagination['current_page']);
$this->assertEquals(11, $pagination['from']);
$this->assertEquals(20, $pagination['to']);
}
public function test_index_with_multiple_log_levels(): void
{
Log::factory()->create(['level' => LogLevelEnum::ERROR, 'message' => 'Error message']);
Log::factory()->create(['level' => LogLevelEnum::WARNING, 'message' => 'Warning message']);
Log::factory()->create(['level' => LogLevelEnum::INFO, 'message' => 'Info message']);
Log::factory()->create(['level' => LogLevelEnum::DEBUG, 'message' => 'Debug message']);
$response = $this->getJson('/api/v1/logs');
$response->assertStatus(200);
$logs = $response->json('data.logs');
$this->assertCount(4, $logs);
$levels = array_column($logs, 'level');
$this->assertContains('error', $levels);
$this->assertContains('warning', $levels);
$this->assertContains('info', $levels);
$this->assertContains('debug', $levels);
}
2025-08-16 09:00:46 +02:00
public function test_index_handles_negative_per_page(): void
{
Log::factory()->count(5)->create();
$response = $this->getJson('/api/v1/logs?per_page=-5');
$response->assertStatus(200);
$pagination = $response->json('data.pagination');
// Should use default of 20 when negative value provided
$this->assertEquals(20, $pagination['per_page']);
}
public function test_index_handles_zero_per_page(): void
{
Log::factory()->count(5)->create();
$response = $this->getJson('/api/v1/logs?per_page=0');
$response->assertStatus(200);
$pagination = $response->json('data.pagination');
// Should use default of 20 when zero provided
$this->assertEquals(20, $pagination['per_page']);
}
public function test_index_excludes_system_noise_messages(): void
{
// Create a log with system noise message that should be excluded
Log::factory()->create(['message' => 'No active feeds found. Article discovery skipped.']);
Log::factory()->create(['message' => 'Regular log message']);
$response = $this->getJson('/api/v1/logs');
$response->assertStatus(200);
$logs = $response->json('data.logs');
// Should only get the regular log, not the system noise
$this->assertCount(1, $logs);
$this->assertEquals('Regular log message', $logs[0]['message']);
}
public function test_index_handles_non_numeric_per_page(): void
{
Log::factory()->count(5)->create();
$response = $this->getJson('/api/v1/logs?per_page=invalid');
$response->assertStatus(200);
$pagination = $response->json('data.pagination');
// Should use default of 20 when invalid value provided
$this->assertEquals(20, $pagination['per_page']);
}
2025-08-05 21:53:49 +02:00
}