From 3a3ab31d2b037929dc9bb7d1e2df8a294f3b438e Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 18 Apr 2026 21:08:59 +0100 Subject: [PATCH] test: dedupe plugin contract helper assertions --- test/helpers/plugins/plugin-runtime-mock.ts | 57 +++++++-------- .../plugins/provider-contract-suites.ts | 70 +++++++++++-------- 2 files changed, 65 insertions(+), 62 deletions(-) diff --git a/test/helpers/plugins/plugin-runtime-mock.ts b/test/helpers/plugins/plugin-runtime-mock.ts index 67b9b297b44..cbe276154bd 100644 --- a/test/helpers/plugins/plugin-runtime-mock.ts +++ b/test/helpers/plugins/plugin-runtime-mock.ts @@ -40,40 +40,33 @@ function mergeDeep(base: T, overrides: DeepPartial): T { return result as T; } +function createTaskFlowSessionMock() { + return { + sessionKey: "agent:main:main", + createManaged: vi.fn(), + get: vi.fn(), + list: vi.fn(() => []), + findLatest: vi.fn(), + resolve: vi.fn(), + getTaskSummary: vi.fn(), + setWaiting: vi.fn(), + resume: vi.fn(), + finish: vi.fn(), + fail: vi.fn(), + requestCancel: vi.fn(), + cancel: vi.fn(), + runTask: vi.fn(), + }; +} + export function createPluginRuntimeMock(overrides: DeepPartial = {}): PluginRuntime { const taskFlow = { - bindSession: vi.fn(() => ({ - sessionKey: "agent:main:main", - createManaged: vi.fn(), - get: vi.fn(), - list: vi.fn(() => []), - findLatest: vi.fn(), - resolve: vi.fn(), - getTaskSummary: vi.fn(), - setWaiting: vi.fn(), - resume: vi.fn(), - finish: vi.fn(), - fail: vi.fn(), - requestCancel: vi.fn(), - cancel: vi.fn(), - runTask: vi.fn(), - })) as unknown as PluginRuntime["taskFlow"]["bindSession"], - fromToolContext: vi.fn(() => ({ - sessionKey: "agent:main:main", - createManaged: vi.fn(), - get: vi.fn(), - list: vi.fn(() => []), - findLatest: vi.fn(), - resolve: vi.fn(), - getTaskSummary: vi.fn(), - setWaiting: vi.fn(), - resume: vi.fn(), - finish: vi.fn(), - fail: vi.fn(), - requestCancel: vi.fn(), - cancel: vi.fn(), - runTask: vi.fn(), - })) as unknown as PluginRuntime["taskFlow"]["fromToolContext"], + bindSession: vi.fn( + createTaskFlowSessionMock, + ) as unknown as PluginRuntime["taskFlow"]["bindSession"], + fromToolContext: vi.fn( + createTaskFlowSessionMock, + ) as unknown as PluginRuntime["taskFlow"]["fromToolContext"], }; const base: PluginRuntime = { version: "1.0.0-test", diff --git a/test/helpers/plugins/provider-contract-suites.ts b/test/helpers/plugins/provider-contract-suites.ts index d000f6c98dd..183c082e584 100644 --- a/test/helpers/plugins/provider-contract-suites.ts +++ b/test/helpers/plugins/provider-contract-suites.ts @@ -8,10 +8,48 @@ import type { type Lazy = T | (() => T); +type WebProviderCredentialContract = Pick< + WebSearchProviderPlugin, + | "createTool" + | "docsUrl" + | "envVars" + | "getCredentialValue" + | "hint" + | "id" + | "label" + | "placeholder" + | "setCredentialValue" + | "signupUrl" +>; + function resolveLazy(value: Lazy): T { return typeof value === "function" ? (value as () => T)() : value; } +function expectWebProviderCredentialContract( + provider: WebProviderCredentialContract, + credentialValue: unknown, +) { + expect(provider.id).toMatch(/^[a-z0-9][a-z0-9-]*$/); + expect(provider.label.trim()).not.toBe(""); + expect(provider.hint.trim()).not.toBe(""); + expect(provider.placeholder.trim()).not.toBe(""); + expect(provider.signupUrl.startsWith("https://")).toBe(true); + if (provider.docsUrl) { + expect(provider.docsUrl.startsWith("http")).toBe(true); + } + + expect(provider.envVars).toEqual([...new Set(provider.envVars)]); + expect(provider.envVars.every((entry) => entry.trim().length > 0)).toBe(true); + + const configTarget: Record = {}; + provider.setCredentialValue(configTarget, credentialValue); + expect(provider.getCredentialValue(configTarget)).toEqual(credentialValue); + + expect(typeof provider.createTool).toBe("function"); + return configTarget; +} + export function installProviderPluginContractSuite(params: { provider: Lazy }) { it("satisfies the base provider plugin contract", () => { const provider = resolveLazy(params.provider); @@ -99,23 +137,7 @@ export function installWebSearchProviderContractSuite(params: { const provider = resolveLazy(params.provider); const credentialValue = resolveLazy(params.credentialValue); - expect(provider.id).toMatch(/^[a-z0-9][a-z0-9-]*$/); - expect(provider.label.trim()).not.toBe(""); - expect(provider.hint.trim()).not.toBe(""); - expect(provider.placeholder.trim()).not.toBe(""); - expect(provider.signupUrl.startsWith("https://")).toBe(true); - if (provider.docsUrl) { - expect(provider.docsUrl.startsWith("http")).toBe(true); - } - - expect(provider.envVars).toEqual([...new Set(provider.envVars)]); - expect(provider.envVars.every((entry) => entry.trim().length > 0)).toBe(true); - - const searchConfigTarget: Record = {}; - provider.setCredentialValue(searchConfigTarget, credentialValue); - expect(provider.getCredentialValue(searchConfigTarget)).toEqual(credentialValue); - - expect(typeof provider.createTool).toBe("function"); + const searchConfigTarget = expectWebProviderCredentialContract(provider, credentialValue); expect(provider.getCredentialValue(searchConfigTarget)).toEqual(credentialValue); if (provider.runSetup) { expect(typeof provider.runSetup).toBe("function"); @@ -132,17 +154,7 @@ export function installWebFetchProviderContractSuite(params: { const provider = resolveLazy(params.provider); const credentialValue = resolveLazy(params.credentialValue); - expect(provider.id).toMatch(/^[a-z0-9][a-z0-9-]*$/); - expect(provider.label.trim()).not.toBe(""); - expect(provider.hint.trim()).not.toBe(""); - expect(provider.placeholder.trim()).not.toBe(""); - expect(provider.signupUrl.startsWith("https://")).toBe(true); - if (provider.docsUrl) { - expect(provider.docsUrl.startsWith("http")).toBe(true); - } - - expect(provider.envVars).toEqual([...new Set(provider.envVars)]); - expect(provider.envVars.every((entry) => entry.trim().length > 0)).toBe(true); + expectWebProviderCredentialContract(provider, credentialValue); expect(provider.credentialPath.trim()).not.toBe(""); if (provider.inactiveSecretPaths) { expect(provider.inactiveSecretPaths).toEqual([...new Set(provider.inactiveSecretPaths)]); @@ -163,7 +175,5 @@ export function installWebFetchProviderContractSuite(params: { const applied = provider.applySelectionConfig({} as OpenClawConfig); expect(applied.plugins?.entries?.[params.pluginId]?.enabled).toBe(true); } - - expect(typeof provider.createTool).toBe("function"); }); }