*/ private array $opsAgent; protected function setUp(): void { $db = Database::inMemory(); $agents = new AgentRepository($db); $this->opsAgent = $agents->register('OPs', 'ops')['agent']; $this->hosts = new HostConfigRepository($db); $this->systems = new SystemRepository($db); $this->controller = new HostConfigController($this->hosts, $this->systems); } public function testIndexReturnsDerivedSystemIds(): void { $this->hosts->create([ 'agent_id' => $this->opsAgent['id'], 'hostname' => 'Nextcloud(lokal)', 'address' => '192.168.2.7', ]); $body = $this->controller->index(Request::create('GET', '/api/v1/hosts'))->body(); self::assertSame( ['Nextcloud(lokal)', 'nextcloud-lokal'], $body['hosts'][0]['system_ids'] ); self::assertSame('OPs', $body['hosts'][0]['agent_name']); } public function testDeleteAlsoRemovesTilesOfBothReportingPaths(): void { $host = $this->hosts->create([ 'agent_id' => $this->opsAgent['id'], 'hostname' => 'Nextcloud(lokal)', 'address' => '192.168.2.7', ]); // So wuerde derselbe Host in den Monitor kommen: per REST unter dem Slug, // per status.txt-Import unter dem Namen. $this->systems->reportStatus('nextcloud-lokal', ['status' => 'error']); $this->systems->importLegacyRows([[ 'id' => 'Nextcloud(lokal)', 'name' => 'Nextcloud(lokal)', 'status' => 'error', 'detail' => '192.168.2.7', 'last_check_at' => '2026-01-01 00:00', ]]); $this->controller->delete(Request::create('DELETE', '/api/v1/hosts/1'), ['id' => (string) $host['id']]); self::assertNull($this->systems->find('nextcloud-lokal')); self::assertNull($this->systems->find('Nextcloud(lokal)')); } public function testUpdateRemovesTileOfPreviousHostname(): void { $host = $this->hosts->create([ 'agent_id' => $this->opsAgent['id'], 'hostname' => 'alt', 'address' => '10.0.0.1', ]); $this->systems->reportStatus('alt', ['status' => 'ok']); $this->controller->update( Request::create('PATCH', '/api/v1/hosts/1', [], ['hostname' => 'neu', 'address' => '10.0.0.1']), ['id' => (string) $host['id']] ); self::assertNull($this->systems->find('alt')); } public function testConfReturnsPlainHostsFileForAuthenticatedAgent(): void { $this->hosts->create(['agent_id' => $this->opsAgent['id'], 'hostname' => 'Web', 'address' => '10.0.0.1']); $response = $this->controller->conf(Request::create('GET', '/api/v1/hosts/conf'), [], $this->opsAgent); self::assertSame(200, $response->status); self::assertStringContainsString("Web 10.0.0.1\n", (string) $response->body()); } public function testConfAnswers204BeforeTheFirstImport(): void { $response = $this->controller->conf(Request::create('GET', '/api/v1/hosts/conf'), [], $this->opsAgent); self::assertSame(204, $response->status); } public function testConfAnswers200WithAnEmptyListAfterTheImport(): void { // Alle Hosts im Frontend entfernt: der Ping-Rechner soll seine Datei leeren, nicht // die alte Liste behalten - also 200 mit leerer Liste statt 204. $this->controller->import( Request::create('POST', '/api/v1/hosts/import', [], [], [], "Web 10.0.0.1\n"), [], $this->opsAgent ); foreach ($this->hosts->allForAgent((int) $this->opsAgent['id']) as $host) { $this->hosts->delete((int) $host['id']); } $response = $this->controller->conf(Request::create('GET', '/api/v1/hosts/conf'), [], $this->opsAgent); self::assertSame(200, $response->status); self::assertStringNotContainsString('Web', (string) $response->body()); } public function testConfRejectsAgentWithoutOpsRole(): void { $response = $this->controller->conf( Request::create('GET', '/api/v1/hosts/conf'), [], ['id' => 99, 'role' => 'entwickler'] ); self::assertSame(403, $response->status); } public function testImportFillsListFromUploadedHostsConf(): void { $conf = "# Kommentar\nWeb 10.0.0.1\nMail 10.0.0.2\n"; $response = $this->controller->import( Request::create('POST', '/api/v1/hosts/import', [], [], [], $conf), [], $this->opsAgent ); self::assertSame(2, $response->body()['imported']); self::assertCount(2, $this->hosts->allForAgent((int) $this->opsAgent['id'])); } public function testImportDoesNotOverwriteExistingList(): void { $this->hosts->create(['agent_id' => $this->opsAgent['id'], 'hostname' => 'Web', 'address' => '10.0.0.1']); $response = $this->controller->import( Request::create('POST', '/api/v1/hosts/import', [], [], [], "Anders 10.0.0.9\n"), [], $this->opsAgent ); self::assertSame(0, $response->body()['imported']); self::assertCount(1, $this->hosts->allForAgent((int) $this->opsAgent['id'])); } }