reset(); $this->bearerToken = null; unset($GLOBALS['__TEST_JSON_BODY']); $_GET = []; $_POST = []; } /** * @return array{status: int, body: array, raw: string} */ protected function api( string $method, string $route, ?array $jsonBody = null, ?string $token = null, array $query = [], ): array { $_GET = $query; $_POST = []; $_SERVER['REQUEST_METHOD'] = strtoupper($method); $_SERVER['REQUEST_URI'] = '/api/' . ltrim($route, '/'); $_SERVER['SCRIPT_NAME'] = '/api/index.php'; $_SERVER['HTTP_AUTHORIZATION'] = ($token ?? $this->bearerToken) ? 'Bearer ' . ($token ?? $this->bearerToken) : ''; if ($jsonBody !== null) { $GLOBALS['__TEST_JSON_BODY'] = json_encode($jsonBody, JSON_THROW_ON_ERROR); } else { unset($GLOBALS['__TEST_JSON_BODY']); } ob_start(); $status = 200; $body = []; try { require_once dirname(__DIR__, 2) . '/api/dispatch.php'; qdb_dispatch_api_request(); } catch (QdbHttpResponse $e) { $status = $e->status; $body = $e->body; } $raw = (string) ob_get_clean(); if ($raw !== '' && $body === []) { $decoded = json_decode($raw, true); if (is_array($decoded)) { $body = $decoded; } } if ($body === [] && $raw !== '') { $body = ['_raw' => $raw]; } if (!isset($body['ok']) && isset($body['error'])) { // legacy auth envelope — body kept as-is } elseif ($status === 200 && !isset($body['ok']) && $raw === '') { $status = http_response_code() ?: 200; } return ['status' => $status, 'body' => $body, 'raw' => $raw]; } /** * @return array{status: int, body: array, raw: string} */ protected function loginAs(string $username, string $password = DatabaseFixture::PASSWORD): array { $res = $this->api('POST', 'auth/login', [ 'username' => $username, 'password' => $password, ]); if (($res['body']['ok'] ?? false) === true) { $this->bearerToken = $res['body']['data']['token'] ?? null; } return $res; } protected function assertOk(array $response): void { $this->assertTrue($response['body']['ok'] ?? false, $response['raw'] ?: json_encode($response['body'])); } protected function assertError(array $response, ?string $code = null): void { $this->assertFalse($response['body']['ok'] ?? true); if ($code !== null) { $this->assertSame($code, $response['body']['error']['code'] ?? null); } } protected function assertLegacyAuthError(array $response, int $status, string $message): void { $this->assertSame($status, $response['status']); $this->assertSame($message, $response['body']['error'] ?? null); } }