From eddb09175ace4509e062cf71807de495975f3e0e Mon Sep 17 00:00:00 2001 From: diegosouzapw Date: Tue, 9 Jun 2026 22:26:25 -0300 Subject: [PATCH] test: align bypass-prefix schema test to the restored layer-1 contract + real waitFor headroom MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit appearance-widget-settings-schema asserted that /api/cli-tools/runtime/ was ACCEPTED into the bypass list — written against the buggy schema (missing BYPASS_PREFIX_NOT_ALLOWED refine, restored in #3536) and consecrating the bug the AC-8 orphan test guards against. Split into accept-safe + reject-spawn-capable cases. chatcore waitFor ceiling 1500→10000ms (green runs return immediately; observed 1580ms expiry on 2-core CI runners). --- .../appearance-widget-settings-schema.test.ts | 26 +++++++++++++++---- tests/unit/chatcore-translation-paths.test.ts | 6 ++++- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/tests/unit/appearance-widget-settings-schema.test.ts b/tests/unit/appearance-widget-settings-schema.test.ts index e4eb5a2de1..2f00412149 100644 --- a/tests/unit/appearance-widget-settings-schema.test.ts +++ b/tests/unit/appearance-widget-settings-schema.test.ts @@ -40,18 +40,34 @@ test("appearance widget visibility settings reject non-boolean values", () => { }); test("localOnlyManageScopeBypass settings are accepted by the settings PATCH schema", () => { + // Only NON-spawn-capable prefixes are acceptable. This test previously asserted + // that "/api/cli-tools/runtime/" was accepted — it was written against the buggy + // schema (the BYPASS_PREFIX_NOT_ALLOWED layer-1 refine documented in routeGuard.ts + // was missing) and consecrated the bug. The real contract (Hard Rules #15/#17 + + // authz-bypass AC-8) is covered by the rejection test below. const validation = updateSettingsSchema.safeParse({ localOnlyManageScopeBypassEnabled: true, - localOnlyManageScopeBypassPrefixes: ["/api/mcp/", "/api/cli-tools/runtime/"], + localOnlyManageScopeBypassPrefixes: ["/api/mcp/"], }); assert.equal(validation.success, true); if (!validation.success) return; assert.equal(validation.data.localOnlyManageScopeBypassEnabled, true); - assert.deepEqual(validation.data.localOnlyManageScopeBypassPrefixes, [ - "/api/mcp/", - "/api/cli-tools/runtime/", - ]); + assert.deepEqual(validation.data.localOnlyManageScopeBypassPrefixes, ["/api/mcp/"]); +}); + +test("localOnlyManageScopeBypassPrefixes rejects spawn-capable prefixes (BYPASS_PREFIX_NOT_ALLOWED)", () => { + const validation = updateSettingsSchema.safeParse({ + localOnlyManageScopeBypassEnabled: true, + localOnlyManageScopeBypassPrefixes: ["/api/mcp/", "/api/cli-tools/runtime/"], + }); + + assert.equal(validation.success, false); + if (validation.success) return; + assert.ok( + validation.error.issues.some((i) => i.message.includes("BYPASS_PREFIX_NOT_ALLOWED")), + "expected a BYPASS_PREFIX_NOT_ALLOWED issue for the spawn-capable prefix" + ); }); test("localOnlyManageScopeBypassEnabled rejects non-boolean values", () => { diff --git a/tests/unit/chatcore-translation-paths.test.ts b/tests/unit/chatcore-translation-paths.test.ts index ffd4137a53..a9cb0eef64 100644 --- a/tests/unit/chatcore-translation-paths.test.ts +++ b/tests/unit/chatcore-translation-paths.test.ts @@ -274,7 +274,11 @@ async function resetStorage() { fs.mkdirSync(TEST_DATA_DIR, { recursive: true }); } -async function waitFor(fn, timeoutMs = 1500) { +// 10s ceiling: on 2-core CI runners under shard contention the 1500ms budget +// expired mid-flight (observed: 1580ms fail on the upstream-timeout test) — +// green runs return as soon as the condition holds, so the ceiling only +// bounds the failure case. +async function waitFor(fn, timeoutMs = 10000) { const startedAt = Date.now(); while (Date.now() - startedAt < timeoutMs) { const result = await fn();