Enable Discovery debug logging for production troubleshooting

- Add DISCOVERY_LOG_LEVEL=debug
- Add DISCOVERY_SHOW_PROGRESS=true
- Temporary changes for debugging InitializerProcessor fixes on production
This commit is contained in:
2025-08-11 20:13:26 +02:00
parent 59fd3dd3b1
commit 55a330b223
3683 changed files with 2956207 additions and 16948 deletions

View File

@@ -0,0 +1,123 @@
<?php
declare(strict_types=1);
namespace Tests\Framework\View\Processors;
use App\Framework\Http\Session\FormIdGenerator;
use App\Framework\Meta\MetaData;
use App\Framework\View\DomFormService;
use App\Framework\View\DomWrapper;
use App\Framework\View\Processors\FormProcessor;
use App\Framework\View\RenderContext;
use PHPUnit\Framework\TestCase;
final class FormProcessorTest extends TestCase
{
private FormProcessor $processor;
protected function setUp(): void
{
// Use real instances since classes are final
$formIdGenerator = new FormIdGenerator();
$formService = new DomFormService();
$this->processor = new FormProcessor(
$formService,
$formIdGenerator
);
}
public function test_finds_simple_form(): void
{
$html = '<html><body><form action="/test" method="post">
<input type="text" name="username" />
<input type="submit" value="Submit" />
</form></body></html>';
$dom = DomWrapper::fromString($html);
$context = new RenderContext('test', new MetaData('Test'), []);
$result = $this->processor->process($dom, $context);
// Check that placeholders were added
$finalHtml = $result->document->saveHTML();
$this->assertStringContainsString('___TOKEN___', $finalHtml);
$this->assertStringContainsString('___OLD_INPUT_username___', $finalHtml);
// Form ID will be generated dynamically, just check it exists
$this->assertStringContainsString('name="_form_id"', $finalHtml);
}
public function test_finds_contact_form(): void
{
$html = '<html><body>
<form action="/kontakt" method="post">
<input type="text" name="name" />
<input type="email" name="email" />
<select name="subject">
<option value="1">Option 1</option>
<option value="2">Option 2</option>
</select>
<textarea name="message"></textarea>
<input type="submit" value="Senden" />
</form>
</body></html>';
$dom = DomWrapper::fromString($html);
$context = new RenderContext('contact', new MetaData('Contact'), []);
$result = $this->processor->process($dom, $context);
$finalHtml = $result->document->saveHTML();
// Check form found and processed
$this->assertStringContainsString('___TOKEN___', $finalHtml);
$this->assertStringContainsString('___OLD_INPUT_name___', $finalHtml);
$this->assertStringContainsString('___OLD_INPUT_email___', $finalHtml);
$this->assertStringContainsString('___OLD_INPUT_message___', $finalHtml);
$this->assertStringContainsString('name="_form_id"', $finalHtml);
// Check select options have placeholders
$this->assertStringContainsString('data-selected-if="___OLD_SELECT_subject_1___"', $finalHtml);
$this->assertStringContainsString('data-selected-if="___OLD_SELECT_subject_2___"', $finalHtml);
}
public function test_handles_no_forms(): void
{
$html = '<html><body><h1>No forms here</h1></body></html>';
$dom = DomWrapper::fromString($html);
$context = new RenderContext('test', new MetaData('Test'), []);
$result = $this->processor->process($dom, $context);
$finalHtml = $result->document->saveHTML();
$this->assertStringNotContainsString('___TOKEN___', $finalHtml);
$this->assertStringNotContainsString('___OLD_INPUT_', $finalHtml);
}
public function test_handles_layout_tag_content(): void
{
// This tests the specific case from contact.view.php
$html = '<layout src="main"/>
<section>
<h1>Kontakt</h1>
<form action="/kontakt" method="post">
<input type="text" name="name" id="name">
<input type="email" name="email" id="email">
<input type="submit" value="Senden">
</form>
</section>';
$dom = DomWrapper::fromString($html);
$context = new RenderContext('contact', new MetaData('Contact'), []);
$result = $this->processor->process($dom, $context);
$finalHtml = $result->document->saveHTML();
// Should find the form even with layout tag
$this->assertStringContainsString('___TOKEN___', $finalHtml);
$this->assertStringContainsString('___OLD_INPUT_name___', $finalHtml);
$this->assertStringContainsString('___OLD_INPUT_email___', $finalHtml);
}
}

