Files
Pien-Studio/apps/web/lib/project-equality.test.ts
2026-05-31 03:04:30 +07:00

135 lines
3.1 KiB
TypeScript

import { describe, expect, it } from "vitest";
import type { Project } from "@pien-studio/types";
import { hasProjectChanged } from "./project-equality";
function makeProject(): Project {
return {
id: "p1",
title: "Project",
createdAt: "2024-01-01T00:00:00.000Z",
updatedAt: "2024-01-01T00:00:00.000Z",
aspectRatio: "1:1",
canvas: { width: 100, height: 100, unit: "px" },
layers: [textLayer("l1")],
};
}
function textLayer(id: string) {
return {
id,
type: "text" as const,
x: 0,
y: 0,
width: 120,
height: 48,
scale: 1,
rotation: 0,
opacity: 1,
effects: [],
visible: true,
text: "Text",
fontFamily: "system-ui",
fontSize: 24,
color: "#000",
};
}
function rasterLayer(id: string) {
return {
id,
type: "raster" as const,
x: 0,
y: 0,
width: 120,
height: 80,
scale: 1,
rotation: 0,
opacity: 1,
effects: [],
visible: true,
asset: null,
};
}
describe("hasProjectChanged", () => {
it("returns false for equal projects", () => {
const a = makeProject();
const b = makeProject();
expect(hasProjectChanged(a, b)).toBe(false);
});
it("detects canvas changes", () => {
const a = makeProject();
const b = makeProject();
b.canvas.width = 101;
expect(hasProjectChanged(a, b)).toBe(true);
});
it("detects face blur region changes", () => {
const a = makeProject();
const b = makeProject();
a.layers[0] = rasterLayer("l1");
b.layers[0] = rasterLayer("l1");
a.layers[0].effects = [
{
kind: "face-blur",
enabled: true,
method: "gaussian",
amount: 14,
regions: [{ x: 1, y: 1, width: 10, height: 10 }],
},
];
b.layers[0].effects = [
{
kind: "face-blur",
enabled: true,
method: "gaussian",
amount: 14,
regions: [{ x: 1, y: 1, width: 11, height: 10 }],
},
];
expect(hasProjectChanged(a, b)).toBe(true);
});
it("detects layer order changes", () => {
const a = makeProject();
const b = makeProject();
a.layers.push({ ...textLayer("l2"), x: 3, y: 4 });
b.layers.push({ ...textLayer("l2"), x: 3, y: 4 });
b.layers = [b.layers[1], b.layers[0]];
expect(hasProjectChanged(a, b)).toBe(true);
});
it("detects visibility changes", () => {
const a = makeProject();
const b = makeProject();
b.layers[0].visible = false;
expect(hasProjectChanged(a, b)).toBe(true);
});
it("treats missing optional fields and undefined as equal", () => {
const a = makeProject();
const b = makeProject();
a.layers[0].name = undefined;
b.layers[0].name = undefined;
expect(hasProjectChanged(a, b)).toBe(false);
});
it("detects face blur removal", () => {
const a = makeProject();
const b = makeProject();
a.layers[0] = rasterLayer("l1");
b.layers[0] = rasterLayer("l1");
a.layers[0].effects = [
{
kind: "face-blur",
enabled: true,
method: "gaussian",
amount: 14,
regions: [{ x: 1, y: 1, width: 10, height: 10 }],
},
];
expect(hasProjectChanged(a, b)).toBe(true);
});
});