<?php /** * Tests for `includes/dba_pdo.php`. * * SPDX-FileCopyrightText: 2024 Hubzilla Community * SPDX-FileContributor: Harald Eilertsen * * SPDX-License-Identifier: MIT */ namespace Zotlabs\Tests\Unit\includes; use DBA; use PDO; use PDOStatement; use PHPUnit\Framework\Attributes\DataProvider; use Zotlabs\Tests\Unit\UnitTestCase; class DbaPdoTest extends UnitTestCase { public function testInsertingRowWithRturningClauseReturnsInsertedRow(): void { // MySQL does not support the `returning` clause, so we skip the test // for that DB backend. $this->skipIfMySQL(); // Let's manually insert a row in the config table. // This is just because it's a conventient table to test // against $res = q(<<<SQL INSERT INTO config (cat, k, v) VALUES ('test', 'a key', 'A value') RETURNING * SQL); $this->assertIsArray($res); $this->assertIsArray($res[0]); $this->assertTrue($res[0]['id'] > 0); $this->assertEquals('test', $res[0]['cat']); $this->assertEquals('a key', $res[0]['k']); $this->assertEquals('A value', $res[0]['v']); } #[DataProvider('insertRowProvider')] public function testInsertRow(string $table, array $data, string $id): void { $res = DBA::$dba->insert($table, $data, $id); $this->assertIsArray($res); // Make sure the result contains the expected id $this->assertArrayHasKey($id, $res); foreach ($data as $key => $value) { $this->assertEquals($value, $res[$key]); } } #[DataProvider('insertRowProvider')] public function testInsertShouldReturnFalseIfInsertFails( string $table, array $data, string $id ): void { $res1 = DBA::$dba->insert($table, $data, $id); $this->assertIsArray($res1); // Inserting the same row again should fail. $res2 = DBA::$dba->insert($table, $data, $id); $this->assertFalse($res2); } /** * Dataprovider for testInertRow. * * @return array An array of [ $table, $data, $id ] elements. */ public static function insertRowProvider(): array { return [ 'table with numeric primary id' => [ 'config', [ 'cat' => 'test', 'k' => 'a key', 'v' => 'A value' ], 'id', ], 'table with text primary id' => [ 'cache', [ 'k' => 'some key', 'v' => 'cached value', 'updated' => date('Y-m-d H:i:s')], 'k', ], ]; } public function testUpdateRow(): void { // Let's fetch a row from the config table $res = q("SELECT * FROM config WHERE cat = 'system' AND k = 'baseurl'"); $this->assertIsArray($res); $this->assertIsArray($res[0]); $row = $res[0]; // Update the baseurl $updated = DBA::$dba->update( 'config', [ 'v' => 'https://some.other_site.test/' ], 'id', $row['id'] ); $this->assertTrue($updated); // Verify that the record was updated $updated_res = q("SELECT * FROM config WHERE cat = 'system' AND k = 'baseurl'"); $this->assertIsArray($updated_res); $updated_row = $updated_res[0]; $this->assertIsArray($updated_row); $this->assertEquals($row['id'], $updated_row['id']); $this->assertEquals('system', $updated_row['cat']); $this->assertEquals('baseurl', $updated_row['k']); $this->assertEquals('https://some.other_site.test/', $updated_row['v']); } /** * Mark the test as skipped if the current db is MySQL. */ private function skipIfMySQL(): void { $driver = DBA::$dba->db->getAttribute(PDO::ATTR_DRIVER_NAME); $version = DBA::$dba->db->getAttribute(PDO::ATTR_SERVER_VERSION); if ($driver === 'mysql' && stripos($version, 'mariadb') === false) { $this->markTestSkipped("RETURNING clause not supported for {$driver}"); } } }