import { beforeEach, describe, expect, it, vi } from "vitest"; const capabilitiesMock = vi.hoisted(() => vi.fn()); const openFileMock = vi.hoisted(() => vi.fn()); const pickFilesMock = vi.hoisted(() => vi.fn()); const saveFileMock = vi.hoisted(() => vi.fn()); const messageInfoMock = vi.hoisted(() => vi.fn()); const messageSuccessMock = vi.hoisted(() => vi.fn()); vi.mock("../runtime", () => ({ clientRuntime: { capabilities: capabilitiesMock, }, openFile: openFileMock, pickFiles: pickFilesMock, saveFile: saveFileMock, })); vi.mock("element-plus", () => ({ ElMessage: { info: messageInfoMock, success: messageSuccessMock, }, })); const output = { suggestedName: "report.pdf", mimeType: "application/pdf", data: new Blob(["content"], { type: "application/pdf" }), }; describe("file task feedback", () => { beforeEach(() => { vi.clearAllMocks(); capabilitiesMock.mockReturnValue({ nativeFiles: false }); pickFilesMock.mockResolvedValue([]); saveFileMock.mockResolvedValue("saved"); openFileMock.mockResolvedValue(undefined); }); it("reports native file picker selections", async () => { const files = [ new File(["a"], "a.txt", { type: "text/plain" }), new File(["b"], "b.txt", { type: "text/plain" }), ]; pickFilesMock.mockResolvedValue(files); const { pickFilesWithFeedback } = await import("./fileTaskFeedback"); const selected = await pickFilesWithFeedback({ multiple: true, title: "附件" }); expect(selected).toBe(files); expect(pickFilesMock).toHaveBeenCalledWith({ multiple: true, title: "附件" }); expect(messageSuccessMock).toHaveBeenCalledWith("已选择 2 个文件"); }); it("does not show a selection toast when the picker is cancelled", async () => { const { pickFilesWithFeedback } = await import("./fileTaskFeedback"); await expect(pickFilesWithFeedback({ multiple: true })).resolves.toEqual([]); expect(messageSuccessMock).not.toHaveBeenCalled(); }); it("uses download feedback for web save flows", async () => { const { saveFileWithFeedback } = await import("./fileTaskFeedback"); await expect(saveFileWithFeedback(output)).resolves.toBe("saved"); expect(saveFileMock).toHaveBeenCalledWith(output); expect(messageSuccessMock).toHaveBeenCalledWith("文件下载已开始"); }); it("uses saved feedback for native save flows", async () => { capabilitiesMock.mockReturnValue({ nativeFiles: true }); const { saveFileWithFeedback } = await import("./fileTaskFeedback"); await expect(saveFileWithFeedback(output)).resolves.toBe("saved"); expect(messageSuccessMock).toHaveBeenCalledWith("文件已保存"); }); it("reports cancelled save flows without treating them as downloads", async () => { saveFileMock.mockResolvedValue("cancelled"); const { saveFileWithFeedback } = await import("./fileTaskFeedback"); await expect(saveFileWithFeedback(output)).resolves.toBe("cancelled"); expect(messageInfoMock).toHaveBeenCalledWith("已取消保存文件"); expect(messageSuccessMock).not.toHaveBeenCalled(); }); it("reports external open completion", async () => { const { openFileWithFeedback } = await import("./fileTaskFeedback"); await openFileWithFeedback(output); expect(openFileMock).toHaveBeenCalledWith(output); expect(messageSuccessMock).toHaveBeenCalledWith("文件已打开"); }); });