Upload via GUI (267 Dateien)

This commit is contained in:
2026-10-19 18:05:51 +00:00
parent 845abfa9d9
commit 42554bdadf
18 changed files with 1629 additions and 13 deletions
@@ -4,10 +4,27 @@ declare(strict_types=1);
$root = dirname(__DIR__);
$sourceDb = $root . '/database/deskhub.sqlite';
$tempDb = tempnam(sys_get_temp_dir(), 'deskhub-api-');
if ($tempDb === false || !copy($sourceDb, $tempDb)) {
if ($tempDb === false) {
fwrite(STDERR, "Testdatenbank konnte nicht erstellt werden.\n");
exit(1);
}
if (is_file($sourceDb)) {
copy($sourceDb, $tempDb);
} else {
// Keine Entwicklungsdatenbank vorhanden (frische Kopie, CI): Datenbank aus Schema und Migrationen aufbauen
require_once $root . '/includes/db.php';
require_once $root . '/database/migrate.php';
$fresh = new PDO('sqlite:' . $tempDb);
$fresh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$fresh->exec('PRAGMA foreign_keys = ON');
$fresh->exec(convert_schema_to_sqlite((string) file_get_contents($root . '/database/schema.sql')));
$migrated = run_migrations($fresh, true);
if ($migrated['errors']) {
fwrite(STDERR, 'Testdatenbank konnte nicht aufgebaut werden: ' . implode('; ', $migrated['errors']) . "\n");
exit(1);
}
$fresh = null;
}
$pdo = new PDO('sqlite:' . $tempDb);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
@@ -42,6 +59,17 @@ $pdo->prepare(
VALUES (?,'customer',?,0,?)"
)->execute([$ticketId, 'Bitte mobil bearbeiten.', $now]);
// Signaturen (Mitarbeiter und Abteilung 1) und Textbausteine für zwei Abteilungen
$pdo->exec("UPDATE departments SET signature = '<p>Abteilungs-Team<br><img src=\"https://example.org/logo.png\"></p>' WHERE id = 1");
$pdo->exec("UPDATE staff SET signature = '<p>Viele Grüße<br>Admin persönlich</p>' WHERE email = 'admin@example.com'");
$pdo->exec("INSERT INTO departments (name, email, is_default) VALUES ('Zweite Abteilung', 'zweite@example.org', 0)");
$secondDeptId = (int) $pdo->lastInsertId();
$pdo->exec('DELETE FROM canned_responses');
$cannedIns = $pdo->prepare('INSERT INTO canned_responses (title, body, department_id, created_at) VALUES (?,?,?,?)');
$cannedIns->execute(['Nur Abteilung eins', 'A', 1, $now]);
$cannedIns->execute(['Nur Abteilung zwei', 'B', $secondDeptId, $now]);
$cannedIns->execute(['Für alle', 'C', null, $now]);
$port = random_int(18080, 18999);
$command = [PHP_BINARY, '-S', "127.0.0.1:$port", '-t', $root];
$previousDbPath = getenv('DESKHUB_SQLITE_PATH');
@@ -106,6 +134,20 @@ try {
assert_same(200, $status, 'Ticketliste muss abrufbar sein.');
assert_same($number, $tickets['items'][0]['number'] ?? null, 'Ticketsuche liefert nicht das Testticket.');
// Antwort-Signaturen im Ticket und Textbausteine nach Abteilung (für Windows- und Android-App)
[$status, $ticketData] = request($port, 'GET', '/api/staff/v1/ticket.php?number=' . rawurlencode($number), null, $headers);
$rs = $ticketData['ticket']['replySignatures'] ?? [];
assert_same(200, $status, 'Ticket muss abrufbar sein.');
assert_same('own', $rs['default'] ?? null, 'Voreinstellung: eigene Signatur, wenn vorhanden.');
assert_true(($rs['own']['available'] ?? false) === true && str_contains((string) ($rs['own']['text'] ?? ''), 'Admin persönlich'), 'Eigene Signatur kommt als Klartext.');
assert_true(($rs['department']['available'] ?? false) === true && str_contains((string) ($rs['department']['text'] ?? ''), 'Abteilungs-Team') && ($rs['department']['hasImage'] ?? false) === true, 'Abteilungs-Signatur mit Hinweis auf Bild.');
assert_true(($rs['own']['hasImage'] ?? true) === false && !str_contains((string) ($rs['own']['text'] ?? ''), '<'), 'Klartext enthält kein HTML.');
[$status, $cannedAll] = request($port, 'GET', '/api/staff/v1/canned_responses.php', null, $headers);
assert_same(3, count($cannedAll['items'] ?? []), 'Ohne Filter: alle Textbausteine.');
[$status, $cannedDept] = request($port, 'GET', '/api/staff/v1/canned_responses.php?departmentId=1', null, $headers);
$titles = array_column($cannedDept['items'] ?? [], 'title');
assert_true(in_array('Nur Abteilung eins', $titles, true) && in_array('Für alle', $titles, true) && !in_array('Nur Abteilung zwei', $titles, true), 'Mit departmentId: Textbausteine dieser Abteilung und die für alle, keine fremden.');
$pdo->exec('UPDATE tickets SET locked_by = NULL, locked_at = NULL'); // das Abrufen oben hat die Ticket-Sperre des Admins gesetzt, die spätere Tests nicht stören soll
[, $departmentLogin] = request($port, 'POST', '/api/staff/v1/login.php', [
'email' => 'dept-agent@example.com',
'password' => $agentPassword,