test: expand coverage to 3,382 tests across all layers

- Unit: 1,353 tests (42 files) — +256 new tests covering AI bridge
  modules, image-engine sharpen/optimize-for-web, Zustand stores, and
  icon-map validation
- Integration: 1,640 tests (57 files) — +826 new tests across all
  tool routes, pipeline/progress/batch infrastructure, user-files,
  edit-metadata, and a 321-test cross-format matrix
- E2E-Docker: 389 passing (20 spec files) — 6 new spec files for
  batch processing, format conversion, layout, optimization,
  watermark/overlay, and pipeline chains. Tests verified against fresh
  Docker container with all 6 AI bundles installed.

Bug fixes discovered during testing:
- fix(compress): SVG/BMP/exotic formats crashed Sharp encoder — added
  format-safety fallback to PNG
- fix(rate-limit): increase default login attempt limit from 10 to 500
  per minute — previous value caused false test failures and is too
  restrictive for a self-hosted app
- fix(auth.setup): wait for consent button visibility before clicking
  to prevent flaky E2E-Docker auth setup
This commit is contained in:
SnapOtter
2026-04-24 22:43:14 +08:00
parent bc82781282
commit 7f62bc32db
48 changed files with 13121 additions and 154 deletions
+228
View File
@@ -363,4 +363,232 @@ describe("Border", () => {
expect(res.statusCode).toBe(401);
});
// ── Edge cases ──────────────────────────────────────────────────
it("handles zero-width border (no-op border, dimensions unchanged)", async () => {
const { body, contentType } = createMultipartPayload([
{ name: "file", filename: "test.png", contentType: "image/png", content: PNG },
{
name: "settings",
content: JSON.stringify({ borderWidth: 0, borderColor: "#000000" }),
},
]);
const res = await app.inject({
method: "POST",
url: "/api/v1/tools/border",
headers: { authorization: `Bearer ${adminToken}`, "content-type": contentType },
body,
});
expect(res.statusCode).toBe(200);
const result = JSON.parse(res.body);
const dlRes = await app.inject({
method: "GET",
url: result.downloadUrl,
headers: { authorization: `Bearer ${adminToken}` },
});
const meta = await sharp(dlRes.rawPayload).metadata();
// Zero border should not change dimensions
expect(meta.width).toBe(200);
expect(meta.height).toBe(150);
});
it("handles very large border (max 2000px)", async () => {
const { body, contentType } = createMultipartPayload([
{ name: "file", filename: "test.png", contentType: "image/png", content: PNG },
{
name: "settings",
content: JSON.stringify({ borderWidth: 2000, borderColor: "#FF0000" }),
},
]);
const res = await app.inject({
method: "POST",
url: "/api/v1/tools/border",
headers: { authorization: `Bearer ${adminToken}`, "content-type": contentType },
body,
});
expect(res.statusCode).toBe(200);
const result = JSON.parse(res.body);
const dlRes = await app.inject({
method: "GET",
url: result.downloadUrl,
headers: { authorization: `Bearer ${adminToken}` },
});
const meta = await sharp(dlRes.rawPayload).metadata();
expect(meta.width).toBe(200 + 2000 * 2);
expect(meta.height).toBe(150 + 2000 * 2);
});
it("applies corner radius with rounded corners and shadow together", async () => {
const { body, contentType } = createMultipartPayload([
{ name: "file", filename: "test.png", contentType: "image/png", content: PNG },
{
name: "settings",
content: JSON.stringify({
borderWidth: 10,
borderColor: "#000000",
cornerRadius: 30,
shadow: true,
shadowBlur: 15,
shadowOffsetX: 5,
shadowOffsetY: 5,
shadowColor: "#000000",
shadowOpacity: 60,
}),
},
]);
const res = await app.inject({
method: "POST",
url: "/api/v1/tools/border",
headers: { authorization: `Bearer ${adminToken}`, "content-type": contentType },
body,
});
expect(res.statusCode).toBe(200);
const result = JSON.parse(res.body);
const dlRes = await app.inject({
method: "GET",
url: result.downloadUrl,
headers: { authorization: `Bearer ${adminToken}` },
});
const meta = await sharp(dlRes.rawPayload).metadata();
expect(meta.format).toBe("png");
expect(meta.channels).toBe(4); // alpha from corner radius + shadow
});
it("handles corner radius larger than image half-dimension (clamps)", async () => {
const { body, contentType } = createMultipartPayload([
{ name: "file", filename: "test.png", contentType: "image/png", content: PNG },
{
name: "settings",
content: JSON.stringify({
borderWidth: 5,
borderColor: "#000000",
cornerRadius: 2000,
}),
},
]);
const res = await app.inject({
method: "POST",
url: "/api/v1/tools/border",
headers: { authorization: `Bearer ${adminToken}`, "content-type": contentType },
body,
});
// Should succeed - the route clamps radius to min(radius, w/2, h/2)
expect(res.statusCode).toBe(200);
const result = JSON.parse(res.body);
expect(result.processedSize).toBeGreaterThan(0);
});
it("handles shadow with negative offsets", async () => {
const { body, contentType } = createMultipartPayload([
{ name: "file", filename: "test.png", contentType: "image/png", content: PNG },
{
name: "settings",
content: JSON.stringify({
borderWidth: 5,
borderColor: "#333333",
shadow: true,
shadowBlur: 10,
shadowOffsetX: -10,
shadowOffsetY: -10,
shadowColor: "#000000",
shadowOpacity: 50,
}),
},
]);
const res = await app.inject({
method: "POST",
url: "/api/v1/tools/border",
headers: { authorization: `Bearer ${adminToken}`, "content-type": contentType },
body,
});
expect(res.statusCode).toBe(200);
const result = JSON.parse(res.body);
expect(result.processedSize).toBeGreaterThan(0);
});
it("handles padding only, zero border", async () => {
const padding = 20;
const { body, contentType } = createMultipartPayload([
{ name: "file", filename: "test.png", contentType: "image/png", content: PNG },
{
name: "settings",
content: JSON.stringify({
borderWidth: 0,
padding,
paddingColor: "#FF00FF",
}),
},
]);
const res = await app.inject({
method: "POST",
url: "/api/v1/tools/border",
headers: { authorization: `Bearer ${adminToken}`, "content-type": contentType },
body,
});
expect(res.statusCode).toBe(200);
const result = JSON.parse(res.body);
const dlRes = await app.inject({
method: "GET",
url: result.downloadUrl,
headers: { authorization: `Bearer ${adminToken}` },
});
const meta = await sharp(dlRes.rawPayload).metadata();
// Only padding, no border
expect(meta.width).toBe(200 + padding * 2);
expect(meta.height).toBe(150 + padding * 2);
});
it("handles HEIC input", async () => {
const HEIC = readFileSync(join(FIXTURES, "test-200x150.heic"));
const { body, contentType } = createMultipartPayload([
{ name: "file", filename: "photo.heic", contentType: "image/heic", content: HEIC },
{
name: "settings",
content: JSON.stringify({ borderWidth: 10, borderColor: "#0000FF" }),
},
]);
const res = await app.inject({
method: "POST",
url: "/api/v1/tools/border",
headers: { authorization: `Bearer ${adminToken}`, "content-type": contentType },
body,
});
expect(res.statusCode).toBe(200);
const result = JSON.parse(res.body);
expect(result.processedSize).toBeGreaterThan(0);
});
it("rejects negative border width", async () => {
const { body, contentType } = createMultipartPayload([
{ name: "file", filename: "test.png", contentType: "image/png", content: PNG },
{
name: "settings",
content: JSON.stringify({ borderWidth: -5, borderColor: "#000000" }),
},
]);
const res = await app.inject({
method: "POST",
url: "/api/v1/tools/border",
headers: { authorization: `Bearer ${adminToken}`, "content-type": contentType },
body,
});
expect(res.statusCode).toBe(400);
});
});