not->toBeFalse(); expect($route)->toContain("'reason' => 'no_license_plate_detected'"); expect($route)->toContain('], 200);'); expect($route)->not->toContain("throw new Exception('License plate extraction failed.')"); }); it('returns low-confidence LPR results without a failed HTTP status', function (): void { $route = file_get_contents(app_path('routes/moduleScannerRoute.php')); expect($route)->not->toBeFalse(); expect($route)->toContain("'reason' => 'low_confidence_license_plate'"); expect($route)->toContain("'message' => 'License plate recognition confidence too low.'"); expect($route)->toContain("'confidence' => \$lpr_result['confidence']"); expect($route)->not->toContain('License plate recognition confidence too low. Score:'); expect($route)->not->toContain('use Exception;'); }); it('does not store scanner images before LPR recognition', function (): void { $route = file_get_contents(app_path('routes/moduleScannerRoute.php')); expect($route)->not->toBeFalse(); expect($route)->toContain('new licenseplaterecognizer(false)'); expect($route)->toContain('getLPRImageUpload()'); expect($route)->toContain('getLPRRawImageUpload()'); expect($route)->toContain('$base64_image = null;'); expect($route)->toContain('if ($image_upload === null && $raw_image_upload === null)'); expect($route)->toContain('licenseplaterecognizerUploadFile($image_upload'); expect($route)->toContain('licenseplaterecognizerUploadUncached($raw_image_upload'); expect($route)->toContain("'path' => \$tmp_name"); expect($route)->toContain("'data' => \$image_data"); expect($route)->toContain("file_get_contents('php://input')"); expect($route)->toContain("str_starts_with(\$mime_type, 'image/')"); expect($route)->toContain('$recognizer->licenseplaterecognizer((string)$base64_image)'); expect($route)->toContain('$route_started_at = microtime(true);'); expect($route)->toContain('$client_timings = self::getLPRClientTimings();'); expect($route)->toContain('array_merge($client_timings, $recognizer->getLastTimings())'); expect($route)->toContain("header('Server-Timing: '"); expect($route)->toContain("'client_capture'"); expect($route)->toContain("'client_preflight'"); expect($route)->toContain("'client_visual_fingerprint'"); expect($route)->toContain("'client_draw'"); expect($route)->toContain("'client_encode'"); expect($route)->toContain("'client_frame_width'"); expect($route)->toContain("'client_frame_height'"); expect($route)->toContain("'client_frame_bytes'"); expect($route)->toContain("'cache'"); expect($route)->toContain("'cache_hit'"); expect($route)->toContain("'cache_miss'"); expect($route)->toContain("\$timings['local'] = self::getLPRLocalDuration(\$timings);"); expect($route)->toContain("'local'"); expect($route)->toContain("'upstream_dns'"); expect($route)->toContain("'upstream_connect'"); expect($route)->toContain("'upstream_tls'"); expect($route)->toContain("'upstream_pretransfer'"); expect($route)->toContain("'upstream_ttfb'"); expect($route)->toContain("'upstream_total'"); expect($route)->toContain("'upstream_processing'"); expect($route)->toContain("'route_total'"); expect($route)->toContain("'request_total'"); expect($route)->toContain('HTTP_X_LPR_CLIENT_CAPTURE_MS'); expect($route)->toContain('HTTP_X_LPR_CLIENT_FRAME_BYTES'); expect($route)->toContain('$value = $_GET[$field] ?? null;'); expect($route)->toContain("isset(\$_SERVER['REQUEST_TIME_FLOAT'])"); expect($route)->not->toContain("requireParameters(['base64_image'])"); expect($route)->not->toContain('file_get_contents($tmp_name)'); expect($route)->not->toContain('storeTempImageFromBase64'); expect($route)->not->toContain('new upload_store'); expect($route)->not->toContain('new openai'); }); it('reads raw scanner client timing metadata from request query parameters', function (): void { $previousGet = $_GET; $previousPost = $_POST; $headerNames = [ 'HTTP_X_LPR_CLIENT_CAPTURE_MS', 'HTTP_X_LPR_CLIENT_PREFLIGHT_MS', 'HTTP_X_LPR_CLIENT_DRAW_MS', 'HTTP_X_LPR_CLIENT_ENCODE_MS', 'HTTP_X_LPR_CLIENT_VISUAL_FINGERPRINT_MS', 'HTTP_X_LPR_CLIENT_FRAME_WIDTH', 'HTTP_X_LPR_CLIENT_FRAME_HEIGHT', 'HTTP_X_LPR_CLIENT_FRAME_BYTES', ]; $previousHeaders = []; foreach ($headerNames as $headerName) { $previousHeaders[$headerName] = $_SERVER[$headerName] ?? null; } try { $_GET = [ 'client_capture_ms' => '12.345', 'client_preflight_ms' => '1.500', 'client_draw_ms' => '2.250', 'client_encode_ms' => '8.500', 'client_visual_fingerprint_ms' => '0.750', 'client_frame_width' => '384', 'client_frame_height' => '216', 'client_frame_bytes' => '12345', ]; $_POST = []; $reflection = new ReflectionClass(moduleScannerRoute::class); $method = $reflection->getMethod('getLPRClientTimings'); expect($method->invoke(null))->toMatchArray([ 'client_capture' => 12.345, 'client_preflight' => 1.5, 'client_draw' => 2.25, 'client_encode' => 8.5, 'client_visual_fingerprint' => 0.75, 'client_frame_width' => 384.0, 'client_frame_height' => 216.0, 'client_frame_bytes' => 12345.0, ]); } finally { $_GET = $previousGet; $_POST = $previousPost; foreach ($previousHeaders as $headerName => $previousValue) { if ($previousValue === null) { unset($_SERVER[$headerName]); } else { $_SERVER[$headerName] = $previousValue; } } } });