Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: add DB transaction tests #6912

Merged
merged 2 commits into from
Dec 6, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
238 changes: 238 additions & 0 deletions tests/system/Database/Live/TransactionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
<?php

/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/

namespace CodeIgniter\Database\Live;

use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait;
use Config\Database;
use Exception;
use Tests\Support\Database\Seeds\CITestSeeder;

/**
* @group DatabaseLive
*
* @internal
*/
final class TransactionTest extends CIUnitTestCase
{
use DatabaseTestTrait;

protected $refresh = true;
protected $seed = CITestSeeder::class;

protected function setUp(): void
{
// Reset connection instance.
$this->db = Database::connect($this->DBGroup, false);

parent::setUp();
}

/**
* Sets $DBDebug to false.
*
* WARNING: this value will persist! take care to roll it back.
*/
protected function disableDBDebug(): void
{
$this->setPrivateProperty($this->db, 'DBDebug', false);
}

/**
* Sets $DBDebug to true.
*/
protected function enableDBDebug(): void
{
$this->setPrivateProperty($this->db, 'DBDebug', true);
}

public function testTransStartDBDebugTrue()
{
$builder = $this->db->table('job');
$e = null;

try {
$this->db->transStart();

$jobData = [
'name' => 'Grocery Sales',
'description' => 'Discount!',
];
$builder->insert($jobData);

// Duplicate entry '1' for key 'PRIMARY'
$jobData = [
'id' => 1,
'name' => 'Comedian',
'description' => 'Theres something in your teeth',
];
$builder->insert($jobData);

$this->db->transComplete();
} catch (Exception $e) {
// Do nothing.

// MySQLi
// mysqli_sql_exception: Duplicate entry '1' for key 'PRIMARY'

// SQLite3
// ErrorException: SQLite3::exec(): UNIQUE constraint failed: db_job.id

// Postgres
// ErrorException: pg_query(): Query failed: ERROR: duplicate key value violates unique constraint "pk_db_job"
// DETAIL: Key (id)=(1) already exists.

// SQLSRV
// Exception: [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Cannot insert explicit
// value for identity column in table 'db_job' when IDENTITY_INSERT is set to OFF.

// OCI8
// ErrorException: oci_execute(): ORA-00001: unique constraint (ORACLE.pk_db_job) violated
}

$this->assertInstanceOf(Exception::class, $e);
$this->dontSeeInDatabase('job', ['name' => 'Grocery Sales']);
}

public function testTransStartDBDebugFalse()
{
$this->disableDBDebug();

$builder = $this->db->table('job');

$this->db->transStart();

$jobData = [
'name' => 'Grocery Sales',
'description' => 'Discount!',
];
$builder->insert($jobData);

$this->assertTrue($this->db->transStatus());

// Duplicate entry '1' for key 'PRIMARY'
$jobData = [
'id' => 1,
'name' => 'Comedian',
'description' => 'Theres something in your teeth',
];
$builder->insert($jobData);

$this->assertFalse($this->db->transStatus());

$this->db->transComplete();

$this->dontSeeInDatabase('job', ['name' => 'Grocery Sales']);

$this->enableDBDebug();
}

public function testTransStrictTrueAndDBDebugFalse()
{
$this->disableDBDebug();

$builder = $this->db->table('job');

// The first transaction group
$this->db->transStart();

$jobData = [
'name' => 'Grocery Sales',
'description' => 'Discount!',
];
$builder->insert($jobData);

$this->assertTrue($this->db->transStatus());

// Duplicate entry '1' for key 'PRIMARY'
$jobData = [
'id' => 1,
'name' => 'Comedian',
'description' => 'Theres something in your teeth',
];
$builder->insert($jobData);

$this->assertFalse($this->db->transStatus());

$this->db->transComplete();

$this->dontSeeInDatabase('job', ['name' => 'Grocery Sales']);

// The second transaction group
$this->db->transStart();

$jobData = [
'name' => 'Comedian',
'description' => 'Theres something in your teeth',
];
$builder->insert($jobData);

$this->assertFalse($this->db->transStatus());

$this->db->transComplete();

$this->dontSeeInDatabase('job', ['name' => 'Comedian']);

$this->enableDBDebug();
}

public function testTransStrictFalseAndDBDebugFalse()
{
$this->disableDBDebug();

$builder = $this->db->table('job');

$this->db->transStrict(false);

// The first transaction group
$this->db->transStart();

$jobData = [
'name' => 'Grocery Sales',
'description' => 'Discount!',
];
$builder->insert($jobData);

$this->assertTrue($this->db->transStatus());

// Duplicate entry '1' for key 'PRIMARY'
$jobData = [
'id' => 1,
'name' => 'Comedian',
'description' => 'Theres something in your teeth',
];
$builder->insert($jobData);

$this->assertFalse($this->db->transStatus());

$this->db->transComplete();

$this->dontSeeInDatabase('job', ['name' => 'Grocery Sales']);

// The second transaction group
$this->db->transStart();

$jobData = [
'name' => 'Comedian',
'description' => 'Theres something in your teeth',
];
$builder->insert($jobData);

$this->assertTrue($this->db->transStatus());

$this->db->transComplete();

$this->seeInDatabase('job', ['name' => 'Comedian']);

$this->enableDBDebug();
}
}