test: dedupe plugin contract helper assertions

This commit is contained in:
Peter Steinberger
2026-04-18 21:08:59 +01:00
parent 1d7d268a63
commit 3a3ab31d2b
2 changed files with 65 additions and 62 deletions

View File

@@ -40,40 +40,33 @@ function mergeDeep<T>(base: T, overrides: DeepPartial<T>): 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> = {}): 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",

View File

@@ -8,10 +8,48 @@ import type {
type Lazy<T> = T | (() => T);
type WebProviderCredentialContract = Pick<
WebSearchProviderPlugin,
| "createTool"
| "docsUrl"
| "envVars"
| "getCredentialValue"
| "hint"
| "id"
| "label"
| "placeholder"
| "setCredentialValue"
| "signupUrl"
>;
function resolveLazy<T>(value: Lazy<T>): 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<string, unknown> = {};
provider.setCredentialValue(configTarget, credentialValue);
expect(provider.getCredentialValue(configTarget)).toEqual(credentialValue);
expect(typeof provider.createTool).toBe("function");
return configTarget;
}
export function installProviderPluginContractSuite(params: { provider: Lazy<ProviderPlugin> }) {
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<string, unknown> = {};
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");
});
}