logger = $this->createMock(Logger::class); $this->handler = new FallbackErrorHandler($this->logger); }); it('handles any exception', function () { $exception = new \RuntimeException('Any error'); expect($this->handler->canHandle($exception))->toBeTrue(); }); it('logs exception with full context', function () { $exception = new \RuntimeException('Test error'); $this->logger ->expects($this->once()) ->method('error') ->with('Unhandled exception', $this->callback(function ($context) use ($exception) { return $context instanceof \App\Framework\Logging\ValueObjects\LogContext && $context->structured['exception_class'] === \RuntimeException::class && $context->structured['message'] === 'Test error' && isset($context->structured['file']) && isset($context->structured['line']) && isset($context->structured['trace']); })); $this->handler->handle($exception); }); it('returns generic error message', function () { $exception = new \RuntimeException('Detailed error'); $result = $this->handler->handle($exception); expect($result->handled)->toBeTrue(); expect($result->message)->toBe('An unexpected error occurred'); expect($result->isFinal)->toBeTrue(); expect($result->statusCode)->toBe(500); expect($result->data['error_type'])->toBe('unhandled'); expect($result->data['exception_class'])->toBe(\RuntimeException::class); }); it('marks result as final', function () { $exception = new \RuntimeException('Test'); $result = $this->handler->handle($exception); expect($result->isFinal)->toBeTrue(); }); it('has LOWEST priority', function () { expect($this->handler->getPriority())->toBe(ErrorHandlerPriority::LOWEST); }); it('has correct name', function () { expect($this->handler->getName())->toBe('fallback_error_handler'); }); });