mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-12 17:51:22 +00:00
test: inject provider auth command fixtures
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { resolveAgentModelPrimaryValue } from "../config/model-input.js";
|
||||
import { __testing as providerAuthChoiceTesting } from "../plugins/provider-auth-choice.js";
|
||||
import type { ProviderAuthContext, ProviderPlugin } from "../plugins/types.js";
|
||||
import type { WizardPrompter } from "../wizard/prompts.js";
|
||||
import { applyAuthChoice } from "./auth-choice.js";
|
||||
import {
|
||||
@@ -27,6 +29,75 @@ describe("applyAuthChoice (moonshot)", () => {
|
||||
const env = await setupAuthTestEnv("openclaw-auth-");
|
||||
lifecycle.setStateDir(env.stateDir);
|
||||
delete process.env.MOONSHOT_API_KEY;
|
||||
providerAuthChoiceTesting.setDepsForTest({
|
||||
loadPluginProviderRuntime: async () =>
|
||||
({
|
||||
resolvePluginProviders: () =>
|
||||
[
|
||||
{
|
||||
id: "moonshot",
|
||||
label: "Moonshot",
|
||||
auth: [
|
||||
{
|
||||
id: "api-key-cn",
|
||||
label: "Moonshot API key (.cn)",
|
||||
kind: "api_key",
|
||||
run: async ({ prompter }: ProviderAuthContext) => {
|
||||
const key = await prompter.text({
|
||||
message: "Enter Moonshot API key (.cn)",
|
||||
});
|
||||
return {
|
||||
profiles: [
|
||||
{
|
||||
profileId: "moonshot:default",
|
||||
credential: {
|
||||
type: "api_key",
|
||||
provider: "moonshot",
|
||||
key,
|
||||
},
|
||||
},
|
||||
],
|
||||
configPatch: {
|
||||
models: {
|
||||
providers: {
|
||||
moonshot: {
|
||||
api: "openai-completions",
|
||||
baseUrl: "https://api.moonshot.cn/v1",
|
||||
models: [
|
||||
{
|
||||
id: "kimi-k2.5",
|
||||
name: "kimi-k2.5",
|
||||
input: ["text", "image"],
|
||||
reasoning: true,
|
||||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
||||
contextWindow: 128_000,
|
||||
maxTokens: 8192,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
defaultModel: "moonshot/kimi-k2.5",
|
||||
};
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
] as ProviderPlugin[],
|
||||
resolveProviderPluginChoice: ({
|
||||
choice,
|
||||
providers,
|
||||
}: {
|
||||
choice: string;
|
||||
providers: ProviderPlugin[];
|
||||
}) =>
|
||||
choice === "moonshot-api-key-cn"
|
||||
? { provider: providers[0], method: providers[0]?.auth[0] }
|
||||
: null,
|
||||
runProviderModelSelectedHook: async () => {},
|
||||
}) as never,
|
||||
});
|
||||
}
|
||||
|
||||
async function readAuthProfiles() {
|
||||
@@ -53,6 +124,7 @@ describe("applyAuthChoice (moonshot)", () => {
|
||||
}
|
||||
|
||||
afterEach(async () => {
|
||||
providerAuthChoiceTesting.resetDepsForTest();
|
||||
await lifecycle.cleanup();
|
||||
});
|
||||
|
||||
|
||||
@@ -1,122 +1,65 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { note } from "../terminal/note.js";
|
||||
import { withEnvAsync } from "../test-utils/env.js";
|
||||
import { runDoctorConfigWithInput } from "./doctor-config-flow.test-utils.js";
|
||||
|
||||
vi.mock("../terminal/note.js", () => ({
|
||||
note: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("./doctor-legacy-config.js", async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import("./doctor-legacy-config.js")>();
|
||||
return {
|
||||
...actual,
|
||||
normalizeCompatibilityConfigValues: (cfg: unknown) => ({
|
||||
config: cfg,
|
||||
changes: [],
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
import { loadAndMaybeMigrateDoctorConfig } from "./doctor-config-flow.js";
|
||||
|
||||
const noteSpy = vi.mocked(note);
|
||||
import { describe, expect, it } from "vitest";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import {
|
||||
collectMissingDefaultAccountBindingWarnings,
|
||||
collectMissingExplicitDefaultAccountWarnings,
|
||||
} from "./doctor/shared/default-account-warnings.js";
|
||||
|
||||
describe("doctor missing default account binding warning", () => {
|
||||
beforeEach(() => {
|
||||
noteSpy.mockClear();
|
||||
});
|
||||
|
||||
it("emits a doctor warning when named accounts have no valid account-scoped bindings", async () => {
|
||||
await withEnvAsync(
|
||||
{
|
||||
TELEGRAM_BOT_TOKEN: undefined,
|
||||
TELEGRAM_BOT_TOKEN_FILE: undefined,
|
||||
},
|
||||
async () => {
|
||||
await runDoctorConfigWithInput({
|
||||
config: {
|
||||
channels: {
|
||||
telegram: {
|
||||
accounts: {
|
||||
alerts: {},
|
||||
work: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
bindings: [{ agentId: "ops", match: { channel: "telegram" } }],
|
||||
it("warns when named accounts have no valid account-scoped bindings", () => {
|
||||
const warnings = collectMissingDefaultAccountBindingWarnings({
|
||||
channels: {
|
||||
telegram: {
|
||||
accounts: {
|
||||
alerts: {},
|
||||
work: {},
|
||||
},
|
||||
run: loadAndMaybeMigrateDoctorConfig,
|
||||
});
|
||||
},
|
||||
},
|
||||
);
|
||||
bindings: [{ agentId: "ops", match: { channel: "telegram" } }],
|
||||
} as OpenClawConfig);
|
||||
|
||||
expect(noteSpy).toHaveBeenCalledWith(
|
||||
expect(warnings).toEqual([
|
||||
expect.stringContaining("channels.telegram: accounts.default is missing"),
|
||||
"Doctor warnings",
|
||||
);
|
||||
]);
|
||||
});
|
||||
|
||||
it("emits a warning when multiple accounts have no explicit default", async () => {
|
||||
await withEnvAsync(
|
||||
{
|
||||
TELEGRAM_BOT_TOKEN: undefined,
|
||||
TELEGRAM_BOT_TOKEN_FILE: undefined,
|
||||
},
|
||||
async () => {
|
||||
await runDoctorConfigWithInput({
|
||||
config: {
|
||||
channels: {
|
||||
telegram: {
|
||||
accounts: {
|
||||
alerts: {},
|
||||
work: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
it("warns when multiple accounts have no explicit default", () => {
|
||||
const warnings = collectMissingExplicitDefaultAccountWarnings({
|
||||
channels: {
|
||||
telegram: {
|
||||
accounts: {
|
||||
alerts: {},
|
||||
work: {},
|
||||
},
|
||||
run: loadAndMaybeMigrateDoctorConfig,
|
||||
});
|
||||
},
|
||||
},
|
||||
);
|
||||
} as OpenClawConfig);
|
||||
|
||||
expect(noteSpy).toHaveBeenCalledWith(
|
||||
expect(warnings).toEqual([
|
||||
expect.stringContaining(
|
||||
"channels.telegram: multiple accounts are configured but no explicit default is set",
|
||||
),
|
||||
"Doctor warnings",
|
||||
);
|
||||
]);
|
||||
});
|
||||
|
||||
it("emits a warning when defaultAccount does not match configured accounts", async () => {
|
||||
await withEnvAsync(
|
||||
{
|
||||
TELEGRAM_BOT_TOKEN: undefined,
|
||||
TELEGRAM_BOT_TOKEN_FILE: undefined,
|
||||
},
|
||||
async () => {
|
||||
await runDoctorConfigWithInput({
|
||||
config: {
|
||||
channels: {
|
||||
telegram: {
|
||||
defaultAccount: "missing",
|
||||
accounts: {
|
||||
alerts: {},
|
||||
work: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
it("warns when defaultAccount does not match configured accounts", () => {
|
||||
const warnings = collectMissingExplicitDefaultAccountWarnings({
|
||||
channels: {
|
||||
telegram: {
|
||||
defaultAccount: "missing",
|
||||
accounts: {
|
||||
alerts: {},
|
||||
work: {},
|
||||
},
|
||||
run: loadAndMaybeMigrateDoctorConfig,
|
||||
});
|
||||
},
|
||||
},
|
||||
);
|
||||
} as OpenClawConfig);
|
||||
|
||||
expect(noteSpy).toHaveBeenCalledWith(
|
||||
expect(warnings).toEqual([
|
||||
expect.stringContaining(
|
||||
'channels.telegram: defaultAccount is set to "missing" but does not match configured accounts',
|
||||
),
|
||||
"Doctor warnings",
|
||||
);
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -78,10 +78,31 @@ function restoreConfiguredPrimaryModel(
|
||||
};
|
||||
}
|
||||
|
||||
type ProviderAuthChoiceRuntime = typeof import("./provider-auth-choice.runtime.js");
|
||||
|
||||
const defaultProviderAuthChoiceDeps = {
|
||||
loadPluginProviderRuntime: async (): Promise<ProviderAuthChoiceRuntime> =>
|
||||
import("./provider-auth-choice.runtime.js"),
|
||||
};
|
||||
|
||||
let providerAuthChoiceDeps = defaultProviderAuthChoiceDeps;
|
||||
|
||||
async function loadPluginProviderRuntime() {
|
||||
return import("./provider-auth-choice.runtime.js");
|
||||
return await providerAuthChoiceDeps.loadPluginProviderRuntime();
|
||||
}
|
||||
|
||||
export const __testing = {
|
||||
resetDepsForTest(): void {
|
||||
providerAuthChoiceDeps = defaultProviderAuthChoiceDeps;
|
||||
},
|
||||
setDepsForTest(deps: Partial<typeof defaultProviderAuthChoiceDeps>): void {
|
||||
providerAuthChoiceDeps = {
|
||||
...defaultProviderAuthChoiceDeps,
|
||||
...deps,
|
||||
};
|
||||
},
|
||||
} as const;
|
||||
|
||||
export async function runProviderPluginAuthMethod(params: {
|
||||
config: OpenClawConfig;
|
||||
env?: NodeJS.ProcessEnv;
|
||||
|
||||
Reference in New Issue
Block a user