mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
fix: increase test timeouts for slow CI operations
- adversarial resize 50000x50000: 60s → 120s - format-matrix HEIF tests: 30s (default) → 90s
This commit is contained in:
@@ -487,7 +487,7 @@ describe("Extreme dimension requests", () => {
|
|||||||
// May succeed (Sharp allows large), fail at processing (422), or be
|
// May succeed (Sharp allows large), fail at processing (422), or be
|
||||||
// rejected by validation (400). Must not crash.
|
// rejected by validation (400). Must not crash.
|
||||||
expect([200, 400, 422]).toContain(res.statusCode);
|
expect([200, 400, 422]).toContain(res.statusCode);
|
||||||
}, 60_000);
|
}, 120_000);
|
||||||
|
|
||||||
it("rejects crop region larger than image dimensions", async () => {
|
it("rejects crop region larger than image dimensions", async () => {
|
||||||
const res = await postTool("crop", [
|
const res = await postTool("crop", [
|
||||||
|
|||||||
@@ -349,82 +349,88 @@ describe("Cross-format matrix", () => {
|
|||||||
// Skip "Convert to PNG" when input is already PNG (no-op conversion)
|
// Skip "Convert to PNG" when input is already PNG (no-op conversion)
|
||||||
if (tool.id === "convert" && fmt.name === "PNG") continue;
|
if (tool.id === "convert" && fmt.name === "PNG") continue;
|
||||||
|
|
||||||
it(`${tool.label}`, async () => {
|
const perTestTimeout = fmt.needsHeifDecoder ? 90_000 : undefined;
|
||||||
if (!existsSync(fixturePath)) return;
|
|
||||||
|
|
||||||
const buffer = readFileSync(fixturePath);
|
it(
|
||||||
const { body: payload, contentType } = buildPayload(fmt, tool, buffer);
|
`${tool.label}`,
|
||||||
|
async () => {
|
||||||
|
if (!existsSync(fixturePath)) return;
|
||||||
|
|
||||||
const res = await app.inject({
|
const buffer = readFileSync(fixturePath);
|
||||||
method: "POST",
|
const { body: payload, contentType } = buildPayload(fmt, tool, buffer);
|
||||||
url: `/api/v1/tools/${tool.id}`,
|
|
||||||
headers: {
|
|
||||||
authorization: `Bearer ${adminToken}`,
|
|
||||||
"content-type": contentType,
|
|
||||||
},
|
|
||||||
body: payload,
|
|
||||||
});
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------
|
const res = await app.inject({
|
||||||
// Assert status code
|
method: "POST",
|
||||||
// ------------------------------------------------------------------
|
url: `/api/v1/tools/${tool.id}`,
|
||||||
if (needsFallback(fmt)) {
|
headers: {
|
||||||
// Formats with optional decoders: accept success or graceful error
|
authorization: `Bearer ${adminToken}`,
|
||||||
expect(ACCEPTABLE_FALLBACK_CODES).toContain(res.statusCode);
|
"content-type": contentType,
|
||||||
} else {
|
},
|
||||||
// Core formats must always succeed
|
body: payload,
|
||||||
expect(res.statusCode).toBe(200);
|
});
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
// If successful, validate the response shape
|
// Assert status code
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
if (res.statusCode === 200) {
|
if (needsFallback(fmt)) {
|
||||||
const body = JSON.parse(res.body);
|
// Formats with optional decoders: accept success or graceful error
|
||||||
|
expect(ACCEPTABLE_FALLBACK_CODES).toContain(res.statusCode);
|
||||||
switch (tool.responseType) {
|
} else {
|
||||||
case "download":
|
// Core formats must always succeed
|
||||||
expect(body.downloadUrl).toBeDefined();
|
expect(res.statusCode).toBe(200);
|
||||||
expect(typeof body.downloadUrl).toBe("string");
|
|
||||||
expect(body.processedSize).toBeGreaterThan(0);
|
|
||||||
expect(body.originalSize).toBeGreaterThan(0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "info":
|
|
||||||
expect(body.width).toBeGreaterThan(0);
|
|
||||||
expect(body.height).toBeGreaterThan(0);
|
|
||||||
expect(body.fileSize).toBeGreaterThan(0);
|
|
||||||
expect(body.format).toBeDefined();
|
|
||||||
expect(body.channels).toBeGreaterThan(0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "base64":
|
|
||||||
// image-to-base64 returns { results: [...], errors: [...] }
|
|
||||||
expect(Array.isArray(body.results)).toBe(true);
|
|
||||||
expect(body.results.length + body.errors.length).toBeGreaterThan(0);
|
|
||||||
if (body.results.length > 0) {
|
|
||||||
const r = body.results[0];
|
|
||||||
expect(r.base64).toBeDefined();
|
|
||||||
expect(typeof r.base64).toBe("string");
|
|
||||||
expect(r.base64.length).toBeGreaterThan(0);
|
|
||||||
expect(r.dataUri).toMatch(/^data:/);
|
|
||||||
expect(r.width).toBeGreaterThan(0);
|
|
||||||
expect(r.height).toBeGreaterThan(0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
// If the API returned an error, verify it is a clean JSON error
|
// If successful, validate the response shape
|
||||||
// (not a raw crash / stack trace / HTML error page)
|
// ------------------------------------------------------------------
|
||||||
// ------------------------------------------------------------------
|
if (res.statusCode === 200) {
|
||||||
if (res.statusCode !== 200) {
|
const body = JSON.parse(res.body);
|
||||||
const body = JSON.parse(res.body);
|
|
||||||
expect(body.error).toBeDefined();
|
switch (tool.responseType) {
|
||||||
expect(typeof body.error).toBe("string");
|
case "download":
|
||||||
}
|
expect(body.downloadUrl).toBeDefined();
|
||||||
});
|
expect(typeof body.downloadUrl).toBe("string");
|
||||||
|
expect(body.processedSize).toBeGreaterThan(0);
|
||||||
|
expect(body.originalSize).toBeGreaterThan(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "info":
|
||||||
|
expect(body.width).toBeGreaterThan(0);
|
||||||
|
expect(body.height).toBeGreaterThan(0);
|
||||||
|
expect(body.fileSize).toBeGreaterThan(0);
|
||||||
|
expect(body.format).toBeDefined();
|
||||||
|
expect(body.channels).toBeGreaterThan(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "base64":
|
||||||
|
// image-to-base64 returns { results: [...], errors: [...] }
|
||||||
|
expect(Array.isArray(body.results)).toBe(true);
|
||||||
|
expect(body.results.length + body.errors.length).toBeGreaterThan(0);
|
||||||
|
if (body.results.length > 0) {
|
||||||
|
const r = body.results[0];
|
||||||
|
expect(r.base64).toBeDefined();
|
||||||
|
expect(typeof r.base64).toBe("string");
|
||||||
|
expect(r.base64.length).toBeGreaterThan(0);
|
||||||
|
expect(r.dataUri).toMatch(/^data:/);
|
||||||
|
expect(r.width).toBeGreaterThan(0);
|
||||||
|
expect(r.height).toBeGreaterThan(0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
// If the API returned an error, verify it is a clean JSON error
|
||||||
|
// (not a raw crash / stack trace / HTML error page)
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
if (res.statusCode !== 200) {
|
||||||
|
const body = JSON.parse(res.body);
|
||||||
|
expect(body.error).toBeDefined();
|
||||||
|
expect(typeof body.error).toBe("string");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
perTestTimeout,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user