91 lines
3.3 KiB
TypeScript
91 lines
3.3 KiB
TypeScript
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");
|
|
});
|
|
});
|