143 lines
4.5 KiB
TypeScript
143 lines
4.5 KiB
TypeScript
import { expect, test } from "@playwright/test";
|
|
import sharp from "sharp";
|
|
import {
|
|
prepareAlibabaImageInputBuffer,
|
|
selectAlibabaInputImageUrls,
|
|
} from "@/lib/ai/providers/alibaba-image-input";
|
|
import {
|
|
resolveDetailAgentApiKey,
|
|
} from "@/lib/ai/detail-agent-model-config";
|
|
import {
|
|
DEFAULT_DETAIL_REPLACEMENT_VISION_MODEL_ID,
|
|
normalizeDetailReplacementVisionModelConfig,
|
|
} from "@/lib/ai/detail-replacement-vision-model-config";
|
|
import { selectDetailReplacementGenerationInputs } from "@/lib/ai/detail-replacement-inputs";
|
|
|
|
test("preserves the final layout image when Alibaba accepts only three inputs", () => {
|
|
expect(
|
|
selectAlibabaInputImageUrls([
|
|
"https://assets.test/product.png",
|
|
"https://assets.test/model.png",
|
|
"https://assets.test/supplement.png",
|
|
"https://assets.test/layout.png",
|
|
]),
|
|
).toEqual([
|
|
"https://assets.test/product.png",
|
|
"https://assets.test/model.png",
|
|
"https://assets.test/layout.png",
|
|
]);
|
|
});
|
|
|
|
test("packs product, required model identity, and final layout into the three-image contract", () => {
|
|
const selected = selectDetailReplacementGenerationInputs({
|
|
productImageUrls: [
|
|
"https://assets.test/product-main.png",
|
|
"https://assets.test/product-side.png",
|
|
],
|
|
modelImageUrl: "https://assets.test/person.png",
|
|
includeModelImage: true,
|
|
rerunReferenceImageUrls: ["https://assets.test/old-result.png"],
|
|
referenceImageUrl: "https://assets.test/layout.png",
|
|
});
|
|
|
|
expect(selected.imageUrls).toEqual([
|
|
"https://assets.test/product-main.png",
|
|
"https://assets.test/person.png",
|
|
"https://assets.test/layout.png",
|
|
]);
|
|
expect(selected.inputImageRoleByUrl).toEqual({
|
|
"https://assets.test/product-main.png": "product",
|
|
"https://assets.test/person.png": "model",
|
|
"https://assets.test/layout.png": "layout",
|
|
});
|
|
});
|
|
|
|
test("uses a rerun result as the second input without dropping the final layout", () => {
|
|
const selected = selectDetailReplacementGenerationInputs({
|
|
productImageUrls: ["https://assets.test/product.png"],
|
|
includeModelImage: false,
|
|
rerunReferenceImageUrls: ["https://assets.test/old-result.png"],
|
|
referenceImageUrl: "https://assets.test/layout.png",
|
|
});
|
|
|
|
expect(selected.imageUrls).toEqual([
|
|
"https://assets.test/product.png",
|
|
"https://assets.test/old-result.png",
|
|
"https://assets.test/layout.png",
|
|
]);
|
|
});
|
|
|
|
test("crops transparent product padding and flattens it onto white for Qwen", async () => {
|
|
const product = await sharp({
|
|
create: {
|
|
width: 1000,
|
|
height: 1000,
|
|
channels: 4,
|
|
background: { r: 0, g: 0, b: 0, alpha: 0 },
|
|
},
|
|
})
|
|
.composite([
|
|
{
|
|
input: await sharp({
|
|
create: {
|
|
width: 600,
|
|
height: 240,
|
|
channels: 4,
|
|
background: { r: 25, g: 25, b: 25, alpha: 1 },
|
|
},
|
|
})
|
|
.png()
|
|
.toBuffer(),
|
|
left: 200,
|
|
top: 380,
|
|
},
|
|
])
|
|
.png()
|
|
.toBuffer();
|
|
const prepared = await prepareAlibabaImageInputBuffer({
|
|
buffer: product,
|
|
contentType: "image/png",
|
|
inputRole: "product",
|
|
maxInputBytes: 9.5 * 1024 * 1024,
|
|
maxSide: 4096,
|
|
modelId: "qwen-image-3.0-pro",
|
|
});
|
|
const metadata = await sharp(prepared.buffer).metadata();
|
|
const corner = await sharp(prepared.buffer)
|
|
.extract({ left: 0, top: 0, width: 1, height: 1 })
|
|
.raw()
|
|
.toBuffer();
|
|
|
|
expect(prepared.transformed).toBe(true);
|
|
expect(prepared.transparentProductTrimmed).toBe(true);
|
|
expect(prepared.extension).toBe("jpg");
|
|
expect(metadata.width).toBeLessThan(800);
|
|
expect(metadata.height).toBeLessThan(440);
|
|
expect([...corner]).toEqual([255, 255, 255]);
|
|
});
|
|
|
|
test("uses the enabled Alibaba provider key for a DashScope detail planner", () => {
|
|
expect(
|
|
resolveDetailAgentApiKey({
|
|
configuredApiKey: "stale-setting-key",
|
|
configuredBaseUrl: "https://dashscope.aliyuncs.com/compatible-mode/v1",
|
|
enabledAlibabaProviders: [
|
|
{
|
|
apiKey: "current-provider-key",
|
|
baseUrl: "https://dashscope.aliyuncs.com/compatible-mode/v1",
|
|
},
|
|
],
|
|
}),
|
|
).toBe("current-provider-key");
|
|
});
|
|
|
|
test("uses the dedicated high-accuracy vision model for detail replacement", () => {
|
|
expect(DEFAULT_DETAIL_REPLACEMENT_VISION_MODEL_ID).toBe("qwen3.7-plus");
|
|
expect(normalizeDetailReplacementVisionModelConfig(null)).toEqual({
|
|
modelId: "qwen3.7-plus",
|
|
});
|
|
expect(
|
|
normalizeDetailReplacementVisionModelConfig({ modelId: "custom-vision" }),
|
|
).toEqual({ modelId: "custom-vision" });
|
|
});
|