import { describe, it, expect } from "vitest"; import { validateEcommerceImageFiles, summarizeRejectedImages, normalizeEcommerceImageMime, ECOMMERCE_MAX_IMAGE_BYTES, } from "./ecommerceImageValidation"; function makeFile(name: string, type: string, size: number): File { return new File([new Uint8Array(size)], name, { type }); } describe("validateEcommerceImageFiles", () => { it("accepts supported types under the size limit", () => { const result = validateEcommerceImageFiles([ makeFile("a.png", "image/png", 1024), makeFile("b.jpg", "image/jpeg", 1024), makeFile("c.webp", "image/webp", 1024), makeFile("d.gif", "image/gif", 1024), ]); expect(result.accepted).toHaveLength(4); expect(result.rejected).toHaveLength(0); }); it("rejects unsupported mime types", () => { const result = validateEcommerceImageFiles([makeFile("x.bmp", "image/bmp", 1024)]); expect(result.accepted).toHaveLength(0); expect(result.rejected[0]).toMatchObject({ name: "x.bmp", reason: "不支持的图片格式" }); }); it("rejects files over 10MB", () => { const result = validateEcommerceImageFiles([ makeFile("big.png", "image/png", ECOMMERCE_MAX_IMAGE_BYTES + 1), ]); expect(result.accepted).toHaveLength(0); expect(result.rejected[0]).toMatchObject({ name: "big.png", reason: "图片超过 10MB" }); }); it("accepts exactly 10MB (boundary)", () => { const result = validateEcommerceImageFiles([ makeFile("edge.png", "image/png", ECOMMERCE_MAX_IMAGE_BYTES), ]); expect(result.accepted).toHaveLength(1); }); it("partitions a mixed batch", () => { const result = validateEcommerceImageFiles([ makeFile("ok.png", "image/png", 100), makeFile("bad.bmp", "image/bmp", 100), makeFile("huge.jpg", "image/jpeg", ECOMMERCE_MAX_IMAGE_BYTES + 1), ]); expect(result.accepted).toHaveLength(1); expect(result.rejected).toHaveLength(2); }); }); describe("summarizeRejectedImages", () => { it("returns empty string for no rejections", () => { expect(summarizeRejectedImages([])).toBe(""); }); it("summarizes a single rejection", () => { expect(summarizeRejectedImages([{ name: "a.bmp", reason: "不支持的图片格式" }])).toBe( "a.bmp 已跳过:不支持的图片格式", ); }); it("appends count suffix for multiple rejections", () => { const summary = summarizeRejectedImages([ { name: "a.bmp", reason: "不支持的图片格式" }, { name: "b.bmp", reason: "不支持的图片格式" }, ]); expect(summary).toBe("a.bmp 等 2 个文件 已跳过:不支持的图片格式"); }); }); describe("normalizeEcommerceImageMime", () => { it("passes through supported types", () => { expect(normalizeEcommerceImageMime("image/png")).toBe("image/png"); expect(normalizeEcommerceImageMime("image/jpeg")).toBe("image/jpeg"); expect(normalizeEcommerceImageMime("image/webp")).toBe("image/webp"); expect(normalizeEcommerceImageMime("image/gif")).toBe("image/gif"); }); it("falls back to image/png for unsupported or empty types", () => { expect(normalizeEcommerceImageMime("image/bmp")).toBe("image/png"); expect(normalizeEcommerceImageMime("")).toBe("image/png"); expect(normalizeEcommerceImageMime("application/octet-stream")).toBe("image/png"); }); });