monitor/api/tests/Unit/Metrics/HookCounterTest.php
fds2610-bot 79ccef099d Hooks-KPI im KPI-Monitor ergaenzen (Issue #38)
Die im Issue beschriebene Event-Anzeige (neuestes Event oben, aeltere
schieben nach, Ueberschuss wird abgeschnitten) ist bereits seit Phase 4
umgesetzt (buildEventLines()/MAX_EVENT_LINES, F5) und braucht keine
Aenderung.

Neu ist die vierte, immer sichtbare KPI-Kachel ganz rechts im
KPI-Monitor: "Hooks: n" zaehlt die seit dem letzten Start des
api-Containers empfangenen Webhooks. Der Zaehler ist dateibasiert
(Metrics\HookCounter), weil der eingebaute PHP-Server jede Anfrage als
eigene Skriptausfuehrung behandelt; docker/entrypoint.sh setzt die Datei
beim Start des api-Containers (nicht des sync-Containers) zurueck. Neuer
oeffentlicher Endpunkt GET /api/v1/webhooks/stats liefert den Stand,
das Frontend haengt ihn als eigene Kachel an (buildHooksKpi()) und
reserviert ihr dafuer eine feste Kachel statt sie der MAX_KPI_TILES-
Kappung der uebrigen KPIs zu unterwerfen. Der Wert fliesst zusaetzlich
in den SSE-Fingerabdruck (ChangeFeed) ein.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-04 13:18:05 +02:00

68 lines
1.8 KiB
PHP

<?php
declare(strict_types=1);
namespace Monitor\Api\Tests\Metrics;
use Monitor\Api\Metrics\HookCounter;
use PHPUnit\Framework\TestCase;
final class HookCounterTest extends TestCase
{
private string $path;
protected function setUp(): void
{
$this->path = sys_get_temp_dir() . '/monitor-hook-counter-' . uniqid() . '/hooks-count';
}
protected function tearDown(): void
{
if (file_exists($this->path)) {
unlink($this->path);
}
if (is_dir(dirname($this->path))) {
rmdir(dirname($this->path));
}
}
public function testCountIsZeroWithoutAnyIncrement(): void
{
self::assertSame(0, (new HookCounter($this->path))->count());
}
public function testIncrementReturnsTheNewCountAndPersistsIt(): void
{
$counter = new HookCounter($this->path);
self::assertSame(1, $counter->increment());
self::assertSame(2, $counter->increment());
self::assertSame(3, $counter->increment());
self::assertSame(3, $counter->count());
}
/** Ein zweites Objekt auf demselben Pfad muss den bereits geschriebenen Stand sehen. */
public function testCountIsSharedAcrossInstancesOnTheSamePath(): void
{
(new HookCounter($this->path))->increment();
(new HookCounter($this->path))->increment();
self::assertSame(2, (new HookCounter($this->path))->count());
}
public function testIncrementCreatesMissingDirectory(): void
{
(new HookCounter($this->path))->increment();
self::assertFileExists($this->path);
}
public function testFingerprintReflectsTheCurrentCount(): void
{
$counter = new HookCounter($this->path);
self::assertSame('0', $counter->fingerprint());
$counter->increment();
self::assertSame('1', $counter->fingerprint());
}
}