168 lines
5.4 KiB
PHP
168 lines
5.4 KiB
PHP
<?php
|
|
|
|
namespace Tests\Unit;
|
|
|
|
use PDO;
|
|
use PHPUnit\Framework\TestCase;
|
|
use ReflectionClass;
|
|
use Services\Database;
|
|
use Services\DataBase\Classes\PdoConnection;
|
|
use Services\DataBase\Classes\Profiler;
|
|
use System\Classes\Config;
|
|
use System\Classes\MyException;
|
|
use System\Classes\Repository;
|
|
|
|
class RepositoryTestItemRepository extends Repository
|
|
{
|
|
public function __construct(?string $connection = null)
|
|
{
|
|
parent::__construct('repository_test_items', connection: $connection);
|
|
}
|
|
}
|
|
|
|
class RepositoryTest extends TestCase
|
|
{
|
|
private PdoConnection $connection;
|
|
private RepositoryTestItemRepository $repository;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
$config = Config::get('db', 'default') ?? [];
|
|
$this->connection = new PdoConnection($config);
|
|
|
|
try {
|
|
$this->connection->pdo();
|
|
} catch (MyException $e) {
|
|
$this->markTestSkipped('Нет живого подключения к MariaDB (заполните App/config/config.local.php): ' . $e->getMessage());
|
|
}
|
|
|
|
$this->connection->exec('DROP TABLE IF EXISTS repository_test_items');
|
|
$this->connection->exec('CREATE TABLE repository_test_items (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255), qty INT)');
|
|
|
|
$this->repository = new RepositoryTestItemRepository();
|
|
}
|
|
|
|
protected function tearDown(): void
|
|
{
|
|
Profiler::reset();
|
|
|
|
if (isset($this->connection)) {
|
|
try {
|
|
$this->connection->exec('DROP TABLE IF EXISTS repository_test_items');
|
|
} catch (MyException) {
|
|
}
|
|
}
|
|
|
|
// Database::instance() кэширует подключение статически — сбрасываем между тестами
|
|
$ref = new ReflectionClass(Database::class);
|
|
$prop = $ref->getProperty('_instances');
|
|
$prop->setAccessible(true);
|
|
$prop->setValue(null, []);
|
|
}
|
|
|
|
public function testCreateAndGet(): void
|
|
{
|
|
$id = $this->repository->create(['name' => 'foo', 'qty' => 3]);
|
|
$row = $this->repository->get($id);
|
|
|
|
$this->assertSame('foo', $row->name);
|
|
$this->assertSame(3, (int) $row->qty);
|
|
}
|
|
|
|
public function testGetMissingReturnsFalse(): void
|
|
{
|
|
$this->assertFalse($this->repository->get(999999));
|
|
}
|
|
|
|
public function testGetListWithWhere(): void
|
|
{
|
|
$this->repository->create(['name' => 'a', 'qty' => 1]);
|
|
$this->repository->create(['name' => 'b', 'qty' => 2]);
|
|
$this->repository->create(['name' => 'a', 'qty' => 5]);
|
|
|
|
$rows = $this->repository->getList('*', ['name' => 'a'], '', 'ASC', PDO::FETCH_ASSOC);
|
|
|
|
$this->assertCount(2, $rows);
|
|
}
|
|
|
|
public function testGetItemWhere(): void
|
|
{
|
|
$this->repository->create(['name' => 'foo', 'qty' => 1]);
|
|
$row = $this->repository->getItemWhere("name = 'foo'");
|
|
|
|
$this->assertSame('foo', $row->name);
|
|
}
|
|
|
|
public function testGetItemWhereEmptyReturnsNull(): void
|
|
{
|
|
$this->assertNull($this->repository->getItemWhere(''));
|
|
}
|
|
|
|
public function testUpdate(): void
|
|
{
|
|
$id = $this->repository->create(['name' => 'foo', 'qty' => 1]);
|
|
$affected = $this->repository->update(['id' => $id, 'qty' => 10]);
|
|
|
|
$this->assertSame(1, $affected);
|
|
$this->assertSame(10, (int) $this->repository->get($id)->qty);
|
|
}
|
|
|
|
public function testUpdateWithoutPrimaryKeyThrows(): void
|
|
{
|
|
$this->expectException(MyException::class);
|
|
$this->repository->update(['qty' => 10]);
|
|
}
|
|
|
|
public function testDelete(): void
|
|
{
|
|
$id = $this->repository->create(['name' => 'foo', 'qty' => 1]);
|
|
|
|
$this->assertTrue($this->repository->delete($id));
|
|
$this->assertFalse($this->repository->get($id));
|
|
}
|
|
|
|
public function testDeleteWhere(): void
|
|
{
|
|
$this->repository->create(['name' => 'a', 'qty' => 1]);
|
|
$this->repository->create(['name' => 'a', 'qty' => 2]);
|
|
$this->repository->create(['name' => 'b', 'qty' => 3]);
|
|
|
|
$this->repository->deleteWhere('name = ?', ['a']);
|
|
|
|
$this->assertCount(1, $this->repository->getList('*', [], '', 'ASC', PDO::FETCH_ASSOC));
|
|
}
|
|
|
|
public function testTransactionRollsBackOnException(): void
|
|
{
|
|
try {
|
|
$this->repository->transaction(function () {
|
|
$this->repository->create(['name' => 'should_rollback', 'qty' => 1]);
|
|
throw new \RuntimeException('boom');
|
|
});
|
|
$this->fail('Ожидалось RuntimeException');
|
|
} catch (\RuntimeException) {
|
|
}
|
|
|
|
$this->assertCount(0, $this->repository->getList('*', ['name' => 'should_rollback'], '', 'ASC', PDO::FETCH_ASSOC));
|
|
}
|
|
|
|
public function testGetListFetchAssoc(): void
|
|
{
|
|
$this->repository->create(['name' => 'foo', 'qty' => 1]);
|
|
$rows = $this->repository->getList('*', [], '', 'ASC', PDO::FETCH_ASSOC);
|
|
|
|
$this->assertIsArray($rows[0]);
|
|
$this->assertSame('foo', $rows[0]['name']);
|
|
}
|
|
|
|
public function testGetListDefaultFetchClassUsesObjClass(): void
|
|
{
|
|
// По умолчанию (без явного $fetch) getList() отдаёт $this->obj_class — не generic stdClass.
|
|
$this->repository->create(['name' => 'foo', 'qty' => 1]);
|
|
$rows = $this->repository->getList('*');
|
|
|
|
$this->assertInstanceOf(\Services\DataBase\Model::class, $rows[0]);
|
|
$this->assertSame('foo', $rows[0]->name);
|
|
}
|
|
}
|