62 lines
3.5 KiB
TypeScript
62 lines
3.5 KiB
TypeScript
import { readFile } from "node:fs/promises";
|
|
import { describe, expect, it } from "vitest";
|
|
|
|
const createStudioUrl = new URL("../components/create-studio.tsx", import.meta.url);
|
|
|
|
async function pasteFlowSource() {
|
|
const source = await readFile(createStudioUrl, "utf8");
|
|
const start = source.indexOf("function handleImagePaste(");
|
|
const end = source.indexOf("async function uploadTemplatePreview(", start);
|
|
expect(start).toBeGreaterThanOrEqual(0);
|
|
expect(end).toBeGreaterThan(start);
|
|
return { source, flow: source.slice(start, end) };
|
|
}
|
|
|
|
describe("create studio image paste wiring", () => {
|
|
it("handles paste in both the prompt and workspace, leaving text paste to the browser", async () => {
|
|
const { source, flow } = await pasteFlowSource();
|
|
expect(source).toContain("onPaste={handleImagePaste}");
|
|
expect(source).toContain("onPasteImage={handleImagePaste}");
|
|
expect(flow.indexOf("if (!files.length && !imageURL) return;")).toBeLessThan(flow.indexOf("event.preventDefault()"));
|
|
expect(flow).toContain("clipboardImageFiles(event.clipboardData)");
|
|
});
|
|
|
|
it("requires confirmation before downloading an entire URL and keeps canceled links as native text paste", async () => {
|
|
const { flow } = await pasteFlowSource();
|
|
expect(flow).toContain("files.length ? null : clipboardImageURL(event.clipboardData)");
|
|
const confirmation = flow.indexOf("if (imageURL && !window.confirm(");
|
|
expect(confirmation).toBeGreaterThanOrEqual(0);
|
|
expect(confirmation).toBeLessThan(flow.indexOf("event.preventDefault()"));
|
|
expect(flow).toContain('fetch("/api/assets/import-image"');
|
|
expect(flow).toContain('headers: { "Content-Type": "application/json" }');
|
|
expect(flow).toContain("receiveMaterialAssets(() => importImageURL(imageURL), options, 1)");
|
|
expect(flow).toContain("receiveMaterialAssets(() => uploadAssetFiles(selectedFiles), options, allFiles.length)");
|
|
expect(flow).toContain("new URL(imageURL).hostname");
|
|
expect(flow).toContain('asset.kind !== "image"');
|
|
expect(flow).toContain('options.importedURL && options.seedreamSourceMode === "single"');
|
|
});
|
|
|
|
it("blocks concurrent uploads and discards a stale result after a mode or target switch", async () => {
|
|
const { flow } = await pasteFlowSource();
|
|
expect(flow).toContain("if (uploadingRef.current || busy)");
|
|
expect(flow).toContain("uploadingRef.current = true");
|
|
expect(flow).toContain("uploadingRef.current = false");
|
|
expect(flow).toContain("options.paste.contextKey !== pasteContextRef.current");
|
|
expect(flow.indexOf("options.paste.contextKey !== pasteContextRef.current"))
|
|
.toBeLessThan(flow.indexOf("setMaterials(next)"));
|
|
});
|
|
|
|
it("routes special modes through existing source limits and adds references only for basic image or video", async () => {
|
|
const { flow } = await pasteFlowSource();
|
|
expect(flow).toContain('imageCreationMode === "interactive" ? "append" : "single"');
|
|
expect(flow).toContain("isSeedreamLayerInputFile(files[0])");
|
|
expect(flow).toContain("if (selectedSeedreamSource && !window.confirm(");
|
|
expect(flow).toContain("options.maxFiles = 1");
|
|
expect(flow).toContain("options.replaceAll = true");
|
|
expect(flow).toContain("options.maxFiles = remaining");
|
|
expect(flow).toContain("insertReferences: !specializedImageMode");
|
|
expect(flow).toContain('const labels = addedMaterials.map((material) => material.label || "");');
|
|
expect(flow).toContain("insertClipboardImageReferences(items[pasted.mode], labels, selection)");
|
|
});
|
|
});
|