Выполнение шага 5:
• Updated Plan
└ Продолжаю итерацию 5 как отдельный рабочий срез поверх текущих SSH credentials.
□ Добавить модель/миграцию/repository для host_scans и покрыть repository тестами
□ Добавить SSH command runner и LinuxHostScanner с whitelist read-only команд
□ Подключить controller/routes/UI для запуска deep scan и просмотра результата
□ Прогнать проверки и зафиксировать ограничения Docker-верификации
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Domovoy\Tests\Repositories;
|
||||
|
||||
use Domovoy\Models\HostScan;
|
||||
use Domovoy\Repositories\HostScanRepository;
|
||||
use PDO;
|
||||
use PDOStatement;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
final class HostScanRepositoryTest extends TestCase
|
||||
{
|
||||
public function testSaveAndFindByIdRoundTripsSummary(): void
|
||||
{
|
||||
$pdo = new FakeHostScanPdo();
|
||||
$repository = new HostScanRepository($pdo);
|
||||
|
||||
$scan = new HostScan();
|
||||
$scan->deviceId = 5;
|
||||
$scan->credentialId = 9;
|
||||
$scan->status = 'done';
|
||||
$scan->summary = ['hostname' => 'server-1'];
|
||||
$scan->rawPath = 'storage/scans/test.json';
|
||||
$scan->startedAt = new \DateTimeImmutable('2026-05-29 10:00:00');
|
||||
$scan->finishedAt = new \DateTimeImmutable('2026-05-29 10:00:05');
|
||||
|
||||
$repository->save($scan);
|
||||
$loaded = $repository->findById(1);
|
||||
|
||||
self::assertSame(1, $scan->id);
|
||||
self::assertSame(['hostname' => 'server-1'], $loaded?->summary);
|
||||
self::assertSame('done', $loaded?->status);
|
||||
}
|
||||
}
|
||||
|
||||
final class FakeHostScanPdo extends PDO
|
||||
{
|
||||
/** @var array<int, array<string, mixed>> */
|
||||
public array $rows = [];
|
||||
public int $lastId = 0;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function prepare(string $query, array $options = []): PDOStatement|false
|
||||
{
|
||||
return new FakeHostScanStatement($this, $query);
|
||||
}
|
||||
|
||||
public function lastInsertId(?string $name = null): string|false
|
||||
{
|
||||
return (string)$this->lastId;
|
||||
}
|
||||
}
|
||||
|
||||
final class FakeHostScanStatement extends PDOStatement
|
||||
{
|
||||
/** @var array<string, mixed>|false */
|
||||
private array|false $result = false;
|
||||
|
||||
public function __construct(
|
||||
private FakeHostScanPdo $pdo,
|
||||
private string $query
|
||||
) {
|
||||
}
|
||||
|
||||
public function execute(?array $params = null): bool
|
||||
{
|
||||
$params ??= [];
|
||||
|
||||
if (str_contains($this->query, 'INSERT INTO host_scans')) {
|
||||
$this->pdo->lastId++;
|
||||
$params['id'] = $this->pdo->lastId;
|
||||
$params['created_at'] ??= '2026-05-29 00:00:00';
|
||||
$this->pdo->rows[$this->pdo->lastId] = $params;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (str_contains($this->query, 'SELECT * FROM host_scans WHERE id = :id')) {
|
||||
$this->result = $this->pdo->rows[(int)$params['id']] ?? false;
|
||||
return true;
|
||||
}
|
||||
|
||||
throw new \RuntimeException('Unexpected query: ' . $this->query);
|
||||
}
|
||||
|
||||
public function fetch(int $mode = PDO::FETCH_DEFAULT, int $cursorOrientation = PDO::FETCH_ORI_NEXT, int $cursorOffset = 0): mixed
|
||||
{
|
||||
return $this->result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user