Setzt Visualization.md Abschnitt 9, Phasen 3-5 vollstaendig um: Phase 3 (Kanban-Board live): Board zeigt echte Ticket-Daten aus GET /api/v1/tickets (office-api.js), Klick auf eine Spalte oeffnet ein Modal mit Titel/Beschreibung/Typ und einem Link auf die Codeberg-Quelle bei per Sync angelegten Tickets (F4). Phase 4 (Monitor-Wand live): Event-, System- und KPI-Monitor zeigen echte Daten, Klick-Modals fuer alle drei. Neuer SSE-Endpoint GET /api/v1/stream (F13) meldet per ChangeFeed-Fingerabdruck, welche Ressourcen sich geaendert haben; office-realtime.js nutzt EventSource mit Polling-Fallback. KPI-Monitor zeichnet eine eigene SVG-Sparkline (F10, kein Chart-Lib) sobald KPIs gemeldet wurden, sonst weiterhin der Phase-2-Platzhalter (F7 bleibt inhaltlich offen). API-Antworten tragen jetzt CORS-Header, da Frontend (:8090) und API (:8091) im Docker-Compose-Setup unterschiedliche Origins sind. Phase 5 (Agenten & Animation): resolveAgentVisualState bildet gemeldete Agenten-Zustaende auf Ort/Pose ab; Agenten-Avatare sind eine per CSS transition animierte, von Board/ Schreibtisch-Moebeln entkoppelte Schicht, die zwischen Schreibtisch, Board, Monitor-Wand und einer neuen Kaffee-Ecke laufen. Idle-Varianten (Zeitung/Kaffee/Schwaetzchen) werden rein kosmetisch client-seitig zufaellig ausgeloest (F8), eine AnimationQueue serialisiert Update-Animationen bei vielen gleichzeitigen Ereignissen (F9). 29 Node-Tests (100% Line-Coverage office-scene.js) und neue PHPUnit-Tests fuer Response::stream(), ChangeFeed, StreamController und die neuen Repository::fingerprint()- Methoden. PHP/Docker-Ausfuehrung konnte in dieser Umgebung nicht verifiziert werden (kein PHP verfuegbar) - vor dem Merge bitte `docker compose run --rm api composer test` pruefen. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
64 lines
2.2 KiB
PHP
64 lines
2.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Monitor\Api\Tests;
|
|
|
|
use Monitor\Api\Config;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
final class ConfigTest extends TestCase
|
|
{
|
|
public function testDefaultsAreUsedWhenNothingConfigured(): void
|
|
{
|
|
$config = new Config([]);
|
|
|
|
self::assertSame('https://codeberg.org/api/v1', $config->codebergApiBase());
|
|
self::assertSame('fds2610', $config->codebergOwner());
|
|
self::assertSame('monitor', $config->codebergRepo());
|
|
self::assertNull($config->codebergToken());
|
|
self::assertNull($config->adminApiKey());
|
|
self::assertSame(8, $config->deskCount());
|
|
self::assertSame(30, $config->sseMaxIterations());
|
|
self::assertSame(2, $config->ssePollIntervalSeconds());
|
|
}
|
|
|
|
/**
|
|
* Regression: get() griff frueher selbst auf getenv() zurueck, wodurch ein in der
|
|
* Umgebung gesetzter CODEBERG_TOKEN in eine explizit gebaute Config (und damit in
|
|
* Testausgaben) durchschlug.
|
|
*/
|
|
public function testExplicitEnvArrayDoesNotFallBackToProcessEnvironment(): void
|
|
{
|
|
putenv('CODEBERG_TOKEN=darf-nicht-durchsickern');
|
|
|
|
try {
|
|
self::assertNull((new Config([]))->codebergToken());
|
|
} finally {
|
|
putenv('CODEBERG_TOKEN');
|
|
}
|
|
}
|
|
|
|
public function testValuesCanBeOverridden(): void
|
|
{
|
|
$config = new Config([
|
|
'CODEBERG_API_BASE' => 'https://example.org/api/v1/',
|
|
'CODEBERG_OWNER' => 'someone',
|
|
'CODEBERG_REPO' => 'somerepo',
|
|
'CODEBERG_TOKEN' => 'tok',
|
|
'MONITOR_ADMIN_API_KEY' => 'secret',
|
|
'MONITOR_DESK_COUNT' => '3',
|
|
'MONITOR_SSE_MAX_ITERATIONS' => '5',
|
|
'MONITOR_SSE_POLL_INTERVAL' => '1',
|
|
]);
|
|
|
|
self::assertSame('https://example.org/api/v1', $config->codebergApiBase());
|
|
self::assertSame('someone', $config->codebergOwner());
|
|
self::assertSame('somerepo', $config->codebergRepo());
|
|
self::assertSame('tok', $config->codebergToken());
|
|
self::assertSame('secret', $config->adminApiKey());
|
|
self::assertSame(3, $config->deskCount());
|
|
self::assertSame(5, $config->sseMaxIterations());
|
|
self::assertSame(1, $config->ssePollIntervalSeconds());
|
|
}
|
|
}
|