diff --git a/src/tests/headless-v2-migration.test.ts b/src/tests/headless-v2-migration.test.ts index 9f0deca99..76a6d8db8 100644 --- a/src/tests/headless-v2-migration.test.ts +++ b/src/tests/headless-v2-migration.test.ts @@ -66,6 +66,7 @@ class MockRpcClient { sendUICalls: SendUICall[] = []; initCalled = false; initShouldFail = false; + stopCalled = false; sendUIResponse( id: string, @@ -88,6 +89,26 @@ class MockRpcClient { } return { protocolVersion: 2 }; } + + async stop(): Promise { + this.stopCalled = true; + } +} + +async function negotiateV2ForTest( + client: MockRpcClient, + allowLegacyFallback = false, +): Promise<"v2" | "legacy" | "fatal"> { + try { + await client.init({ clientId: "sf-headless" }); + return "v2"; + } catch { + if (!allowLegacyFallback) { + await client.stop(); + return "fatal"; + } + return "legacy"; + } } // ─── Extracted handleExtensionUIRequest (mirrors headless-ui.ts) ──────────── @@ -512,19 +533,24 @@ test("v2 init success sets v2Enabled", async () => { assert.equal(v2Enabled, true); }); -test("v2 init failure falls back gracefully (v1 mode)", async () => { +test("v2 init failure is fatal by default", async () => { const client = new MockRpcClient(); client.initShouldFail = true; - let v2Enabled = false; - try { - await client.init({ clientId: "sf-headless" }); - v2Enabled = true; - } catch { - // fall back to v1 — this is expected - } + const mode = await negotiateV2ForTest(client); assert.equal(client.initCalled, true); - assert.equal(v2Enabled, false); + assert.equal(client.stopCalled, true); + assert.equal(mode, "fatal"); +}); + +test("v2 init failure uses v1 only with explicit legacy fallback opt-in", async () => { + const client = new MockRpcClient(); + client.initShouldFail = true; + const mode = await negotiateV2ForTest(client, true); + + assert.equal(client.initCalled, true); + assert.equal(client.stopCalled, false); + assert.equal(mode, "legacy"); }); // ─── injector adapter ───────────────────────────────────────────────────────