50 lines
2.3 KiB
TypeScript
50 lines
2.3 KiB
TypeScript
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("");
|
|
}
|
|
});
|