1
0
Files
breadcrumb-the-shire/tests/Http/ErrorRendererTest.php

156 lines
5.8 KiB
PHP
Raw Normal View History

<?php
namespace MintyPHP\Tests\Http;
use MintyPHP\Http\ErrorRenderer;
use PHPUnit\Framework\TestCase;
class ErrorRendererTest extends TestCase
{
public function testRenderDevReturnsCompleteHtmlDocument(): void
{
$data = self::sampleData();
$html = ErrorRenderer::renderDev($data);
$this->assertStringContainsString('<!DOCTYPE html>', $html);
$this->assertStringContainsString('</html>', $html);
$this->assertStringContainsString('<style>', $html);
$this->assertStringContainsString('<script>', $html);
}
public function testRenderDevContainsExceptionDetails(): void
{
$data = self::sampleData();
$html = ErrorRenderer::renderDev($data);
$this->assertStringContainsString('RuntimeException', $html);
$this->assertStringContainsString('Test error message', $html);
$this->assertStringContainsString('test-request-id-123', $html);
}
public function testRenderDevContainsAllFourTabs(): void
{
$data = self::sampleData();
$html = ErrorRenderer::renderDev($data);
$this->assertStringContainsString('panel-exception', $html);
$this->assertStringContainsString('panel-request', $html);
$this->assertStringContainsString('panel-environment', $html);
$this->assertStringContainsString('panel-queries', $html);
}
public function testRenderDevEscapesHtmlInExceptionMessage(): void
{
$data = self::sampleData();
$data['exception']['message'] = '<script>alert("xss")</script>';
$html = ErrorRenderer::renderDev($data);
$this->assertStringNotContainsString('<script>alert("xss")</script>', $html);
$this->assertStringContainsString('&lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt;', $html);
}
public function testRenderDevShowsRedactedValues(): void
{
$data = self::sampleData();
$data['request']['headers']['authorization'] = '[REDACTED]';
$html = ErrorRenderer::renderDev($data);
$this->assertStringContainsString('[REDACTED]', $html);
}
public function testRenderProdShowsRequestIdOnly(): void
{
$html = ErrorRenderer::renderProd('abc-def-123');
$this->assertStringContainsString('<!DOCTYPE html>', $html);
$this->assertStringContainsString('abc-def-123', $html);
$this->assertStringContainsString('An unexpected error occurred', $html);
$this->assertStringContainsString('Back to start', $html);
}
public function testRenderProdDoesNotContainDebugInfo(): void
{
$html = ErrorRenderer::renderProd('request-id');
// Prod page must not render actual debug HTML elements (panels, stack frames).
// Note: CSS class names may appear in the inlined stylesheet — we check for HTML attributes only.
$this->assertStringNotContainsString('id="panel-exception"', $html);
$this->assertStringNotContainsString('id="panel-request"', $html);
$this->assertStringNotContainsString('data-panel=', $html);
}
public function testRenderProdEscapesRequestId(): void
{
$html = ErrorRenderer::renderProd('<script>alert(1)</script>');
$this->assertStringNotContainsString('<script>alert(1)</script>', $html);
$this->assertStringContainsString('&lt;script&gt;', $html);
}
public function testEscMethodEscapesSpecialChars(): void
{
$this->assertSame('&lt;b&gt;test&lt;/b&gt;', ErrorRenderer::esc('<b>test</b>'));
$this->assertSame('a &amp; b', ErrorRenderer::esc('a & b'));
$this->assertSame('&quot;quoted&quot;', ErrorRenderer::esc('"quoted"'));
$this->assertSame('it&#039;s', ErrorRenderer::esc("it's"));
}
/**
* @return array{exception: array<string, mixed>, request: array<string, mixed>, environment: array<string, mixed>, queries: array<string, mixed>}
*/
private static function sampleData(): array
{
return [
'exception' => [
'class' => 'RuntimeException',
'message' => 'Test error message',
'code' => 0,
'file' => '/app/web/index.php',
'line' => 45,
'trace' => [
[
'file' => '/app/web/index.php',
'line' => 45,
'function' => null,
'class' => null,
'code_snippet' => [
44 => ' $expected = "abc";',
45 => ' throw new RuntimeException("Test");',
46 => ' // unreachable',
],
],
],
],
'request' => [
'request_id' => 'test-request-id-123',
'channel' => 'web',
'method' => 'GET',
'url' => '/admin/dashboard',
'ip' => '127.0.0.1',
'user_agent' => 'TestAgent/1.0',
'headers' => ['accept' => 'text/html'],
'get' => [],
'post' => [],
'session_keys' => [],
'user_id' => null,
'tenant_id' => null,
],
'environment' => [
'php_version' => '8.5.0',
'php_sapi' => 'cli',
'extensions' => ['Core', 'json', 'mbstring'],
'memory_current' => 8 * 1024 * 1024,
'memory_peak' => 12 * 1024 * 1024,
'env' => ['APP_DEBUG' => 'true', 'APP_ENV' => 'dev'],
'modules' => [],
],
'queries' => [
'available' => true,
'queries' => [],
'start' => microtime(true),
'count' => 0,
],
];
}
}