Files
michaelschiemer/tests/Framework/Http/Session/SessionTest.php
Michael Schiemer 55a330b223 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
2025-08-11 20:13:26 +02:00

230 lines
8.6 KiB
PHP

<?php
declare(strict_types=1);
use App\Framework\DateTime\FrozenClock;
use App\Framework\Http\Session\Session;
use App\Framework\Http\Session\SessionId;
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('testsessionid1234567890abcdefgh12');
$this->session = new Session($this->sessionId, $this->clock, $this->csrfTokenGenerator);
});
describe('Session Basic Operations', function () {
test('session starts correctly', function () {
expect($this->session->isStarted())->toBeTrue();
});
test('session has correct id', function () {
expect($this->session->id)->toBe($this->sessionId);
});
test('session data operations work correctly', function () {
// Set data
$this->session->set('key1', 'value1');
$this->session->set('key2', 42);
// Get data
expect($this->session->get('key1'))->toBe('value1');
expect($this->session->get('key2'))->toBe(42);
expect($this->session->get('nonexistent'))->toBeNull();
expect($this->session->get('nonexistent', 'default'))->toBe('default');
});
test('session has() method works correctly', function () {
$this->session->set('existing_key', 'value');
expect($this->session->has('existing_key'))->toBeTrue();
expect($this->session->has('nonexistent_key'))->toBeFalse();
});
test('session remove() method works correctly', function () {
$this->session->set('key_to_remove', 'value');
expect($this->session->has('key_to_remove'))->toBeTrue();
$this->session->remove('key_to_remove');
expect($this->session->has('key_to_remove'))->toBeFalse();
});
test('session all() method returns all data', function () {
$this->session->set('key1', 'value1');
$this->session->set('key2', 'value2');
$allData = $this->session->all();
// Die Komponenten fügen ihre eigenen Keys hinzu
expect($allData)->toHaveKey('key1');
expect($allData)->toHaveKey('key2');
expect($allData['key1'])->toBe('value1');
expect($allData['key2'])->toBe('value2');
// Komponenten-Keys sollten auch existieren
expect($allData)->toHaveKey('__flash');
expect($allData)->toHaveKey('__validation_errors');
expect($allData)->toHaveKey('__form_data');
expect($allData)->toHaveKey('__csrf');
});
test('session clear() method removes all data', function () {
$this->session->set('key1', 'value1');
$this->session->set('key2', 'value2');
$this->session->clear();
expect($this->session->all())->toBe([]);
});
});
describe('Session fromArray functionality', function () {
test('fromArray() sets session data correctly', function () {
$data = [
'user_id' => 123,
'username' => 'testuser',
'preferences' => ['theme' => 'dark'],
];
$this->session->fromArray($data);
expect($this->session->get('user_id'))->toBe(123);
expect($this->session->get('username'))->toBe('testuser');
expect($this->session->get('preferences'))->toBe(['theme' => 'dark']);
});
test('fromArray() initializes components after setting data', function () {
// Komponenten sollten nach fromArray() verfügbar sein
$this->session->fromArray(['some' => 'data']);
expect($this->session->flash)->toBeInstanceOf(\App\Framework\Http\Session\FlashBag::class);
expect($this->session->validation)->toBeInstanceOf(\App\Framework\Http\Session\ValidationErrorBag::class);
expect($this->session->form)->toBeInstanceOf(\App\Framework\Http\Session\FormDataStorage::class);
expect($this->session->security)->toBeInstanceOf(\App\Framework\Http\Session\SecurityManager::class);
expect($this->session->csrf)->toBeInstanceOf(\App\Framework\Http\Session\CsrfProtection::class);
});
test('fromArray() preserves existing data structure', function () {
// Teste ob komplexe Datenstrukturen korrekt gespeichert werden
$complexData = [
'user' => [
'id' => 123,
'profile' => [
'name' => 'Test User',
'settings' => [
'notifications' => true,
'theme' => 'dark',
],
],
],
'session_data' => [
'csrf_token' => 'token123',
'flash_messages' => [
'success' => ['Message saved!'],
'error' => ['Validation failed!'],
],
],
];
$this->session->fromArray($complexData);
expect($this->session->get('user'))->toBe($complexData['user']);
expect($this->session->get('session_data'))->toBe($complexData['session_data']);
// Teste nested access
$user = $this->session->get('user');
expect($user['profile']['name'])->toBe('Test User');
});
});
describe('Session Component Integration', function () {
test('components are properly initialized after fromArray()', function () {
$this->session->fromArray([]);
// Teste ob alle Komponenten korrekt initialisiert sind
expect($this->session->flash)->toBeInstanceOf(\App\Framework\Http\Session\FlashBag::class);
expect($this->session->validation)->toBeInstanceOf(\App\Framework\Http\Session\ValidationErrorBag::class);
expect($this->session->form)->toBeInstanceOf(\App\Framework\Http\Session\FormDataStorage::class);
expect($this->session->security)->toBeInstanceOf(\App\Framework\Http\Session\SecurityManager::class);
expect($this->session->csrf)->toBeInstanceOf(\App\Framework\Http\Session\CsrfProtection::class);
});
test('components can access session data', function () {
$this->session->fromArray([
'flash' => ['success' => ['Test message']],
'csrf_token' => 'test-token',
]);
// Flash component sollte auf die Session-Daten zugreifen können
expect($this->session->get('flash'))->toBe(['success' => ['Test message']]);
expect($this->session->get('csrf_token'))->toBe('test-token');
});
test('double initialization is prevented', function () {
$this->session->fromArray([]);
$flash1 = $this->session->flash;
// Zweite Initialisierung sollte die gleichen Instanzen zurückgeben
$this->session->fromArray(['new' => 'data']);
$flash2 = $this->session->flash;
expect($flash1)->toBe($flash2);
});
});
describe('Session Edge Cases', function () {
test('handles null values correctly', function () {
$this->session->set('null_value', null);
expect($this->session->has('null_value'))->toBeTrue();
expect($this->session->get('null_value'))->toBeNull();
});
test('handles empty string values correctly', function () {
$this->session->set('empty_string', '');
expect($this->session->has('empty_string'))->toBeTrue();
expect($this->session->get('empty_string'))->toBe('');
});
test('handles boolean values correctly', function () {
$this->session->set('true_value', true);
$this->session->set('false_value', false);
expect($this->session->get('true_value'))->toBeTrue();
expect($this->session->get('false_value'))->toBeFalse();
});
test('handles array values correctly', function () {
$arrayValue = ['nested' => ['deep' => 'value']];
$this->session->set('array_value', $arrayValue);
expect($this->session->get('array_value'))->toBe($arrayValue);
});
test('handles object serialization edge cases', function () {
// Teste was passiert wenn Objekte in der Session gespeichert werden
$stdClass = new stdClass();
$stdClass->property = 'value';
$this->session->set('object_value', $stdClass);
$retrieved = $this->session->get('object_value');
expect($retrieved)->toBeInstanceOf(stdClass::class);
expect($retrieved->property)->toBe('value');
});
});
describe('Session Debug Information', function () {
test('__debugInfo() returns correct format', function () {
$this->session->set('debug_key', 'debug_value');
$debugInfo = $this->session->__debugInfo();
expect($debugInfo[0])->toBe($this->sessionId->toString());
expect($debugInfo['debug_key'])->toBe('debug_value');
});
});