import { describe, expect, it } from "vitest"; import { buildEvolinkImagePayload, extractEvolinkResultUrls, getEvolinkTaskId, mapEvolinkStatus } from "@/lib/evolink/image-client"; describe("EvoLink image client helpers", () => { it("builds GPT Image 2 payloads with the platform 1K resolution", () => { const payload = buildEvolinkImagePayload("image.generate", { prompt: "商品海报", imageUrls: ["https://example.com/ref.png"], width: 2048, height: 2048 }, { baseUrl: "https://api.evolink.ai", model: "gpt-image-2", quality: "medium" }); expect(payload).toMatchObject({ model: "gpt-image-2", prompt: "商品海报", image_urls: ["https://example.com/ref.png"], size: "1:1", quality: "medium", resolution: "1K", n: 1 }); }); it.each(["gpt-image-2.5-flare", "gpt-image-2.5-sunburst"])("selects %s for a single 1K image", (model) => { const payload = buildEvolinkImagePayload("image.generate", { prompt: "商品海报", model, quality: "high" }, { baseUrl: "https://api.evolink.ai", model: "gpt-image-2" }); expect(payload).toMatchObject({ model, quality: "high", n: 1, resolution: "1K", size: "1:1" }); expect(buildEvolinkImagePayload("image.generate", { prompt: "商品海报", model }, { baseUrl: "https://api.evolink.ai", model: "gpt-image-2" }).quality).toBe("medium"); }); it("rejects arbitrary models supplied by a caller but preserves a configured default model", () => { const settings = { baseUrl: "https://api.evolink.ai", model: "custom-image-model" }; expect(() => buildEvolinkImagePayload("image.generate", { prompt: "海报", model: "arbitrary-model" }, settings)) .toThrow("Unsupported EvoLink image model."); expect(buildEvolinkImagePayload("image.generate", { prompt: "海报" }, settings).model).toBe("custom-image-model"); expect(buildEvolinkImagePayload("image.generate", { prompt: "海报", model: "custom-image-model" }, settings).model).toBe("custom-image-model"); }); it.each([ [{ quality: 1 }, "quality"], [{ quality: "ultra" }, "quality"], [{ resolution: "2K" }, "resolution"], [{ n: 2 }, "n"], [{ imageCount: 2 }, "imageCount"], [{ size: "2048x2048" }, "size"], [{ width: 3504, height: 2400 }, "dimensions"], [{ width: 1000, height: 992 }, "dimensions"], [{ width: 1200 }, "both width and height"], [{ force_single: false }, "force_single"], [{ settings: { resolution: "2K" } }, "resolution"], [{ settings: { n: 2 } }, "n"], [{ imageUrls: Array(17).fill("https://example.com/ref.png") }, "16 reference images"] ])("rejects invalid Image 2.5 input %j", (invalid, reason) => { expect(() => buildEvolinkImagePayload("image.generate", { prompt: "海报", model: "gpt-image-2.5-flare", ...invalid }, { baseUrl: "https://api.evolink.ai", model: "gpt-image-2" })).toThrow(reason); }); it("rejects an invalid configured quality for Image 2.5", () => { expect(() => buildEvolinkImagePayload("image.generate", { prompt: "海报", model: "gpt-image-2.5-flare" }, { baseUrl: "https://api.evolink.ai", model: "gpt-image-2", quality: "ultra" })).toThrow("quality"); }); it("accepts a bounded 16px custom size and A4 presets", () => { const settings = { baseUrl: "https://api.evolink.ai", model: "gpt-image-2.5-flare" }; expect(buildEvolinkImagePayload("image.generate", { prompt: "海报", width: 1024, height: 768 }, settings).size).toBe("4:3"); expect(buildEvolinkImagePayload("image.generate", { prompt: "海报", width: 848, height: 1200 }, settings).size).toBe("848x1200"); expect(buildEvolinkImagePayload("image.generate", { prompt: "海报", width: 1280, height: 736 }, settings).size).toBe("1280x736"); }); it("normalizes task ids, statuses, and result URLs", () => { const response = { data: { task_id: "task-1", status: "completed", results: [ "https://example.com/a.png", { image_url: "https://example.com/b.png" } ] } }; expect(getEvolinkTaskId(response)).toBe("task-1"); expect(mapEvolinkStatus(response)).toBe("succeeded"); expect(extractEvolinkResultUrls(response)).toEqual([ "https://example.com/a.png", "https://example.com/b.png" ]); }); });