tickets = new TicketRepository($db); $this->events = new EventRepository($db); $systems = new SystemRepository($db); $kpis = new KpiRepository($db); $agents = new AgentRepository($db); $this->hooksPath = sys_get_temp_dir() . '/monitor-changefeed-hooks-' . uniqid() . '/hooks-count'; $this->hooks = new HookCounter($this->hooksPath); $this->recordingsStorageDir = sys_get_temp_dir() . '/monitor-changefeed-recordings-' . uniqid(); $this->recordings = new VoiceRecordingRepository($db, $this->recordingsStorageDir); $this->changeFeed = new ChangeFeed($this->tickets, $this->events, $systems, $kpis, $agents, $this->hooks, $this->recordings); } protected function tearDown(): void { if (file_exists($this->hooksPath)) { unlink($this->hooksPath); } if (is_dir(dirname($this->hooksPath))) { rmdir(dirname($this->hooksPath)); } if (is_dir($this->recordingsStorageDir)) { foreach (glob($this->recordingsStorageDir . '/*') ?: [] as $file) { unlink($file); } rmdir($this->recordingsStorageDir); } } public function testCurrentFingerprintCoversAllSevenResources(): void { $fingerprint = $this->changeFeed->currentFingerprint(); self::assertSame( ['tickets', 'events', 'systems', 'kpis', 'agents', 'hooks', 'recordings'], array_keys($fingerprint) ); } public function testDiffIsEmptyWithoutChanges(): void { $fingerprint = $this->changeFeed->currentFingerprint(); self::assertSame([], $this->changeFeed->diff($fingerprint, $fingerprint)); } public function testDiffReportsOnlyTheChangedResource(): void { $before = $this->changeFeed->currentFingerprint(); $this->tickets->create(['title' => 'Neu']); $after = $this->changeFeed->currentFingerprint(); self::assertSame(['tickets'], $this->changeFeed->diff($before, $after)); } public function testDiffReportsMultipleChangedResources(): void { $before = $this->changeFeed->currentFingerprint(); $this->tickets->create(['title' => 'Neu']); $this->events->create(['name' => 'Ping', 'message' => 'down', 'severity' => 'error']); $after = $this->changeFeed->currentFingerprint(); $changed = $this->changeFeed->diff($before, $after); sort($changed); self::assertSame(['events', 'tickets'], $changed); } /** Ein empfangener Webhook (Issue #38) muss denselben SSE-Push ausloesen wie andere Ressourcen. */ public function testDiffReportsAReceivedWebhook(): void { $before = $this->changeFeed->currentFingerprint(); $this->hooks->increment(); $after = $this->changeFeed->currentFingerprint(); self::assertSame(['hooks'], $this->changeFeed->diff($before, $after)); } }