added unit tests

This commit is contained in:
2026-06-04 21:40:59 +02:00
parent d80a8de559
commit 48a619ee4b
64 changed files with 3807 additions and 33 deletions

View File

@ -56,6 +56,9 @@ function qdb_handler_fail(
?string $tmpDb = null,
$lockFp = null
): never {
if (defined('QDB_TESTING') && qdb_test_is_control_flow_exception($e)) {
throw $e;
}
if ($pdo !== null && $pdo->inTransaction()) {
try {
$pdo->rollBack();
@ -74,6 +77,9 @@ function qdb_handler_fail(
*/
function qdb_emit_api_error(Throwable $e, string $contextLabel): never
{
if (defined('QDB_TESTING') && qdb_test_is_control_flow_exception($e)) {
throw $e;
}
if (function_exists('qdb_api_log_note_exception')) {
qdb_api_log_note_exception($e);
}

View File

@ -2,7 +2,36 @@
require_once __DIR__ . '/encrypted_payload.php';
/** @internal PHPUnit: inject request body (cleared by qdb_test_reset_http_state). */
function qdb_test_set_request_body(string $body): void
{
if (!defined('QDB_TESTING')) {
throw new RuntimeException('qdb_test_set_request_body is only available in tests');
}
$GLOBALS['qdb_test_request_body'] = $body;
}
/** @internal PHPUnit: reset cached body between API calls. */
function qdb_test_reset_http_state(): void
{
if (!defined('QDB_TESTING')) {
return;
}
unset($GLOBALS['qdb_test_request_body']);
}
/** @internal PHPUnit: rethrow response control-flow exceptions. */
function qdb_test_is_control_flow_exception(\Throwable $e): bool
{
return $e instanceof \Tests\Support\JsonSuccessResponse
|| $e instanceof \Tests\Support\JsonErrorResponse
|| $e instanceof \Tests\Support\RawHttpResponse;
}
function json_success(mixed $data, int $status = 200): never {
if (defined('QDB_TESTING')) {
throw new \Tests\Support\JsonSuccessResponse($data, $status);
}
http_response_code($status);
header('Content-Type: application/json; charset=UTF-8');
echo json_encode(["ok" => true, "data" => $data]);
@ -12,7 +41,28 @@ function json_success(mixed $data, int $status = 200): never {
/**
* @param mixed $details Optional structured payload (e.g. validation error list).
*/
/**
* Send a non-JSON download response (CSV, ZIP, etc.).
*
* @param array<string, string> $headers
*/
function qdb_http_download(string $body, array $headers, int $status = 200): never
{
if (defined('QDB_TESTING')) {
throw new \Tests\Support\RawHttpResponse($body, $headers, $status);
}
http_response_code($status);
foreach ($headers as $name => $value) {
header($name . ': ' . $value);
}
echo $body;
exit;
}
function json_error(string $code, string $message, int $status = 400, mixed $details = null): never {
if (defined('QDB_TESTING')) {
throw new \Tests\Support\JsonErrorResponse($code, $message, $status, $details);
}
if (function_exists('qdb_api_log_note_api_error')) {
qdb_api_log_note_api_error($code, $message, $status);
}
@ -28,6 +78,9 @@ function json_error(string $code, string $message, int $status = 400, mixed $det
/** Raw request body (cached; php://input is single-read). */
function qdb_raw_request_body(): string {
if (defined('QDB_TESTING') && array_key_exists('qdb_test_request_body', $GLOBALS)) {
return (string)$GLOBALS['qdb_test_request_body'];
}
static $raw = null;
if ($raw === null) {
$read = file_get_contents('php://input');

View File

@ -365,12 +365,12 @@ function qdb_export_rows_to_csv_string(array $rows, array $fallbackHeader = []):
}
fwrite($fp, "\xEF\xBB\xBF");
if (!empty($rows)) {
fputcsv($fp, array_keys($rows[0]));
fputcsv($fp, array_keys($rows[0]), ',', '"', '\\');
foreach ($rows as $row) {
fputcsv($fp, array_values($row));
fputcsv($fp, array_values($row), ',', '"', '\\');
}
} elseif ($fallbackHeader !== []) {
fputcsv($fp, $fallbackHeader);
fputcsv($fp, $fallbackHeader, ',', '"', '\\');
}
rewind($fp);
$csv = stream_get_contents($fp);