create(['must_change_password' => false]); } private function operator(): User { return User::factory()->operator()->create(['must_change_password' => false]); } private function viewer(): User { return User::factory()->viewer()->create(['must_change_password' => false]); } private function server(string $name = 'box', string $ip = '10.0.0.1'): Server { $s = Server::create(['name' => $name, 'ip' => $ip, 'ssh_port' => 22, 'status' => 'online']); $s->credential()->create(['username' => 'root', 'auth_type' => 'password', 'secret' => 'x']); return $s; } public function test_viewer_cannot_open_posture(): void { $this->actingAs($this->viewer())->get('/posture')->assertForbidden(); } public function test_operator_can_open_posture(): void { $this->actingAs($this->operator())->get('/posture')->assertOk(); } public function test_scan_scores_each_active_credential_server(): void { $this->actingAs($this->operator()); $this->server('web1', '10.0.0.1'); $posture = Mockery::mock(PostureService::class); $posture->shouldReceive('score')->once()->andReturn([ 'score' => 75, 'rating' => 'fair', 'passed' => 3, 'applicable' => 4, 'checks' => [], ]); app()->instance(PostureService::class, $posture); Livewire::test(Index::class) ->call('scan') ->assertOk() ->assertSet('ready', true) ->assertSee('75') ->assertSee(__('posture.rating_fair')); } public function test_a_server_that_cannot_be_scanned_shows_an_error_row_not_a_crash(): void { $this->actingAs($this->operator()); $this->server('down', '10.0.0.9'); $posture = Mockery::mock(PostureService::class); $posture->shouldReceive('score')->once()->andThrow(new \RuntimeException('ssh unreachable')); app()->instance(PostureService::class, $posture); Livewire::test(Index::class) ->call('scan') ->assertOk() ->assertSet('ready', true) ->assertSee(__('posture.scan_error')); } }