From 867e655d51d892c47ee68fc7f02c7e8ca0a5628d Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 14 Sep 2026 13:39:07 -0700 Subject: [PATCH] test: route provider integration and wizard recovery tests correctly (#148504) * test(plugins): keep registered provider auth coverage in integration tests Move the existing Radius registration and device-code cancellation flow to the root integration suite so core tests no longer pull the bundled provider into their type graph. Preserve generic auth adapter coverage and all flow assertions. Co-authored-by: Ayaan Zaidi * test: restore database worker routing for wizard recovery --------- Co-authored-by: Ayaan Zaidi --- src/plugins/provider-auth-method.test.ts | 52 +--------------- ...der-auth-method.radius.integration.test.ts | 61 +++++++++++++++++++ .../vitest.database-worker-core-paths.mjs | 1 + 3 files changed, 63 insertions(+), 51 deletions(-) create mode 100644 test/provider-auth-method.radius.integration.test.ts diff --git a/src/plugins/provider-auth-method.test.ts b/src/plugins/provider-auth-method.test.ts index 3991206b5452..c55ef4b043ed 100644 --- a/src/plugins/provider-auth-method.test.ts +++ b/src/plugins/provider-auth-method.test.ts @@ -1,18 +1,13 @@ import { afterEach, describe, expect, it, vi } from "vitest"; -import radiusPlugin from "../../extensions/radius/index.js"; import { createWizardPrompter } from "../../test/helpers/wizard-prompter.js"; import { createNonExitingRuntime } from "../runtime.js"; -import { registerSingleProviderPlugin } from "../test-utils/plugin-registration.js"; -import { WizardSession } from "../wizard/session.js"; import { runProviderPluginAuthMethodUnpersisted } from "./provider-auth-method.js"; import type { ProviderAuthMethod } from "./provider-authentication.types.js"; -const { openHostBrowser, guardedFetch } = vi.hoisted(() => ({ +const { openHostBrowser } = vi.hoisted(() => ({ openHostBrowser: vi.fn(async () => true), - guardedFetch: vi.fn(), })); vi.mock("../infra/browser-open.js", () => ({ openUrl: openHostBrowser })); -vi.mock("openclaw/plugin-sdk/ssrf-runtime", () => ({ fetchWithSsrFGuard: guardedFetch })); afterEach(() => vi.clearAllMocks()); @@ -84,49 +79,4 @@ describe("runProviderPluginAuthMethodUnpersisted", () => { expect(presentUrl).not.toHaveBeenCalled(); expect(openHostBrowser).not.toHaveBeenCalled(); }); - - it.each([false, true])( - "keeps the registered Radius device destination with its code and cancellation (remote=%s)", - async (isRemote) => { - guardedFetch.mockResolvedValueOnce({ - response: Response.json({ - device_code: "synthetic-device-secret", - user_code: "ABCD-EFGH", - verification_uri: "https://radius.earendil.com/device", - expires_in: 300, - interval: 5, - }), - release: async () => undefined, - }); - const provider = await registerSingleProviderPlugin(radiusPlugin); - const method = provider.auth.find((entry) => entry.id === "oauth"); - if (!method) { - throw new Error("Radius did not register its OAuth method"); - } - const session = new WizardSession(async (prompter, signal) => { - await runProviderPluginAuthMethodUnpersisted({ - ...options, - method, - prompter, - signal, - isRemote, - }); - }); - try { - const pending = await session.next(); - expect(pending.step).toMatchObject({ - type: "progress", - externalUrl: "https://radius.earendil.com/device", - deviceCode: { code: "ABCD-EFGH", expiresInMinutes: 5 }, - }); - expect(openHostBrowser).not.toHaveBeenCalled(); - session.cancel(); - expect(await session.next()).toMatchObject({ done: true, status: "cancelled" }); - } finally { - session.cancel(); - await session.whenSettled(); - } - expect(guardedFetch).toHaveBeenCalledOnce(); - }, - ); }); diff --git a/test/provider-auth-method.radius.integration.test.ts b/test/provider-auth-method.radius.integration.test.ts new file mode 100644 index 000000000000..b24154ab5560 --- /dev/null +++ b/test/provider-auth-method.radius.integration.test.ts @@ -0,0 +1,61 @@ +import { afterEach, expect, it, vi } from "vitest"; +import radiusPlugin from "../extensions/radius/index.js"; +import { runProviderPluginAuthMethodUnpersisted } from "../src/plugins/provider-auth-method.js"; +import { createNonExitingRuntime } from "../src/runtime.js"; +import { registerSingleProviderPlugin } from "../src/test-utils/plugin-registration.js"; +import { WizardSession } from "../src/wizard/session.js"; + +const { openHostBrowser, guardedFetch } = vi.hoisted(() => ({ + openHostBrowser: vi.fn(async () => true), + guardedFetch: vi.fn(), +})); +vi.mock("../src/infra/browser-open.js", () => ({ openUrl: openHostBrowser })); +vi.mock("openclaw/plugin-sdk/ssrf-runtime", () => ({ fetchWithSsrFGuard: guardedFetch })); + +afterEach(() => vi.clearAllMocks()); + +it.each([false, true])( + "keeps the registered Radius device destination with its code and cancellation (remote=%s)", + async (isRemote) => { + guardedFetch.mockResolvedValueOnce({ + response: Response.json({ + device_code: "synthetic-device-secret", + user_code: "ABCD-EFGH", + verification_uri: "https://radius.earendil.com/device", + expires_in: 300, + interval: 5, + }), + release: async () => undefined, + }); + const provider = await registerSingleProviderPlugin(radiusPlugin); + const method = provider.auth.find((entry) => entry.id === "oauth"); + if (!method) { + throw new Error("Radius did not register its OAuth method"); + } + const session = new WizardSession(async (prompter, signal) => { + await runProviderPluginAuthMethodUnpersisted({ + config: {}, + runtime: createNonExitingRuntime(), + method, + prompter, + signal, + isRemote, + }); + }); + try { + const pending = await session.next(); + expect(pending.step).toMatchObject({ + type: "progress", + externalUrl: "https://radius.earendil.com/device", + deviceCode: { code: "ABCD-EFGH", expiresInMinutes: 5 }, + }); + expect(openHostBrowser).not.toHaveBeenCalled(); + session.cancel(); + expect(await session.next()).toMatchObject({ done: true, status: "cancelled" }); + } finally { + session.cancel(); + await session.whenSettled(); + } + expect(guardedFetch).toHaveBeenCalledOnce(); + }, +); diff --git a/test/vitest/vitest.database-worker-core-paths.mjs b/test/vitest/vitest.database-worker-core-paths.mjs index c7ebdb7fdedc..708eb4d68c12 100644 --- a/test/vitest/vitest.database-worker-core-paths.mjs +++ b/test/vitest/vitest.database-worker-core-paths.mjs @@ -7,6 +7,7 @@ export const databaseWorkerCoreTestFiles = [ "src/system-agent/setup-inference.groq-external.integration.test.ts", "src/system-agent/setup-inference-activate.test.ts", "src/system-agent/setup-inference-detect.lifecycle.test.ts", + "src/wizard/setup.inference-recovery.integration.test.ts", "src/wizard/setup.test.ts", "src/wizard/setup.provenance.integration.test.ts", "src/flows/search-setup.test.ts",