feat(test): add multi-engine integration matrix
This commit is contained in:
83
tests/Integration/ModelTransactionTest.php
Normal file
83
tests/Integration/ModelTransactionTest.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Integration;
|
||||
|
||||
use Exception;
|
||||
use PHPUnit\Framework\Attributes\Group;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use ReflectionMethod;
|
||||
use Tests\Models\User;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
* ModelTransactionTest - DuckBrain integration matrix
|
||||
*
|
||||
* Family: beginTransaction, commit, rollBack, plus the implicit rollBack
|
||||
* that Model.php performs when a query fails mid-transaction (and the
|
||||
* Exception it rethrows wrapping the PDO error).
|
||||
*/
|
||||
#[Group('integration')]
|
||||
final class ModelTransactionTest extends TestCase
|
||||
{
|
||||
public static function setUpBeforeClass(): void
|
||||
{
|
||||
self::createTable('users', [
|
||||
'id' => 'pk',
|
||||
'username' => 'string',
|
||||
'email' => 'string',
|
||||
'bio' => 'text',
|
||||
'age' => 'number',
|
||||
'is_active' => 'bool',
|
||||
'last_login' => 'timestamp',
|
||||
]);
|
||||
}
|
||||
|
||||
private static function seed(string $username): User
|
||||
{
|
||||
$user = new User();
|
||||
$user->username = $username;
|
||||
$user->email = $username . '@duckbrain.dev';
|
||||
$user->age = 25;
|
||||
$user->save();
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function commitMakesPendingWritesVisible(): void
|
||||
{
|
||||
User::beginTransaction();
|
||||
$user = self::seed('committed_alice');
|
||||
$this->assertTrue(User::commit());
|
||||
|
||||
$this->assertNotNull(User::getById($user->id));
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function rollBackDiscardsPendingWrites(): void
|
||||
{
|
||||
User::beginTransaction();
|
||||
$user = self::seed('rolled_bob');
|
||||
$this->assertTrue(User::rollBack());
|
||||
|
||||
$this->assertNull(User::getById($user->id));
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function aFailingQueryRollsBackTheOpenTransaction(): void
|
||||
{
|
||||
User::beginTransaction();
|
||||
$user = self::seed('wrecked_carol');
|
||||
|
||||
try {
|
||||
(new ReflectionMethod(User::class, 'query'))
|
||||
->invokeArgs(null, ['SELECT * FROM table_that_does_not_exist']);
|
||||
$this->fail('a failing query inside a transaction must throw');
|
||||
} catch (Exception $e) {
|
||||
$this->assertStringContainsString('Error at query to database', $e->getMessage());
|
||||
}
|
||||
|
||||
$this->assertFalse(self::db()->inTransaction(), 'the exception path must close the transaction');
|
||||
$this->assertNull(User::where('username', 'wrecked_carol')->getFirst(), 'pending insert must be undone');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user