View File

@@ -0,0 +1,88 @@
<?php
declare(strict_types=1);
namespace Tests\Framework\View\Processors;
use App\Framework\View\DomWrapper;
use App\Framework\View\Processors\LayoutTagProcessor;
use PHPUnit\Framework\TestCase;
/**
* Simplified test to check if LayoutTagProcessor preserves forms
*/
final class LayoutTagProcessorSimpleTest extends TestCase
{
public function test_layout_processing_preserves_form_content(): void
{
// Test what happens when we simulate the LayoutTagProcessor behavior
// 1. Original content with layout tag and form
$originalContent = '<layout src="main"/>
<section>
<h1>Kontakt</h1>
<form action="/kontakt" method="post">
<input type="text" name="name" />
<input type="email" name="email" />
<input type="submit" value="Submit" />
</form>
</section>';
// 2. Layout template
$layoutTemplate = '<!DOCTYPE html>
<html>
<head><title>Layout</title></head>
<body>
<header>Header</header>
<main>This will be replaced</main>
<footer>Footer</footer>
</body>
</html>';
// 3. Simulate what LayoutTagProcessor does
$contentDom = DomWrapper::fromString($originalContent);
$layoutTag = $contentDom->document->querySelector('layout[src]');
// This is the content that should go into the layout
$contentToInsert = $layoutTag->innerHTML;
echo "Content to insert:\n" . $contentToInsert . "\n\n";
// Check that the content contains the form
$this->assertStringContainsString('<form action="/kontakt"', $contentToInsert);
$this->assertStringContainsString('name="name"', $contentToInsert);
$this->assertStringContainsString('name="email"', $contentToInsert);
// 4. Now simulate inserting into layout
$layoutDom = DomWrapper::fromString($layoutTemplate);
$mainSlot = $layoutDom->document->querySelector('main');
$this->assertNotNull($mainSlot, 'Layout should have main slot');
// This is what LayoutTagProcessor does
$mainSlot->innerHTML = $contentToInsert;
$finalHtml = $layoutDom->document->saveHTML();
echo "Final HTML:\n" . $finalHtml . "\n\n";
// Check that form is preserved in final result
$this->assertStringContainsString('<form action="/kontakt"', $finalHtml);
$this->assertStringContainsString('name="name"', $finalHtml);
$this->assertStringContainsString('name="email"', $finalHtml);
// Check that layout structure is there
$this->assertStringContainsString('<header>Header</header>', $finalHtml);
$this->assertStringContainsString('<footer>Footer</footer>', $finalHtml);
// The form should be inside main
$this->assertStringContainsString('<main>', $finalHtml);
// Now test if querySelectorAll still works on final result
$finalDom = DomWrapper::fromString($finalHtml);
$forms = $finalDom->document->querySelectorAll('form');
$this->assertEquals(1, count($forms), 'Should find 1 form in final HTML');
$this->assertEquals('/kontakt', $forms[0]->getAttribute('action'));
}
}

View File

