Files
michaelschiemer/tests/debug/test-sse-attribute-simple.php
Michael Schiemer fc3d7e6357 feat(Production): Complete production deployment infrastructure
- Add comprehensive health check system with multiple endpoints
- Add Prometheus metrics endpoint
- Add production logging configurations (5 strategies)
- Add complete deployment documentation suite:
  * QUICKSTART.md - 30-minute deployment guide
  * DEPLOYMENT_CHECKLIST.md - Printable verification checklist
  * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle
  * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference
  * production-logging.md - Logging configuration guide
  * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation
  * README.md - Navigation hub
  * DEPLOYMENT_SUMMARY.md - Executive summary
- Add deployment scripts and automation
- Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment
- Update README with production-ready features

All production infrastructure is now complete and ready for deployment.
2025-10-25 19:18:37 +02:00

197 lines
4.8 KiB
PHP

<?php
declare(strict_types=1);
/**
* Simple Test: SSE Channel Attribute Rendering
*
* Tests LiveComponentRenderer::renderWithWrapper() to verify
* data-sse-channel attribute is rendered when provided.
*/
require_once __DIR__ . '/../../vendor/autoload.php';
use App\Framework\Http\Session\SessionInterface;
use App\Framework\Security\Csrf\CsrfToken;
use App\Framework\View\LiveComponentRenderer;
use App\Framework\View\TemplateRenderer;
echo "=== SSE Channel Attribute Test ===\n\n";
// Create mock session for CSRF
$session = new class () implements SessionInterface {
public object $csrf;
public function __construct()
{
$this->csrf = new class () {
public function generateToken(string $formId): CsrfToken
{
return new CsrfToken('test-csrf-token-' . $formId);
}
};
}
public function getId(): string
{
return 'test-session';
}
public function start(): void
{
}
public function destroy(): void
{
}
public function regenerateId(): void
{
}
public function get(string $key, mixed $default = null): mixed
{
return $default;
}
public function set(string $key, mixed $value): void
{
}
public function has(string $key): bool
{
return false;
}
public function remove(string $key): void
{
}
public function clear(): void
{
}
public function getFlashBag(): mixed
{
return null;
}
};
// Create a mock TemplateRenderer (we won't use it for this test)
$templateRenderer = new class () implements TemplateRenderer {
public function render(...$args): string
{
return '';
}
public function renderPartial(...$args): string
{
return '';
}
};
// Create LiveComponentRenderer
$renderer = new LiveComponentRenderer($templateRenderer, $session);
// Test 1: Render WITHOUT SSE channel
echo "Test 1: Render without SSE channel\n";
echo "-----------------------------------\n";
$html1 = $renderer->renderWithWrapper(
componentId: 'test-component:demo',
componentHtml: '<p>Test Content</p>',
state: ['count' => 0],
sseChannel: null
);
if (str_contains($html1, 'data-sse-channel=')) {
echo "❌ FAIL: data-sse-channel should NOT be present when sseChannel is null\n";
} else {
echo "✅ SUCCESS: data-sse-channel not present (as expected)\n";
}
// Verify other attributes are present
$requiredAttrs = ['data-live-component', 'data-state', 'data-csrf-token'];
foreach ($requiredAttrs as $attr) {
if (str_contains($html1, $attr . '=')) {
echo "{$attr} present\n";
} else {
echo "{$attr} MISSING\n";
}
}
echo "\n";
// Test 2: Render WITH SSE channel
echo "Test 2: Render with SSE channel\n";
echo "-----------------------------------\n";
$html2 = $renderer->renderWithWrapper(
componentId: 'notification-center:user-123',
componentHtml: '<div>Notifications</div>',
state: ['notifications' => []],
sseChannel: 'user:user-123'
);
if (str_contains($html2, 'data-sse-channel=')) {
echo "✅ SUCCESS: data-sse-channel attribute found\n";
// Extract and verify value
if (preg_match('/data-sse-channel="([^"]+)"/', $html2, $matches)) {
$channel = $matches[1];
echo " Channel value: {$channel}\n";
if ($channel === 'user:user-123') {
echo "✅ Channel value correct\n";
} else {
echo "❌ Channel value incorrect. Expected: user:user-123, Got: {$channel}\n";
}
}
} else {
echo "❌ FAIL: data-sse-channel should be present when sseChannel is provided\n";
echo "HTML: " . substr($html2, 0, 200) . "\n";
}
// Verify all attributes are present
foreach ($requiredAttrs as $attr) {
if (str_contains($html2, $attr . '=')) {
echo "{$attr} present\n";
} else {
echo "{$attr} MISSING\n";
}
}
echo "\n";
// Test 3: Full HTML structure verification
echo "Test 3: HTML Structure\n";
echo "-----------------------------------\n";
echo "Sample HTML (first 400 chars):\n";
echo substr($html2, 0, 400) . "\n\n";
// Test 4: Special characters in channel name
echo "Test 4: Special characters handling\n";
echo "-----------------------------------\n";
$html3 = $renderer->renderWithWrapper(
componentId: 'test:special',
componentHtml: '<p>Test</p>',
state: ['test' => true],
sseChannel: 'presence:room-<special>&"chars"'
);
if (preg_match('/data-sse-channel="([^"]+)"/', $html3, $matches)) {
$channel = $matches[1];
echo "Rendered channel: {$channel}\n";
// Check if HTML entities are escaped properly
if (str_contains($channel, '&lt;') || str_contains($channel, '&quot;')) {
echo "✅ Special characters properly escaped\n";
} else {
echo "⚠️ Special characters may not be escaped: {$channel}\n";
}
}
echo "\n=== Test Complete ===\n";