Files
michaelschiemer/tests/Unit/Framework/Logging/ChannelSystemTest.php
Michael Schiemer 5050c7d73a docs: consolidate documentation into organized structure
- Move 12 markdown files from root to docs/ subdirectories
- Organize documentation by category:
  • docs/troubleshooting/ (1 file)  - Technical troubleshooting guides
  • docs/deployment/      (4 files) - Deployment and security documentation
  • docs/guides/          (3 files) - Feature-specific guides
  • docs/planning/        (4 files) - Planning and improvement proposals

Root directory cleanup:
- Reduced from 16 to 4 markdown files in root
- Only essential project files remain:
  • CLAUDE.md (AI instructions)
  • README.md (Main project readme)
  • CLEANUP_PLAN.md (Current cleanup plan)
  • SRC_STRUCTURE_IMPROVEMENTS.md (Structure improvements)

This improves:
 Documentation discoverability
 Logical organization by purpose
 Clean root directory
 Better maintainability
2025-10-05 11:05:04 +02:00

226 lines
8.6 KiB
PHP

<?php
declare(strict_types=1);
namespace Tests\Unit\Framework\Logging;
use App\Framework\Logging\DefaultLogger;
use App\Framework\Logging\LogChannel;
use App\Framework\Logging\LogHandler;
use App\Framework\Logging\LogLevel;
use App\Framework\Logging\LogRecord;
use App\Framework\Logging\ProcessorManager;
use PHPUnit\Framework\TestCase;
final class ChannelSystemTest extends TestCase
{
private array $capturedRecords = [];
private DefaultLogger $logger;
protected function setUp(): void
{
$this->capturedRecords = [];
// Test-Handler der alle Records captured
$testHandler = new class ($this->capturedRecords) implements LogHandler {
public function __construct(private array &$records)
{
}
public function isHandling(LogRecord $record): bool
{
return true;
}
public function handle(LogRecord $record): void
{
$this->records[] = $record;
}
};
$this->logger = new DefaultLogger(
minLevel: LogLevel::DEBUG,
handlers: [$testHandler],
processorManager: new ProcessorManager()
);
}
public function test_channel_system_basic_functionality(): void
{
// Teste alle Channel-Logger
$this->logger->security->warning('Security alert', ['ip' => '192.168.1.1']);
$this->logger->cache->debug('Cache miss', ['key' => 'user_123']);
$this->logger->database->error('Query failed', ['table' => 'users']);
$this->logger->framework->info('Route registered', ['path' => '/api/test']);
$this->logger->error->critical('System failure', ['component' => 'auth']);
expect($this->capturedRecords)->toHaveCount(5);
// Prüfe Channels
expect($this->capturedRecords[0]->getChannel())->toBe('security');
expect($this->capturedRecords[1]->getChannel())->toBe('cache');
expect($this->capturedRecords[2]->getChannel())->toBe('database');
expect($this->capturedRecords[3]->getChannel())->toBe('framework');
expect($this->capturedRecords[4]->getChannel())->toBe('error');
// Prüfe Messages
expect($this->capturedRecords[0]->getMessage())->toBe('Security alert');
expect($this->capturedRecords[1]->getMessage())->toBe('Cache miss');
expect($this->capturedRecords[2]->getMessage())->toBe('Query failed');
expect($this->capturedRecords[3]->getMessage())->toBe('Route registered');
expect($this->capturedRecords[4]->getMessage())->toBe('System failure');
// Prüfe Levels
expect($this->capturedRecords[0]->getLevel())->toBe(LogLevel::WARNING);
expect($this->capturedRecords[1]->getLevel())->toBe(LogLevel::DEBUG);
expect($this->capturedRecords[2]->getLevel())->toBe(LogLevel::ERROR);
expect($this->capturedRecords[3]->getLevel())->toBe(LogLevel::INFO);
expect($this->capturedRecords[4]->getLevel())->toBe(LogLevel::CRITICAL);
}
public function test_standard_logging_vs_channel_logging(): void
{
// Standard-Logging
$this->logger->info('Standard log');
// Channel-Logging
$this->logger->security->info('Channel log');
expect($this->capturedRecords)->toHaveCount(2);
// Standard-Log hat keinen Channel
expect($this->capturedRecords[0]->getChannel())->toBeNull();
expect($this->capturedRecords[0]->getMessage())->toBe('Standard log');
// Channel-Log hat Channel
expect($this->capturedRecords[1]->getChannel())->toBe('security');
expect($this->capturedRecords[1]->getMessage())->toBe('Channel log');
}
public function test_all_log_levels_work_with_channels(): void
{
$this->logger->security->debug('Debug message');
$this->logger->security->info('Info message');
$this->logger->security->notice('Notice message');
$this->logger->security->warning('Warning message');
$this->logger->security->error('Error message');
$this->logger->security->critical('Critical message');
$this->logger->security->alert('Alert message');
$this->logger->security->emergency('Emergency message');
expect($this->capturedRecords)->toHaveCount(8);
$expectedLevels = [
LogLevel::DEBUG,
LogLevel::INFO,
LogLevel::NOTICE,
LogLevel::WARNING,
LogLevel::ERROR,
LogLevel::CRITICAL,
LogLevel::ALERT,
LogLevel::EMERGENCY,
];
foreach ($this->capturedRecords as $index => $record) {
expect($record->getChannel())->toBe('security');
expect($record->getLevel())->toBe($expectedLevels[$index]);
}
}
public function test_context_data_passed_correctly(): void
{
$context = [
'user_id' => 123,
'action' => 'login',
'metadata' => ['ip' => '127.0.0.1', 'browser' => 'Chrome'],
];
$this->logger->security->warning('Authentication event', $context);
expect($this->capturedRecords)->toHaveCount(1);
expect($this->capturedRecords[0]->getContext())->toBe($context);
expect($this->capturedRecords[0]->getChannel())->toBe('security');
}
public function test_channel_isolation(): void
{
// Jeder Channel sollte unabhängig funktionieren
$this->logger->security->error('Security error');
$this->logger->cache->error('Cache error');
$this->logger->database->error('Database error');
expect($this->capturedRecords)->toHaveCount(3);
// Alle sollten ERROR level haben, aber verschiedene Channels
foreach ($this->capturedRecords as $record) {
expect($record->getLevel())->toBe(LogLevel::ERROR);
}
expect($this->capturedRecords[0]->getChannel())->toBe('security');
expect($this->capturedRecords[1]->getChannel())->toBe('cache');
expect($this->capturedRecords[2]->getChannel())->toBe('database');
expect($this->capturedRecords[0]->getMessage())->toBe('Security error');
expect($this->capturedRecords[1]->getMessage())->toBe('Cache error');
expect($this->capturedRecords[2]->getMessage())->toBe('Database error');
}
public function test_channel_enum_integration(): void
{
// Teste dass die Channels den Enum-Werten entsprechen
expect($this->logger->security->getChannel())->toBe(LogChannel::SECURITY);
expect($this->logger->cache->getChannel())->toBe(LogChannel::CACHE);
expect($this->logger->database->getChannel())->toBe(LogChannel::DATABASE);
expect($this->logger->framework->getChannel())->toBe(LogChannel::FRAMEWORK);
expect($this->logger->error->getChannel())->toBe(LogChannel::ERROR);
// Teste dass die Channel-Namen korrekt sind
expect(LogChannel::SECURITY->value)->toBe('security');
expect(LogChannel::CACHE->value)->toBe('cache');
expect(LogChannel::DATABASE->value)->toBe('database');
expect(LogChannel::FRAMEWORK->value)->toBe('framework');
expect(LogChannel::ERROR->value)->toBe('error');
}
public function test_realistic_usage_scenario(): void
{
// Simuliere eine realistische Anwendungssequenz
// 1. Framework startet
$this->logger->framework->info('Application starting');
// 2. User versucht Login
$this->logger->security->info('Login attempt', ['email' => 'user@test.com']);
// 3. Cache Miss
$this->logger->cache->debug('User cache miss', ['email' => 'user@test.com']);
// 4. Database Query
$this->logger->database->debug('User lookup query', ['table' => 'users']);
// 5. Successful authentication
$this->logger->security->info('Login successful', ['user_id' => 42]);
// 6. Cache Store
$this->logger->cache->info('User cached', ['user_id' => 42, 'ttl' => 3600]);
// 7. Später: Ein Fehler
$this->logger->database->error('Connection timeout', ['host' => 'db.example.com']);
$this->logger->error->critical('Service degraded', ['affected' => ['users', 'orders']]);
expect($this->capturedRecords)->toHaveCount(8);
// Prüfe die Sequenz
$channels = array_map(fn ($record) => $record->getChannel(), $this->capturedRecords);
$expected = ['framework', 'security', 'cache', 'database', 'security', 'cache', 'database', 'error'];
expect($channels)->toBe($expected);
// Prüfe dass jeder Record den richtigen Channel hat
foreach ($this->capturedRecords as $index => $record) {
expect($record->getChannel())->toBe($expected[$index]);
}
}
}