CluPilotCloud/app/Services/Ssh/FakeRemoteShell.php

109 lines
2.6 KiB
PHP

<?php
namespace App\Services\Ssh;
/**
* Test double: script command output by substring, record everything.
*/
class FakeRemoteShell implements RemoteShell
{
/** @var array<string, CommandResult|callable> */
private array $scripts = [];
/** @var array<int, string> */
private array $recorded = [];
/** @var array<string, string> */
private array $files = [];
/** @var array<int, array{0:string,1:string,2:string}> */
public array $connections = [];
public string $fingerprint = 'SHA256:fakehostkeyfingerprint';
private CommandResult $default;
public function __construct()
{
$this->default = CommandResult::success();
}
public function script(string $substring, CommandResult|callable $result): static
{
$this->scripts[$substring] = $result;
return $this;
}
public function defaultResult(CommandResult $result): static
{
$this->default = $result;
return $this;
}
public function connectWithPassword(string $host, string $user, string $password): void
{
$this->connections[] = ['password', $host, $user];
}
public function connectWithKey(string $host, string $user, string $privateKey): void
{
$this->connections[] = ['key', $host, $user];
}
public function run(string $command): CommandResult
{
$this->recorded[] = $command;
foreach ($this->scripts as $substring => $result) {
if (str_contains($command, $substring)) {
return is_callable($result) ? $result($command) : $result;
}
}
return $this->default;
}
public function putFile(string $remotePath, string $contents): void
{
$this->files[$remotePath] = $contents;
}
public function hostKeyFingerprint(): string
{
return $this->fingerprint;
}
// --- introspection helpers for tests ---
/** @return array<int, string> */
public function recorded(): array
{
return $this->recorded;
}
public function ran(string $substring): bool
{
foreach ($this->recorded as $command) {
if (str_contains($command, $substring)) {
return true;
}
}
return false;
}
/** @return array<string, string> */
public function files(): array
{
return $this->files;
}
/** @return array<int, mixed> */
public function connectionsWith(string $type): array
{
return array_values(array_filter($this->connections, fn ($c) => $c[0] === $type));
}
}