aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/items.php2
-rw-r--r--tests/unit/UnitTestCase.php65
-rw-r--r--view/js/main.js23
-rw-r--r--view/theme/redbasic/css/style.css6
-rw-r--r--view/tpl/hdr.tpl1
-rw-r--r--view/tpl/notifications_widget.tpl8
6 files changed, 87 insertions, 18 deletions
diff --git a/include/items.php b/include/items.php
index 2300f70ef..dc9e9a7d9 100644
--- a/include/items.php
+++ b/include/items.php
@@ -208,8 +208,6 @@ function collect_recipients($item, &$private_envelope, $include_groups = true) {
$recipients[] = $item['owner_xchan'];
}
-hz_syslog(print_r($recipients, true));
-
return $recipients;
}
diff --git a/tests/unit/UnitTestCase.php b/tests/unit/UnitTestCase.php
index a4ea94b13..9ab6a534a 100644
--- a/tests/unit/UnitTestCase.php
+++ b/tests/unit/UnitTestCase.php
@@ -33,29 +33,30 @@ require_once __DIR__ . '/../../boot.php';
require_once 'include/dba/dba_driver.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();
/**
- * Override the PHPUnit\Framework\TestCase::run method, so we can
- * wrap it in a database transaction.
+ * Override the run method, so we can wrap it in a database transaction.
+ *
+ * The transaction is automatically rolled back when the test completes, to
+ * leave the test database in a known pristine state.
*
* @SuppressWarnings(PHPMD.UnusedLocalVariable)
*/
public function run(TestResult $result = null): TestResult {
- // $myclass = get_class($this);
- // logger("[*] Running test: {$myclass}::{$this->getName(true)}", LOGGER_DEBUG);
-
if (! \DBA::$dba) {
- //logger('[*] Connecting to test db...');
$this->connect_to_test_db();
}
@@ -74,6 +75,22 @@ class UnitTestCase extends TestCase {
return $result;
}
+ /**
+ * 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 +118,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 +134,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 +145,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];
diff --git a/view/js/main.js b/view/js/main.js
index c9798dede..8904f8b4c 100644
--- a/view/js/main.js
+++ b/view/js/main.js
@@ -1305,7 +1305,8 @@ function dropItem(url, object, b64mid) {
$(object + ', #pinned-wrapper-' + id).remove();
$('body').css('cursor', 'auto');
- $.jGrowl(aStr.itemdel, { sticky: false, theme: 'info', life: 3000 });
+ toast(aStr.itemdel, 'info')
+ //$.jGrowl(aStr.itemdel, { sticky: false, theme: 'info', life: 3000 });
if (typeof b64mid !== typeof undefined) {
$('[data-b64mid=\'' + b64mid + '\']').fadeOut(function() {
@@ -1408,7 +1409,8 @@ function submitPoll(id) {
$.post('vote/' + id,
$('#question-form-' + id).serialize(),
function(data) {
- $.jGrowl(data.message, { sticky: false, theme: ((data.success) ? 'info' : 'notice'), life: 10000 });
+ toast(data.message, ((data.success) ? 'info' : 'danger'));
+ //$.jGrowl(data.message, { sticky: false, theme: ((data.success) ? 'info' : 'notice'), life: 10000 });
if(timer) clearTimeout(timer);
timer = setTimeout(updateInit, 500);
}
@@ -1815,3 +1817,20 @@ function toggleAside() {
$('<div id="overlay"></div>').appendTo('body').one('click', function() { toggleAside(); });
}
}
+
+function toast(string, severity) {
+ let container = document.getElementById('toast-container');
+ let toast = document.createElement('div');
+
+ toast.innerHTML = '<div class="d-flex"><div class="toast-body">' + string + '</div><button type="button" class="btn-close me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button></div>';
+ toast.classList.add('toast', 'p-2', 'm-3', 'bg-' + severity + '-subtle', 'text-' + severity + '-emphasis', 'border-' + severity);
+ container.prepend(toast);
+
+ let toastInstance = bootstrap.Toast.getOrCreateInstance(toast);
+
+ if (severity === 'danger') {
+ toastInstance._config.autohide = false;
+ }
+
+ toastInstance.show();
+}
diff --git a/view/theme/redbasic/css/style.css b/view/theme/redbasic/css/style.css
index 56194c735..05cd75422 100644
--- a/view/theme/redbasic/css/style.css
+++ b/view/theme/redbasic/css/style.css
@@ -168,6 +168,11 @@ input[type=text], textarea {
color: #FF0000;
}
+#toast-container {
+ z-index: 1030;
+ width: 300px;
+}
+
#powered-by {
font-size: 0.5rem;
position: absolute;
@@ -719,6 +724,7 @@ div.jGrowl div.info {
color: #ffffff;
padding-left: 58px;
}
+
#jGrowl.top-right {
top: 4.5rem;
right: .25rem;
diff --git a/view/tpl/hdr.tpl b/view/tpl/hdr.tpl
index e69de29bb..ba63830eb 100644
--- a/view/tpl/hdr.tpl
+++ b/view/tpl/hdr.tpl
@@ -0,0 +1 @@
+<div id="toast-container" class="d-flex position-fixed top-0 end-0"></div>
diff --git a/view/tpl/notifications_widget.tpl b/view/tpl/notifications_widget.tpl
index 9ea5ffec6..aa53905ad 100644
--- a/view/tpl/notifications_widget.tpl
+++ b/view/tpl/notifications_widget.tpl
@@ -337,17 +337,19 @@
sse_setNotificationsStatus();
// notice and info
- $.jGrowl.defaults.closerTemplate = '<div>[ ' + aStr.closeAll + ']</div>';
+ //$.jGrowl.defaults.closerTemplate = '<div>[ ' + aStr.closeAll + ']</div>';
if(obj.notice) {
$(obj.notice.notifications).each(function() {
- $.jGrowl(this, { sticky: true, theme: 'notice' });
+ toast(this, 'danger');
+ //$.jGrowl(this, { sticky: true, theme: 'notice' });
});
}
if(obj.info) {
$(obj.info.notifications).each(function(){
- $.jGrowl(this, { sticky: false, theme: 'info', life: 10000 });
+ toast(this, 'info');
+ //$.jGrowl(this, { sticky: false, theme: 'info', life: 10000 });
});
}