diff --git a/apps/web/src/test/pages/generate/useStep5Voice.test.tsx b/apps/web/src/test/pages/generate/useStep5Voice.test.tsx new file mode 100644 index 000000000..8fd9f9dc1 --- /dev/null +++ b/apps/web/src/test/pages/generate/useStep5Voice.test.tsx @@ -0,0 +1,97 @@ +/** + * useStep5Voice Hook smoke test + * 确保 vitest related 模式能匹配到 useStep5Voice.tsx 的改动 + */ +import { describe, it, expect, vi } from "vitest" +import { renderHook } from "@testing-library/react" + +// mock 所有子 Hook +vi.mock("@/pages/generate/hooks/step5-voice/useVoiceAudio", () => ({ + useVoiceAudio: () => ({ + playingVoice: null, + toggleVoicePlay: vi.fn(), + }), +})) + +vi.mock("@/pages/generate/hooks/step5-voice/useVoiceRecommend", () => ({ + useVoiceRecommend: () => ({ + presetVoices: [], + presetVoicesLoading: false, + voiceRecommendLoading: false, + voiceRecommendations: [], + hasVoiceRecommend: false, + handleVoiceRecommend: vi.fn(), + }), +})) + +vi.mock("@/pages/generate/hooks/step5-voice/useTtsSynthesis", () => ({ + useTtsSynthesis: () => ({ + customVoiceText: "", + setCustomVoiceText: vi.fn(), + customAudioUrl: null, + ttsError: null, + ttsJobId: null, + completedTtsJobId: null, + synthesizeMutation: { isPending: false, mutate: vi.fn() }, + handleSynthesizeVoice: vi.fn(), + resetTtsState: vi.fn(), + }), +})) + +vi.mock("@/pages/generate/hooks/step5-voice/useSaveToLibrary", () => ({ + useSaveToLibrary: () => ({ + saveModalOpen: false, + setSaveModalOpen: vi.fn(), + saveName: "", + setSaveName: vi.fn(), + saveTagIds: [], + setSaveTagIds: vi.fn(), + saveNewTag: "", + setSaveNewTag: vi.fn(), + allTags: [], + saveToLibraryMutation: { isPending: false, mutate: vi.fn() }, + handleOpenSaveModal: vi.fn(), + handleConfirmSave: vi.fn(), + handleAddTagInModal: vi.fn(), + }), +})) + +vi.mock("@/pages/generate/hooks/step5-voice/useVoiceModeSelection", () => ({ + useVoiceModeSelection: () => ({ + handleSelectRecommendedVoice: vi.fn(), + handleSelectPresetVoice: vi.fn(), + handleSelectCloneVoice: vi.fn(), + handleSelectClonedVoice: vi.fn(), + handleOpenCloneModal: vi.fn(), + handleCloneSuccess: vi.fn(), + }), +})) + +vi.mock("@/api/voice-clone", () => ({ + VoiceCloneStatus: { READY: "ready", PROCESSING: "processing", FAILED: "failed" }, +})) + +describe("useStep5Voice smoke test", () => { + it("should import and render hook without crashing", async () => { + // 动态 import 确保 mock 生效 + const { useStep5Voice } = await import("@/pages/generate/hooks/useStep5Voice") + const { result } = renderHook(() => + useStep5Voice({ + selectedVoice: "", + onSelectedVoiceChange: vi.fn(), + voiceMode: "preset", + onVoiceModeChange: vi.fn(), + selectedClonedVoice: "", + onSelectedClonedVoiceChange: vi.fn(), + clonedVoices: [], + addClone: vi.fn(), + hasProcessing: false, + cloneModalOpen: false, + onCloneModalOpenChange: vi.fn(), + titleText: "测试标题", + }), + ) + expect(result.current).toBeDefined() + expect(typeof result.current.handlePlayCloneSample).toBe("function") + }) +})