analyze([$logPath]); expect($report['summary']['total_lines'])->toBe(4) ->and($report['summary']['matched_requests'])->toBe(3) ->and($report['summary']['legacy_key_requests'])->toBe(3) ->and($report['summary']['unique_client_ips'])->toBe(2) ->and($report['summary']['unique_api_key_fingerprints'])->toBe(2) ->and($report['endpoints'])->toHaveKey('pressrelease/list') ->and($report['endpoints'])->toHaveKey('pressrelease/create') ->and($report['endpoints'])->toHaveKey('company/list') ->and(json_encode($report))->not->toContain('secret-one'); }); test('legacy api access log command renders a summary', function () { /** @var TestCase $this */ $logPath = storage_path('framework/testing/legacy-api-access-command.log'); if (! is_dir(dirname($logPath))) { mkdir(dirname($logPath), 0775, true); } file_put_contents($logPath, '203.0.113.10 - - [28/Apr/2026:10:00:00 +0200] "GET /newsletter/subscribe?api_key=secret-one HTTP/1.1" 200 123 "-" "Client A"'); $this->artisan('api:analyze-legacy-access-logs', [ 'paths' => [$logPath], '--no-report' => true, ]) ->expectsOutput('Legacy-API-Access-Log-Auswertung') ->expectsOutput('Legacy-API-Requests: 1') ->expectsOutput('Requests mit api_key: 1') ->assertSuccessful(); });