operator()->create(['must_change_password' => false]); } private function viewer(): User { return User::factory()->viewer()->create(['must_change_password' => false]); } public function test_viewer_cannot_open_health(): void { $this->actingAs($this->viewer())->get('/health')->assertForbidden(); } public function test_operator_can_open_health(): void { $this->actingAs($this->operator())->get('/health')->assertOk(); } public function test_operator_adds_an_http_check_and_it_is_audited(): void { $this->actingAs($this->operator()); Livewire::test(Index::class) ->set('type', 'http') ->set('target', 'https://svc.example.com/health') ->call('addCheck') ->assertHasNoErrors(); $this->assertDatabaseHas('health_checks', ['type' => 'http', 'target' => 'https://svc.example.com/health', 'port' => null]); $this->assertDatabaseHas('audit_events', ['action' => 'health.check_add']); } public function test_http_check_rejects_a_non_url(): void { $this->actingAs($this->operator()); Livewire::test(Index::class) ->set('type', 'http') ->set('target', 'not a url; rm -rf') ->call('addCheck') ->assertHasErrors('target'); $this->assertDatabaseCount('health_checks', 0); } public function test_tcp_check_requires_a_host_and_port(): void { $this->actingAs($this->operator()); Livewire::test(Index::class) ->set('type', 'tcp') ->set('target', 'db.example.com') ->set('port', 5432) ->call('addCheck') ->assertHasNoErrors(); $this->assertDatabaseHas('health_checks', ['type' => 'tcp', 'target' => 'db.example.com', 'port' => 5432]); } public function test_tcp_check_rejects_a_missing_port(): void { $this->actingAs($this->operator()); Livewire::test(Index::class) ->set('type', 'tcp') ->set('target', 'db.example.com') ->set('port', null) ->call('addCheck') ->assertHasErrors('port'); } public function test_scan_probes_each_check(): void { $this->actingAs($this->operator()); HealthCheck::create(['type' => 'http', 'target' => 'https://svc.example.com']); $health = Mockery::mock(HealthService::class); $health->shouldReceive('probe')->once()->andReturn(['ok' => true, 'latency' => 42, 'detail' => 'HTTP 200']); app()->instance(HealthService::class, $health); Livewire::test(Index::class) ->call('scan') ->assertOk() ->assertSet('ready', true) ->assertSee(__('health.status_up')) ->assertViewHas('up', 1); } public function test_operator_deletes_a_check_via_a_confirmed_token(): void { $this->actingAs($this->operator()); $check = HealthCheck::create(['type' => 'http', 'target' => 'https://gone.example.com']); $token = ConfirmToken::issue('healthCheckDeleted', ['uuid' => $check->uuid], 'health.check_delete', $check->target, null); ConfirmToken::confirm($token); Livewire::test(Index::class)->call('deleteCheck', $token)->assertOk(); $this->assertDatabaseMissing('health_checks', ['id' => $check->id]); } }