import { describe, expect, it, vi } from "vitest"; import { downloadToolcraftArtifact } from "./artifact-download"; describe("downloadToolcraftArtifact", () => { it("sanitizes the filename and revokes the object URL after the click", () => { const events: string[] = []; const anchor = { click: vi.fn(() => events.push("click")), download: "", href: "", remove: vi.fn(() => events.push("remove")), }; const schedule = vi.fn((callback: () => void) => { events.push("schedule-revoke"); callback(); return 1; }); const result = downloadToolcraftArtifact({ appendAnchor: () => events.push("append"), blob: new Blob(["png"], { type: "image/png" }), createAnchor: () => anchor, createObjectUrl: () => "blob:artifact", extension: ".png", rawBaseFileName: " Unsafe / name ", revokeObjectUrl: () => events.push("revoke"), schedule, }); expect(result.fileName).toBe("Unsafe-name.png"); expect(anchor.download).toBe("Unsafe-name.png"); expect(events).toEqual([ "append", "click", "remove", "schedule-revoke", "revoke", ]); }); it("types click failures and still removes and revokes", () => { const remove = vi.fn(); const revoke = vi.fn(); expect(() => downloadToolcraftArtifact({ appendAnchor: vi.fn(), blob: new Blob(["png"]), createAnchor: () => ({ click: () => { throw new Error("blocked"); }, download: "", href: "", remove, }), createObjectUrl: () => "blob:artifact", extension: ".png", rawBaseFileName: "", revokeObjectUrl: revoke, schedule: (callback) => { callback(); return 1; }, }), ).toThrow("could not start the artifact download"); expect(remove).toHaveBeenCalledOnce(); expect(revoke).toHaveBeenCalledWith("blob:artifact"); }); });