128 lines
3.8 KiB
PHP
128 lines
3.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Domovoy\Tests\Repositories;
|
|
|
|
use Domovoy\Models\Credential;
|
|
use Domovoy\Repositories\CredentialRepository;
|
|
use PDO;
|
|
use PDOStatement;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
final class CredentialRepositoryTest extends TestCase
|
|
{
|
|
public function testFindByIdAndDeleteScopeCredentialsToDevice(): void
|
|
{
|
|
$pdo = new FakeCredentialPdo();
|
|
$repository = new CredentialRepository($pdo);
|
|
|
|
$credential = new Credential();
|
|
$credential->deviceId = 7;
|
|
$credential->name = 'main';
|
|
$credential->username = 'root';
|
|
$credential->encryptedSecret = 'encrypted';
|
|
$repository->save($credential);
|
|
|
|
self::assertSame('root', $repository->findById(1)?->username);
|
|
|
|
$repository->deleteForDevice(1, 99);
|
|
self::assertCount(1, $pdo->rows);
|
|
|
|
$repository->deleteForDevice(1, 7);
|
|
self::assertSame([], $pdo->rows);
|
|
}
|
|
|
|
public function testUpdateTestResultPersistsStatusAndTimestamp(): void
|
|
{
|
|
$pdo = new FakeCredentialPdo();
|
|
$repository = new CredentialRepository($pdo);
|
|
|
|
$credential = new Credential();
|
|
$credential->deviceId = 7;
|
|
$credential->name = 'main';
|
|
$credential->username = 'root';
|
|
$credential->encryptedSecret = 'encrypted';
|
|
$repository->save($credential);
|
|
|
|
$repository->updateTestResult(1, 'ok');
|
|
|
|
self::assertSame('ok', $pdo->rows[1]['last_test_status']);
|
|
self::assertNotNull($pdo->rows[1]['last_test_at']);
|
|
}
|
|
}
|
|
|
|
final class FakeCredentialPdo 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 FakeCredentialStatement($this, $query);
|
|
}
|
|
|
|
public function lastInsertId(?string $name = null): string|false
|
|
{
|
|
return (string)$this->lastId;
|
|
}
|
|
}
|
|
|
|
final class FakeCredentialStatement extends PDOStatement
|
|
{
|
|
/** @var array<string, mixed>|false */
|
|
private array|false $result = false;
|
|
|
|
public function __construct(
|
|
private FakeCredentialPdo $pdo,
|
|
private string $query
|
|
) {
|
|
}
|
|
|
|
public function execute(?array $params = null): bool
|
|
{
|
|
$params ??= [];
|
|
|
|
if (str_contains($this->query, 'SELECT * FROM credentials WHERE id = :id')) {
|
|
$this->result = $this->pdo->rows[(int)$params['id']] ?? false;
|
|
return true;
|
|
}
|
|
|
|
if (str_contains($this->query, 'INSERT INTO credentials')) {
|
|
$this->pdo->lastId++;
|
|
$params['id'] = $this->pdo->lastId;
|
|
$params['created_at'] ??= '2026-05-29 00:00:00';
|
|
$params['updated_at'] ??= '2026-05-29 00:00:00';
|
|
$this->pdo->rows[$this->pdo->lastId] = $params;
|
|
return true;
|
|
}
|
|
|
|
if (str_contains($this->query, 'DELETE FROM credentials WHERE id = :id AND device_id = :device_id')) {
|
|
$id = (int)$params['id'];
|
|
if (($this->pdo->rows[$id]['device_id'] ?? null) === $params['device_id']) {
|
|
unset($this->pdo->rows[$id]);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
if (str_contains($this->query, 'UPDATE credentials SET last_test_status')) {
|
|
$id = (int)$params['id'];
|
|
$this->pdo->rows[$id]['last_test_status'] = $params['last_test_status'];
|
|
$this->pdo->rows[$id]['last_test_at'] = $params['last_test_at'];
|
|
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;
|
|
}
|
|
}
|