mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
test(integration): accept 202 async for DNG in format-matrix smoke tests (#291)
* test(integration): accept 202 async for DNG in format-matrix smoke tests Follow-up to #290. Full-resolution DNG decode (3474x2314 vs the old 1024px preview) pushes expensive operations (AVIF encode, image-enhancement) past the 8s sync window on CI runners, so the API correctly returns 202 Accepted and processes the job asynchronously. The format-matrix smoke tests only allowed [200, 400, 422] and required a clean error body on any non-200, so they failed on the 202 (Integration shard 4/4 went red on main). 202 (accepted, async) is a valid clean response for these "no crash / clean response" checks. Make the matrix allowlists 202-tolerant and require an error body only for true error codes: - add 202 to ACCEPTABLE_CODES / ACCEPTABLE_FALLBACK_CODES + inline allowlists - change `if (statusCode !== 200)` error-body checks to `>= 400` Verified locally against Postgres+Redis: DNG tests pass both normally (200) and with SYNC_WAIT_MS=1 forcing 202 (68 passed, 0 failed each run). * test(integration): treat 202 as non-error in DNG conversion else-branches The first pass added 202 to status allowlists and switched `if (!== 200)` error checks to `>= 400`, but missed the `if (200) {...} else {...}` shape in the exotic conversion matrix and the expanded color-blindness test: their `else` caught 202 and then asserted body.error (which async responses lack). Reproduced locally by temporarily lowering the test sync-window floor to force 202 on every DNG op, then fixed every flagged assertion. Change the two `else` branches to `else if (statusCode >= 400)` so 202 (accepted, async) is a valid outcome with no sync body to verify. Verified: forced-202 across all 4 DNG matrix files = 123 passed / 0 failed; normal sync window = 34 DNG tests passed; typecheck + biome clean.
This commit is contained in:
@@ -189,7 +189,7 @@ const CORE_FORMATS = PRIMARY_FORMATS.filter(
|
||||
(f) => !f.needsCliDecoder && !f.needsHeifDecoder && !f.mayFailValidation,
|
||||
);
|
||||
|
||||
const ACCEPTABLE_FALLBACK_CODES = [200, 400, 422];
|
||||
const ACCEPTABLE_FALLBACK_CODES = [200, 202, 400, 422];
|
||||
|
||||
function needsFallback(fmt: FormatDef): boolean {
|
||||
return fmt.needsCliDecoder || fmt.needsHeifDecoder || fmt.mayFailValidation;
|
||||
@@ -699,7 +699,7 @@ describe("Image enhancement across all 16 primary formats", () => {
|
||||
});
|
||||
|
||||
if (needsFallback(fmt)) {
|
||||
expect([200, 400, 422]).toContain(res.statusCode);
|
||||
expect([200, 202, 400, 422]).toContain(res.statusCode);
|
||||
} else {
|
||||
expect(res.statusCode).toBe(200);
|
||||
}
|
||||
@@ -922,7 +922,7 @@ describe("No-crash matrix: 16 formats x 12 tools", () => {
|
||||
expect(typeof body).toBe("object");
|
||||
|
||||
// If error, verify clean error shape
|
||||
if (res.statusCode !== 200) {
|
||||
if (res.statusCode >= 400) {
|
||||
expect(body.error).toBeDefined();
|
||||
expect(typeof body.error).toBe("string");
|
||||
expect(body.error.length).toBeGreaterThan(0);
|
||||
@@ -1031,7 +1031,7 @@ describe("Exotic format error shape verification", () => {
|
||||
if (!res) return;
|
||||
|
||||
expect(res.statusCode).not.toBe(500);
|
||||
expect([200, 400, 422]).toContain(res.statusCode);
|
||||
expect([200, 202, 400, 422]).toContain(res.statusCode);
|
||||
|
||||
// Response must be valid JSON (not HTML, not raw text)
|
||||
let body: Record<string, unknown>;
|
||||
@@ -1043,7 +1043,7 @@ describe("Exotic format error shape verification", () => {
|
||||
);
|
||||
}
|
||||
|
||||
if (res.statusCode !== 200) {
|
||||
if (res.statusCode >= 400) {
|
||||
expect(body.error).toBeDefined();
|
||||
expect(typeof body.error).toBe("string");
|
||||
// Error message should not contain raw stack trace indicators
|
||||
@@ -1093,10 +1093,10 @@ describe("HEIC/HEIF graceful handling", () => {
|
||||
expect(res.statusCode).not.toBe(500);
|
||||
|
||||
// Accept success (200) or clean error (400/422)
|
||||
expect([200, 400, 422]).toContain(res.statusCode);
|
||||
expect([200, 202, 400, 422]).toContain(res.statusCode);
|
||||
|
||||
const body = JSON.parse(res.body);
|
||||
if (res.statusCode !== 200) {
|
||||
if (res.statusCode >= 400) {
|
||||
expect(body.error).toBeDefined();
|
||||
expect(typeof body.error).toBe("string");
|
||||
}
|
||||
@@ -1188,7 +1188,7 @@ describe("SVG through raster tools", () => {
|
||||
|
||||
// SVG should either be rasterized and processed (200) or cleanly rejected
|
||||
expect(res.statusCode).not.toBe(500);
|
||||
expect([200, 400, 422]).toContain(res.statusCode);
|
||||
expect([200, 202, 400, 422]).toContain(res.statusCode);
|
||||
|
||||
const body = JSON.parse(res.body);
|
||||
if (res.statusCode === 200) {
|
||||
@@ -1234,10 +1234,10 @@ describe("ICO (multi-size format) through tools", () => {
|
||||
|
||||
// ICO requires CLI decoder; accept success or clean error
|
||||
expect(res.statusCode).not.toBe(500);
|
||||
expect([200, 400, 422]).toContain(res.statusCode);
|
||||
expect([200, 202, 400, 422]).toContain(res.statusCode);
|
||||
|
||||
const body = JSON.parse(res.body);
|
||||
if (res.statusCode !== 200) {
|
||||
if (res.statusCode >= 400) {
|
||||
expect(body.error).toBeDefined();
|
||||
expect(typeof body.error).toBe("string");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user