/** * @file apiJsonGuard.test.ts * @description `request()` refuses a 200 that is not JSON (an index.html from a * proxy or dev server) with a translated error instead of the raw * "Unexpected token '<'" a bare `res.json()` would throw. * @author Nguyễn Ngọc Trí Vĩ */ import { describe, it, expect, vi, afterEach } from "vitest"; import i18n from "i18next"; import { api } from "../api"; afterEach(() => vi.unstubAllGlobals()); function stub(type: string | null, body: string) { vi.stubGlobal( "fetch", vi .fn() .mockResolvedValue( new Response(body, { status: 200, headers: type ? { "content-type": type } : {} }) ) ); } describe("request() JSON guard", () => { it("throws EBADRESPONSE with the translated message on an HTML 200", async () => { stub("text/html; charset=utf-8", ""); await expect(api.aiTools.list()).rejects.toMatchObject({ code: "EBADRESPONSE", message: i18n.t("errors:badResponse"), }); }); it("throws the same error when a JSON-less body fails to parse", async () => { stub(null, ""); await expect(api.aiTools.list()).rejects.toMatchObject({ code: "EBADRESPONSE" }); }); it("still parses a JSON 200", async () => { stub("application/json", JSON.stringify({ default: "claude", tools: [] })); await expect(api.aiTools.list()).resolves.toEqual({ default: "claude", tools: [] }); }); });