responseFactory = $this->createMock(ResponseFactoryInterface::class); $this->responseFactory ->method('createResponse') ->willReturnCallback(static fn (int $statusCode): Response => new Response($statusCode)); $this->twig = $this->createMock(Twig::class); } public function testInvokeRendersFriendlyNotFoundPage(): void { $request = (new ServerRequestFactory())->createServerRequest('GET', '/missing'); $exception = new HttpNotFoundException($request); $this->twig ->expects(self::once()) ->method('render') ->willReturnCallback(function (Response $response, string $template, array $data): Response { self::assertSame(404, $response->getStatusCode()); self::assertSame('@Kernel/error.twig', $template); self::assertSame(404, $data['status']); self::assertSame('La page demandée est introuvable.', $data['message']); $response->getBody()->write('404: ' . $data['message']); return $response; }); $handler = new DefaultErrorHandler($this->responseFactory, $this->twig, false); $response = $handler($request, $exception, false, true, true); self::assertSame(404, $response->getStatusCode()); self::assertStringContainsString('404: La page demandée est introuvable.', (string) $response->getBody()); } public function testInvokeRendersDatabaseProvisioningErrorAs503(): void { $request = (new ServerRequestFactory())->createServerRequest('GET', '/'); $exception = new DatabaseNotProvisionedException('La base de données doit être provisionnée.'); $this->twig ->expects(self::once()) ->method('render') ->willReturnCallback(function (Response $response, string $template, array $data): Response { self::assertSame(503, $response->getStatusCode()); self::assertSame('@Kernel/error.twig', $template); self::assertSame(503, $data['status']); self::assertSame('La base de données doit être provisionnée.', $data['message']); $response->getBody()->write('503: ' . $data['message']); return $response; }); $handler = new DefaultErrorHandler($this->responseFactory, $this->twig, false); $response = $handler($request, $exception, false, true, true); self::assertSame(503, $response->getStatusCode()); self::assertStringContainsString('503: La base de données doit être provisionnée.', (string) $response->getBody()); } public function testInvokeDoesNotRethrowHttpExceptionsInDevelopment(): void { $request = (new ServerRequestFactory())->createServerRequest('GET', '/missing'); $exception = new HttpNotFoundException($request); $this->twig ->expects(self::once()) ->method('render') ->willReturnCallback(function (Response $response, string $template, array $data): Response { self::assertSame(404, $response->getStatusCode()); self::assertSame('@Kernel/error.twig', $template); self::assertSame(404, $data['status']); self::assertSame('La page demandée est introuvable.', $data['message']); $response->getBody()->write('404 dev: ' . $data['message']); return $response; }); $handler = new DefaultErrorHandler($this->responseFactory, $this->twig, true); $response = $handler($request, $exception, true, true, true); self::assertSame(404, $response->getStatusCode()); self::assertStringContainsString('404 dev: La page demandée est introuvable.', (string) $response->getBody()); } public function testInvokeRethrowsUnexpectedExceptionsInDevelopment(): void { $request = (new ServerRequestFactory())->createServerRequest('GET', '/boom'); $exception = new \RuntimeException('boom'); $this->twig->expects(self::never())->method('render'); $handler = new DefaultErrorHandler($this->responseFactory, $this->twig, true); $this->expectExceptionObject($exception); $handler($request, $exception, true, true, true); } }