repository = new KpiRepository(Database::inMemory(), historyLimit: 3); } public function testReportCreatesKpiWithCurrentValue(): void { $kpi = $this->repository->report('open_tickets', 5.0, 'Offene Tickets', 'count', '2026-01-01T00:00:00Z'); self::assertSame('open_tickets', $kpi['key']); self::assertSame(5.0, $kpi['current_value']); self::assertCount(1, $kpi['history']); } public function testReportAppendsHistoryAndUpdatesCurrentValue(): void { $this->repository->report('open_tickets', 5.0, null, null, '2026-01-01T00:00:00Z'); $kpi = $this->repository->report('open_tickets', 7.0, null, null, '2026-01-02T00:00:00Z'); self::assertSame(7.0, $kpi['current_value']); self::assertCount(2, $kpi['history']); } public function testHistoryIsLimited(): void { for ($i = 0; $i < 5; $i++) { $this->repository->report('kpi', (float) $i, null, null, sprintf('2026-01-0%dT00:00:00Z', $i + 1)); } $kpi = $this->repository->find('kpi'); self::assertCount(3, $kpi['history']); } public function testFindReturnsNullForUnknownKey(): void { self::assertNull($this->repository->find('unknown')); } public function testAllListsAllKpis(): void { $this->repository->report('a', 1.0, null, null, '2026-01-01T00:00:00Z'); $this->repository->report('b', 2.0, null, null, '2026-01-01T00:00:00Z'); self::assertCount(2, $this->repository->all()); } public function testFingerprintChangesWhenAValueIsReported(): void { $before = $this->repository->fingerprint(); $this->repository->report('open_tickets', 1.0, null, null, '2026-01-01T00:00:00Z'); self::assertNotSame($before, $this->repository->fingerprint()); } }