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:
123
tests/Framework/View/Processors/FormProcessorTest.php
Normal file
123
tests/Framework/View/Processors/FormProcessorTest.php
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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'));
|
||||
}
|
||||
}
|
||||
142
tests/Framework/View/Processors/LayoutTagProcessorTest.php
Normal file
142
tests/Framework/View/Processors/LayoutTagProcessorTest.php
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user