viewer()->create(['must_change_password' => false]); } private function operator(): User { return User::factory()->operator()->create(['must_change_password' => false]); } private function server(): Server { $server = Server::create(['name' => 'box', 'ip' => '10.0.0.2', 'ssh_port' => 22, 'status' => 'online']); $server->credential()->create(['username' => 'root', 'auth_type' => 'password', 'secret' => 'x']); // Re-load with the withExists('credential') attribute the component reads. return Server::withExists('credential')->find($server->id); } private function stubDocker(array $containers = []): DockerService { $docker = Mockery::mock(DockerService::class); $docker->shouldReceive('available')->andReturn(true); $docker->shouldReceive('containers')->andReturn($containers); app()->instance(DockerService::class, $docker); return $docker; } public function test_viewer_can_browse_the_server_container_list(): void { $this->actingAs($this->viewer()); $server = $this->server(); $this->stubDocker([['id' => 'abc', 'name' => 'web', 'image' => 'nginx', 'state' => 'running', 'status' => 'Up', 'ports' => '80/tcp']]); Livewire::test(ServerDocker::class, ['server' => $server]) ->call('load') ->assertOk() ->assertSet('connected', true) ->assertSee('web'); } public function test_viewer_cannot_run_a_server_container_action(): void { $this->actingAs($this->viewer()); $server = $this->server(); $docker = $this->stubDocker(); $docker->shouldReceive('containerAction')->never(); Livewire::test(ServerDocker::class, ['server' => $server]) ->call('action', 'web', 'stop') ->assertForbidden(); } public function test_operator_can_run_a_server_container_action_and_it_is_audited(): void { $this->actingAs($this->operator()); $server = $this->server(); $docker = $this->stubDocker(); $docker->shouldReceive('containerAction')->once() ->with(Mockery::type(Server::class), 'web', 'restart') ->andReturn(['ok' => true, 'output' => 'web']); Livewire::test(ServerDocker::class, ['server' => $server]) ->call('action', 'web', 'restart') ->assertOk(); $this->assertDatabaseHas('audit_events', ['action' => 'docker.action', 'server_id' => $server->id]); } public function test_shows_a_clean_not_installed_state(): void { $this->actingAs($this->viewer()); $server = $this->server(); $docker = Mockery::mock(DockerService::class); $docker->shouldReceive('available')->once()->andReturn(false); $docker->shouldReceive('containers')->never(); app()->instance(DockerService::class, $docker); Livewire::test(ServerDocker::class, ['server' => $server]) ->call('load') ->assertOk() ->assertSet('notInstalled', true) ->assertSee(__('docker.not_installed_title')); } public function test_viewer_cannot_open_server_logs(): void { $this->actingAs($this->viewer()); $server = $this->server(); $this->stubDocker(); Livewire::test(ServerDocker::class, ['server' => $server]) ->call('viewLogs', 'web') ->assertForbidden(); } }