aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Zotlabs/Lib/QueueWorker.php38
-rw-r--r--include/channel.php4
-rw-r--r--include/plugin.php21
-rw-r--r--tests/unit/Access/PermissionsTest.php26
-rw-r--r--tests/unit/CallHooksTest.php65
-rw-r--r--tests/unit/CreateIdentityTest.php65
-rw-r--r--tests/unit/Lib/PermissionDescriptionTest.php20
7 files changed, 157 insertions, 82 deletions
diff --git a/Zotlabs/Lib/QueueWorker.php b/Zotlabs/Lib/QueueWorker.php
index ce239809f..24114438e 100644
--- a/Zotlabs/Lib/QueueWorker.php
+++ b/Zotlabs/Lib/QueueWorker.php
@@ -6,6 +6,8 @@ use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\Exception\UnableToBuildUuidException;
use Zotlabs\Lib\Config;
+require_once 'include/dba/dba_transaction.php';
+
class QueueWorker {
public static $queueworker = null;
@@ -29,18 +31,6 @@ class QueueWorker {
'Expire'
];
- private static function qstart() {
- q('START TRANSACTION');
- }
-
- private static function qcommit() {
- q("COMMIT");
- }
-
- private static function qrollback() {
- q("ROLLBACK");
- }
-
public static function Summon($argv) {
if ($argv[0] !== 'Queueworker') {
@@ -66,7 +56,7 @@ class QueueWorker {
logger('queueworker_stats_summon: cmd:' . $argv[0] . ' ' . 'timestamp:' . time());
- self::qstart();
+ $transaction = new \DbaTransaction(\DBA::$dba);
$r = q("INSERT INTO workerq (workerq_priority, workerq_data, workerq_uuid, workerq_cmd) VALUES (%d, '%s', '%s', '%s')",
intval($priority),
$workinfo_json,
@@ -74,11 +64,11 @@ class QueueWorker {
dbesc($argv[0])
);
if (!$r) {
- self::qrollback();
+ // Transaction is autmatically rolled back on return
logger("INSERT FAILED", LOGGER_DEBUG);
return;
}
- self::qcommit();
+ $transaction->commit();
logger('INSERTED: ' . $workinfo_json, LOGGER_DEBUG);
}
@@ -112,7 +102,7 @@ class QueueWorker {
return;
}
- self::qstart();
+ $transaction = new \DbaTransaction(\DBA::$dba);
$r = q("INSERT INTO workerq (workerq_priority, workerq_data, workerq_uuid, workerq_cmd) VALUES (%d, '%s', '%s', '%s')",
intval($priority),
$workinfo_json,
@@ -120,11 +110,11 @@ class QueueWorker {
dbesc($argv[0])
);
if (!$r) {
- self::qrollback();
+ // Transaction is automatically rolled back on return
logger("Insert failed: " . $workinfo_json, LOGGER_DEBUG);
return;
}
- self::qcommit();
+ $transaction->commit();
logger('INSERTED: ' . $workinfo_json, LOGGER_DEBUG);
}
@@ -141,7 +131,7 @@ class QueueWorker {
self::$workermaxage = self::$workermaxage > 120 ? self::$workermaxage : 300;
}
- self::qstart();
+ $transaction = new \DbaTransaction(\DBA::$dba);
// skip locked is preferred but is not supported by mariadb < 10.6 which is still used a lot - hence make it optional
$sql_quirks = ((Config::Get('system', 'db_skip_locked_supported')) ? 'SKIP LOCKED' : 'NOWAIT');
@@ -159,7 +149,7 @@ class QueueWorker {
$u = dbq("update workerq set workerq_reservationid = null where workerq_id in ($ids)");
}
- self::qcommit();
+ $transaction->commit();
//q("update workerq set workerq_reservationid = null where workerq_reservationid is not null and workerq_processtimeout < %s",
//db_utcnow()
@@ -197,7 +187,7 @@ class QueueWorker {
private static function getWorkId() {
self::GetWorkerCount();
- self::qstart();
+ $transaction = new \DbaTransaction(\DBA::$dba);
// skip locked is preferred but is not supported by mariadb < 10.6 which is still used a lot - hence make it optional
$sql_quirks = ((Config::Get('system', 'db_skip_locked_supported')) ? 'SKIP LOCKED' : 'NOWAIT');
@@ -205,7 +195,7 @@ class QueueWorker {
$work = dbq("SELECT workerq_id, workerq_cmd FROM workerq WHERE workerq_reservationid IS NULL ORDER BY workerq_priority DESC, workerq_id ASC LIMIT 1 FOR UPDATE $sql_quirks");
if (!$work) {
- self::qrollback();
+ // Transaction automatically rolled back on return
return false;
}
@@ -225,13 +215,13 @@ class QueueWorker {
);
if (!$work) {
- self::qrollback();
+ // Transaction automatically rolled back on return
logger("Could not update workerq.", LOGGER_DEBUG);
return false;
}
logger("GOTWORK: " . json_encode($work), LOGGER_DEBUG);
- self::qcommit();
+ $transaction->commit();
return $id;
}
diff --git a/include/channel.php b/include/channel.php
index 568ad052a..22b5bcde1 100644
--- a/include/channel.php
+++ b/include/channel.php
@@ -199,8 +199,8 @@ function create_identity($arr) {
$ret = array('success' => false);
- if(! $arr['account_id']) {
- $ret['message'] = t('No account identifier');
+ if(empty($arr['account_id'])) {
+ $ret['message'] = t('No account identifier');
return $ret;
}
$ret = identity_check_service_class($arr['account_id']);
diff --git a/include/plugin.php b/include/plugin.php
index 4601cb544..62b643c3e 100644
--- a/include/plugin.php
+++ b/include/plugin.php
@@ -488,18 +488,19 @@ function call_hooks($name, &$data = null) {
@include_once($hook[0]);
}
- if(preg_match('|^a:[0-9]+:{.*}$|s', $hook[1])) {
- $hook[1] = unserialize($hook[1]);
- }
- elseif(strpos($hook[1],'::')) {
- // We shouldn't need to do this, but it appears that PHP
- // isn't able to directly execute a string variable with a class
- // method in the manner we are attempting it, so we'll
- // turn it into an array.
- $hook[1] = explode('::',$hook[1]);
+ if(is_string($hook[1])) {
+ if (preg_match('|^a:[0-9]+:{.*}$|s', $hook[1])) {
+ $hook[1] = unserialize($hook[1]);
+ }
+ elseif(strpos($hook[1],'::')) {
+ // We shouldn't need to do this, but it appears that PHP
+ // isn't able to directly execute a string variable with a class
+ // method in the manner we are attempting it, so we'll
+ // turn it into an array.
+ $hook[1] = explode('::',$hook[1]);
+ }
}
-
if(is_callable($hook[1])) {
$func = $hook[1];
$func($data);
diff --git a/tests/unit/Access/PermissionsTest.php b/tests/unit/Access/PermissionsTest.php
index dd001e68a..f9cb25b64 100644
--- a/tests/unit/Access/PermissionsTest.php
+++ b/tests/unit/Access/PermissionsTest.php
@@ -63,14 +63,6 @@ class PermissionsTest extends UnitTestCase {
// There are 17 default perms
$permsCount = 17;
- // Create a stub for global function t() with expectation
- $t = $this->getFunctionMock('Zotlabs\Access', 't');
- $t->expects($this->exactly(2*$permsCount))->willReturnCallback(
- function ($string) {
- return $string;
- }
- );
-
// static method Perms()
$perms = Permissions::Perms();
@@ -97,14 +89,6 @@ class PermissionsTest extends UnitTestCase {
// There are 17 default perms
$permsCount = 17;
- // Create a stub for global function t() with expectation
- $t = $this->getFunctionMock('Zotlabs\Access', 't');
- $t->expects($this->exactly(2*$permsCount))->willReturnCallback(
- function ($string) {
- return $string;
- }
- );
-
$perms = Permissions::Perms('view_');
$this->assertEquals($permsCount, count($perms));
@@ -125,9 +109,6 @@ class PermissionsTest extends UnitTestCase {
* @param array $expected The expected result perms array
*/
public function testFilledPerms($permarr, $expected) {
- // Create a stub for global function t()
- $t = $this->getFunctionMock('Zotlabs\Access', 't');
-
$this->assertEquals($expected, Permissions::FilledPerms($permarr));
}
/**
@@ -209,13 +190,6 @@ class PermissionsTest extends UnitTestCase {
* @uses ::call_hooks
*/
public function testFilledPermsNull() {
- // Create a stub for global function t() with expectation
- $t = $this->getFunctionMock('Zotlabs\Access', 't');
- $t->expects($this->atLeastOnce());
- // Create a stub for global function bt() with expectations
- $bt = $this->getFunctionMock('Zotlabs\Access', 'btlogger');
- $bt->expects($this->once())->with($this->equalTo('FilledPerms: null'));
-
$result = [
'view_stream' => 0,
'send_stream' => 0,
diff --git a/tests/unit/CallHooksTest.php b/tests/unit/CallHooksTest.php
new file mode 100644
index 000000000..0170f31d0
--- /dev/null
+++ b/tests/unit/CallHooksTest.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ * Unit tests for the `call_hooks` function, located in include/plugin.php.
+ *
+ * SPDX-FileCopyrightText: 2024 Hubzilla Community
+ * SPDX-FileContributor: Harald Eilertsen
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+namespace Zotlabs\Tests\Unit;
+
+use PHPUnit\Framework\Attributes\BackupStaticProperties;
+use App;
+
+#[BackupStaticProperties(App::class)]
+class CallHooksTest extends UnitTestCase {
+
+ /**
+ * Test using a freestanding function as callback.
+ *
+ * @SuppressWarnings(PHPMD.EvalExpression)
+ */
+ public function test_freestanding_function_as_string(): void {
+ eval('function hook_test_function(array &$args): void { $args["called"] = true; }');
+ insert_hook('test_hook', 'hook_test_function');
+ $this->assertHookInvoked();
+ }
+
+ public function test_static_class_function_as_string(): void {
+ insert_hook('test_hook', 'Zotlabs\Tests\Unit\CallHooksTest::static_test_hook');
+ $this->assertHookInvoked();
+ }
+
+ public function test_static_class_function_as_array(): void {
+ insert_hook('test_hook', ['Zotlabs\Tests\Unit\CallHooksTest', 'static_test_hook']);
+ $this->assertHookInvoked();
+ }
+
+ public function test_static_class_function_as_serialized_array(): void {
+ insert_hook('test_hook', serialize(['Zotlabs\Tests\Unit\CallHooksTest', 'static_test_hook']));
+ $this->assertHookInvoked();
+ }
+
+ public function test_instance_function_as_array(): void {
+ insert_hook('test_hook', [$this, 'instance_test_hook']);
+ $this->assertHookInvoked();
+ }
+
+
+ public function assertHookInvoked(): void {
+ $test_hook_args = ['called' => false];
+ call_hooks('test_hook', $test_hook_args);
+
+ $this->assertTrue($test_hook_args['called']);
+ }
+
+ public function instance_test_hook(array &$args): void {
+ $args['called'] = true;
+ }
+ public static function static_test_hook(array &$args): void {
+ $args['called'] = true;
+ }
+}
+
diff --git a/tests/unit/CreateIdentityTest.php b/tests/unit/CreateIdentityTest.php
new file mode 100644
index 000000000..a5e0f278a
--- /dev/null
+++ b/tests/unit/CreateIdentityTest.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ * Unit tests for the `create_identity` function.
+ *
+ * SPDX-FileCopyrightText: 2024 Hubzilla Community
+ * SPDX-FileContributor: Harald Eilertsen
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+namespace Zotlabs\Tests\Unit;
+
+class CreateIdentityTest extends UnitTestCase {
+
+ private bool $queueworker_started = false;
+
+ public function test_empty_args() {
+ insert_hook('proc_run', [$this, 'proc_run_hook']);
+ $result = create_identity([]);
+ $this->assertEquals(
+ ['success' => false, 'message' => 'No account identifier'],
+ $result);
+
+ $this->assertFalse($this->queueworker_started);
+ }
+
+ public function test_create_new_channel_with_valid_account_id(): void {
+ insert_hook('proc_run', [$this, 'proc_run_hook']);
+ $result = create_identity([
+ 'account_id' => $this->fixtures['account'][0]['account_id'],
+ 'nickname' => 'testuser',
+ 'name' => 'Olga Testuser',
+ ]);
+
+ $this->assertTrue($result['success']);
+ $this->assertTrue($this->queueworker_started);
+ }
+
+ public function test_create_new_channel_with_nnexistant_account_id(): void {
+ insert_hook('proc_run', [$this, 'proc_run_hook']);
+ $result = create_identity([
+ 'account_id' => 666,
+ 'nickname' => 'testuser',
+ 'name' => 'Olga Testuser',
+ ]);
+
+ /*
+ * We would expect this fo fail, but...
+ *
+ * The create_identity function will happily create a new channel with an
+ * non-existent account_id. The New_channel module will perform a check
+ * to ensure that only valid (and logged in) accounts can create a new channel.
+ *
+ * This is a bit weak, but for now we let it pass...
+ */
+ $this->assertTrue($result['success']);
+ $this->assertTrue($this->queueworker_started);
+ }
+
+ public function proc_run_hook(array &$args): void {
+ $args['run_cmd'] = false;
+ $this->queueworker_started =
+ $args['args'] === ['php', 'Zotlabs/Daemon/Master.php', 'Queueworker'];
+ }
+}
diff --git a/tests/unit/Lib/PermissionDescriptionTest.php b/tests/unit/Lib/PermissionDescriptionTest.php
index fdd676f61..1e4b5292c 100644
--- a/tests/unit/Lib/PermissionDescriptionTest.php
+++ b/tests/unit/Lib/PermissionDescriptionTest.php
@@ -46,16 +46,6 @@ class PermissionDescriptionTest extends UnitTestCase {
}
public function testFromStandalonePermission() {
- // Create a stub for global function t()
- $t = $this->getFunctionMock('Zotlabs\Lib', 't');
- $t->expects($this->atLeastOnce())->willReturnCallback(
- function ($string) {
- return $string;
- }
- );
- // Create a mock for global function logger()
- $this->getFunctionMock('Zotlabs\Lib', 'logger');
-
$permDescUnknown = PermissionDescription::fromStandalonePermission(-1);
$permDescSelf = PermissionDescription::fromStandalonePermission(0);
@@ -113,16 +103,6 @@ class PermissionDescriptionTest extends UnitTestCase {
}
public function testGetPermissionDescription() {
- // Create a stub for global function t()
- $t = $this->getFunctionMock('Zotlabs\Lib', 't');
- $t->expects($this->atLeastOnce())->willReturnCallback(
- function ($string) {
- return $string;
- }
- );
- // Create a mock for global function logger()
- $this->getFunctionMock('Zotlabs\Lib', 'logger');
-
// Create a stub for the PermissionDescription class
$stub = $this->createMock(PermissionDescription::class);
$stub->method('get_permission_description')