$ct); } test('validator rejects oversize body', function () { $body = str_repeat('a', 20000); $result = csp_report_validate_payload(_csp_headers('application/csp-report'), $body, 16384); expect($result['ok'])->toBeFalse(); expect(strtolower($result['reason']))->toContain('size'); }); test('validator rejects wrong content type', function () { $result = csp_report_validate_payload(_csp_headers('text/plain'), '{"csp-report":{}}', 16384); expect($result['ok'])->toBeFalse(); expect(strtolower($result['reason']))->toContain('content-type'); }); test('validator rejects malformed JSON', function () { $result = csp_report_validate_payload(_csp_headers('application/csp-report'), 'not json{', 16384); expect($result['ok'])->toBeFalse(); expect(strtolower($result['reason']))->toContain('json'); }); test('validator accepts legacy csp-report format', function () { $body = json_encode(array( 'csp-report' => array( 'violated-directive' => 'script-src', 'blocked-uri' => 'inline', 'document-uri' => 'https://x/y', ), )); $result = csp_report_validate_payload(_csp_headers('application/csp-report'), $body, 16384); expect($result['ok'])->toBeTrue(); expect($result['summary'])->toContain('script-src'); expect($result['summary'])->toContain('inline'); expect($result['summary'])->toContain('https://x/y'); }); test('validator accepts Reporting API body format', function () { $body = json_encode(array( 'type' => 'csp-violation', 'body' => array( 'effectiveDirective' => 'script-src', 'blockedURL' => 'https://evil.example/x.js', 'documentURL' => 'https://app.example/page', ), )); $result = csp_report_validate_payload(_csp_headers('application/json'), $body, 16384); expect($result['ok'])->toBeTrue(); expect($result['summary'])->toContain('script-src'); }); test('sanitizer strips CR/LF so a report cannot forge log lines', function () { $dirty = "script-src\r\nFORGED LOG LINE"; $clean = csp_report_sanitize_field($dirty); expect($clean)->not->toContain("\r"); expect($clean)->not->toContain("\n"); }); test('sanitizer truncates overlong fields', function () { $clean = csp_report_sanitize_field(str_repeat('a', 500)); expect(strlen($clean))->toBeLessThanOrEqual(256); });