import { afterEach, expect, it, vi } from "vitest"; import { fetchSpeechVoiceCatalog } from "./speech-voice-catalog"; afterEach(() => vi.unstubAllGlobals()); it("preserves a service failure message for a useful retry explanation", async () => { vi.stubGlobal("fetch", vi.fn(async () => new Response(JSON.stringify({ error: "音色列表暂时不可用,请稍后重试" }), { status: 503 }))); await expect(fetchSpeechVoiceCatalog("/api/tts/edge/voices")).rejects.toThrow("音色列表暂时不可用,请稍后重试"); }); it("explains an incompatible cached catalog or an HTML response without exposing parser details", async () => { const fetchMock = vi.fn().mockResolvedValueOnce(new Response(JSON.stringify({ voices: [], defaultVoice: "old" }))) .mockResolvedValueOnce(new Response("")); vi.stubGlobal("fetch", fetchMock); for (let attempt = 0; attempt < 2; attempt += 1) { await expect(fetchSpeechVoiceCatalog("/api/tts/edge/voices")).rejects.toThrow("音色列表格式不匹配,请刷新页面后重试"); } });