Files
openclaw/extensions/openai/test-support/provider-catalog.contract-test-support.ts
2026-04-06 18:04:18 +01:00

124 lines
4.7 KiB
TypeScript

import { beforeEach, describe, it, vi } from "vitest";
import {
expectAugmentedCodexCatalog,
expectCodexBuiltInSuppression,
expectCodexMissingAuthHint,
importProviderRuntimeCatalogModule,
loadBundledPluginPublicSurfaceSync,
} from "../../../test/helpers/plugins/provider-catalog.js";
import type { ProviderPlugin } from "../../../test/helpers/plugins/provider-catalog.js";
import {
registerProviderPlugin,
requireRegisteredProvider,
} from "../../../test/helpers/plugins/provider-registration.js";
const PROVIDER_CATALOG_CONTRACT_TIMEOUT_MS = 300_000;
type ResolvePluginProviders = (params?: { onlyPluginIds?: string[] }) => ProviderPlugin[];
type ResolveOwningPluginIdsForProvider = (params: { provider: string }) => string[] | undefined;
type ResolveCatalogHookProviderPluginIds = (params: unknown) => string[];
const resolvePluginProvidersMock = vi.hoisted(() => vi.fn<ResolvePluginProviders>(() => []));
const resolveOwningPluginIdsForProviderMock = vi.hoisted(() =>
vi.fn<ResolveOwningPluginIdsForProvider>(() => undefined),
);
const resolveCatalogHookProviderPluginIdsMock = vi.hoisted(() =>
vi.fn<ResolveCatalogHookProviderPluginIds>((_) => [] as string[]),
);
vi.mock("../../../src/plugins/providers.js", () => ({
resolveOwningPluginIdsForProvider: (params: unknown) =>
resolveOwningPluginIdsForProviderMock(params as never),
resolveCatalogHookProviderPluginIds: (params: unknown) =>
resolveCatalogHookProviderPluginIdsMock(params as never),
}));
vi.mock("../../../src/plugins/providers.runtime.js", () => ({
isPluginProvidersLoadInFlight: () => false,
resolvePluginProviders: (params: unknown) => resolvePluginProvidersMock(params as never),
}));
export function describeOpenAIProviderCatalogContract() {
const contractDepsPromise = (async () => {
vi.resetModules();
const openaiPlugin = loadBundledPluginPublicSurfaceSync<{
default: Parameters<typeof registerProviderPlugin>[0]["plugin"];
}>({
pluginId: "openai",
artifactBasename: "index.js",
});
const openaiProviders = (
await registerProviderPlugin({
plugin: openaiPlugin.default,
id: "openai",
name: "OpenAI",
})
).providers;
const openaiProvider = requireRegisteredProvider(openaiProviders, "openai", "provider");
const {
augmentModelCatalogWithProviderPlugins,
resetProviderRuntimeHookCacheForTest,
resolveProviderBuiltInModelSuppression,
} = await importProviderRuntimeCatalogModule();
return {
augmentModelCatalogWithProviderPlugins,
resetProviderRuntimeHookCacheForTest,
resolveProviderBuiltInModelSuppression,
openaiProviders,
openaiProvider,
};
})();
describe(
"openai provider catalog contract",
{ timeout: PROVIDER_CATALOG_CONTRACT_TIMEOUT_MS },
() => {
beforeEach(async () => {
const { resetProviderRuntimeHookCacheForTest, openaiProviders } = await contractDepsPromise;
resetProviderRuntimeHookCacheForTest();
resolvePluginProvidersMock.mockReset();
resolvePluginProvidersMock.mockImplementation((params?: { onlyPluginIds?: string[] }) => {
const onlyPluginIds = params?.onlyPluginIds;
if (!onlyPluginIds || onlyPluginIds.length === 0) {
return openaiProviders;
}
return onlyPluginIds.includes("openai") ? openaiProviders : [];
});
resolveOwningPluginIdsForProviderMock.mockReset();
resolveOwningPluginIdsForProviderMock.mockImplementation((params) => {
switch (params.provider) {
case "azure-openai-responses":
case "openai":
case "openai-codex":
return ["openai"];
default:
return undefined;
}
});
resolveCatalogHookProviderPluginIdsMock.mockReset();
resolveCatalogHookProviderPluginIdsMock.mockReturnValue(["openai"]);
});
it("keeps codex-only missing-auth hints wired through the provider runtime", async () => {
const { openaiProvider } = await contractDepsPromise;
expectCodexMissingAuthHint(
(params) => openaiProvider.buildMissingAuthMessage?.(params.context) ?? undefined,
);
});
it("keeps built-in model suppression wired through the provider runtime", async () => {
const { resolveProviderBuiltInModelSuppression } = await contractDepsPromise;
expectCodexBuiltInSuppression(resolveProviderBuiltInModelSuppression);
});
it("keeps bundled model augmentation wired through the provider runtime", async () => {
const { augmentModelCatalogWithProviderPlugins } = await contractDepsPromise;
await expectAugmentedCodexCatalog(augmentModelCatalogWithProviderPlugins);
});
},
);
}