import assert from "node:assert/strict"; import { randomUUID } from "node:crypto"; import { after, before, test } from "node:test"; import { eq } from "drizzle-orm"; import { db } from "@/lib/db"; import { canvasProject, user } from "@/lib/db/schema"; import { resolveCanvasCapabilityContext } from "@/lib/canvas/capabilities/context"; import { createCanvasCapabilityClientCommand } from "@/lib/canvas/capabilities/client-command"; import { executeCanvasCapabilityRuntime } from "@/lib/canvas/capabilities/runtime"; import { downloadCanvasImageAsPng } from "@/lib/client/canvas-image-download"; const database = new URL(process.env.POSTGRES_URL || "http://missing"); if (!["127.0.0.1", "localhost"].includes(database.hostname) || !/_test$/.test(database.pathname)) { throw new Error("Use a disposable local test database"); } const owner = randomUUID(); const stranger = randomUUID(); const projectId = randomUUID(); const unsavedNodeId = randomUUID(); const textNodeId = randomUUID(); const download = () => createCanvasCapabilityClientCommand({ capabilityId: "image.download", nodeIds: [unsavedNodeId], projectId, source: "toolbar" }); before(async () => { await db.insert(user).values([{ id: owner, email: `${owner}@download.invalid` }, { id: stranger, email: `${stranger}@download.invalid` }]); await db.insert(canvasProject).values({ id: projectId, userId: owner, title: "Local download regression", canvasData: { nodes: [{ id: textNodeId, type: "text", data: { text: "Not an image" } }], edges: [] } }); }); after(async () => { await db.delete(user).where(eq(user.id, owner)); await db.delete(user).where(eq(user.id, stranger)); await db.$client.end({ timeout: 2 }); }); test("download dispatch succeeds while a generated node is waiting for autosave", async () => { const result = await executeCanvasCapabilityRuntime({ command: download(), projectId, userId: owner, requestHeaders: new Headers(), requestUrl: "https://test.invalid" }); assert.equal(result.mode, "interactive"); assert.equal(result.clientCommand?.capabilityId, "image.download"); assert.deepEqual(result.clientCommand?.nodeIds, [unsavedNodeId]); assert.equal(result.task.status, "succeeded"); }); test("unsaved download permission never bypasses project ownership", async () => { await assert.rejects(resolveCanvasCapabilityContext({ command: download(), projectId, userId: stranger, allowUnsavedDownloadTargets: true }), { code: "CANVAS_CAPABILITY_PROJECT_NOT_FOUND" }); }); test("other image operations still require a persisted node", async () => { const command = createCanvasCapabilityClientCommand({ capabilityId: "image.enhance", nodeIds: [unsavedNodeId], projectId, source: "toolbar" }); await assert.rejects(resolveCanvasCapabilityContext({ command, projectId, userId: owner, allowUnsavedDownloadTargets: true }), { code: "CANVAS_CAPABILITY_NODE_NOT_FOUND" }); }); test("existing non-image nodes cannot masquerade as downloadable images", async () => { const command = createCanvasCapabilityClientCommand({ capabilityId: "image.download", nodeIds: [textNodeId], projectId, source: "toolbar" }); await assert.rejects(resolveCanvasCapabilityContext({ command, projectId, userId: owner, allowUnsavedDownloadTargets: true }), { code: "CANVAS_CAPABILITY_INVALID_NODE_TYPE" }); }); test("the browser download uses the current image URL without node persistence or a model call", async () => { const original = { fetch: globalThis.fetch, document: globalThis.document, window: globalThis.window }; const requests: Array<{ path: string; body: Record }> = []; const frames: Array<{ src?: string }> = []; try { globalThis.fetch = async (input, init) => { requests.push({ path: String(input), body: JSON.parse(String(init?.body)) }); return Response.json({ delivery: "cdn", downloadUrl: "https://cdn.example/download.png", filename: "original.png", bytes: 123 }); }; globalThis.document = { createElement: () => ({}), body: { appendChild: (frame: { src?: string }) => frames.push(frame) } } as unknown as Document; globalThis.window = { setTimeout: () => 1 } as unknown as Window & typeof globalThis; const result = await downloadCanvasImageAsPng({ url: "https://provider.example/new-unsaved-image.png", name: "Original" }); assert.equal(result.filename, "original.png"); assert.equal(requests.length, 1); assert.equal(requests[0].path, "/api/canvas/download-image"); assert.equal(requests[0].body.url, "https://provider.example/new-unsaved-image.png"); assert.equal(requests[0].body.nodeIds, undefined); assert.equal(frames[0].src, "https://cdn.example/download.png"); } finally { globalThis.fetch = original.fetch; globalThis.document = original.document; globalThis.window = original.window; } });