@@ -0,0 +1,142 @@
<?php
declare(strict_types=1);
namespace Tests\Framework\View\Processors;
use App\Framework\Meta\MetaData;
use App\Framework\View\DomWrapper;
use App\Framework\View\Loading\TemplateLoader;
use App\Framework\View\Processors\LayoutTagProcessor;
use App\Framework\View\RenderContext;
use PHPUnit\Framework\TestCase;
final class LayoutTagProcessorTest extends TestCase
{
public function test_processes_layout_tag_and_preserves_form(): void
{
// Content with layout tag and form (like contact.view.php)
$contentHtml = '<layout src="test-layout"/>
<section>
<h1>Contact</h1>
<form action="/kontakt" method="post">
<input type="text" name="name" />
<input type="email" name="email" />
<input type="submit" value="Submit" />
</form>
</section>';
// Simple layout file content
$layoutHtml = '<!DOCTYPE html>
<html>
<head><title>Test Layout</title></head>
<body>
<header>Site Header</header>
<main>Original main content</main>
<footer>Site Footer</footer>
</body>
</html>';
// Create temporary layout file
$tempLayoutFile = tempnam(sys_get_temp_dir(), 'layout_') . '.view.php';
file_put_contents($tempLayoutFile, $layoutHtml);
try {
// Create mocked TemplateLoader that returns our temp file
$templateLoader = $this->createMock(TemplateLoader::class);
$templateLoader->method('getTemplatePath')
->with('test-layout')
->willReturn($tempLayoutFile);
$processor = new LayoutTagProcessor($templateLoader);
$dom = DomWrapper::fromString($contentHtml);
$context = new RenderContext('contact', new MetaData('Contact'), []);
$result = $processor->process($dom, $context);
$finalHtml = $result->document->saveHTML();
// Should have layout structure
$this->assertStringContainsString('<header>Site Header</header>', $finalHtml);
$this->assertStringContainsString('<footer>Site Footer</footer>', $finalHtml);
// Should preserve the form from the content
$this->assertStringContainsString('<form action="/kontakt"', $finalHtml);
$this->assertStringContainsString('name="name"', $finalHtml);
$this->assertStringContainsString('name="email"', $finalHtml);
// Original main content should be replaced
$this->assertStringNotContainsString('Original main content', $finalHtml);
// Content should be in main section
$this->assertStringContainsString('<main>', $finalHtml);
$this->assertStringContainsString('<h1>Contact</h1>', $finalHtml);
} finally {
// Clean up temp file
if (file_exists($tempLayoutFile)) {
unlink($tempLayoutFile);
}
}
}
public function test_handles_missing_layout(): void
{
$contentHtml = '<div>No layout tag here</div>';
$templateLoader = $this->createMock(TemplateLoader::class);
$processor = new LayoutTagProcessor($templateLoader);
$dom = DomWrapper::fromString($contentHtml);
$context = new RenderContext('test', new MetaData('Test'), []);
$result = $processor->process($dom, $context);
// Should return unchanged DOM when no layout tag
$this->assertEquals($dom->document->saveHTML(), $result->document->saveHTML());
}
public function test_handles_layout_without_main_slot(): void
{
$contentHtml = '<layout src="no-main"/>
<section>
<form action="/test" method="post">
<input type="text" name="test" />
</form>
</section>';
$layoutWithoutMain = '<!DOCTYPE html>
<html>
<head><title>No Main</title></head>
<body>
<div>No main tag here</div>
</body>
</html>';
$tempLayoutFile = tempnam(sys_get_temp_dir(), 'layout_') . '.view.php';
file_put_contents($tempLayoutFile, $layoutWithoutMain);
try {
$templateLoader = $this->createMock(TemplateLoader::class);
$templateLoader->method('getTemplatePath')
->with('no-main')
->willReturn($tempLayoutFile);
$processor = new LayoutTagProcessor($templateLoader);
$dom = DomWrapper::fromString($contentHtml);
$context = new RenderContext('test', new MetaData('Test'), []);
$result = $processor->process($dom, $context);
// Should return original DOM when no main slot in layout
$finalHtml = $result->document->saveHTML();
$this->assertStringContainsString('<form action="/test"', $finalHtml);
} finally {
if (file_exists($tempLayoutFile)) {
unlink($tempLayoutFile);
}
}
}
}