"use strict"; const { test, describe } = require("node:test"); const assert = require("node:assert/strict"); const { XaiImageClient } = require("../src/core/xai/client"); const { buildGrokEditPrompt } = require("../src/core/engines/grok-edit-engine"); const { loadConfig } = require("../src/config"); describe("xAI Grok image edit", () => { test("sends JSON to /images/edits and decodes b64_json", async () => { let captured; const fetchImpl = async (url, opts) => { captured = { url, opts, body: JSON.parse(opts.body) }; return new Response(JSON.stringify({ data: [{ b64_json: Buffer.from("JPEGDATA").toString("base64"), mime_type: "image/jpeg" }] }), { status: 200 }); }; const c = new XaiImageClient({ apiKey: "k", baseUrl: "https://api.x.ai/v1/", fetchImpl }); const r = await c.edit({ prompt: "p", images: [{ buffer: Buffer.from("a"), mimetype: "image/png" }] }); assert.equal(captured.url, "https://api.x.ai/v1/images/edits"); assert.equal(captured.opts.headers.Authorization, "Bearer k"); assert.equal(captured.body.model, "grok-imagine-image-2.0"); assert.equal(captured.body.response_format, "b64_json"); assert.equal(captured.body.image.type, "image_url"); assert.ok(captured.body.image.url.startsWith("data:image/png;base64,")); assert.equal(r.buffer.toString(), "JPEGDATA"); }); test("uses images[] for multiple inputs and surfaces API errors", async () => { let body; const fetchImpl = async (_u, o) => { body = JSON.parse(o.body); return new Response(JSON.stringify({ error: "bad" }), { status: 400 }); }; const c = new XaiImageClient({ apiKey: "k", fetchImpl }); const img = { buffer: Buffer.from("a"), mimetype: "image/jpeg" }; await assert.rejects(c.edit({ prompt: "p", images: [img, img] }), /Grok API 400: bad/); assert.equal(body.images.length, 2); assert.equal(body.image, undefined); }); test("fails clearly without API key", async () => { const c = new XaiImageClient({ apiKey: "" }); await assert.rejects(c.edit({ prompt: "p", images: [{ buffer: Buffer.from("a") }] }), /XAI_API_KEY/); }); test("prompt mentions reference region", () => { const t = buildGrokEditPrompt({ prompt: "add hat", hasReference: true, region: { x: 1, y: 2, w: 3, h: 4 } }); assert.match(t, /add hat/); assert.match(t, /x=1, y=2, width=3, height=4/); }); test("config defaults and key is not in sanitized output", () => { const cfg = loadConfig({ XAI_API_KEY: "secret" }); assert.equal(cfg.EDIT_ENGINE, "grok"); assert.equal(cfg.XAI_IMAGE_MODEL, "grok-imagine-image-2.0"); const s = cfg.getSanitized(); assert.equal(s.XAI_API_KEY, undefined); assert.equal(s.XAI_API_KEY_SET, true); assert.throws(() => loadConfig({ EDIT_ENGINE: "foo" })); }); });