mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-28 08:53:34 +00:00
fix(qa): reject non-object mock Anthropic JSON
This commit is contained in:
@@ -4240,7 +4240,7 @@ describe("qa mock openai server", () => {
|
||||
expect(body).not.toContain("HEARTBEAT_OK");
|
||||
});
|
||||
|
||||
it("rejects malformed Anthropic /v1/messages JSON with an invalid_request_error", async () => {
|
||||
it("rejects malformed or non-object Anthropic /v1/messages JSON", async () => {
|
||||
const server = await startQaMockOpenAiServer({
|
||||
host: "127.0.0.1",
|
||||
port: 0,
|
||||
@@ -4249,20 +4249,25 @@ describe("qa mock openai server", () => {
|
||||
await server.stop();
|
||||
});
|
||||
|
||||
const response = await fetch(`${server.baseUrl}/v1/messages`, {
|
||||
method: "POST",
|
||||
headers: { "content-type": "application/json" },
|
||||
body: '{"model":"claude-opus-4-8","messages":[',
|
||||
});
|
||||
for (const rawBody of ['{"model":"claude-opus-4-8","messages":[', "null", "[]", '"text"']) {
|
||||
const response = await fetch(`${server.baseUrl}/v1/messages`, {
|
||||
method: "POST",
|
||||
headers: { "content-type": "application/json" },
|
||||
body: rawBody,
|
||||
});
|
||||
|
||||
expect(response.status).toBe(400);
|
||||
const body = (await response.json()) as {
|
||||
type: string;
|
||||
error: { type: string; message: string };
|
||||
};
|
||||
expect(body.type).toBe("error");
|
||||
expect(body.error.type).toBe("invalid_request_error");
|
||||
expect(body.error.message).toContain("Malformed JSON body");
|
||||
expect(response.status).toBe(400);
|
||||
const body = (await response.json()) as {
|
||||
type: string;
|
||||
error: { type: string; message: string };
|
||||
};
|
||||
expect(body.type).toBe("error");
|
||||
expect(body.error.type).toBe("invalid_request_error");
|
||||
expect(body.error.message).toContain("Malformed JSON body");
|
||||
}
|
||||
|
||||
const health = await fetch(`${server.baseUrl}/healthz`);
|
||||
expect(health.status).toBe(200);
|
||||
});
|
||||
|
||||
it("rejects malformed OpenAI-compatible JSON without crashing the mock server", async () => {
|
||||
|
||||
@@ -228,7 +228,7 @@ function readBody(req: IncomingMessage): Promise<string> {
|
||||
});
|
||||
}
|
||||
|
||||
function parseOpenAiJsonBody(raw: string): Record<string, unknown> | null {
|
||||
function parseJsonObjectBody(raw: string): Record<string, unknown> | null {
|
||||
try {
|
||||
const parsed = raw ? (JSON.parse(raw) as unknown) : {};
|
||||
return parsed && typeof parsed === "object" && !Array.isArray(parsed)
|
||||
@@ -3438,7 +3438,7 @@ export async function startQaMockOpenAiServer(params?: { host?: string; port?: n
|
||||
}
|
||||
if (req.method === "POST" && url.pathname === "/v1/images/generations") {
|
||||
const raw = await readBody(req);
|
||||
const body = parseOpenAiJsonBody(raw);
|
||||
const body = parseJsonObjectBody(raw);
|
||||
if (!body) {
|
||||
writeOpenAiMalformedJsonError(res, "OpenAI Images");
|
||||
return;
|
||||
@@ -3466,7 +3466,7 @@ export async function startQaMockOpenAiServer(params?: { host?: string; port?: n
|
||||
}
|
||||
if (req.method === "POST" && url.pathname === "/v1/embeddings") {
|
||||
const raw = await readBody(req);
|
||||
const body = parseOpenAiJsonBody(raw);
|
||||
const body = parseJsonObjectBody(raw);
|
||||
if (!body) {
|
||||
writeOpenAiMalformedJsonError(res, "OpenAI Embeddings");
|
||||
return;
|
||||
@@ -3492,7 +3492,7 @@ export async function startQaMockOpenAiServer(params?: { host?: string; port?: n
|
||||
}
|
||||
if (req.method === "POST" && url.pathname === "/v1/responses") {
|
||||
const raw = await readBody(req);
|
||||
const body = parseOpenAiJsonBody(raw);
|
||||
const body = parseJsonObjectBody(raw);
|
||||
if (!body) {
|
||||
writeOpenAiMalformedJsonError(res, "OpenAI Responses");
|
||||
return;
|
||||
@@ -3534,10 +3534,8 @@ export async function startQaMockOpenAiServer(params?: { host?: string; port?: n
|
||||
}
|
||||
if (req.method === "POST" && url.pathname === "/v1/messages") {
|
||||
const raw = await readBody(req);
|
||||
let body: AnthropicMessagesRequest;
|
||||
try {
|
||||
body = raw ? (JSON.parse(raw) as AnthropicMessagesRequest) : {};
|
||||
} catch {
|
||||
const body = parseJsonObjectBody(raw) as AnthropicMessagesRequest | null;
|
||||
if (!body) {
|
||||
writeJson(res, 400, {
|
||||
type: "error",
|
||||
error: {
|
||||
|
||||
Reference in New Issue
Block a user