Upload via GUI (275 Dateien)

This commit is contained in:
2026-10-23 11:14:28 +00:00
parent 7fcdfa9d2c
commit a96fed78b4
6 changed files with 260 additions and 3 deletions
@@ -163,6 +163,64 @@ try {
$check($s === 302 && $lockedBy('T-LOCK-WEB') === null, 'Web: „Sperre aufheben und übernehmen“ funktioniert (HTTP ' . $s . ')');
[$s, $page] = $call('GET', '/staff/ticket_view.php?n=T-LOCK-WEB', null, null, [], $jarChef, ['Sec-Fetch-Mode: navigate']);
$check($s === 200 && (int) $lockedBy('T-LOCK-WEB') === $ids['Chef'], 'Web: danach besitzt der Admin die Sperre');
// ── Mehrere Tabs: der CSRF-Token bleibt für die Sitzung gleich (kein "Token ungültig" nach dem Absenden in einem anderen Tab) ──
$tokenOf = function (string $jar, string $path) use ($call): string {
[, $p] = $call('GET', $path, null, null, [], $jar, ['Sec-Fetch-Mode: navigate']);
preg_match('/name="csrf_token" value="([a-f0-9]+)"/', is_string($p) ? $p : '', $mm);
return $mm[1] ?? '';
};
$mkTicket('T-TAB-1');
$mkTicket('T-TAB-2');
$tab1 = $tokenOf($jarChef, '/staff/ticket_view.php?n=T-TAB-1');
$tab2 = $tokenOf($jarChef, '/staff/ticket_view.php?n=T-TAB-2');
$check($tab1 !== '' && $tab1 === $tab2, 'Zwei Tabs bekommen denselben CSRF-Token');
[$s] = $call('POST', '/staff/ticket_view.php?n=T-TAB-1', null, null, ['csrf_token' => $tab1, 'action' => 'release_lock'], $jarChef);
$check($s === 302, 'Absenden im ersten Tab klappt (HTTP ' . $s . ')');
[$s] = $call('POST', '/staff/ticket_view.php?n=T-TAB-2', null, null, ['csrf_token' => $tab2, 'action' => 'release_lock'], $jarChef);
$check($s === 302, 'Danach klappt auch das Absenden im zweiten Tab mit dem älteren Token (HTTP ' . $s . ')');
[$s, $body] = $call('POST', '/staff/ticket_view.php?n=T-TAB-2', null, null, ['csrf_token' => 'falsch', 'action' => 'release_lock'], $jarChef);
$check($s === 403, 'Ein falscher Token wird weiterhin abgelehnt (HTTP ' . $s . ')');
[$s] = $call('POST', '/staff/ticket_view.php?n=T-TAB-2', null, null, ['action' => 'release_lock'], $jarChef);
$check($s === 403, 'Ohne Token wird abgelehnt (HTTP ' . $s . ')');
$jarNew = $webLogin('chef@test.de');
$check($tokenOf($jarNew, '/staff/availability.php') !== $tab1, 'Nach einer neuen Anmeldung gibt es einen neuen Token');
@unlink($jarNew);
// ── Beim Öffnen zuweisen ──
$assignee = fn(string $number) => $pdo()->query("SELECT assigned_staff_id FROM tickets WHERE ticket_number = '$number'")->fetchColumn();
$mkTicket('T-OPEN-1');
[$s, $r] = $call('GET', '/api/staff/v1/ticket.php?number=T-OPEN-1', null, $agent);
$check($s === 200 && (int) $assignee('T-OPEN-1') === $ids['Agent'] && ($r['ticket']['assignedStaff']['name'] ?? '') === 'Agent', 'Öffnen eines unzugewiesenen Tickets weist es dem Öffnenden zu (App/API) (HTTP ' . $s . ')');
$logged = $pdo()->query("SELECT COUNT(*) FROM activity_log a JOIN tickets t ON t.id = a.ticket_id WHERE t.ticket_number = 'T-OPEN-1' AND a.action = 'Beim Öffnen automatisch zugewiesen'")->fetchColumn();
$check((int) $logged === 1, 'Das steht im Ticket-Verlauf');
$call('POST', '/api/staff/v1/ticket_unlock.php', ['number' => 'T-OPEN-1'], $agent);
[$s] = $call('GET', '/api/staff/v1/ticket.php?number=T-OPEN-1', null, $other);
$check($s === 200 && (int) $assignee('T-OPEN-1') === $ids['Agent'], 'Ein bereits zugewiesenes Ticket bleibt beim Bearbeiter, auch wenn ein anderer es öffnet');
$call('POST', '/api/staff/v1/ticket_unlock.php', ['number' => 'T-OPEN-1'], $other);
$mkTicket('T-OPEN-2');
$pdo()->exec("UPDATE tickets SET status = 'closed' WHERE ticket_number = 'T-OPEN-2'");
$call('GET', '/api/staff/v1/ticket.php?number=T-OPEN-2', null, $agent);
$check($assignee('T-OPEN-2') === null, 'Geschlossene Tickets werden beim Öffnen nicht zugewiesen');
$mkTicket('T-OPEN-3');
$call('GET', '/api/staff/v1/ticket.php?number=T-OPEN-3', null, $agent); // Agent hält die Sperre und ist zugewiesen
$pdo()->exec("UPDATE tickets SET assigned_staff_id = NULL WHERE ticket_number = 'T-OPEN-3'");
$call('GET', '/api/staff/v1/ticket.php?number=T-OPEN-3', null, $chef); // Admin schaut nur, die Sperre des Agenten besteht
$check($assignee('T-OPEN-3') === null, 'Ein Admin, der ein fremd gesperrtes Ticket nur ansieht, bekommt es nicht zugewiesen');
$pdo()->exec("INSERT OR REPLACE INTO settings (setting_key, setting_value) VALUES ('auto_assign_on_open', '0')");
$mkTicket('T-OPEN-4');
$call('GET', '/api/staff/v1/ticket.php?number=T-OPEN-4', null, $other);
$check($assignee('T-OPEN-4') === null, 'Ausgeschaltet in den Einstellungen: keine Zuweisung beim Öffnen');
$pdo()->exec("DELETE FROM settings WHERE setting_key = 'auto_assign_on_open'");
// Weboberfläche
$mkTicket('T-OPEN-5');
[$s] = $call('GET', '/staff/ticket_view.php?n=T-OPEN-5', null, null, [], $jarChef, ['Sec-Fetch-Mode: navigate']);
$check($s === 200 && (int) $assignee('T-OPEN-5') === $ids['Chef'], 'Auch im Browser: Öffnen weist das Ticket zu (HTTP ' . $s . ')');
// Ticketliste: Spalte mit dem Eingangsdatum
[$s, $list] = $call('GET', '/staff/tickets.php', null, null, [], $jarChef, ['Sec-Fetch-Mode: navigate']);
$list = is_string($list) ? $list : '';
$check($s === 200 && str_contains($list, '<th>Eingang</th>') && str_contains($list, date('d.m.Y ')), 'Ticketliste zeigt die Spalte „Eingang“ mit Datum und Uhrzeit (HTTP ' . $s . ', ' . strlen($list) . ' Zeichen, Tabelle: ' . (str_contains($list, '<table') ? 'ja' : 'nein') . ', leer: ' . (str_contains($list, 'Keine Tickets') ? 'ja' : 'nein') . ')');
@unlink($jarChef);
@unlink($jarOther);
} finally {