aboutsummaryrefslogtreecommitdiffstats
path: root/tests/unit/UnitTestCase.php
diff options
context:
space:
mode:
Diffstat (limited to 'tests/unit/UnitTestCase.php')
-rw-r--r--tests/unit/UnitTestCase.php91
1 files changed, 73 insertions, 18 deletions
diff --git a/tests/unit/UnitTestCase.php b/tests/unit/UnitTestCase.php
index a4ea94b13..afc309205 100644
--- a/tests/unit/UnitTestCase.php
+++ b/tests/unit/UnitTestCase.php
@@ -22,8 +22,8 @@
namespace Zotlabs\Tests\Unit;
+use PHPUnit\Framework\Attributes\{Before, After};
use PHPUnit\Framework\TestCase;
-use PHPUnit\Framework\TestResult;
/*
* Make sure global constants and the global App object is available to the
@@ -31,49 +31,78 @@ use PHPUnit\Framework\TestResult;
*/
require_once __DIR__ . '/../../boot.php';
require_once 'include/dba/dba_driver.php' ;
+require_once 'include/dba/dba_transaction.php';
/**
- * @brief Base class for our Unit Tests.
+ * Base class for our Unit Tests.
*
- * Empty class at the moment, but you should extend this class for unit test
- * cases, so we could and for sure we will need to implement basic behaviour
- * for all of our unit tests.
+ * Base class for Hubzilla unit/integration tests. This extends the base
+ * TestCase class from PHPUnit by connecting to a test database, and making the
+ * database connection available to the code under test via the normal Hubzilla
+ * mechanisms, i.e the \DBA::$dba global variable.
*
- * @author Klaus Weidenbach
+ * It also automatically loads database fixtures from yaml files in the
+ * tests/unit/includes/dba/_files directory. And wraps each test run in it's
+ * own database transaction.
*/
class UnitTestCase extends TestCase {
protected array $fixtures = array();
+ protected ?\DbaTransaction $db_transacton = null;
/**
- * Override the PHPUnit\Framework\TestCase::run method, so we can
- * wrap it in a database transaction.
+ * Connect to the test db, load fixtures and global config.
*
- * @SuppressWarnings(PHPMD.UnusedLocalVariable)
+ * This function is executed before every test.
+ *
+ * The transaction is rolled back in the `cleanup_test_db()` function
+ * that's executed after every test.
*/
- public function run(TestResult $result = null): TestResult {
- // $myclass = get_class($this);
- // logger("[*] Running test: {$myclass}::{$this->getName(true)}", LOGGER_DEBUG);
-
+ #[Before]
+ protected function setup_test_db(): void {
if (! \DBA::$dba) {
- //logger('[*] Connecting to test db...');
$this->connect_to_test_db();
}
// The $transactuion variable is needed to hold the transaction until the
// function returns.
- $transaction = new \DbaTransaction(\DBA::$dba);
+ $this->db_transaction = new \DbaTransaction(\DBA::$dba);
$this->loadFixtures();
// Make sure app config is reset and loaded from fixtures
\App::$config = array();
\Zotlabs\Lib\Config::Load('system');
+ }
- $result = parent::run($result);
-
- return $result;
+ /**
+ * Roll back test database to it's original state, cleaning up
+ * any changes from the test.
+ *
+ * This function is executes after evert tests.
+ */
+ #[After]
+ protected function cleanup_test_db(): void {
+ // Setting the transaction to `null`, runs the destructor
+ // which rolls backk the transacton.
+ $this->db_transaction = null;
}
+ /**
+ * Connect to the test database,
+ *
+ * By default it will connect to a MySQL database with the following settings:
+ *
+ * - HZ_TEST_DB_HOST: db
+ * - HZ_TEST_DB_PORT: default
+ * - HZ_TEST_DB_USER: test_user
+ * - HZ_TEST_DB_PASS: hubzilla
+ * - HZ_TEST_DB_DATABASE: hubzilla_test_db
+ * - HZ_TEST_DB_TYPE: mysql (can also be "postgres")
+ * - HZ_TEST_DB_CHARSET: UTF8
+ *
+ * All of these settings can be overridden by the test runner by setting ENV vars
+ * named as above with the values you want to override.
+ */
protected function connect_to_test_db() : void {
if ( !\DBA::$dba ) {
\DBA::dba_factory(
@@ -101,6 +130,14 @@ class UnitTestCase extends TestCase {
}
}
+ /**
+ * Return the database type from a string.
+ *
+ * @param string $type The database type, can be either mysql or postgres.
+ *
+ * @return The database type constant matching the passed in type, or DBTYPE_MYSQL
+ * if $type is empty or invalid.
+ */
private static function dbtype(string $type): int {
if (trim(strtolower($type)) === 'postgres') {
return DBTYPE_POSTGRES;
@@ -109,6 +146,9 @@ class UnitTestCase extends TestCase {
}
}
+ /**
+ * Load database fixtures from the fixture path.
+ */
private function loadFixtures() : void {
$files = glob(__DIR__ . '/includes/dba/_files/*.yml');
if ($files === false || empty($files)) {
@@ -117,6 +157,21 @@ class UnitTestCase extends TestCase {
array_walk($files, fn($file) => $this->loadFixture($file));
}
+ /**
+ * Load database fixtures from a specific file.
+ *
+ * The file must be a yaml file named the same as the table in the database
+ * it should populate.
+ *
+ * The file also need to have a root key with the same name as the table.
+ * Under which it contains an array of rows that should be inserted into
+ * the db table.
+ *
+ * @param string $file The path and filename of the fixture to load.
+ * The path name is relative to the current working
+ * directory of the process, which should normally
+ * be the Hubzilla root directory.
+ */
private function loadFixture($file) : void {
$table_name = basename($file, '.yml');
$this->fixtures[$table_name] = yaml_parse_file($file)[$table_name];