connection = $oConnection; } } // phpcs:ignore PSR1.Classes.ClassDeclaration.MultipleClasses class DBTest extends \PHPUnit\Framework\TestCase { public function testReusingConnection() { $oDB = new NominatimSubClassedDB(''); $oDB->setConnection('anything'); $this->assertTrue($oDB->connect()); } public function testCheckConnection() { $oDB = new \Nominatim\DB(''); $this->assertFalse($oDB->checkConnection()); } public function testErrorHandling() { $this->expectException(DatabaseError::class); $this->expectExceptionMessage('Failed to establish database connection'); $oDB = new \Nominatim\DB('pgsql:dbname=abc'); $oDB->connect(); } public function testErrorHandling2() { $this->expectException(DatabaseError::class); $this->expectExceptionMessage('Database query failed'); $oPDOStub = $this->getMockBuilder(PDO::class) ->setMethods(array('query', 'quote')) ->getMock(); $oPDOStub->method('query') ->will($this->returnCallback(function ($sVal) { return "'$sVal'"; })); $oPDOStub->method('query') ->will($this->returnCallback(function () { throw new \PDOException('ERROR: syntax error at or near "FROM"'); })); $oDB = new NominatimSubClassedDB(''); $oDB->setConnection($oPDOStub); $oDB->getOne('SELECT name FROM'); } public function testGetPostgresVersion() { $oDBStub = $this->getMockBuilder(\Nominatim\DB::class) ->disableOriginalConstructor() ->setMethods(array('getOne')) ->getMock(); $oDBStub->method('getOne') ->willReturn('100006'); $this->assertEquals(10, $oDBStub->getPostgresVersion()); } public function testGetPostgisVersion() { $oDBStub = $this->getMockBuilder(\Nominatim\DB::class) ->disableOriginalConstructor() ->setMethods(array('getOne')) ->getMock(); $oDBStub->method('getOne') ->willReturn('2.4.4'); $this->assertEquals(2.4, $oDBStub->getPostgisVersion()); } public function testParseDSN() { $this->assertEquals( array(), \Nominatim\DB::parseDSN('') ); $this->assertEquals( array( 'database' => 'db1', 'hostspec' => 'machine1' ), \Nominatim\DB::parseDSN('pgsql:dbname=db1;host=machine1') ); $this->assertEquals( array( 'database' => 'db1', 'hostspec' => 'machine1', 'port' => '1234', 'username' => 'john', 'password' => 'secret' ), \Nominatim\DB::parseDSN('pgsql:dbname=db1;host=machine1;port=1234;user=john;password=secret') ); } public function testGenerateDSN() { $this->assertEquals( 'pgsql:', \Nominatim\DB::generateDSN(array()) ); $this->assertEquals( 'pgsql:host=machine1;dbname=db1', \Nominatim\DB::generateDSN(\Nominatim\DB::parseDSN('pgsql:host=machine1;dbname=db1')) ); } public function testAgainstDatabase() { $unit_test_dsn = getenv('UNIT_TEST_DSN') != false ? getenv('UNIT_TEST_DSN') : 'pgsql:dbname=nominatim_unit_tests'; $this->assertRegExp( '/unit_test/', $unit_test_dsn, 'Test database will get destroyed, thus should have a name like unit_test to be safe' ); ## Create the database. { $aDSNParsed = \Nominatim\DB::parseDSN($unit_test_dsn); $sDbname = $aDSNParsed['database']; $aDSNParsed['database'] = 'postgres'; $oDB = new \Nominatim\DB(\Nominatim\DB::generateDSN($aDSNParsed)); $oDB->connect(); $oDB->exec('DROP DATABASE IF EXISTS ' . $sDbname); $oDB->exec('CREATE DATABASE ' . $sDbname); } $oDB = new \Nominatim\DB($unit_test_dsn); $oDB->connect(); $this->assertTrue( $oDB->checkConnection($sDbname) ); # Tables, Indices { $this->assertEmpty($oDB->getListOfTables()); $oDB->exec('CREATE TABLE table1 (id integer, city varchar, country varchar)'); $oDB->exec('CREATE TABLE table2 (id integer, city varchar, country varchar)'); $this->assertEquals( array('table1', 'table2'), $oDB->getListOfTables() ); $this->assertTrue($oDB->deleteTable('table2')); $this->assertTrue($oDB->deleteTable('table99')); $this->assertEquals( array('table1'), $oDB->getListOfTables() ); $this->assertTrue($oDB->tableExists('table1')); $this->assertFalse($oDB->tableExists('table99')); $this->assertFalse($oDB->tableExists(null)); $this->assertEmpty($oDB->getListOfIndices()); $oDB->exec('CREATE UNIQUE INDEX table1_index ON table1 (id)'); $this->assertEquals( array('table1_index'), $oDB->getListOfIndices() ); $this->assertEmpty($oDB->getListOfIndices('table2')); } # select queries { $oDB->exec( "INSERT INTO table1 VALUES (1, 'Berlin', 'Germany'), (2, 'Paris', 'France')" ); $this->assertEquals( array( array('city' => 'Berlin'), array('city' => 'Paris') ), $oDB->getAll('SELECT city FROM table1') ); $this->assertEquals( array(), $oDB->getAll('SELECT city FROM table1 WHERE id=999') ); $this->assertEquals( array('id' => 1, 'city' => 'Berlin', 'country' => 'Germany'), $oDB->getRow('SELECT * FROM table1 WHERE id=1') ); $this->assertEquals( false, $oDB->getRow('SELECT * FROM table1 WHERE id=999') ); $this->assertEquals( array('Berlin', 'Paris'), $oDB->getCol('SELECT city FROM table1') ); $this->assertEquals( array(), $oDB->getCol('SELECT city FROM table1 WHERE id=999') ); $this->assertEquals( 'Berlin', $oDB->getOne('SELECT city FROM table1 WHERE id=1') ); $this->assertEquals( null, $oDB->getOne('SELECT city FROM table1 WHERE id=999') ); $this->assertEquals( array('Berlin' => 'Germany', 'Paris' => 'France'), $oDB->getAssoc('SELECT city, country FROM table1') ); $this->assertEquals( array(), $oDB->getAssoc('SELECT city, country FROM table1 WHERE id=999') ); } } }