4 * Copyright © 2003-2024 The Galette Team
6 * This file is part of Galette (https://galette.eu).
8 * Galette is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
13 * Galette is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with Galette. If not, see <http://www.gnu.org/licenses/>.
22 namespace Galette\Core\test\units
;
24 use PHPUnit\Framework\TestCase
;
27 * Database tests class
29 * @author Johan Cwiklinski <johan@x-tnd.be>
31 class Db
extends TestCase
33 private \Galette\Core\Db
$db;
34 private array $have_warnings = [];
41 public function setUp(): void
43 $this->db
= new \Galette\Core\
Db();
51 public function tearDown(): void
53 if (TYPE_DB
=== 'mysql') {
54 $this->assertEquals($this->db
->getWarnings(), $this->have_warnings
);
57 $this->db
= new \Galette\Core\
Db();
58 $delete = $this->db
->delete(\Galette\Entity\Title
::TABLE
);
59 $delete->where([\Galette\Entity\Title
::PK
=> '150']);
60 $this->db
->execute($delete);
68 public function testConstructor()
70 $db = new \Galette\Core\
Db();
72 $this->assertSame(TYPE_DB
, $type);
82 $db = new \Galette\Core\
Db($dsn);
84 $is_pg = $db->isPostgres();
89 $this->assertTrue($is_pg);
90 $this->assertSame(\Galette\Core\Db
::PGSQL
, $type);
92 case \Galette\Core\Db
::MYSQL
:
93 $this->assertFalse($is_pg);
94 $this->assertSame(\Galette\Core\Db
::MYSQL
, $type);
98 $this->expectException(\Exception
::class);
99 $dsn['TYPE_DB'] = 'DOES_NOT_EXISTS';
100 $db = new \Galette\Core\
Db($dsn);
104 * Test database connectivity
108 public function testConnectivity()
110 $res = $this->db
->testConnectivity(
118 $this->assertTrue($res);
122 * Test database grants
126 public function testGrant()
128 $result = $this->db
->dropTestTable();
138 $result = $this->db
->grantCheck();
140 $this->assertSame($expected, $result);
142 //in update mode, we need alter
143 $result = $this->db
->grantCheck('u');
145 $expected['alter'] = true;
146 $this->assertSame($result, $expected);
150 * Test database grants that throws an exception
154 public function testGrantWException()
158 //test insert failing
159 $this->db
= $this->getMockBuilder(\Galette\Core\Db
::class)
160 ->onlyMethods(array('execute'))
163 $this->db
->method('execute')
165 $this->returnCallback(
167 if ($o instanceof \Laminas\Db\Sql\Insert
) {
168 throw new \
LogicException('Error executing query!', 123);
174 $result = $this->db
->grantCheck('u');
176 $this->assertTrue($result['create']);
177 $this->assertTrue($result['alter']);
178 $this->assertInstanceOf(\LogicException
::class, $result['insert']);
179 $this->assertFalse($result['update']);
180 $this->assertFalse($result['select']);
181 $this->assertFalse($result['delete']);
182 $this->assertTrue($result['drop']);
184 //test select failing
185 $this->db
= $this->getMockBuilder(\Galette\Core\Db
::class)
186 ->onlyMethods(array('execute'))
189 $this->db
->method('execute')
191 $this->returnCallback(
193 if ($o instanceof \Laminas\Db\Sql\Select
) {
194 throw new \
LogicException('Error executing query!', 123);
196 $rs = $this->getMockBuilder(\Laminas\Db\ResultSet\ResultSet
::class)
197 ->onlyMethods(array('count'))
207 $result = $this->db
->grantCheck('u');
209 $this->assertTrue($result['create']);
210 $this->assertTrue($result['alter']);
211 $this->assertTrue($result['insert']);
212 $this->assertTrue($result['update']);
213 $this->assertInstanceOf(\LogicException
::class, $result['select']);
214 $this->assertTrue($result['delete']);
215 $this->assertTrue($result['drop']);
217 //test update failing
218 $this->db
= $this->getMockBuilder(\Galette\Core\Db
::class)
219 ->onlyMethods(array('execute'))
222 $this->db
->method('execute')
224 $this->returnCallback(
226 if ($o instanceof \Laminas\Db\Sql\Update
) {
227 throw new \
LogicException('Error executing query!', 123);
229 $rs = $this->getMockBuilder(\Laminas\Db\ResultSet\ResultSet
::class)
230 ->onlyMethods(array('count'))
240 $result = $this->db
->grantCheck('u');
242 $this->assertTrue($result['create']);
243 $this->assertTrue($result['alter']);
244 $this->assertTrue($result['insert']);
245 $this->assertInstanceOf(\LogicException
::class, $result['update']);
246 $this->assertTrue($result['select']);
247 $this->assertTrue($result['delete']);
248 $this->assertTrue($result['drop']);
250 //test delete failing
251 $this->db
= $this->getMockBuilder(\Galette\Core\Db
::class)
252 ->onlyMethods(array('execute'))
255 $this->db
->method('execute')
257 $this->returnCallback(
259 if ($o instanceof \Laminas\Db\Sql\Delete
) {
260 throw new \
LogicException('Error executing query!', 123);
262 $rs = $this->getMockBuilder(\Laminas\Db\ResultSet\ResultSet
::class)
263 ->onlyMethods(array('count'))
273 $result = $this->db
->grantCheck('u');
275 $this->assertTrue($result['create']);
276 $this->assertTrue($result['alter']);
277 $this->assertTrue($result['insert']);
278 $this->assertTrue($result['update']);
279 $this->assertTrue($result['select']);
280 $this->assertInstanceOf(\LogicException
::class, $result['delete']);
281 $this->assertTrue($result['drop']);
285 * Is database Postgresql powered?
289 public function testIsPostgres()
291 $is_pg = $this->db
->isPostgres();
295 $this->assertTrue($is_pg);
298 $this->assertFalse($is_pg);
308 public function testGetters()
312 $type = $this->db
->type_db
;
313 $this->assertSame('pgsql', $type);
316 $type = $this->db
->type_db
;
317 $this->assertSame('mysql', $type);
322 $this->assertInstanceOf('Laminas\Db\Adapter\Adapter', $db);
324 $sql = $this->db
->sql
;
325 $this->assertInstanceOf('Laminas\Db\Sql\Sql', $sql);
327 $connection = $this->db
->connection
;
328 $this->assertInstanceOf('Laminas\Db\Adapter\Driver\Pdo\Connection', $connection);
330 $driver = $this->db
->driver
;
331 $this->assertInstanceOf('Laminas\Db\Adapter\Driver\Pdo\Pdo', $driver);
339 public function testSelect()
341 $select = $this->db
->select('preferences', 'p');
342 $select->where(array('p.nom_pref' => 'pref_nom'));
344 $results = $this->db
->execute($select);
346 $query = $this->db
->query_string
;
348 $expected = 'SELECT "p".* FROM "galette_preferences" AS "p" ' .
349 'WHERE "p"."nom_pref" = \'pref_nom\'';
351 if (TYPE_DB
=== 'mysql') {
352 $expected = 'SELECT `p`.* FROM `galette_preferences` AS `p` ' .
353 'WHERE `p`.`nom_pref` = \'pref_nom\'';
356 $this->assertSame($expected, $query);
364 public function testSelectAll()
366 $all = $this->db
->selectAll('preferences');
367 $this->assertInstanceOf('Laminas\Db\ResultSet\ResultSet', $all);
375 public function testInsert()
377 $insert = $this->db
->insert('titles');
380 'short_label' => 'Dr',
381 'long_label' => 'Doctor'
383 $insert->values($data);
384 $res = $this->db
->execute($insert);
386 $select = $this->db
->select('titles', 't');
387 $select->where(['t.id_title' => $data['id_title']]);
389 $results = $this->db
->execute($select);
390 $this->assertSame(1, $results->count());
392 if (TYPE_DB
=== 'pgsql') {
393 $data['id_title'] = (int)$data['id_title'];
395 $this->assertEquals((array)$results->current(), $data);
403 public function testUpdate()
405 $insert = $this->db
->insert('titles');
408 'short_label' => 'Dr',
409 'long_label' => 'Doctor'
411 $insert->values($data);
412 $res = $this->db
->execute($insert);
414 $update = $this->db
->update('titles');
416 'long_label' => 'DoctorS'
418 $where = ['id_title' => 150];
420 $select = $this->db
->select('titles', 't');
421 $select->columns(['long_label']);
422 $select->where($where);
423 $results = $this->db
->execute($select);
425 $long_label = $results->current()->long_label
;
426 $this->assertSame('Doctor', $long_label);
429 $update->where($where);
430 $res = $this->db
->execute($update);
431 $this->assertSame(1, $res->count());
433 $results = $this->db
->execute($select);
434 $this->assertSame(1, $results->count());
436 $long_label = $results->current()->long_label
;
437 $this->assertSame('DoctorS', $long_label);
445 public function testDelete()
447 $insert = $this->db
->insert('titles');
450 'short_label' => 'Dr',
451 'long_label' => 'Doctor'
453 $insert->values($data);
454 $res = $this->db
->execute($insert);
456 $delete = $this->db
->delete('titles');
457 $where = ['id_title' => 150];
459 $select = $this->db
->select('titles', 't');
460 $select->where($where);
461 $results = $this->db
->execute($select);
462 $this->assertSame(1, $results->count());
464 $delete->where($where);
465 $res = $this->db
->execute($delete);
466 $this->assertSame(1, $res->count());
468 $results = $this->db
->execute($select);
469 $this->assertSame(0, $results->count());
473 * Test database version
477 public function testDbVersion()
479 $db_version = $this->db
->getDbVersion();
480 $this->assertSame(GALETTE_DB_VERSION
, $db_version);
482 $res = $this->db
->checkDbVersion();
483 $this->assertTrue($res);
487 * Test database version that throws an exception
491 public function testDbVersionWException()
493 $this->db
= $this->getMockBuilder(\Galette\Core\Db
::class)
494 ->onlyMethods(array('execute'))
496 $this->db
->method('execute')
498 $this->returnCallback(
499 function ($table, $where) {
500 throw new \
LogicException('Error executing query!', 123);
505 $this->expectException('LogicException');
506 $this->db
->getDbVersion();
507 $this->assertFalse($this->db
->checkDbVersion());
511 * Test get columns method
515 public function testGetColumns()
517 $cols = $this->db
->getColumns('preferences');
519 $this->assertCount(3, $cols);
522 foreach ($cols as $c) {
523 $columns[] = $c->getName();
532 array_values($columns)
539 * FIXME: this test will fail if some plugins tables are present
543 public function testTables()
546 'galette_groups_members',
547 'galette_transactions',
549 'galette_types_cotisation',
550 'galette_paymenttypes',
558 'galette_groups_managers',
559 'galette_dynamic_fields',
560 'galette_fields_config',
561 'galette_tmppasswds',
565 'galette_import_model',
566 'galette_cotisations',
567 'galette_field_types',
568 'galette_fields_categories',
569 'galette_mailing_history',
571 'galette_preferences',
576 $tables = $this->db
->getTables();
578 //tables created in grantCheck are sometimes
580 if (in_array('galette_test', $tables)) {
581 unset($tables[array_search('galette_test', $tables)]);
587 $this->assertSame($expected, $tables);
591 * Test UTF conversion, for MySQL only
595 public function testConvertToUtf()
597 $convert = $this->db
->convertToUTF();
598 $this->assertNull($convert);
606 public function testGetPlatform()
608 $quoted = $this->db
->platform
->quoteValue('somethin\' to "quote"');
610 $expected = ($this->db
->isPostgres()) ?
611 "'somethin'' to \"quote\"'" :
612 "'somethin\\' to \\\"quote\\\"'";
614 $this->assertSame($expected, $quoted);
618 * Test execute Method
622 public function testExecute()
624 $select = $this->db
->select('preferences', 'p');
625 $select->where(['p.nom_pref' => 'azerty']);
626 $results = $this->db
->execute($select);
628 $this->assertInstanceOf('\Laminas\Db\ResultSet\ResultSet', $results);
632 * Test execute Method
636 public function testExecuteWException()
638 $this->have_warnings
= [
643 'Message' => "Unknown column 'p.notknown' in 'where clause'"
647 $select = $this->db
->select('preferences', 'p');
648 $select->where(['p.nom_pref' => 'azerty']);
649 $select->where(['p.notknown' => 'azerty']);
651 $this->expectException('\PDOException');
652 $results = $this->db
->execute($select);
660 public function testSerialization()
663 $serialized = serialize($db);
664 $this->assertNotNull($serialized);
666 $unserialized = unserialize($serialized);
667 $this->assertInstanceOf('Galette\Core\Db', $unserialized);