mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
test: massive test coverage expansion (+1,437 tests, 22 new files)
Expand test coverage across all layers via 14 parallel agents: Unit tests (3,378 total, +534): - First-ever AI sidecar tests (157 tests covering bridge lifecycle, all 12 tool modules) - API route infrastructure (auth, pipeline, batch, settings, teams, roles, audit, api-keys, files, docs) - Lib coverage improvements (audit 7%->95%, worker-pool 33%->100%) - Web store/lib gap fills (features-store, tool-registry) Integration tests (4,403 total, +903): - Expanded 19 tool test files with parameter variations, format edge cases, boundary values - Cross-format matrix: 290 tests covering 14 tools x 17 formats - Adversarial/edge cases: 63 tests for extreme inputs, concurrent requests, corrupted files E2E-Docker (125 new tests): - Expanded 8 spec files + 1 new file covering all 49 tools - Added HEIC/format handling, auth failures, download verification GUI E2E (expanded 28 spec files): - Navigation, responsive layout, keyboard shortcuts - All 51 tool UIs with settings, processing, display modes - Batch/pipeline workflows, settings/RBAC, visual regression - Resilience, accessibility (ARIA, contrast, focus), performance budgets
This commit is contained in:
@@ -544,6 +544,136 @@ test.describe("Border — extended", () => {
|
||||
});
|
||||
});
|
||||
|
||||
// ─── Collage — Output Verification ──────────────────────────────
|
||||
|
||||
test.describe("Collage — output verification", () => {
|
||||
test("collage output can be downloaded", async ({ request }) => {
|
||||
const { body, contentType } = buildMultipart(
|
||||
[
|
||||
{ name: "file", filename: "a.png", contentType: "image/png", buffer: PNG_200x150 },
|
||||
{ name: "file", filename: "b.jpg", contentType: "image/jpeg", buffer: JPG_100x100 },
|
||||
],
|
||||
[
|
||||
{
|
||||
name: "settings",
|
||||
value: JSON.stringify({
|
||||
templateId: "2-h-equal",
|
||||
width: 400,
|
||||
outputFormat: "png",
|
||||
}),
|
||||
},
|
||||
],
|
||||
);
|
||||
const res = await request.post("/api/v1/tools/collage", {
|
||||
headers: { Authorization: `Bearer ${token}`, "Content-Type": contentType },
|
||||
data: body,
|
||||
});
|
||||
expect(res.ok()).toBe(true);
|
||||
const json = await res.json();
|
||||
expect(json.downloadUrl).toBeTruthy();
|
||||
|
||||
// Verify the collage can be downloaded
|
||||
const dlRes = await request.get(json.downloadUrl, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
});
|
||||
expect(dlRes.ok()).toBe(true);
|
||||
const buffer = Buffer.from(await dlRes.body());
|
||||
expect(buffer.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
test("collage with HEIC images", async ({ request }) => {
|
||||
const { body, contentType } = buildMultipart(
|
||||
[
|
||||
{ name: "file", filename: "a.heic", contentType: "image/heic", buffer: HEIC_200x150 },
|
||||
{ name: "file", filename: "b.png", contentType: "image/png", buffer: PNG_200x150 },
|
||||
],
|
||||
[
|
||||
{
|
||||
name: "settings",
|
||||
value: JSON.stringify({
|
||||
templateId: "2-h-equal",
|
||||
width: 400,
|
||||
outputFormat: "png",
|
||||
}),
|
||||
},
|
||||
],
|
||||
);
|
||||
const res = await request.post("/api/v1/tools/collage", {
|
||||
headers: { Authorization: `Bearer ${token}`, "Content-Type": contentType },
|
||||
data: body,
|
||||
});
|
||||
expect(res.ok()).toBe(true);
|
||||
const json = await res.json();
|
||||
expect(json.downloadUrl).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
// ─── Stitch — Output Verification ───────────────────────────────
|
||||
|
||||
test.describe("Stitch — output verification", () => {
|
||||
test("stitched image can be downloaded", async ({ request }) => {
|
||||
const { body, contentType } = buildMultipart(
|
||||
[
|
||||
{ name: "file", filename: "a.png", contentType: "image/png", buffer: PNG_200x150 },
|
||||
{ name: "file", filename: "b.jpg", contentType: "image/jpeg", buffer: JPG_100x100 },
|
||||
],
|
||||
[{ name: "settings", value: JSON.stringify({ direction: "horizontal", gap: 0 }) }],
|
||||
);
|
||||
const res = await request.post("/api/v1/tools/stitch", {
|
||||
headers: { Authorization: `Bearer ${token}`, "Content-Type": contentType },
|
||||
data: body,
|
||||
});
|
||||
expect(res.ok()).toBe(true);
|
||||
const json = await res.json();
|
||||
expect(json.downloadUrl).toBeTruthy();
|
||||
|
||||
const dlRes = await request.get(json.downloadUrl, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
});
|
||||
expect(dlRes.ok()).toBe(true);
|
||||
const buffer = Buffer.from(await dlRes.body());
|
||||
expect(buffer.length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
// ─── Border — Output Verification ───────────────────────────────
|
||||
|
||||
test.describe("Border — output verification", () => {
|
||||
test("bordered image can be downloaded and is larger", async ({ request }) => {
|
||||
const res = await request.post("/api/v1/tools/border", {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
multipart: {
|
||||
file: { name: "test.png", mimeType: "image/png", buffer: PNG_200x150 },
|
||||
settings: JSON.stringify({ size: 20, color: "#FF0000" }),
|
||||
},
|
||||
});
|
||||
expect(res.ok()).toBe(true);
|
||||
const body = await res.json();
|
||||
expect(body.downloadUrl).toBeTruthy();
|
||||
|
||||
// Download and verify the bordered image
|
||||
const dlRes = await request.get(body.downloadUrl, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
});
|
||||
expect(dlRes.ok()).toBe(true);
|
||||
const buffer = Buffer.from(await dlRes.body());
|
||||
expect(buffer.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
test("border with minimum size (1px)", async ({ request }) => {
|
||||
const res = await request.post("/api/v1/tools/border", {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
multipart: {
|
||||
file: { name: "test.jpg", mimeType: "image/jpeg", buffer: JPG_100x100 },
|
||||
settings: JSON.stringify({ size: 1, color: "#000000" }),
|
||||
},
|
||||
});
|
||||
expect(res.ok()).toBe(true);
|
||||
const body = await res.json();
|
||||
expect(body.downloadUrl).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
// ─── Auth Failure ──────────────────────────────────────────────────
|
||||
|
||||
test.describe("Auth failure", () => {
|
||||
@@ -566,4 +696,39 @@ test.describe("Auth failure", () => {
|
||||
});
|
||||
expect(res.status()).toBe(401);
|
||||
});
|
||||
|
||||
test("collage without token returns 401", async ({ request }) => {
|
||||
const { body, contentType } = buildMultipart(
|
||||
[
|
||||
{ name: "file", filename: "a.png", contentType: "image/png", buffer: PNG_200x150 },
|
||||
{ name: "file", filename: "b.jpg", contentType: "image/jpeg", buffer: JPG_100x100 },
|
||||
],
|
||||
[
|
||||
{
|
||||
name: "settings",
|
||||
value: JSON.stringify({ templateId: "2-h-equal", width: 400 }),
|
||||
},
|
||||
],
|
||||
);
|
||||
const res = await request.post("/api/v1/tools/collage", {
|
||||
headers: { "Content-Type": contentType },
|
||||
data: body,
|
||||
});
|
||||
expect(res.status()).toBe(401);
|
||||
});
|
||||
|
||||
test("stitch without token returns 401", async ({ request }) => {
|
||||
const { body, contentType } = buildMultipart(
|
||||
[
|
||||
{ name: "file", filename: "a.png", contentType: "image/png", buffer: PNG_200x150 },
|
||||
{ name: "file", filename: "b.jpg", contentType: "image/jpeg", buffer: JPG_100x100 },
|
||||
],
|
||||
[{ name: "settings", value: JSON.stringify({ direction: "horizontal" }) }],
|
||||
);
|
||||
const res = await request.post("/api/v1/tools/stitch", {
|
||||
headers: { "Content-Type": contentType },
|
||||
data: body,
|
||||
});
|
||||
expect(res.status()).toBe(401);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user