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:
193
tests/Framework/Http/Session/SessionComponentLazyInitTest.php
Normal file
193
tests/Framework/Http/Session/SessionComponentLazyInitTest.php
Normal file
@@ -0,0 +1,193 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Framework\DateTime\FrozenClock;
|
||||
use App\Framework\Http\Session\InMemorySessionStorage;
|
||||
use App\Framework\Http\Session\Session;
|
||||
use App\Framework\Http\Session\SessionId;
|
||||
use App\Framework\Http\Session\SessionKey;
|
||||
use App\Framework\Random\TestableRandomGenerator;
|
||||
use App\Framework\Security\CsrfTokenGenerator;
|
||||
|
||||
beforeEach(function () {
|
||||
$this->clock = new FrozenClock();
|
||||
$this->randomGenerator = new TestableRandomGenerator();
|
||||
$this->csrfTokenGenerator = new CsrfTokenGenerator($this->randomGenerator);
|
||||
$this->sessionId = SessionId::fromString('testlazyinitsessionid1234567890ab');
|
||||
});
|
||||
|
||||
describe('Session Component Lazy Initialization', function () {
|
||||
test('only used component keys appear in session data', function () {
|
||||
// 1. Session erstellen
|
||||
$session = new Session($this->sessionId, $this->clock, $this->csrfTokenGenerator);
|
||||
$session->fromArray([]);
|
||||
|
||||
// 2. Nur einige Komponenten verwenden
|
||||
$session->flash->add('info', 'Test message');
|
||||
$session->csrf->generateToken('test_form');
|
||||
// Bewusst NICHT verwenden: validation und form
|
||||
|
||||
// 3. Session-Daten prüfen
|
||||
$sessionData = $session->all();
|
||||
|
||||
// 4. Nur verwendete Keys sollten existieren
|
||||
expect($sessionData)->toHaveKey(SessionKey::FLASH->value);
|
||||
expect($sessionData)->toHaveKey(SessionKey::CSRF->value);
|
||||
|
||||
// 5. Nicht verwendete Keys sollten NICHT existieren
|
||||
expect($sessionData)->not->toHaveKey(SessionKey::VALIDATION_ERRORS->value);
|
||||
expect($sessionData)->not->toHaveKey(SessionKey::FORM_DATA->value);
|
||||
|
||||
// 6. Inhalt der verwendeten Keys prüfen
|
||||
expect($sessionData[SessionKey::FLASH->value])->toHaveKey('info');
|
||||
expect($sessionData[SessionKey::CSRF->value])->toHaveKey('test_form');
|
||||
});
|
||||
|
||||
test('accessing component creates its key even if empty', function () {
|
||||
// 1. Session erstellen
|
||||
$session = new Session($this->sessionId, $this->clock, $this->csrfTokenGenerator);
|
||||
$session->fromArray([]);
|
||||
|
||||
// 2. Komponente zugreifen ohne Daten hinzuzufügen
|
||||
$errors = $session->validation->get('nonexistent_form'); // Sollte [] zurückgeben
|
||||
expect($errors)->toBe([]);
|
||||
|
||||
// 3. Jetzt sollte der Key existieren (da Komponente initialisiert wurde)
|
||||
$sessionData = $session->all();
|
||||
expect($sessionData)->toHaveKey(SessionKey::VALIDATION_ERRORS->value);
|
||||
expect($sessionData[SessionKey::VALIDATION_ERRORS->value])->toBe([]);
|
||||
});
|
||||
|
||||
test('component keys persist after session reload', function () {
|
||||
$storage = new InMemorySessionStorage();
|
||||
|
||||
// 1. Session mit gemischter Nutzung erstellen
|
||||
$session1 = new Session($this->sessionId, $this->clock, $this->csrfTokenGenerator);
|
||||
$session1->fromArray([]);
|
||||
|
||||
$session1->flash->add('success', 'Saved!');
|
||||
$session1->csrf->generateToken('edit_form');
|
||||
// validation und form werden NICHT verwendet
|
||||
|
||||
// 2. Session speichern
|
||||
$storage->write($this->sessionId, $session1->all());
|
||||
|
||||
// 3. Session neu laden
|
||||
$loadedData = $storage->read($this->sessionId);
|
||||
$session2 = new Session($this->sessionId, $this->clock, $this->csrfTokenGenerator);
|
||||
$session2->fromArray($loadedData);
|
||||
|
||||
// 4. Nur die Keys die vorher verwendet wurden sollten existieren
|
||||
$reloadedData = $session2->all();
|
||||
expect($reloadedData)->toHaveKey(SessionKey::FLASH->value);
|
||||
expect($reloadedData)->toHaveKey(SessionKey::CSRF->value);
|
||||
expect($reloadedData)->not->toHaveKey(SessionKey::VALIDATION_ERRORS->value);
|
||||
expect($reloadedData)->not->toHaveKey(SessionKey::FORM_DATA->value);
|
||||
|
||||
// 5. Daten sollten korrekt geladen werden
|
||||
expect($session2->flash->get('success'))->toBe(['Saved!']);
|
||||
});
|
||||
|
||||
test('unused components can be accessed after session reload', function () {
|
||||
$storage = new InMemorySessionStorage();
|
||||
|
||||
// 1. Session mit teilweiser Nutzung
|
||||
$session1 = new Session($this->sessionId, $this->clock, $this->csrfTokenGenerator);
|
||||
$session1->fromArray([]);
|
||||
$session1->flash->add('info', 'Test');
|
||||
$storage->write($this->sessionId, $session1->all());
|
||||
|
||||
// 2. Session neu laden
|
||||
$loadedData = $storage->read($this->sessionId);
|
||||
$session2 = new Session($this->sessionId, $this->clock, $this->csrfTokenGenerator);
|
||||
$session2->fromArray($loadedData);
|
||||
|
||||
// 3. Bisher unverwendete Komponenten sollten funktionieren
|
||||
$session2->validation->add('new_form', ['field' => ['New error']]);
|
||||
$session2->form->store('new_form', ['data' => 'New data']);
|
||||
|
||||
// 4. Nach Verwendung sollten die Keys existieren
|
||||
$finalData = $session2->all();
|
||||
expect($finalData)->toHaveKey(SessionKey::VALIDATION_ERRORS->value);
|
||||
expect($finalData)->toHaveKey(SessionKey::FORM_DATA->value);
|
||||
|
||||
// 5. Ursprüngliche Daten sollten erhalten bleiben
|
||||
expect($finalData)->toHaveKey(SessionKey::FLASH->value);
|
||||
});
|
||||
|
||||
test('simulates live system behavior from your example', function () {
|
||||
// 1. Simuliere eine typische Web-App Session
|
||||
$session = new Session($this->sessionId, $this->clock, $this->csrfTokenGenerator);
|
||||
$session->fromArray([]);
|
||||
|
||||
// 2. Simuliere Security Tracking (automatisch durch Framework)
|
||||
$session->security->updateActivity();
|
||||
|
||||
// 3. Simuliere CSRF Token Generierung für verschiedene Formulare
|
||||
$session->csrf->generateToken('form_bf9d2e47868b');
|
||||
$session->csrf->generateToken('form_386bb8ff6647');
|
||||
|
||||
// 4. Flash wird initialisiert aber ist leer (typisch nach Redirect)
|
||||
// Simuliere: Flash wurde bereits abgerufen und ist jetzt leer
|
||||
$session->flash->get('any_type'); // Initialisiert das Array
|
||||
|
||||
// 5. validation und form werden NICHT verwendet (kein Fehler, kein Form-Data)
|
||||
|
||||
// 6. Prüfe Session-Daten (sollte dem Live-System ähneln)
|
||||
$sessionData = $session->all();
|
||||
|
||||
expect($sessionData)->toHaveKey('__security');
|
||||
expect($sessionData)->toHaveKey('__csrf');
|
||||
expect($sessionData)->toHaveKey('__flash');
|
||||
expect($sessionData['__flash'])->toBe([]); // Leer, wie im Live-System
|
||||
|
||||
// Diese Keys fehlen - das ist korrekt!
|
||||
expect($sessionData)->not->toHaveKey('__validation_errors');
|
||||
expect($sessionData)->not->toHaveKey('__form_data');
|
||||
|
||||
// 7. CSRF sollte Tokens für verschiedene Formulare enthalten
|
||||
expect($sessionData['__csrf'])->toHaveKey('form_bf9d2e47868b');
|
||||
expect($sessionData['__csrf'])->toHaveKey('form_386bb8ff6647');
|
||||
});
|
||||
|
||||
test('components become available when first needed', function () {
|
||||
$storage = new InMemorySessionStorage();
|
||||
|
||||
// 1. Session wie im Live-System
|
||||
$existingData = [
|
||||
'__security' => [
|
||||
'user_agent' => 'Mozilla/5.0 (Test Browser)',
|
||||
'ip_address' => '127.0.0.1',
|
||||
'last_activity' => time(),
|
||||
],
|
||||
'__csrf' => [
|
||||
'test_form' => [
|
||||
['token' => 'abc123', 'created_at' => time(), 'used_at' => null],
|
||||
],
|
||||
],
|
||||
'__flash' => [],
|
||||
];
|
||||
|
||||
$session = new Session($this->sessionId, $this->clock, $this->csrfTokenGenerator);
|
||||
$session->fromArray($existingData);
|
||||
|
||||
// 2. Bisher fehlende Komponenten sind trotzdem verfügbar
|
||||
expect($session->validation->has('any_form'))->toBeFalse();
|
||||
expect($session->form->has('any_form'))->toBeFalse();
|
||||
|
||||
// 3. Wenn sie verwendet werden, funktionieren sie
|
||||
$session->validation->add('contact_form', ['email' => ['Required']]);
|
||||
$session->form->store('contact_form', ['name' => 'John']);
|
||||
|
||||
// 4. Jetzt sollten die Keys existieren
|
||||
$finalData = $session->all();
|
||||
expect($finalData)->toHaveKey('__validation_errors');
|
||||
expect($finalData)->toHaveKey('__form_data');
|
||||
|
||||
// 5. Bestehende Daten bleiben erhalten
|
||||
expect($finalData['__security']['user_agent'])->toBe('Mozilla/5.0 (Test Browser)');
|
||||
expect($finalData['__csrf'])->toHaveKey('test_form');
|
||||
expect($finalData['__flash'])->toBe([]);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user