Contracts: stabilize provider plugin test imports
This commit is contained in:
parent
a0e7a2fcc1
commit
6a381e80bc
@ -2,10 +2,13 @@ import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import openAIPlugin from "../../../extensions/openai/index.js";
|
||||
import qwenPortalPlugin from "../../../extensions/qwen-portal-auth/index.js";
|
||||
import { createCapturedPluginRegistration } from "../../test-utils/plugin-registration.js";
|
||||
import { createProviderUsageFetch, makeResponse } from "../../test-utils/provider-usage-fetch.js";
|
||||
import type { OpenClawPluginApi, ProviderPlugin } from "../types.js";
|
||||
import type { ProviderRuntimeModel } from "../types.js";
|
||||
import { requireProviderContractProvider } from "./registry.js";
|
||||
import { registerProviders, requireProvider } from "./testkit.js";
|
||||
import { requireProviderContractProvider as requireBundledProviderContractProvider } from "./registry.js";
|
||||
|
||||
const CONTRACT_SETUP_TIMEOUT_MS = 300_000;
|
||||
|
||||
@ -43,11 +46,38 @@ function createModel(overrides: Partial<ProviderRuntimeModel> & Pick<ProviderRun
|
||||
} satisfies ProviderRuntimeModel;
|
||||
}
|
||||
|
||||
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 requireProviderContractProvider(providerId: string): ProviderPlugin {
|
||||
if (providerId === "openai-codex") {
|
||||
return requireProvider(registerProviders(openAIPlugin), providerId);
|
||||
}
|
||||
if (providerId === "qwen-portal") {
|
||||
return requireProvider(registerProviders(qwenPortalPlugin), providerId);
|
||||
}
|
||||
return requireBundledProviderContractProvider(providerId);
|
||||
}
|
||||
|
||||
describe("provider runtime contract", () => {
|
||||
beforeEach(() => {
|
||||
getOAuthApiKeyMock.mockReset();
|
||||
refreshQwenPortalCredentialsMock.mockReset();
|
||||
}, CONTRACT_SETUP_TIMEOUT_MS);
|
||||
|
||||
describe("anthropic", () => {
|
||||
it("owns anthropic 4.6 forward-compat resolution", () => {
|
||||
const provider = requireProviderContractProvider("anthropic");
|
||||
@ -511,9 +541,7 @@ describe("provider runtime contract", () => {
|
||||
|
||||
describe("openai-codex", () => {
|
||||
it("owns refresh fallback for accountId extraction failures", async () => {
|
||||
vi.resetModules();
|
||||
const openAIPlugin = (await import("../../../extensions/openai/index.js")).default;
|
||||
const provider = requireProvider(registerProviders(openAIPlugin), "openai-codex");
|
||||
const provider = requireProviderContractProvider("openai-codex");
|
||||
const credential = {
|
||||
type: "oauth" as const,
|
||||
provider: "openai-codex",
|
||||
@ -608,9 +636,7 @@ describe("provider runtime contract", () => {
|
||||
|
||||
describe("qwen-portal", () => {
|
||||
it("owns OAuth refresh", async () => {
|
||||
const qwenPortalPlugin = (await import("../../../extensions/qwen-portal-auth/index.js"))
|
||||
.default;
|
||||
const provider = requireProvider(registerProviders(qwenPortalPlugin), "qwen-portal");
|
||||
const provider = requireProviderContractProvider("qwen-portal");
|
||||
const credential = {
|
||||
type: "oauth" as const,
|
||||
provider: "qwen-portal",
|
||||
|
||||
@ -1,7 +1,13 @@
|
||||
import { describe } from "vitest";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { webSearchProviderContractRegistry } from "./registry.js";
|
||||
import { installWebSearchProviderContractSuite } from "./suites.js";
|
||||
|
||||
describe("web search provider contract registry load", () => {
|
||||
it("loads bundled web search providers", () => {
|
||||
expect(webSearchProviderContractRegistry.length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
for (const entry of webSearchProviderContractRegistry) {
|
||||
describe(`${entry.pluginId}:${entry.provider.id} web search contract`, () => {
|
||||
installWebSearchProviderContractSuite({
|
||||
|
||||
@ -1,23 +1,19 @@
|
||||
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import {
|
||||
buildProviderPluginMethodChoice,
|
||||
resolveProviderModelPickerEntries,
|
||||
resolveProviderPluginChoice,
|
||||
resolveProviderWizardOptions,
|
||||
} from "../provider-wizard.js";
|
||||
import type { ProviderPlugin } from "../types.js";
|
||||
import { providerContractPluginIds, uniqueProviderContractProviders } from "./registry.js";
|
||||
|
||||
const CONTRACT_SETUP_TIMEOUT_MS = 300_000;
|
||||
type ResolvePluginProviders = typeof import("../providers.js").resolvePluginProviders;
|
||||
|
||||
const resolvePluginProvidersMock = vi.hoisted(() => vi.fn<ResolvePluginProviders>(() => []));
|
||||
const resolvePluginProvidersMock = vi.fn();
|
||||
|
||||
vi.mock("../providers.js", () => ({
|
||||
resolvePluginProviders: (params?: { onlyPluginIds?: string[] }) =>
|
||||
resolvePluginProvidersMock(params as never),
|
||||
resolvePluginProviders: (...args: unknown[]) => resolvePluginProvidersMock(...args),
|
||||
}));
|
||||
|
||||
let buildProviderPluginMethodChoice: typeof import("../provider-wizard.js").buildProviderPluginMethodChoice;
|
||||
let resolveProviderModelPickerEntries: typeof import("../provider-wizard.js").resolveProviderModelPickerEntries;
|
||||
let resolveProviderPluginChoice: typeof import("../provider-wizard.js").resolveProviderPluginChoice;
|
||||
let resolveProviderWizardOptions: typeof import("../provider-wizard.js").resolveProviderWizardOptions;
|
||||
let providerContractPluginIds: typeof import("./registry.js").providerContractPluginIds;
|
||||
let uniqueProviderContractProviders: typeof import("./registry.js").uniqueProviderContractProviders;
|
||||
|
||||
function resolveExpectedWizardChoiceValues(providers: ProviderPlugin[]) {
|
||||
const values: string[] = [];
|
||||
|
||||
@ -75,25 +71,8 @@ function resolveExpectedModelPickerValues(providers: ProviderPlugin[]) {
|
||||
}
|
||||
|
||||
describe("provider wizard contract", () => {
|
||||
beforeAll(async () => {
|
||||
const actualProviders =
|
||||
await vi.importActual<typeof import("../providers.js")>("../providers.js");
|
||||
resolvePluginProvidersMock.mockImplementation((params?: { onlyPluginIds?: string[] }) =>
|
||||
actualProviders.resolvePluginProviders(params as never),
|
||||
);
|
||||
({ providerContractPluginIds, uniqueProviderContractProviders } =
|
||||
await import("./registry.js"));
|
||||
resolvePluginProvidersMock.mockReturnValue(uniqueProviderContractProviders);
|
||||
({
|
||||
buildProviderPluginMethodChoice,
|
||||
resolveProviderModelPickerEntries,
|
||||
resolveProviderPluginChoice,
|
||||
resolveProviderWizardOptions,
|
||||
} = await import("../provider-wizard.js"));
|
||||
}, CONTRACT_SETUP_TIMEOUT_MS);
|
||||
|
||||
beforeEach(() => {
|
||||
resolvePluginProvidersMock.mockClear();
|
||||
resolvePluginProvidersMock.mockReset();
|
||||
resolvePluginProvidersMock.mockReturnValue(uniqueProviderContractProviders);
|
||||
});
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user