mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-29 01:52:04 +00:00
Tests: dedupe contract helper plumbing (#48760)
* Plugins: share contract test helpers * Channels: collapse inbound contract testkit
This commit is contained in:
@@ -6,13 +6,12 @@ import {
|
||||
readAuthProfilesForAgent,
|
||||
requireOpenClawAgentDir,
|
||||
setupAuthTestEnv,
|
||||
} from "../../../test/helpers/auth-wizard.js";
|
||||
} from "../../commands/test-wizard-helpers.js";
|
||||
import { clearRuntimeAuthProfileStoreSnapshots } from "../../agents/auth-profiles/store.js";
|
||||
import { applyAuthChoiceLoadedPluginProvider } from "../../plugins/provider-auth-choice.js";
|
||||
import { createCapturedPluginRegistration } from "../../test-utils/plugin-registration.js";
|
||||
import { buildProviderPluginMethodChoice } from "../provider-wizard.js";
|
||||
import type { OpenClawPluginApi, ProviderPlugin } from "../types.js";
|
||||
import { requireProviderContractProvider, uniqueProviderContractProviders } from "./registry.js";
|
||||
import { registerProviders, requireProvider } from "./testkit.js";
|
||||
|
||||
type ResolvePluginProviders =
|
||||
typeof import("../../plugins/provider-auth-choice.runtime.js").resolvePluginProviders;
|
||||
@@ -67,22 +66,6 @@ type StoredAuthProfile = {
|
||||
|
||||
const qwenPortalPlugin = (await import("../../../extensions/qwen-portal-auth/index.js")).default;
|
||||
|
||||
function registerProviders(...plugins: Array<{ register(api: OpenClawPluginApi): void }>) {
|
||||
const captured = createCapturedPluginRegistration();
|
||||
for (const plugin of plugins) {
|
||||
plugin.register(captured.api);
|
||||
}
|
||||
return captured.providers;
|
||||
}
|
||||
|
||||
function requireProvider(providers: ProviderPlugin[], providerId: string) {
|
||||
const provider = providers.find((entry) => entry.id === providerId);
|
||||
if (!provider) {
|
||||
throw new Error(`provider ${providerId} missing`);
|
||||
}
|
||||
return provider;
|
||||
}
|
||||
|
||||
describe("provider auth-choice contract", () => {
|
||||
const lifecycle = createAuthTestLifecycle([
|
||||
"OPENCLAW_STATE_DIR",
|
||||
|
||||
@@ -4,14 +4,13 @@ import {
|
||||
replaceRuntimeAuthProfileStoreSnapshots,
|
||||
} from "../../agents/auth-profiles/store.js";
|
||||
import { createNonExitingRuntime } from "../../runtime.js";
|
||||
import { createCapturedPluginRegistration } from "../../test-utils/plugin-registration.js";
|
||||
import type {
|
||||
WizardMultiSelectParams,
|
||||
WizardPrompter,
|
||||
WizardProgress,
|
||||
WizardSelectParams,
|
||||
} from "../../wizard/prompts.js";
|
||||
import type { OpenClawPluginApi, ProviderPlugin } from "../types.js";
|
||||
import { registerProviders, requireProvider } from "./testkit.js";
|
||||
|
||||
type LoginOpenAICodexOAuth =
|
||||
(typeof import("../../plugins/provider-openai-codex-oauth.js"))["loginOpenAICodexOAuth"];
|
||||
@@ -78,22 +77,6 @@ function buildAuthContext() {
|
||||
};
|
||||
}
|
||||
|
||||
function registerProviders(...plugins: Array<{ register(api: OpenClawPluginApi): void }>) {
|
||||
const captured = createCapturedPluginRegistration();
|
||||
for (const plugin of plugins) {
|
||||
plugin.register(captured.api);
|
||||
}
|
||||
return captured.providers;
|
||||
}
|
||||
|
||||
function requireProvider(providers: ProviderPlugin[], providerId: string) {
|
||||
const provider = providers.find((entry) => entry.id === providerId);
|
||||
if (!provider) {
|
||||
throw new Error(`provider ${providerId} missing`);
|
||||
}
|
||||
return provider;
|
||||
}
|
||||
|
||||
describe("provider auth contract", () => {
|
||||
afterEach(() => {
|
||||
loginOpenAICodexOAuthMock.mockReset();
|
||||
|
||||
@@ -5,9 +5,8 @@ import {
|
||||
} from "../../agents/auth-profiles/store.js";
|
||||
import { QWEN_OAUTH_MARKER } from "../../agents/model-auth-markers.js";
|
||||
import type { ModelDefinitionConfig } from "../../config/types.models.js";
|
||||
import { createCapturedPluginRegistration } from "../../test-utils/plugin-registration.js";
|
||||
import { runProviderCatalog } from "../provider-discovery.js";
|
||||
import type { OpenClawPluginApi, ProviderPlugin } from "../types.js";
|
||||
import { registerProviders, requireProvider } from "./testkit.js";
|
||||
|
||||
const resolveCopilotApiTokenMock = vi.hoisted(() => vi.fn());
|
||||
const buildOllamaProviderMock = vi.hoisted(() => vi.fn());
|
||||
@@ -60,22 +59,6 @@ const cloudflareAiGatewayPlugin = (
|
||||
await import("../../../extensions/cloudflare-ai-gateway/index.js")
|
||||
).default;
|
||||
|
||||
function registerProviders(...plugins: Array<{ register(api: OpenClawPluginApi): void }>) {
|
||||
const captured = createCapturedPluginRegistration();
|
||||
for (const plugin of plugins) {
|
||||
plugin.register(captured.api);
|
||||
}
|
||||
return captured.providers;
|
||||
}
|
||||
|
||||
function requireProvider(providers: ProviderPlugin[], providerId: string) {
|
||||
const provider = providers.find((entry) => entry.id === providerId);
|
||||
if (!provider) {
|
||||
throw new Error(`provider ${providerId} missing`);
|
||||
}
|
||||
return provider;
|
||||
}
|
||||
|
||||
function createModelConfig(id: string, name = id): ModelDefinitionConfig {
|
||||
return {
|
||||
id,
|
||||
|
||||
@@ -2,15 +2,8 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { withBundledPluginAllowlistCompat } from "../bundled-compat.js";
|
||||
import { __testing as providerTesting } from "../providers.js";
|
||||
import { resolvePluginWebSearchProviders } from "../web-search-providers.js";
|
||||
import { providerContractPluginIds, webSearchProviderContractRegistry } from "./registry.js";
|
||||
|
||||
function uniqueSortedPluginIds(values: string[]) {
|
||||
return [...new Set(values)].toSorted((left, right) => left.localeCompare(right));
|
||||
}
|
||||
|
||||
function normalizeProviderContractPluginId(pluginId: string) {
|
||||
return pluginId === "kimi-coding" ? "kimi" : pluginId;
|
||||
}
|
||||
import { providerContractCompatPluginIds, webSearchProviderContractRegistry } from "./registry.js";
|
||||
import { uniqueSortedStrings } from "./testkit.js";
|
||||
|
||||
describe("plugin loader contract", () => {
|
||||
beforeEach(() => {
|
||||
@@ -18,9 +11,7 @@ describe("plugin loader contract", () => {
|
||||
});
|
||||
|
||||
it("keeps bundled provider compatibility wired to the provider registry", () => {
|
||||
const providerPluginIds = uniqueSortedPluginIds(
|
||||
providerContractPluginIds.map(normalizeProviderContractPluginId),
|
||||
);
|
||||
const providerPluginIds = uniqueSortedStrings(providerContractCompatPluginIds);
|
||||
const compatPluginIds = providerTesting.resolveBundledProviderCompatPluginIds({
|
||||
config: {
|
||||
plugins: {
|
||||
@@ -38,16 +29,12 @@ describe("plugin loader contract", () => {
|
||||
pluginIds: compatPluginIds,
|
||||
});
|
||||
|
||||
expect(uniqueSortedPluginIds(compatPluginIds)).toEqual(
|
||||
expect.arrayContaining(providerPluginIds),
|
||||
);
|
||||
expect(uniqueSortedStrings(compatPluginIds)).toEqual(expect.arrayContaining(providerPluginIds));
|
||||
expect(compatConfig?.plugins?.allow).toEqual(expect.arrayContaining(providerPluginIds));
|
||||
});
|
||||
|
||||
it("keeps vitest bundled provider enablement wired to the provider registry", () => {
|
||||
const providerPluginIds = uniqueSortedPluginIds(
|
||||
providerContractPluginIds.map(normalizeProviderContractPluginId),
|
||||
);
|
||||
const providerPluginIds = uniqueSortedStrings(providerContractCompatPluginIds);
|
||||
const compatConfig = providerTesting.withBundledProviderVitestCompat({
|
||||
config: undefined,
|
||||
pluginIds: providerPluginIds,
|
||||
@@ -61,19 +48,19 @@ describe("plugin loader contract", () => {
|
||||
});
|
||||
|
||||
it("keeps bundled web search loading scoped to the web search registry", () => {
|
||||
const webSearchPluginIds = uniqueSortedPluginIds(
|
||||
const webSearchPluginIds = uniqueSortedStrings(
|
||||
webSearchProviderContractRegistry.map((entry) => entry.pluginId),
|
||||
);
|
||||
|
||||
const providers = resolvePluginWebSearchProviders({});
|
||||
|
||||
expect(uniqueSortedPluginIds(providers.map((provider) => provider.pluginId))).toEqual(
|
||||
expect(uniqueSortedStrings(providers.map((provider) => provider.pluginId))).toEqual(
|
||||
webSearchPluginIds,
|
||||
);
|
||||
});
|
||||
|
||||
it("keeps bundled web search allowlist compatibility wired to the web search registry", () => {
|
||||
const webSearchPluginIds = uniqueSortedPluginIds(
|
||||
const webSearchPluginIds = uniqueSortedStrings(
|
||||
webSearchProviderContractRegistry.map((entry) => entry.pluginId),
|
||||
);
|
||||
|
||||
@@ -86,7 +73,7 @@ describe("plugin loader contract", () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(uniqueSortedPluginIds(providers.map((provider) => provider.pluginId))).toEqual(
|
||||
expect(uniqueSortedStrings(providers.map((provider) => provider.pluginId))).toEqual(
|
||||
webSearchPluginIds,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -160,6 +160,10 @@ export const providerContractPluginIds = [
|
||||
...new Set(providerContractRegistry.map((entry) => entry.pluginId)),
|
||||
].toSorted((left, right) => left.localeCompare(right));
|
||||
|
||||
export const providerContractCompatPluginIds = providerContractPluginIds.map((pluginId) =>
|
||||
pluginId === "kimi-coding" ? "kimi" : pluginId,
|
||||
);
|
||||
|
||||
export function requireProviderContractProvider(providerId: string): ProviderPlugin {
|
||||
const provider = uniqueProviderContractProviders.find((entry) => entry.id === providerId);
|
||||
if (!provider) {
|
||||
|
||||
26
src/plugins/contracts/testkit.ts
Normal file
26
src/plugins/contracts/testkit.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { createCapturedPluginRegistration } from "../../test-utils/plugin-registration.js";
|
||||
import type { OpenClawPluginApi, ProviderPlugin } from "../types.js";
|
||||
|
||||
type RegistrablePlugin = {
|
||||
register(api: OpenClawPluginApi): void;
|
||||
};
|
||||
|
||||
export function registerProviders(...plugins: RegistrablePlugin[]) {
|
||||
const captured = createCapturedPluginRegistration();
|
||||
for (const plugin of plugins) {
|
||||
plugin.register(captured.api);
|
||||
}
|
||||
return captured.providers;
|
||||
}
|
||||
|
||||
export function requireProvider(providers: ProviderPlugin[], providerId: string) {
|
||||
const provider = providers.find((entry) => entry.id === providerId);
|
||||
if (!provider) {
|
||||
throw new Error(`provider ${providerId} missing`);
|
||||
}
|
||||
return provider;
|
||||
}
|
||||
|
||||
export function uniqueSortedStrings(values: readonly string[]) {
|
||||
return [...new Set(values)].toSorted((left, right) => left.localeCompare(right));
|
||||
}
|
||||
Reference in New Issue
Block a user