From 16f2eae2d3a2fcda82d3cf02aa1e28813e3482ac Mon Sep 17 00:00:00 2001 From: Yaojia Wang Date: Wed, 8 Jul 2026 13:27:45 +0200 Subject: [PATCH] =?UTF-8?q?test(web):=20parseJsonBody=20=E8=A1=A5=E9=9D=9E?= =?UTF-8?q?=E5=AF=B9=E8=B1=A1/=E9=9D=9E=20JSON=20=E5=AE=88=E5=8D=AB?= =?UTF-8?q?=E5=88=86=E6=94=AF=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit server.parseJsonBody 已具边界校验,补两条守卫分支测试(200 返回原始值/非 JSON 体均抛结构化错误)。 --- apps/web/lib/api/server.test.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/apps/web/lib/api/server.test.ts b/apps/web/lib/api/server.test.ts index 2fc3a0a..93706b7 100644 --- a/apps/web/lib/api/server.test.ts +++ b/apps/web/lib/api/server.test.ts @@ -66,3 +66,21 @@ describe("fetchDraft", () => { expect(await fetchDraft("p1", 9)).toBeNull(); }); }); + +// parseJsonBody 边界校验:防御被代理/网关污染的非对象或非 JSON 响应。 +describe("parseJsonBody structural validation", () => { + it("throws on a 200 body that is not a JSON object (primitive)", async () => { + mockFetch(200, "surprise-string"); + + await expect(fetchDraft("p1", 1)).rejects.toThrow("响应体形状异常"); + }); + + it("throws when the 200 body is not valid JSON", async () => { + vi.stubGlobal( + "fetch", + vi.fn(async () => new Response("not json", { status: 200 })), + ); + + await expect(fetchDraft("p1", 1)).rejects.toThrow("响应非 JSON"); + }); +});