import { describe, expect, it, vi } from "vitest"; import { defineToolcraft } from "../schema/define-toolcraft"; import { createToolcraftState } from "../state/create-template-state"; import { createToolcraftRuntimeSceneVisibility } from "../scene"; import { toolcraftImageExportFormatTarget, toolcraftImageExportResolutionTarget, } from "./artifact-export-settings"; import { exportToolcraftImageArtifact } from "./image-artifact-export"; function createState(format: "jpg" | "png" = "png") { return createToolcraftState( defineToolcraft({ canvas: { enabled: true }, panels: {} }), { values: { [toolcraftImageExportFormatTarget]: format, [toolcraftImageExportResolutionTarget]: "2k", }, }, ); } function createCanvas(blob: Blob | null) { const context = { clearRect: vi.fn(), fillRect: vi.fn(), fillStyle: "", restore: vi.fn(), save: vi.fn(), scale: vi.fn(), setTransform: vi.fn(), translate: vi.fn(), }; const canvas = { getContext: vi.fn(() => context), height: 0, toBlob: vi.fn((callback: BlobCallback) => callback(blob)), width: 0, } as unknown as HTMLCanvasElement; return { canvas, context }; } const visibility = createToolcraftRuntimeSceneVisibility({ renderDefaultImages: true, suppressedModelTargets: [], }); describe("exportToolcraftImageArtifact", () => { it("renders and downloads the selected real image format and dimensions", async () => { const { canvas } = createCanvas( new Blob(["jpeg"], { type: "image/jpeg" }), ); const downloadArtifact = vi.fn(() => ({ fileName: "scene.jpg" })); const result = await exportToolcraftImageArtifact({ boundsProvider: undefined, canvasFactory: () => canvas, downloadArtifact, exportRenderer: { baseFileName: "scene", renderFrame: vi.fn(), }, productSceneRequired: true, renderRuntimeScene: async () => undefined, rendererPipeline: null, reportProgress: vi.fn(), state: createState("jpg"), visibility, }); expect(result).toEqual({ byteLength: 4, extension: ".jpg", height: 1152, mediaType: "image/jpeg", width: 2048, }); expect(canvas.width).toBe(1); expect(canvas.height).toBe(1); expect(canvas.toBlob).toHaveBeenCalledWith( expect.any(Function), "image/jpeg", 0.95, ); expect(downloadArtifact).toHaveBeenCalledWith( expect.objectContaining({ extension: ".jpg", rawBaseFileName: "scene" }), ); }); it("fails visibly when canvas encoding returns no blob", async () => { const { canvas } = createCanvas(null); await expect( exportToolcraftImageArtifact({ boundsProvider: undefined, canvasFactory: () => canvas, downloadArtifact: vi.fn(), exportRenderer: undefined, productSceneRequired: false, renderRuntimeScene: async () => undefined, rendererPipeline: null, reportProgress: vi.fn(), state: createState(), visibility, }), ).rejects.toMatchObject({ feedback: { code: "image-encode-failed" }, }); }); });