Beide Tabellen hatten keine Frist; activity_events trägt Namen und Adressen im Klartext, api_usage_logs IP und User-Agent. MassPrunable, täglich 04:05 über model:prune, Fristen in config/monitoring.php (Roadmap 4.2). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
74 lines
2.2 KiB
PHP
74 lines
2.2 KiB
PHP
<?php
|
|
|
|
use App\Enums\ActivityType;
|
|
use App\Models\ActivityEvent;
|
|
use App\Models\ApiUsageLog;
|
|
use Illuminate\Console\Scheduling\Schedule;
|
|
use Tests\TestCase;
|
|
|
|
/**
|
|
* Löschfristen von Aktivitäts-Verlauf und API-Zugriffsprotokoll
|
|
* (Roadmap 4.2, config monitoring.retention).
|
|
*/
|
|
function activityEventAt(int $daysAgo): ActivityEvent
|
|
{
|
|
return ActivityEvent::create([
|
|
'type' => ActivityType::UserLoggedIn,
|
|
'occurred_at' => now()->subDays($daysAgo),
|
|
'description' => 'Anmeldung',
|
|
]);
|
|
}
|
|
|
|
function apiUsageLogAt(int $daysAgo): ApiUsageLog
|
|
{
|
|
return ApiUsageLog::create([
|
|
'method' => 'GET',
|
|
'path' => 'api/v1/press-releases',
|
|
'status_code' => 200,
|
|
'ip_address' => '203.0.113.7',
|
|
'requested_at' => now()->subDays($daysAgo),
|
|
]);
|
|
}
|
|
|
|
test('activity events are pruned after 395 days', function () {
|
|
/** @var TestCase $this */
|
|
$old = activityEventAt(396);
|
|
$recent = activityEventAt(394);
|
|
|
|
$this->artisan('model:prune', ['--model' => [ActivityEvent::class]])->assertSuccessful();
|
|
|
|
$this->assertModelMissing($old);
|
|
$this->assertModelExists($recent);
|
|
});
|
|
|
|
test('api usage logs are pruned after 90 days', function () {
|
|
/** @var TestCase $this */
|
|
$old = apiUsageLogAt(91);
|
|
$recent = apiUsageLogAt(89);
|
|
|
|
$this->artisan('model:prune', ['--model' => [ApiUsageLog::class]])->assertSuccessful();
|
|
|
|
$this->assertModelMissing($old);
|
|
$this->assertModelExists($recent);
|
|
});
|
|
|
|
test('the retention periods follow the configuration', function () {
|
|
/** @var TestCase $this */
|
|
config()->set('monitoring.retention.activity_events_days', 30);
|
|
config()->set('monitoring.retention.api_usage_logs_days', 7);
|
|
$event = activityEventAt(31);
|
|
$log = apiUsageLogAt(8);
|
|
|
|
$this->artisan('model:prune', ['--model' => [ActivityEvent::class, ApiUsageLog::class]])->assertSuccessful();
|
|
|
|
$this->assertModelMissing($event);
|
|
$this->assertModelMissing($log);
|
|
});
|
|
|
|
test('the daily prune run covers both logs', function () {
|
|
$command = collect(app(Schedule::class)->events())
|
|
->map(fn ($event) => (string) $event->command)
|
|
->first(fn (string $command) => str_contains($command, 'model:prune'));
|
|
|
|
expect($command)->toContain('ActivityEvent')->toContain('ApiUsageLog');
|
|
});
|