mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-14 10:41:23 +00:00
test: keep provider auth onboarding tests off runtime auth
This commit is contained in:
159
src/plugins/provider-self-hosted-setup.test.ts
Normal file
159
src/plugins/provider-self-hosted-setup.test.ts
Normal file
@@ -0,0 +1,159 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { configureOpenAICompatibleSelfHostedProviderNonInteractive } from "./provider-self-hosted-setup.js";
|
||||
import type { ProviderAuthMethodNonInteractiveContext } from "./types.js";
|
||||
|
||||
const upsertAuthProfileWithLock = vi.hoisted(() => vi.fn(async () => null));
|
||||
vi.mock("../agents/auth-profiles/upsert-with-lock.js", () => ({
|
||||
upsertAuthProfileWithLock,
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
function createRuntime() {
|
||||
return {
|
||||
error: vi.fn(),
|
||||
exit: vi.fn(),
|
||||
log: vi.fn(),
|
||||
};
|
||||
}
|
||||
|
||||
function createContext(params: {
|
||||
providerId: string;
|
||||
baseUrl?: string;
|
||||
apiKey?: string;
|
||||
modelId?: string;
|
||||
}): ProviderAuthMethodNonInteractiveContext {
|
||||
const resolved = {
|
||||
key: params.apiKey ?? "self-hosted-test-key",
|
||||
source: "flag" as const,
|
||||
};
|
||||
return {
|
||||
authChoice: params.providerId,
|
||||
config: { agents: { defaults: {} } },
|
||||
baseConfig: { agents: { defaults: {} } },
|
||||
opts: {
|
||||
customBaseUrl: params.baseUrl,
|
||||
customApiKey: params.apiKey,
|
||||
customModelId: params.modelId,
|
||||
},
|
||||
runtime: createRuntime() as never,
|
||||
agentDir: "/tmp/openclaw-self-hosted-test-agent",
|
||||
resolveApiKey: vi.fn<ProviderAuthMethodNonInteractiveContext["resolveApiKey"]>(
|
||||
async () => resolved,
|
||||
),
|
||||
toApiKeyCredential: vi.fn<ProviderAuthMethodNonInteractiveContext["toApiKeyCredential"]>(
|
||||
({ provider, resolved: apiKeyResult }) => ({
|
||||
type: "api_key",
|
||||
provider,
|
||||
key: apiKeyResult.key,
|
||||
}),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
function readPrimaryModel(config: Awaited<ReturnType<typeof configureSelfHostedTestProvider>>) {
|
||||
const model = config?.agents?.defaults?.model;
|
||||
return model && typeof model === "object" ? model.primary : undefined;
|
||||
}
|
||||
|
||||
async function configureSelfHostedTestProvider(params: {
|
||||
ctx: ProviderAuthMethodNonInteractiveContext;
|
||||
providerId: string;
|
||||
providerLabel: string;
|
||||
envVar: string;
|
||||
}) {
|
||||
return await configureOpenAICompatibleSelfHostedProviderNonInteractive({
|
||||
ctx: params.ctx,
|
||||
providerId: params.providerId,
|
||||
providerLabel: params.providerLabel,
|
||||
defaultBaseUrl: "http://127.0.0.1:8000/v1",
|
||||
defaultApiKeyEnvVar: params.envVar,
|
||||
modelPlaceholder: "Qwen/Qwen3-32B",
|
||||
});
|
||||
}
|
||||
|
||||
describe("configureOpenAICompatibleSelfHostedProviderNonInteractive", () => {
|
||||
it.each([
|
||||
{
|
||||
providerId: "vllm",
|
||||
providerLabel: "vLLM",
|
||||
envVar: "VLLM_API_KEY",
|
||||
baseUrl: "http://127.0.0.1:8100/v1/",
|
||||
apiKey: "vllm-test-key",
|
||||
modelId: "Qwen/Qwen3-8B",
|
||||
},
|
||||
{
|
||||
providerId: "sglang",
|
||||
providerLabel: "SGLang",
|
||||
envVar: "SGLANG_API_KEY",
|
||||
baseUrl: "http://127.0.0.1:31000/v1",
|
||||
apiKey: "sglang-test-key",
|
||||
modelId: "Qwen/Qwen3-32B",
|
||||
},
|
||||
])("configures $providerLabel config and auth profile", async (params) => {
|
||||
const ctx = createContext(params);
|
||||
|
||||
const cfg = await configureSelfHostedTestProvider({
|
||||
ctx,
|
||||
providerId: params.providerId,
|
||||
providerLabel: params.providerLabel,
|
||||
envVar: params.envVar,
|
||||
});
|
||||
|
||||
const profileId = `${params.providerId}:default`;
|
||||
expect(cfg?.auth?.profiles?.[profileId]).toEqual({
|
||||
provider: params.providerId,
|
||||
mode: "api_key",
|
||||
});
|
||||
expect(cfg?.models?.providers?.[params.providerId]).toEqual({
|
||||
baseUrl: params.baseUrl.replace(/\/+$/, ""),
|
||||
api: "openai-completions",
|
||||
apiKey: params.envVar,
|
||||
models: [
|
||||
expect.objectContaining({
|
||||
id: params.modelId,
|
||||
}),
|
||||
],
|
||||
});
|
||||
expect(readPrimaryModel(cfg)).toBe(`${params.providerId}/${params.modelId}`);
|
||||
expect(ctx.resolveApiKey).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
flagName: "--custom-api-key",
|
||||
envVar: params.envVar,
|
||||
}),
|
||||
);
|
||||
expect(upsertAuthProfileWithLock).toHaveBeenCalledWith({
|
||||
profileId,
|
||||
agentDir: ctx.agentDir,
|
||||
credential: {
|
||||
type: "api_key",
|
||||
provider: params.providerId,
|
||||
key: params.apiKey,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("exits without touching auth when custom model id is missing", async () => {
|
||||
const ctx = createContext({
|
||||
providerId: "vllm",
|
||||
apiKey: "vllm-test-key",
|
||||
});
|
||||
|
||||
const cfg = await configureSelfHostedTestProvider({
|
||||
ctx,
|
||||
providerId: "vllm",
|
||||
providerLabel: "vLLM",
|
||||
envVar: "VLLM_API_KEY",
|
||||
});
|
||||
|
||||
expect(cfg).toBeNull();
|
||||
expect(ctx.runtime.error).toHaveBeenCalledWith(
|
||||
expect.stringContaining("Missing --custom-model-id for --auth-choice vllm."),
|
||||
);
|
||||
expect(ctx.runtime.exit).toHaveBeenCalledWith(1);
|
||||
expect(ctx.resolveApiKey).not.toHaveBeenCalled();
|
||||
expect(upsertAuthProfileWithLock).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user