assertTrue(open_db('open')); $this->assertInstanceOf(FakeDb::class, $GLOBALS['db']); $this->assertSame(array(array('db.test', 'test-user', 'test-pass', 'test-db')), FakeDb::$connections); } public function testOpenTwiceKeepsTheFirstConnection(): void { open_db('open'); $first = $GLOBALS['db']; $this->assertFalse(open_db('open')); $this->assertSame($first, $GLOBALS['db']); $this->assertCount(1, FakeDb::$connections); } public function testCloseClosesAndForgetsTheConnection(): void { open_db('open'); $connection = $GLOBALS['db']; $this->assertTrue(open_db('close')); $this->assertTrue($connection->closed); $this->assertNull($GLOBALS['db']); $this->assertFalse(open_db('close')); } public function testOpenAfterCloseConnectsAgain(): void { open_db('open'); open_db('close'); open_db('open'); $this->assertCount(2, FakeDb::$connections); } public function testDbHostDefaultsToLocalhost(): void { $root = var_export(XXX_ROOT, TRUE); $result = PhpProcess::runPlain( "require $root . '/vendor/autoload.php';\n" . "if (!function_exists('mysqli_report')) { define('MYSQLI_REPORT_OFF', 0); function mysqli_report(\$f) { return TRUE; } }\n" . "require $root . '/open_db.lib.php';\n" . "\$db_class = Xxx\\Tests\\Support\\FakeDb::class;\n" . "open_db('open');\n" . "echo json_encode(Xxx\\Tests\\Support\\FakeDb::\$connections);", array('XXX_ENV_FILE' => $this->tmp . '/none')); $this->assertSame('[["localhost",null,null,null]]', $result['stdout'], $result['stderr']); } public function testConnectErrorStopsThePageAndLogsTheDetails(): void { $result = PhpProcess::run('Xxx\Tests\Support\FakeDb::$connectError = "Access denied for user"; open_db("open"); echo "not reached";'); $this->assertSame('
Sorry, something went wrong. Please try again later.
', $result['stdout']); $this->assertStringContainsString('xxx: database error at open_db.lib.php:', $result['log']); $this->assertStringContainsString('connect error (1045) Access denied for user', $result['log']); $this->assertStringNotContainsString('Access denied', $result['stdout']); } public function testDbFailLogsTheCallerAndTheDatabaseError(): void { $result = PhpProcess::run("open_db('open');\n\$GLOBALS['db']->error = \"Table 'secret' doesn't exist\";\ndb_fail();\necho 'not reached';"); $this->assertSame('Sorry, something went wrong. Please try again later.
', $result['stdout']); $this->assertMatchesRegularExpression("/xxx: database error at xxx-php-\\w+:5: Table 'secret' doesn't exist/", $result['log']); } public function testDbFailWithoutAConnection(): void { $result = PhpProcess::run('db_fail();'); $this->assertStringContainsString('no database connection', $result['log']); } public function testDbFailWithDetail(): void { $result = PhpProcess::run('db_fail("custom detail");'); $this->assertStringContainsString(': custom detail', $result['log']); } public function testFailedQueryInTheCodeStopsThePage(): void { $result = PhpProcess::run('Xxx\Tests\Support\FakeDb::on("/COUNT/", FALSE); open_db("open"); get_count(); echo "not reached";'); $this->assertSame('Sorry, something went wrong. Please try again later.
', $result['stdout']); $this->assertStringContainsString('database error at get_data.lib.php:', $result['log']); } }