test: speed up provider usage auth tests

This commit is contained in:
Peter Steinberger
2026-04-07 15:25:02 +01:00
parent 8894dab3c4
commit 8b2b52dc94
3 changed files with 101 additions and 8 deletions

View File

@@ -153,6 +153,80 @@ const providerRuntimeMocks = vi.hoisted(() => ({
resolveProviderRuntimePlugin: vi.fn(() => undefined),
resolveProviderStreamFn: vi.fn(() => undefined),
resolveProviderSyntheticAuthWithPlugin: vi.fn(() => undefined),
resolveProviderUsageAuthWithPlugin: vi.fn(async (params) => {
const resolveToken = (options?: {
providerIds?: string[];
envDirect?: Array<string | undefined>;
}) => params.context.resolveApiKeyFromConfigAndStore(options);
const resolveLegacyZaiToken = (): string | null => {
const home = params.context.env?.HOME ?? params.context.env?.USERPROFILE;
if (!home) {
return null;
}
try {
const parsed = JSON.parse(
nodeFs.readFileSync(path.join(home, ".pi", "agent", "auth.json"), "utf8"),
) as {
"z-ai"?: { access?: string };
};
return parsed["z-ai"]?.access ?? null;
} catch {
return null;
}
};
if (params.provider === "zai") {
const token = resolveToken({
providerIds: ["zai", "z-ai"],
envDirect: [params.context.env?.ZAI_API_KEY, params.context.env?.Z_AI_API_KEY],
});
return token
? { token }
: resolveLegacyZaiToken()
? { token: resolveLegacyZaiToken()! }
: null;
}
if (params.provider === "minimax") {
const token = resolveToken({
providerIds: ["minimax"],
envDirect: [
params.context.env?.MINIMAX_CODE_PLAN_KEY,
params.context.env?.MINIMAX_CODING_API_KEY,
params.context.env?.MINIMAX_API_KEY,
],
});
return token ? { token } : null;
}
if (params.provider === "xiaomi") {
const token = resolveToken({
providerIds: ["xiaomi"],
envDirect: [params.context.env?.XIAOMI_API_KEY],
});
return token ? { token } : null;
}
if (params.provider === "google-gemini-cli") {
const resolved = await params.context.resolveOAuthToken({
provider: "google-gemini-cli",
});
if (!resolved?.token) {
return null;
}
try {
const parsed = JSON.parse(resolved.token) as { token?: string };
const token = parsed.token ?? resolved.token;
return resolved.accountId ? { token, accountId: resolved.accountId } : { token };
} catch {
return resolved.accountId
? { token: resolved.token, accountId: resolved.accountId }
: { token: resolved.token };
}
}
return null;
}),
resolveProviderXHighThinking: vi.fn(() => undefined),
runProviderDynamicModel: vi.fn(() => undefined),
wrapProviderStreamFn: vi.fn(() => undefined),

View File

@@ -3,6 +3,17 @@ import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
const resolveProviderUsageAuthWithPluginMock = vi.fn(
async (..._args: unknown[]): Promise<unknown> => null,
);
const ensureAuthProfileStoreMock = vi.fn(() => ({
profiles: {},
}));
vi.mock("../agents/auth-profiles.js", () => ({
dedupeProfileIds: (profileIds: string[]) => [...new Set(profileIds)],
ensureAuthProfileStore: (...args: unknown[]) => ensureAuthProfileStoreMock(...args),
listProfilesForProvider: () => [],
resolveApiKeyForProfile: async () => null,
resolveAuthProfileOrder: () => [],
}));
vi.mock("../plugins/provider-runtime.js", async () => {
const actual = await vi.importActual<typeof import("../plugins/provider-runtime.js")>(
@@ -22,6 +33,7 @@ describe("resolveProviderAuths plugin boundary", () => {
});
beforeEach(() => {
ensureAuthProfileStoreMock.mockClear();
resolveProviderUsageAuthWithPluginMock.mockReset();
resolveProviderUsageAuthWithPluginMock.mockResolvedValue(null);
});
@@ -41,5 +53,6 @@ describe("resolveProviderAuths plugin boundary", () => {
token: "plugin-zai-token",
},
]);
expect(ensureAuthProfileStoreMock).not.toHaveBeenCalled();
});
});

View File

@@ -23,11 +23,18 @@ type AuthStore = ReturnType<typeof ensureAuthProfileStore>;
type UsageAuthState = {
cfg: OpenClawConfig;
store: AuthStore;
env: NodeJS.ProcessEnv;
agentDir?: string;
store?: AuthStore;
};
function resolveUsageAuthStore(state: UsageAuthState): AuthStore {
state.store ??= ensureAuthProfileStore(state.agentDir, {
allowKeychainPrompt: false,
});
return state.store;
}
function resolveProviderApiKeyFromConfigAndStore(params: {
state: UsageAuthState;
providerIds: string[];
@@ -52,8 +59,10 @@ function resolveProviderApiKeyFromConfigAndStore(params: {
params.providerIds.map((providerId) => normalizeProviderId(providerId)).filter(Boolean),
);
const cred = [...normalizedProviderIds]
.flatMap((providerId) => listProfilesForProvider(params.state.store, providerId))
.map((id) => params.state.store.profiles[id])
.flatMap((providerId) =>
listProfilesForProvider(resolveUsageAuthStore(params.state), providerId),
)
.map((id) => resolveUsageAuthStore(params.state).profiles[id])
.find(
(
profile,
@@ -85,7 +94,7 @@ async function resolveOAuthToken(params: {
}): Promise<ProviderAuth | null> {
const order = resolveAuthProfileOrder({
cfg: params.state.cfg,
store: params.state.store,
store: resolveUsageAuthStore(params.state),
provider: params.provider,
});
const deduped = dedupeProfileIds(order);
@@ -100,7 +109,7 @@ async function resolveOAuthToken(params: {
// Reuse the already-resolved config snapshot for token/ref resolution so
// usage snapshots don't trigger a second ambient loadConfig() call.
cfg: params.state.cfg,
store: params.state.store,
store: resolveUsageAuthStore(params.state),
profileId,
agentDir: params.state.agentDir,
});
@@ -205,9 +214,6 @@ export async function resolveProviderAuths(params: {
const state: UsageAuthState = {
cfg: params.config ?? loadConfig(),
store: ensureAuthProfileStore(params.agentDir, {
allowKeychainPrompt: false,
}),
env: params.env ?? process.env,
agentDir: params.agentDir,
};