feat: expand intelligent investigation workspace
Generic Container CI/CD / test-build-publish (push) Successful in 1m52s
Frontend CI/CD / build-test-publish-and-deploy (push) Successful in 1m52s

This commit is contained in:
2026-10-30 17:30:19 +08:00
parent ddd03dbff6
commit c0e4231b83
223 changed files with 13155 additions and 5304 deletions
+49
View File
@@ -0,0 +1,49 @@
import { act, renderHook } from "@testing-library/react";
import { beforeEach, expect, it, vi } from "vitest";
import { getSelectedSpeechVoice, getSpeechVoiceDescription, getSpeechVoiceName, setSelectedSpeechVoice, SPEECH_VOICE_STORAGE_KEY, useSelectedSpeechVoice } from "./speech-voices";
beforeEach(() => setSelectedSpeechVoice(""));
it("shares a saved voice across selectors and restores it from browser storage", () => {
const first = renderHook(useSelectedSpeechVoice);
const second = renderHook(useSelectedSpeechVoice);
act(() => setSelectedSpeechVoice("zh-CN-YunyangNeural"));
expect(first.result.current).toBe("zh-CN-YunyangNeural");
expect(second.result.current).toBe("zh-CN-YunyangNeural");
expect(localStorage.getItem(SPEECH_VOICE_STORAGE_KEY)).toBe("zh-CN-YunyangNeural");
act(() => {
localStorage.setItem(SPEECH_VOICE_STORAGE_KEY, "zh-CN-XiaoyiNeural");
window.dispatchEvent(new StorageEvent("storage", { key: SPEECH_VOICE_STORAGE_KEY }));
});
expect(first.result.current).toBe("zh-CN-XiaoyiNeural");
first.unmount(); second.unmount();
});
it("ignores malformed stored values and resets to the server default", () => {
localStorage.setItem(SPEECH_VOICE_STORAGE_KEY, "unsafe<xml>");
expect(getSelectedSpeechVoice()).toBe("");
localStorage.setItem(SPEECH_VOICE_STORAGE_KEY, "en-US-AriaNeural");
expect(getSelectedSpeechVoice()).toBe("");
setSelectedSpeechVoice("zh-CN-YunyangNeural");
setSelectedSpeechVoice("");
expect(getSelectedSpeechVoice()).toBe("");
expect(localStorage.getItem(SPEECH_VOICE_STORAGE_KEY)).toBeNull();
});
it("provides Chinese labels and gender descriptions for Mandarin voices", () => {
const voice = { id: "zh-CN-YunyangNeural", name: "Yunyang", locale: "zh-CN" as const, gender: "Male" as const };
expect(getSpeechVoiceName(voice)).toBe("云扬");
expect(getSpeechVoiceDescription(voice)).toContain("男声");
expect(getSpeechVoiceDescription(voice)).toContain("普通话");
});
it("keeps the choice for this page if browser storage cannot be written", () => {
const write = vi.spyOn(Storage.prototype, "setItem").mockImplementation(() => { throw new Error("quota exceeded"); });
try {
setSelectedSpeechVoice("zh-CN-YunyangNeural");
expect(getSelectedSpeechVoice()).toBe("zh-CN-YunyangNeural");
} finally {
write.mockRestore();
setSelectedSpeechVoice("");
}
});